diff --git a/platform/darwin/src/MLNVectorTileSource.h b/platform/darwin/src/MLNVectorTileSource.h
index 9d7e2e216..a3c807b49 100644
--- a/platform/darwin/src/MLNVectorTileSource.h
+++ b/platform/darwin/src/MLNVectorTileSource.h
@@ -84,6 +84,30 @@ MLN_EXPORT
- (instancetype)initWithIdentifier:(NSString *)identifier
configurationURL:(NSURL *)configurationURL NS_DESIGNATED_INITIALIZER;
+/**
+ Returns a vector tile source initialized with an identifier and a
+ string-based configuration URL.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the ``MLNStyle/addSource:`` method.
+
+ The string may be a full HTTP or HTTPS URL or a canonical URL. The string should
+ point to a JSON file that conforms to the
+ TileJSON specification.
+
+ This constructor can be used for URLs that cause problems with `NSURL`’s URL
+ parsing behavior. For example, URLs starting with `pmtiles://https://` were
+ not parsed correctly on iOS 17.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param configurationURLString A string to a TileJSON configuration file
+ describing the source’s contents and other metadata.
+ @return An initialized vector tile source.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier
+ configurationURLString:(NSString *)configurationURLString NS_DESIGNATED_INITIALIZER;
+
/**
Returns a vector tile source initialized an identifier, tile URL templates, and
options.
diff --git a/platform/darwin/src/MLNVectorTileSource.mm b/platform/darwin/src/MLNVectorTileSource.mm
index dacb5ae5e..08ad59705 100644
--- a/platform/darwin/src/MLNVectorTileSource.mm
+++ b/platform/darwin/src/MLNVectorTileSource.mm
@@ -28,6 +28,17 @@
return self = [super initWithPendingSource:std::move(source)];
}
+- (instancetype)initWithIdentifier:(NSString *)identifier
+ configurationURLString:(NSString *)configurationURLString
+{
+ auto source = std::make_unique(
+ identifier.UTF8String,
+ configurationURLString.UTF8String
+ );
+
+ return self = [super initWithPendingSource:std::move(source)];
+}
+
- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray *)tileURLTemplates options:(nullable NSDictionary *)options {
mbgl::Tileset tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, options);
auto source = std::make_unique(identifier.UTF8String, tileSet);
diff --git a/platform/ios/app/MBXViewController.mm b/platform/ios/app/MBXViewController.mm
index fd8a80b8b..4cfd8ce39 100644
--- a/platform/ios/app/MBXViewController.mm
+++ b/platform/ios/app/MBXViewController.mm
@@ -108,6 +108,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
#if MLN_DRAWABLE_RENDERER
MBXSettingsRuntimeStylingCustomDrawableLayer,
#endif
+ MBXSettingsRuntimeStylingAddFoursquarePOIsPMTiles
};
typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@@ -460,6 +461,7 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
#if MLN_DRAWABLE_RENDERER
@"Add Custom Drawable Layer",
#endif
+ @"Add FourSquare POIs PMTiles Layer"
]];
break;
case MBXSettingsMiscellaneous:
@@ -687,6 +689,9 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
[self addCustomDrawableLayer];
break;
#endif
+ case MBXSettingsRuntimeStylingAddFoursquarePOIsPMTiles:
+ [self addFoursquarePOIsPMTilesLayer];
+ break;
default:
NSAssert(NO, @"All runtime styling setting rows should be implemented");
break;
@@ -1048,6 +1053,45 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
[self.mapView showAnnotations:annotations animated:YES];
}
+// MARK: - Foursquare PMTiles Implementation
+/*
+ Add the new method that creates the PMTiles vector source and circle layer.
+*/
+- (void)addFoursquarePOIsPMTilesLayer {
+ MLNVectorTileSource *foursquareSource = [[MLNVectorTileSource alloc] initWithIdentifier:@"foursquare-10M" configurationURLString:@"pmtiles://https://oliverwipfli.ch/data/foursquare-os-places-10M-2024-11-20.pmtiles"];
+
+ // Also works
+ // MLNVectorTileSource *foursquareSource =
+ // [[MLNVectorTileSource alloc] initWithIdentifier:@"foursquare-10M"
+ // tileURLTemplates:@[@"pmtiles://https://oliverwipfli.ch/data/foursquare-os-places-10M-2024-11-20.pmtiles"]
+ // options:nil];
+
+ [self.mapView.style addSource:foursquareSource];
+
+ MLNCircleStyleLayer *circleLayer = [[MLNCircleStyleLayer alloc] initWithIdentifier:@"foursquare-10M" source:foursquareSource];
+ circleLayer.sourceLayerIdentifier = @"place";
+ circleLayer.maximumZoomLevel = 11;
+ circleLayer.circleColor = [NSExpression expressionForConstantValue:[UIColor colorWithRed:0.8 green:0.2 blue:0.2 alpha:1.0]];
+ circleLayer.circleOpacity = [NSExpression expressionWithMLNJSONObject:@[
+ @"interpolate",
+ @[@"linear"],
+ @[@"zoom"],
+ @6, @0.5,
+ @11, @0.5,
+ @14, @1.0
+ ]];
+ circleLayer.circleRadius = [NSExpression expressionWithMLNJSONObject:@[
+ @"interpolate",
+ @[@"linear"],
+ @[@"zoom"],
+ @6, @1,
+ @11, @3,
+ @16, @4,
+ @18, @8
+ ]];
+ [self.mapView.style addLayer:circleLayer];
+}
+
- (void)styleBuildingExtrusions
{
MLNSource* source = [self.mapView.style sourceWithIdentifier:@"composite"];