summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/MGLAttributionInfo.mm7
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.h12
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.mm61
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.h15
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.mm61
-rw-r--r--platform/darwin/src/MGLDistanceFormatter.m2
-rw-r--r--platform/darwin/src/MGLFillExtrusionStyleLayer.h364
-rw-r--r--platform/darwin/src/MGLFillExtrusionStyleLayer.mm335
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.h15
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.mm61
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.h18
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.mm (renamed from platform/darwin/src/MGLForegroundStyleLayer.m)10
-rw-r--r--platform/darwin/src/MGLGeometry.mm9
-rw-r--r--platform/darwin/src/MGLGeometry_Private.h6
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.h15
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.mm61
-rw-r--r--platform/darwin/src/MGLMapCamera.mm27
-rw-r--r--platform/darwin/src/MGLMultiPoint.h40
-rw-r--r--platform/darwin/src/MGLMultiPoint.mm6
-rw-r--r--platform/darwin/src/MGLOpenGLStyleLayer.h2
-rw-r--r--platform/darwin/src/MGLOpenGLStyleLayer.mm40
-rw-r--r--platform/darwin/src/MGLPointCollection.mm11
-rw-r--r--platform/darwin/src/MGLRasterSource.h103
-rw-r--r--platform/darwin/src/MGLRasterSource.mm80
-rw-r--r--platform/darwin/src/MGLRasterSource_Private.h9
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.h15
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.mm61
-rw-r--r--platform/darwin/src/MGLShapeSource.mm69
-rw-r--r--platform/darwin/src/MGLShapeSource_Private.h4
-rw-r--r--platform/darwin/src/MGLSource.mm39
-rw-r--r--platform/darwin/src/MGLSource_Private.h29
-rw-r--r--platform/darwin/src/MGLStyle.h206
-rw-r--r--platform/darwin/src/MGLStyle.mm128
-rw-r--r--platform/darwin/src/MGLStyleLayer.h20
-rw-r--r--platform/darwin/src/MGLStyleLayer.h.ejs30
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm44
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm.ejs69
-rw-r--r--platform/darwin/src/MGLStyleLayer_Private.h22
-rw-r--r--platform/darwin/src/MGLStyleValue_Private.h5
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h74
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.mm91
-rw-r--r--platform/darwin/src/MGLTileSource.h129
-rw-r--r--platform/darwin/src/MGLTileSource.mm8
-rw-r--r--platform/darwin/src/MGLTypes.h4
-rw-r--r--platform/darwin/src/MGLVectorSource.h120
-rw-r--r--platform/darwin/src/MGLVectorSource.mm72
-rw-r--r--platform/darwin/src/MGLVectorSource_Private.h9
-rw-r--r--platform/darwin/src/headless_backend_cgl.cpp4
-rw-r--r--platform/darwin/src/headless_backend_eagl.mm6
49 files changed, 1600 insertions, 1028 deletions
diff --git a/platform/darwin/src/MGLAttributionInfo.mm b/platform/darwin/src/MGLAttributionInfo.mm
index fa2ae787a5..7583244491 100644
--- a/platform/darwin/src/MGLAttributionInfo.mm
+++ b/platform/darwin/src/MGLAttributionInfo.mm
@@ -93,7 +93,12 @@
return;
}
- MGLAttributionInfo *info = [[MGLAttributionInfo alloc] initWithTitle:title URL:value];
+ // Remove the link, because it forces the text to be blue on macOS 10.12
+ // and above.
+ NSMutableAttributedString *unlinkedTitle = [title mutableCopy];
+ [unlinkedTitle removeAttribute:NSLinkAttributeName range:unlinkedTitle.mgl_wholeRange];
+
+ MGLAttributionInfo *info = [[MGLAttributionInfo alloc] initWithTitle:unlinkedTitle URL:value];
info.feedbackLink = isFeedbackLink;
[infos addObject:info];
}];
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.h b/platform/darwin/src/MGLBackgroundStyleLayer.h
index cd218d9fb4..659903914c 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.h
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.h
@@ -24,7 +24,17 @@ NS_ASSUME_NONNULL_BEGIN
MGL_EXPORT
@interface MGLBackgroundStyleLayer : MGLStyleLayer
-- (instancetype)initWithIdentifier:(NSString *)identifier NS_DESIGNATED_INITIALIZER;
+/**
+Returns a background style layer initialized with an identifier.
+
+After initializing and configuring the style layer, add it to a map view’s
+style using the `-[MGLStyle addLayer:]` or
+`-[MGLStyle insertLayer:belowLayer:]` method.
+
+@param identifier A string that uniquely identifies the source in the style to
+which it is added.
+*/
+- (instancetype)initWithIdentifier:(NSString *)identifier;
#pragma mark - Accessing the Paint Attributes
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm
index 8f416a0ea2..47b491fc65 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.mm
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.mm
@@ -2,35 +2,27 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLBackgroundStyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/background_layer.hpp>
@interface MGLBackgroundStyleLayer ()
-@property (nonatomic) mbgl::style::BackgroundLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::BackgroundLayer *rawLayer;
@end
@implementation MGLBackgroundStyleLayer
-{
- std::unique_ptr<mbgl::style::BackgroundLayer> _pendingLayer;
-}
- (instancetype)initWithIdentifier:(NSString *)identifier
{
- if (self = [super initWithIdentifier:identifier]) {
- auto layer = std::make_unique<mbgl::style::BackgroundLayer>(identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::BackgroundLayer>(identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::BackgroundLayer *)rawLayer
@@ -38,51 +30,6 @@
return (mbgl::style::BackgroundLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::BackgroundLayer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::BackgroundLayer *layer = dynamic_cast<mbgl::style::BackgroundLayer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::BackgroundLayer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
#pragma mark - Accessing the Paint Attributes
- (void)setBackgroundColor:(MGLStyleValue<MGLColor *> *)backgroundColor {
diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h
index 69c823a868..789ff7a258 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.h
+++ b/platform/darwin/src/MGLCircleStyleLayer.h
@@ -79,6 +79,21 @@ typedef NS_ENUM(NSUInteger, MGLCircleTranslationAnchor) {
MGL_EXPORT
@interface MGLCircleStyleLayer : MGLVectorStyleLayer
+/**
+ Returns a circle style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
+
#pragma mark - Accessing the Paint Attributes
/**
diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm
index 330b9cdac0..42961f2e12 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.mm
+++ b/platform/darwin/src/MGLCircleStyleLayer.mm
@@ -2,14 +2,13 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLCircleStyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
namespace mbgl {
@@ -28,23 +27,16 @@ namespace mbgl {
@interface MGLCircleStyleLayer ()
-@property (nonatomic) mbgl::style::CircleLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::CircleLayer *rawLayer;
@end
@implementation MGLCircleStyleLayer
-{
- std::unique_ptr<mbgl::style::CircleLayer> _pendingLayer;
-}
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super initWithIdentifier:identifier source:source]) {
- auto layer = std::make_unique<mbgl::style::CircleLayer>(identifier.UTF8String, source.identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::CircleLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::CircleLayer *)rawLayer
@@ -52,11 +44,6 @@ namespace mbgl {
return (mbgl::style::CircleLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::CircleLayer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
- (NSString *)sourceIdentifier
{
MGLAssertStyleLayerIsValid();
@@ -93,46 +80,6 @@ namespace mbgl {
return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()];
}
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::CircleLayer *layer = dynamic_cast<mbgl::style::CircleLayer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::CircleLayer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
#pragma mark - Accessing the Paint Attributes
- (void)setCircleBlur:(MGLStyleValue<NSNumber *> *)circleBlur {
diff --git a/platform/darwin/src/MGLDistanceFormatter.m b/platform/darwin/src/MGLDistanceFormatter.m
index e77e48b512..a7a2f9c9e1 100644
--- a/platform/darwin/src/MGLDistanceFormatter.m
+++ b/platform/darwin/src/MGLDistanceFormatter.m
@@ -24,7 +24,7 @@ static const double FEET_PER_MILE = YARDS_PER_MILE * 3.0;
return [self stringFromValue:miles unit:unit];
} else {
unit = NSLengthFormatterUnitFoot;
- self.numberFormatter.roundingIncrement = @50;
+ self.numberFormatter.roundingIncrement = @1;
return [self stringFromValue:feet unit:unit];
}
} else {
diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.h b/platform/darwin/src/MGLFillExtrusionStyleLayer.h
new file mode 100644
index 0000000000..84f6bedde4
--- /dev/null
+++ b/platform/darwin/src/MGLFillExtrusionStyleLayer.h
@@ -0,0 +1,364 @@
+// This file is generated.
+// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
+
+#import "MGLFoundation.h"
+#import "MGLStyleValue.h"
+#import "MGLVectorStyleLayer.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Controls the translation reference point.
+
+ Values of this type are used in the `MGLFillExtrusionStyleLayer.fillExtrusionTranslationAnchor`
+ property.
+ */
+typedef NS_ENUM(NSUInteger, MGLFillExtrusionTranslationAnchor) {
+ /**
+ The fill extrusion is translated relative to the map.
+ */
+ MGLFillExtrusionTranslationAnchorMap,
+ /**
+ The fill extrusion is translated relative to the viewport.
+ */
+ MGLFillExtrusionTranslationAnchorViewport,
+};
+
+/**
+ An `MGLFillExtrusionStyleLayer` is a style layer that renders one or more 3D
+ extruded polygons on the map.
+
+ Use a fill-extrusion style layer to configure the visual appearance of polygon
+ or multipolygon features in vector tiles loaded by an `MGLVectorSource` object
+ or `MGLPolygon`, `MGLPolygonFeature`, `MGLMultiPolygon`, or
+ `MGLMultiPolygonFeature` instances in an `MGLShapeSource` object.
+
+ You can access an existing fill-extrusion style layer using the
+ `-[MGLStyle layerWithIdentifier:]` method if you know its identifier;
+ otherwise, find it using the `MGLStyle.layers` property. You can also create a
+ new fill-extrusion style layer and add it to the style using a method such as
+ `-[MGLStyle addLayer:]`.
+
+ ### Example
+
+ ```swift
+ let layer = MGLFillExtrusionStyleLayer(identifier: "buildings", source: buildings)
+ layer.sourceLayerIdentifier = "building"
+ layer.fillExtrusionHeight = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "height", options: nil)
+ layer.fillExtrusionBase = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "min_height", options: nil)
+ layer.predicate = NSPredicate(format: "extrude == TRUE")
+ mapView.style?.addLayer(layer)
+ ```
+ */
+MGL_EXPORT
+@interface MGLFillExtrusionStyleLayer : MGLVectorStyleLayer
+
+/**
+ Returns a fill-extrusion style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
+
+#pragma mark - Accessing the Paint Attributes
+
+/**
+ The height with which to extrude the base of this layer. Must be less than or
+ equal to `fillExtrusionHeight`.
+
+ This property is measured in meters.
+
+ The default value of this property is an `MGLStyleValue` object containing an
+ `NSNumber` object containing the float `0`. Set this property to `nil` to reset
+ it to the default value.
+
+ This property is only applied to the style if `fillExtrusionHeight` is
+ non-`nil`. Otherwise, it is ignored.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillExtrusionBase;
+
+/**
+ The transition affecting any changes to this layer’s `fillExtrusionBase` property.
+
+ This property corresponds to the `fill-extrusion-base-transition` property in the style JSON file format.
+*/
+@property (nonatomic) MGLTransition fillExtrusionBaseTransition;
+
+#if TARGET_OS_IPHONE
+/**
+ The base color of this layer. The extrusion's surfaces will be shaded
+ differently based on this color in combination with the `light` settings. If
+ this color is specified with an alpha component, the alpha component will be
+ ignored; use `fillExtrusionOpacity` to set layer opacityco.
+
+ The default value of this property is an `MGLStyleValue` object containing
+ `UIColor.blackColor`. Set this property to `nil` to reset it to the default
+ value.
+
+ This property is only applied to the style if `fillExtrusionPattern` is set to
+ `nil`. Otherwise, it is ignored.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *fillExtrusionColor;
+#else
+/**
+ The base color of this layer. The extrusion's surfaces will be shaded
+ differently based on this color in combination with the `light` settings. If
+ this color is specified with an alpha component, the alpha component will be
+ ignored; use `fillExtrusionOpacity` to set layer opacityco.
+
+ The default value of this property is an `MGLStyleValue` object containing
+ `NSColor.blackColor`. Set this property to `nil` to reset it to the default
+ value.
+
+ This property is only applied to the style if `fillExtrusionPattern` is set to
+ `nil`. Otherwise, it is ignored.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *fillExtrusionColor;
+#endif
+
+/**
+ The transition affecting any changes to this layer’s `fillExtrusionColor` property.
+
+ This property corresponds to the `fill-extrusion-color-transition` property in the style JSON file format.
+*/
+@property (nonatomic) MGLTransition fillExtrusionColorTransition;
+
+/**
+ The height with which to extrude this layer.
+
+ This property is measured in meters.
+
+ The default value of this property is an `MGLStyleValue` object containing an
+ `NSNumber` object containing the float `0`. Set this property to `nil` to reset
+ it to the default value.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillExtrusionHeight;
+
+/**
+ The transition affecting any changes to this layer’s `fillExtrusionHeight` property.
+
+ This property corresponds to the `fill-extrusion-height-transition` property in the style JSON file format.
+*/
+@property (nonatomic) MGLTransition fillExtrusionHeightTransition;
+
+/**
+ The opacity of the entire fill extrusion layer. This is rendered on a
+ per-layer, not per-feature, basis, and data-driven styling is not available.
+
+ The default value of this property is an `MGLStyleValue` object containing an
+ `NSNumber` object containing the float `1`. Set this property to `nil` to reset
+ it to the default value.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillExtrusionOpacity;
+
+/**
+ The transition affecting any changes to this layer’s `fillExtrusionOpacity` property.
+
+ This property corresponds to the `fill-extrusion-opacity-transition` property in the style JSON file format.
+*/
+@property (nonatomic) MGLTransition fillExtrusionOpacityTransition;
+
+/**
+ Name of image in style images to use for drawing image fill-extrusions. For
+ seamless patterns, image width and height must be a factor of two (2, 4, 8,
+ ..., 512).
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of
+ `MGLInterpolationModeInterval`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *fillExtrusionPattern;
+
+/**
+ The transition affecting any changes to this layer’s `fillExtrusionPattern` property.
+
+ This property corresponds to the `fill-extrusion-pattern-transition` property in the style JSON file format.
+*/
+@property (nonatomic) MGLTransition fillExtrusionPatternTransition;
+
+#if TARGET_OS_IPHONE
+/**
+ The geometry's offset.
+
+ This property is measured in points.
+
+ The default value of this property is an `MGLStyleValue` object containing an
+ `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0
+ points downward. Set this property to `nil` to reset it to the default value.
+
+ This attribute corresponds to the <a
+ href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-translate"><code>fill-extrusion-translate</code></a>
+ layout property in the Mapbox Style Specification.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillExtrusionTranslation;
+#else
+/**
+ The geometry's offset.
+
+ This property is measured in points.
+
+ The default value of this property is an `MGLStyleValue` object containing an
+ `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0
+ points upward. Set this property to `nil` to reset it to the default value.
+
+ This attribute corresponds to the <a
+ href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-translate"><code>fill-extrusion-translate</code></a>
+ layout property in the Mapbox Style Specification.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillExtrusionTranslation;
+#endif
+
+/**
+ The transition affecting any changes to this layer’s `fillExtrusionTranslation` property.
+
+ This property corresponds to the `fill-extrusion-translate-transition` property in the style JSON file format.
+*/
+@property (nonatomic) MGLTransition fillExtrusionTranslationTransition;
+
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillExtrusionTranslate __attribute__((unavailable("Use fillExtrusionTranslation instead.")));
+
+/**
+ Controls the translation reference point.
+
+ The default value of this property is an `MGLStyleValue` object containing an
+ `NSValue` object containing `MGLFillExtrusionTranslationAnchorMap`. Set this
+ property to `nil` to reset it to the default value.
+
+ This property is only applied to the style if `fillExtrusionTranslation` is
+ non-`nil`. Otherwise, it is ignored.
+
+ This attribute corresponds to the <a
+ href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-translate-anchor"><code>fill-extrusion-translate-anchor</code></a>
+ layout property in the Mapbox Style Specification.
+
+ You can set this property to an instance of:
+
+ * `MGLConstantStyleValue`
+ * `MGLCameraStyleFunction` with an interpolation mode of
+ `MGLInterpolationModeInterval`
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillExtrusionTranslationAnchor;
+
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillExtrusionTranslateAnchor __attribute__((unavailable("Use fillExtrusionTranslationAnchor instead.")));
+
+@end
+
+/**
+ Methods for wrapping an enumeration value for a style layer attribute in an
+ `MGLFillExtrusionStyleLayer` object and unwrapping its raw value.
+ */
+@interface NSValue (MGLFillExtrusionStyleLayerAdditions)
+
+#pragma mark Working with Fill extrusion Style Layer Attribute Values
+
+/**
+ Creates a new value object containing the given `MGLFillExtrusionTranslationAnchor` enumeration.
+
+ @param fillExtrusionTranslationAnchor The value for the new object.
+ @return A new value object that contains the enumeration value.
+ */
++ (instancetype)valueWithMGLFillExtrusionTranslationAnchor:(MGLFillExtrusionTranslationAnchor)fillExtrusionTranslationAnchor;
+
+/**
+ The `MGLFillExtrusionTranslationAnchor` enumeration representation of the value.
+ */
+@property (readonly) MGLFillExtrusionTranslationAnchor MGLFillExtrusionTranslationAnchorValue;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.mm b/platform/darwin/src/MGLFillExtrusionStyleLayer.mm
new file mode 100644
index 0000000000..b00ed8e09f
--- /dev/null
+++ b/platform/darwin/src/MGLFillExtrusionStyleLayer.mm
@@ -0,0 +1,335 @@
+// This file is generated.
+// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
+
+#import "MGLSource.h"
+#import "NSPredicate+MGLAdditions.h"
+#import "NSDate+MGLAdditions.h"
+#import "MGLStyleLayer_Private.h"
+#import "MGLStyleValue_Private.h"
+#import "MGLFillExtrusionStyleLayer.h"
+
+#include <mbgl/style/transition_options.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
+
+namespace mbgl {
+
+ MBGL_DEFINE_ENUM(MGLFillExtrusionTranslationAnchor, {
+ { MGLFillExtrusionTranslationAnchorMap, "map" },
+ { MGLFillExtrusionTranslationAnchorViewport, "viewport" },
+ });
+
+}
+
+@interface MGLFillExtrusionStyleLayer ()
+
+@property (nonatomic, readonly) mbgl::style::FillExtrusionLayer *rawLayer;
+
+@end
+
+@implementation MGLFillExtrusionStyleLayer
+
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
+{
+ auto layer = std::make_unique<mbgl::style::FillExtrusionLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
+}
+
+- (mbgl::style::FillExtrusionLayer *)rawLayer
+{
+ return (mbgl::style::FillExtrusionLayer *)super.rawLayer;
+}
+
+- (NSString *)sourceIdentifier
+{
+ MGLAssertStyleLayerIsValid();
+
+ return @(self.rawLayer->getSourceID().c_str());
+}
+
+- (NSString *)sourceLayerIdentifier
+{
+ MGLAssertStyleLayerIsValid();
+
+ auto layerID = self.rawLayer->getSourceLayer();
+ return layerID.empty() ? nil : @(layerID.c_str());
+}
+
+- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
+{
+ MGLAssertStyleLayerIsValid();
+
+ self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
+}
+
+- (void)setPredicate:(NSPredicate *)predicate
+{
+ MGLAssertStyleLayerIsValid();
+
+ self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::NullFilter());
+}
+
+- (NSPredicate *)predicate
+{
+ MGLAssertStyleLayerIsValid();
+
+ return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()];
+}
+
+#pragma mark - Accessing the Paint Attributes
+
+- (void)setFillExtrusionBase:(MGLStyleValue<NSNumber *> *)fillExtrusionBase {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(fillExtrusionBase);
+ self.rawLayer->setFillExtrusionBase(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)fillExtrusionBase {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionBase();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultFillExtrusionBase());
+ }
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionBaseTransition:(MGLTransition )transition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } };
+ self.rawLayer->setFillExtrusionBaseTransition(options);
+}
+
+- (MGLTransition)fillExtrusionBaseTransition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionBaseTransition();
+ MGLTransition transition;
+ transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
+ transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
+
+ return transition;
+}
+
+- (void)setFillExtrusionColor:(MGLStyleValue<MGLColor *> *)fillExtrusionColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toDataDrivenPropertyValue(fillExtrusionColor);
+ self.rawLayer->setFillExtrusionColor(mbglValue);
+}
+
+- (MGLStyleValue<MGLColor *> *)fillExtrusionColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionColor();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toDataDrivenStyleValue(self.rawLayer->getDefaultFillExtrusionColor());
+ }
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toDataDrivenStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionColorTransition:(MGLTransition )transition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } };
+ self.rawLayer->setFillExtrusionColorTransition(options);
+}
+
+- (MGLTransition)fillExtrusionColorTransition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionColorTransition();
+ MGLTransition transition;
+ transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
+ transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
+
+ return transition;
+}
+
+- (void)setFillExtrusionHeight:(MGLStyleValue<NSNumber *> *)fillExtrusionHeight {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(fillExtrusionHeight);
+ self.rawLayer->setFillExtrusionHeight(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)fillExtrusionHeight {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionHeight();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultFillExtrusionHeight());
+ }
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionHeightTransition:(MGLTransition )transition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } };
+ self.rawLayer->setFillExtrusionHeightTransition(options);
+}
+
+- (MGLTransition)fillExtrusionHeightTransition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionHeightTransition();
+ MGLTransition transition;
+ transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
+ transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
+
+ return transition;
+}
+
+- (void)setFillExtrusionOpacity:(MGLStyleValue<NSNumber *> *)fillExtrusionOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(fillExtrusionOpacity);
+ self.rawLayer->setFillExtrusionOpacity(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)fillExtrusionOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionOpacity();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultFillExtrusionOpacity());
+ }
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionOpacityTransition:(MGLTransition )transition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } };
+ self.rawLayer->setFillExtrusionOpacityTransition(options);
+}
+
+- (MGLTransition)fillExtrusionOpacityTransition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionOpacityTransition();
+ MGLTransition transition;
+ transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
+ transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
+
+ return transition;
+}
+
+- (void)setFillExtrusionPattern:(MGLStyleValue<NSString *> *)fillExtrusionPattern {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(fillExtrusionPattern);
+ self.rawLayer->setFillExtrusionPattern(mbglValue);
+}
+
+- (MGLStyleValue<NSString *> *)fillExtrusionPattern {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionPattern();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(self.rawLayer->getDefaultFillExtrusionPattern());
+ }
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionPatternTransition:(MGLTransition )transition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } };
+ self.rawLayer->setFillExtrusionPatternTransition(options);
+}
+
+- (MGLTransition)fillExtrusionPatternTransition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionPatternTransition();
+ MGLTransition transition;
+ transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
+ transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
+
+ return transition;
+}
+
+- (void)setFillExtrusionTranslation:(MGLStyleValue<NSValue *> *)fillExtrusionTranslation {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toInterpolatablePropertyValue(fillExtrusionTranslation);
+ self.rawLayer->setFillExtrusionTranslate(mbglValue);
+}
+
+- (MGLStyleValue<NSValue *> *)fillExtrusionTranslation {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionTranslate();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(self.rawLayer->getDefaultFillExtrusionTranslate());
+ }
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionTranslationTransition:(MGLTransition )transition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } };
+ self.rawLayer->setFillExtrusionTranslateTransition(options);
+}
+
+- (MGLTransition)fillExtrusionTranslationTransition {
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionTranslateTransition();
+ MGLTransition transition;
+ transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
+ transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
+
+ return transition;
+}
+
+- (void)setFillExtrusionTranslate:(MGLStyleValue<NSValue *> *)fillExtrusionTranslate {
+}
+
+- (MGLStyleValue<NSValue *> *)fillExtrusionTranslate {
+ return self.fillExtrusionTranslation;
+}
+
+- (void)setFillExtrusionTranslationAnchor:(MGLStyleValue<NSValue *> *)fillExtrusionTranslationAnchor {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillExtrusionTranslationAnchor>().toEnumPropertyValue(fillExtrusionTranslationAnchor);
+ self.rawLayer->setFillExtrusionTranslateAnchor(mbglValue);
+}
+
+- (MGLStyleValue<NSValue *> *)fillExtrusionTranslationAnchor {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getFillExtrusionTranslateAnchor();
+ if (propertyValue.isUndefined()) {
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillExtrusionTranslationAnchor>().toEnumStyleValue(self.rawLayer->getDefaultFillExtrusionTranslateAnchor());
+ }
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillExtrusionTranslationAnchor>().toEnumStyleValue(propertyValue);
+}
+
+- (void)setFillExtrusionTranslateAnchor:(MGLStyleValue<NSValue *> *)fillExtrusionTranslateAnchor {
+}
+
+- (MGLStyleValue<NSValue *> *)fillExtrusionTranslateAnchor {
+ return self.fillExtrusionTranslationAnchor;
+}
+
+@end
+
+@implementation NSValue (MGLFillExtrusionStyleLayerAdditions)
+
++ (NSValue *)valueWithMGLFillExtrusionTranslationAnchor:(MGLFillExtrusionTranslationAnchor)fillExtrusionTranslationAnchor {
+ return [NSValue value:&fillExtrusionTranslationAnchor withObjCType:@encode(MGLFillExtrusionTranslationAnchor)];
+}
+
+- (MGLFillExtrusionTranslationAnchor)MGLFillExtrusionTranslationAnchorValue {
+ MGLFillExtrusionTranslationAnchor fillExtrusionTranslationAnchor;
+ [self getValue:&fillExtrusionTranslationAnchor];
+ return fillExtrusionTranslationAnchor;
+}
+
+@end
diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h
index 1f3cfc8af5..6e3297bdec 100644
--- a/platform/darwin/src/MGLFillStyleLayer.h
+++ b/platform/darwin/src/MGLFillStyleLayer.h
@@ -52,6 +52,21 @@ typedef NS_ENUM(NSUInteger, MGLFillTranslationAnchor) {
MGL_EXPORT
@interface MGLFillStyleLayer : MGLVectorStyleLayer
+/**
+ Returns a fill style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
+
#pragma mark - Accessing the Paint Attributes
/**
diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm
index 1322a7a0b6..71b01a6661 100644
--- a/platform/darwin/src/MGLFillStyleLayer.mm
+++ b/platform/darwin/src/MGLFillStyleLayer.mm
@@ -2,14 +2,13 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLFillStyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
namespace mbgl {
@@ -23,23 +22,16 @@ namespace mbgl {
@interface MGLFillStyleLayer ()
-@property (nonatomic) mbgl::style::FillLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::FillLayer *rawLayer;
@end
@implementation MGLFillStyleLayer
-{
- std::unique_ptr<mbgl::style::FillLayer> _pendingLayer;
-}
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super initWithIdentifier:identifier source:source]) {
- auto layer = std::make_unique<mbgl::style::FillLayer>(identifier.UTF8String, source.identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::FillLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::FillLayer *)rawLayer
@@ -47,11 +39,6 @@ namespace mbgl {
return (mbgl::style::FillLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::FillLayer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
- (NSString *)sourceIdentifier
{
MGLAssertStyleLayerIsValid();
@@ -88,46 +75,6 @@ namespace mbgl {
return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()];
}
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::FillLayer *layer = dynamic_cast<mbgl::style::FillLayer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::FillLayer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
#pragma mark - Accessing the Paint Attributes
- (void)setFillAntialiased:(MGLStyleValue<NSNumber *> *)fillAntialiased {
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.h b/platform/darwin/src/MGLForegroundStyleLayer.h
index 87763f4634..16a973630e 100644
--- a/platform/darwin/src/MGLForegroundStyleLayer.h
+++ b/platform/darwin/src/MGLForegroundStyleLayer.h
@@ -20,23 +20,7 @@ MGL_EXPORT
#pragma mark Initializing a Style Layer
-- (instancetype)init __attribute__((unavailable("Use -initWithIdentifier:source: instead.")));
-- (instancetype)initWithIdentifier:(NSString *)identifier __attribute__((unavailable("Use -initWithIdentifier:source: instead.")));
-
-/**
- Returns a foreground style layer initialized with an identifier and source.
-
- After initializing and configuring the style layer, add it to a map view’s
- style using the `-[MGLStyle addLayer:]` or
- `-[MGLStyle insertLayer:belowLayer:]` method.
-
- @param identifier A string that uniquely identifies the source in the style to
- which it is added.
- @param source The source from which to obtain the data to style. If the source
- has not yet been added to the current style, the behavior is undefined.
- @return An initialized foreground style layer.
- */
-- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source NS_DESIGNATED_INITIALIZER;
+- (instancetype)init __attribute__((unavailable("Use -init methods of concrete subclasses instead.")));
#pragma mark Specifying a Style Layer’s Content
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.m b/platform/darwin/src/MGLForegroundStyleLayer.mm
index b7a0379af2..6888f89b92 100644
--- a/platform/darwin/src/MGLForegroundStyleLayer.m
+++ b/platform/darwin/src/MGLForegroundStyleLayer.mm
@@ -1,13 +1,11 @@
#import "MGLForegroundStyleLayer.h"
-#import "MGLSource.h"
@implementation MGLForegroundStyleLayer
-- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source {
- if (self = [super initWithIdentifier:identifier]) {
- _sourceIdentifier = source.identifier;
- }
- return self;
+- (NSString *)sourceIdentifier {
+ [NSException raise:@"MGLAbstractClassException"
+ format:@"MGLForegroundStyleLayer is an abstract class"];
+ return nil;
}
- (NSString *)description {
diff --git a/platform/darwin/src/MGLGeometry.mm b/platform/darwin/src/MGLGeometry.mm
index 8c0c5f9cb7..1540a3a741 100644
--- a/platform/darwin/src/MGLGeometry.mm
+++ b/platform/darwin/src/MGLGeometry.mm
@@ -32,6 +32,15 @@ CGRect MGLExtendRect(CGRect rect, CGPoint point) {
return rect;
}
+mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) {
+ try {
+ return mbgl::LatLng(coordinate.latitude, coordinate.longitude);
+ } catch (std::domain_error &error) {
+ [NSException raise:NSInvalidArgumentException format:@"%s", error.what()];
+ return {};
+ }
+}
+
MGL_EXPORT
CLLocationDistance MGLAltitudeForZoomLevel(double zoomLevel, CGFloat pitch, CLLocationDegrees latitude, CGSize size) {
CLLocationDistance metersPerPixel = mbgl::Projection::getMetersPerPixelAtLatitude(latitude, zoomLevel);
diff --git a/platform/darwin/src/MGLGeometry_Private.h b/platform/darwin/src/MGLGeometry_Private.h
index e6b37b3530..3e029e8ee0 100644
--- a/platform/darwin/src/MGLGeometry_Private.h
+++ b/platform/darwin/src/MGLGeometry_Private.h
@@ -12,16 +12,14 @@
/// the given point.
CGRect MGLExtendRect(CGRect rect, CGPoint point);
-NS_INLINE mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) {
- return mbgl::LatLng(coordinate.latitude, coordinate.longitude);
-}
+mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D coordinate);
NS_INLINE mbgl::Point<double> MGLPointFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) {
return mbgl::Point<double>(coordinate.longitude, coordinate.latitude);
}
NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) {
- return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude);
+ return CLLocationCoordinate2DMake(latLng.latitude(), latLng.longitude());
}
NS_INLINE MGLCoordinateBounds MGLCoordinateBoundsFromLatLngBounds(mbgl::LatLngBounds latLngBounds) {
diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h
index e03f3e347e..38513652c5 100644
--- a/platform/darwin/src/MGLLineStyleLayer.h
+++ b/platform/darwin/src/MGLLineStyleLayer.h
@@ -107,6 +107,21 @@ typedef NS_ENUM(NSUInteger, MGLLineTranslationAnchor) {
MGL_EXPORT
@interface MGLLineStyleLayer : MGLVectorStyleLayer
+/**
+ Returns a line style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
+
#pragma mark - Accessing the Layout Attributes
/**
diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm
index e37489cf0b..8b90efd0c4 100644
--- a/platform/darwin/src/MGLLineStyleLayer.mm
+++ b/platform/darwin/src/MGLLineStyleLayer.mm
@@ -2,14 +2,13 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLLineStyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/line_layer.hpp>
namespace mbgl {
@@ -35,23 +34,16 @@ namespace mbgl {
@interface MGLLineStyleLayer ()
-@property (nonatomic) mbgl::style::LineLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::LineLayer *rawLayer;
@end
@implementation MGLLineStyleLayer
-{
- std::unique_ptr<mbgl::style::LineLayer> _pendingLayer;
-}
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super initWithIdentifier:identifier source:source]) {
- auto layer = std::make_unique<mbgl::style::LineLayer>(identifier.UTF8String, source.identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::LineLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::LineLayer *)rawLayer
@@ -59,11 +51,6 @@ namespace mbgl {
return (mbgl::style::LineLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::LineLayer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
- (NSString *)sourceIdentifier
{
MGLAssertStyleLayerIsValid();
@@ -100,46 +87,6 @@ namespace mbgl {
return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()];
}
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::LineLayer *layer = dynamic_cast<mbgl::style::LineLayer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::LineLayer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
#pragma mark - Accessing the Layout Attributes
- (void)setLineCap:(MGLStyleValue<NSValue *> *)lineCap {
diff --git a/platform/darwin/src/MGLMapCamera.mm b/platform/darwin/src/MGLMapCamera.mm
index 613124da66..1611dbf4a3 100644
--- a/platform/darwin/src/MGLMapCamera.mm
+++ b/platform/darwin/src/MGLMapCamera.mm
@@ -1,4 +1,5 @@
#import "MGLMapCamera.h"
+#import "MGLGeometry_Private.h"
#include <mbgl/util/projection.hpp>
@@ -23,17 +24,21 @@ BOOL MGLEqualFloatWithAccuracy(CGFloat left, CGFloat right, CGFloat accuracy)
fromEyeCoordinate:(CLLocationCoordinate2D)eyeCoordinate
eyeAltitude:(CLLocationDistance)eyeAltitude
{
- mbgl::LatLng centerLatLng = mbgl::LatLng(centerCoordinate.latitude, centerCoordinate.longitude);
- mbgl::LatLng eyeLatLng = mbgl::LatLng(eyeCoordinate.latitude, eyeCoordinate.longitude);
-
- mbgl::ProjectedMeters centerMeters = mbgl::Projection::projectedMetersForLatLng(centerLatLng);
- mbgl::ProjectedMeters eyeMeters = mbgl::Projection::projectedMetersForLatLng(eyeLatLng);
- CLLocationDirection heading = std::atan((centerMeters.northing - eyeMeters.northing) /
- (centerMeters.easting - eyeMeters.easting));
-
- double groundDistance = std::hypot(centerMeters.northing - eyeMeters.northing,
- centerMeters.easting - eyeMeters.easting);
- CGFloat pitch = std::atan(eyeAltitude / groundDistance);
+ CLLocationDirection heading = -1;
+ CGFloat pitch = -1;
+ if (CLLocationCoordinate2DIsValid(centerCoordinate) && CLLocationCoordinate2DIsValid(eyeCoordinate)) {
+ mbgl::LatLng centerLatLng = MGLLatLngFromLocationCoordinate2D(centerCoordinate);
+ mbgl::LatLng eyeLatLng = MGLLatLngFromLocationCoordinate2D(eyeCoordinate);
+
+ mbgl::ProjectedMeters centerMeters = mbgl::Projection::projectedMetersForLatLng(centerLatLng);
+ mbgl::ProjectedMeters eyeMeters = mbgl::Projection::projectedMetersForLatLng(eyeLatLng);
+ heading = std::atan((centerMeters.northing() - eyeMeters.northing()) /
+ (centerMeters.easting() - eyeMeters.easting()));
+
+ double groundDistance = std::hypot(centerMeters.northing() - eyeMeters.northing(),
+ centerMeters.easting() - eyeMeters.easting());
+ pitch = std::atan(eyeAltitude / groundDistance);
+ }
return [[self alloc] initWithCenterCoordinate:centerCoordinate
altitude:eyeAltitude
diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h
index ca08e5405a..429bbdb22d 100644
--- a/platform/darwin/src/MGLMultiPoint.h
+++ b/platform/darwin/src/MGLMultiPoint.h
@@ -58,8 +58,12 @@ MGL_EXPORT
- (void)setCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
/**
- Inserts the given vertices into the shape. If the shape is currently visible on
- the map, it is redrawn immediately.
+ Inserts the given vertices into the shape.
+
+ If the shape is currently visible on the map as an annotation, it is redrawn
+ immediately. If the shape is part of an `MGLShapeSource` object, you must
+ explicitly set the `MGLShapeSource.shape` property in order for any style
+ layers that use the source to be redrawn.
@param coords The array of coordinates to insert into the shape. The data in
this array is copied to the shape’s `coordinates` property.
@@ -70,8 +74,12 @@ MGL_EXPORT
- (void)insertCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count atIndex:(NSUInteger)index;
/**
- Appends the given vertices to the shape. If the shape is currently visible on
- the map, it is redrawn immediately.
+ Appends the given vertices to the shape.
+
+ If the shape is currently visible on the map as an annotation, it is redrawn
+ immediately. If the shape is part of an `MGLShapeSource` object, you must
+ explicitly set the `MGLShapeSource.shape` property in order for any style
+ layers that use the source to be redrawn.
@param coords The array of coordinates to add to the shape. The data in this
array is copied to the shape’s `coordinates` property.
@@ -81,8 +89,12 @@ MGL_EXPORT
/**
Replaces the vertices at the given range in the shape with the same number of
- vertices from a given C array. If the shape is currently visible on the map, it
- is redrawn immediately.
+ vertices from a given C array.
+
+ If the shape is currently visible on the map as an annotation, it is redrawn
+ immediately. If the shape is part of an `MGLShapeSource` object, you must
+ explicitly set the `MGLShapeSource.shape` property in order for any style
+ layers that use the source to be redrawn.
The number of coordinates in `coords` must be equal to the length of `range`.
If you want to insert or delete one or more vertices, use the
@@ -103,8 +115,12 @@ MGL_EXPORT
/**
Replaces the vertices at the given range in the shape with the specified number
- of vertices from a given C array. If the shape is currently visible on the map,
- it is redrawn immediately.
+ of vertices from a given C array.
+
+ If the shape is currently visible on the map as an annotation, it is redrawn
+ immediately. If the shape is part of an `MGLShapeSource` object, you must
+ explicitly set the `MGLShapeSource.shape` property in order for any style
+ layers that use the source to be redrawn.
If `count` is greater than the `length` field of `range`, some vertices will
effectively be inserted into the shape. On the other hand, if `count` is less
@@ -128,8 +144,12 @@ MGL_EXPORT
- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
/**
- Removes the vertices at the given range from the shape. If the shape is
- currently visible on the map, it is redrawn immediately.
+ Removes the vertices at the given range from the shape.
+
+ If the shape is currently visible on the map as an annotation, it is redrawn
+ immediately. If the shape is part of an `MGLShapeSource` object, you must
+ explicitly set the `MGLShapeSource.shape` property in order for any style
+ layers that use the source to be redrawn.
If `range` extends beyond the shape’s `coordinates` property, an
`NSRangeException` is raised.
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm
index 8e8c5be304..ef46bbb0fe 100644
--- a/platform/darwin/src/MGLMultiPoint.mm
+++ b/platform/darwin/src/MGLMultiPoint.mm
@@ -163,7 +163,11 @@
if (!_bounds) {
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
for (auto coordinate : _coordinates) {
- bounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
+ if (!CLLocationCoordinate2DIsValid(coordinate)) {
+ bounds = mbgl::LatLngBounds::empty();
+ break;
+ }
+ bounds.extend(MGLLatLngFromLocationCoordinate2D(coordinate));
}
_bounds = bounds;
}
diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.h b/platform/darwin/src/MGLOpenGLStyleLayer.h
index de4fc92b17..bdad5f9d07 100644
--- a/platform/darwin/src/MGLOpenGLStyleLayer.h
+++ b/platform/darwin/src/MGLOpenGLStyleLayer.h
@@ -23,6 +23,8 @@ MGL_EXPORT
@property (nonatomic, weak, readonly) MGLMapView *mapView;
+- (instancetype)initWithIdentifier:(NSString *)identifier;
+
- (void)didMoveToMapView:(MGLMapView *)mapView;
- (void)willMoveFromMapView:(MGLMapView *)mapView;
diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.mm b/platform/darwin/src/MGLOpenGLStyleLayer.mm
index da131b6de8..39eda758eb 100644
--- a/platform/darwin/src/MGLOpenGLStyleLayer.mm
+++ b/platform/darwin/src/MGLOpenGLStyleLayer.mm
@@ -72,7 +72,7 @@ void MGLFinishCustomStyleLayer(void *context) {
*/
@interface MGLOpenGLStyleLayer ()
-@property (nonatomic) mbgl::style::CustomLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::CustomLayer *rawLayer;
/**
The map view whose style currently contains the layer.
@@ -84,9 +84,7 @@ void MGLFinishCustomStyleLayer(void *context) {
@end
-@implementation MGLOpenGLStyleLayer {
- std::unique_ptr<mbgl::style::CustomLayer> _pendingLayer;
-}
+@implementation MGLOpenGLStyleLayer
/**
Returns an OpenGL style layer object initialized with the given identifier.
@@ -100,26 +98,18 @@ void MGLFinishCustomStyleLayer(void *context) {
@return An initialized OpenGL style layer.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier {
- if (self = [super initWithIdentifier:identifier]) {
- auto layer = std::make_unique<mbgl::style::CustomLayer>(identifier.UTF8String,
- MGLPrepareCustomStyleLayer,
- MGLDrawCustomStyleLayer,
- MGLFinishCustomStyleLayer,
- (__bridge void *)self);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::CustomLayer>(identifier.UTF8String,
+ MGLPrepareCustomStyleLayer,
+ MGLDrawCustomStyleLayer,
+ MGLFinishCustomStyleLayer,
+ (__bridge void *)self);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::CustomLayer *)rawLayer {
return (mbgl::style::CustomLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::CustomLayer *)rawLayer {
- super.rawLayer = rawLayer;
-}
-
#pragma mark - Adding to and removing from a map view
- (void)setMapView:(MGLMapView *)mapView {
@@ -134,22 +124,12 @@ void MGLFinishCustomStyleLayer(void *context) {
- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer {
self.mapView = mapView;
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{ otherLayer.identifier.UTF8String };
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
+ [super addToMapView:mapView belowLayer:otherLayer];
}
- (void)removeFromMapView:(MGLMapView *)mapView {
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ [super removeFromMapView:mapView];
self.mapView = nil;
- if (!removedLayer) {
- return;
- }
- _pendingLayer = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::CustomLayer> &>(removedLayer));
- self.rawLayer = _pendingLayer.get();
}
/**
diff --git a/platform/darwin/src/MGLPointCollection.mm b/platform/darwin/src/MGLPointCollection.mm
index ac4aaed60c..8f20d91a42 100644
--- a/platform/darwin/src/MGLPointCollection.mm
+++ b/platform/darwin/src/MGLPointCollection.mm
@@ -54,7 +54,11 @@ NS_ASSUME_NONNULL_BEGIN
if (!_bounds) {
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
for (auto coordinate : _coordinates) {
- bounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
+ if (!CLLocationCoordinate2DIsValid(coordinate)) {
+ bounds = mbgl::LatLngBounds::empty();
+ break;
+ }
+ bounds.extend(MGLLatLngFromLocationCoordinate2D(coordinate));
}
_bounds = bounds;
}
@@ -119,8 +123,9 @@ NS_ASSUME_NONNULL_BEGIN
- (NSString *)description
{
- return [NSString stringWithFormat:@"<%@: %p; count = %lu>",
- NSStringFromClass([self class]), (void *)self, (unsigned long)[self pointCount]];
+ return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>",
+ NSStringFromClass([self class]), (void *)self, (unsigned long)[self pointCount],
+ MGLStringFromCoordinateBounds(self.overlayBounds)];
}
@end
diff --git a/platform/darwin/src/MGLRasterSource.h b/platform/darwin/src/MGLRasterSource.h
index 694a818246..519784f4f1 100644
--- a/platform/darwin/src/MGLRasterSource.h
+++ b/platform/darwin/src/MGLRasterSource.h
@@ -104,6 +104,109 @@ MGL_EXPORT
*/
- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize NS_DESIGNATED_INITIALIZER;
+/**
+ Returns a raster source initialized an identifier, tile URL templates, and
+ options.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ #### Tile URL templates
+
+ Tile URL templates are strings that specify the URLs of the tile images to
+ load. Each template resembles an absolute URL, but with any number of
+ placeholder strings that the source evaluates based on the tile it needs to
+ load. For example:
+
+ <ul>
+ <li><code>http://www.example.com/tiles/{z}/{x}/{y}.pbf</code> could be
+ evaluated as <code>http://www.example.com/tiles/14/6/9.pbf</code>.</li>
+ <li><code>http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png</code> could be
+ evaluated as <code>http://www.example.com/tiles/14/6/9@2x.png</code>.</li>
+ </ul>
+
+ Tile sources support the following placeholder strings in tile URL templates,
+ all of which are optional:
+
+ <table>
+ <thead>
+ <tr><th>Placeholder string</th><th>Description</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>{x}</code></td>
+ <td>The index of the tile along the map’s x axis according to Spherical
+ Mercator projection. If the value is 0, the tile’s left edge corresponds
+ to the 180th meridian west. If the value is 2<sup><var>z</var></sup>−1,
+ the tile’s right edge corresponds to the 180th meridian east.</td>
+ </tr>
+ <tr>
+ <td><code>{y}</code></td>
+ <td>The index of the tile along the map’s y axis according to Spherical
+ Mercator projection. If the value is 0, the tile’s tile edge corresponds
+ to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value
+ is 2<sup><var>z</var></sup>−1, the tile’s bottom edge corresponds to
+ −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is
+ inverted if the <code>options</code> parameter contains
+ <code>MGLTileSourceOptionTileCoordinateSystem</code> with a value of
+ <code>MGLTileCoordinateSystemTMS</code>.</td>
+ </tr>
+ <tr>
+ <td><code>{z}</code></td>
+ <td>The tile’s zoom level. At zoom level 0, each tile covers the entire
+ world map; at zoom level 1, it covers ¼ of the world; at zoom level 2,
+ <sup>1</sup>⁄<sub>16</sub> of the world, and so on. For tiles loaded by
+ a <code>MGLRasterSource</code> object, whether the tile zoom level
+ matches the map’s current zoom level depends on the value of the
+ source’s tile size as specified in the
+ <code>MGLTileSourceOptionTileSize</code> key of the
+ <code>options</code> parameter.</td>
+ </tr>
+ <tr>
+ <td><code>{bbox-epsg-3857}</code></td>
+ <td>The tile’s bounding box, expressed as a comma-separated list of the
+ tile’s western, southern, eastern, and northern extents according to
+ Spherical Mercator (EPSG:3857) projection. The bounding box is typically
+ used with map services conforming to the
+ <a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a>
+ protocol.</td>
+ </tr>
+ <tr>
+ <td><code>{quadkey}</code></td>
+ <td>A quadkey indicating both the tile’s location and its zoom level. The
+ quadkey is typically used with
+ <a href="https://msdn.microsoft.com/en-us/library/bb259689.aspx">Bing Maps</a>.
+ </td>
+ </tr>
+ <tr>
+ <td><code>{ratio}</code></td>
+ <td>A suffix indicating the resolution of the tile image. The suffix is the
+ empty string for standard resolution displays and <code>@2x</code> for
+ Retina displays, including displays for which
+ <code>NSScreen.backingScaleFactor</code> or <code>UIScreen.scale</code>
+ is 3.</td>
+ </tr>
+ <tr>
+ <td><code>{prefix}</code></td>
+ <td>Two hexadecimal digits chosen such that each visible tile has a
+ different prefix. The prefix is typically used for domain sharding.</td>
+ </tr>
+ </tbody>
+ </table>
+
+ For more information about the `{x}`, `{y}`, and `{z}` placeholder strings,
+ consult the
+ <a href="https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames">OpenStreetMap Wiki</a>.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param tileURLTemplates An array of tile URL template strings. Only the first
+ string is used; any additional strings are ignored.
+ @param options A dictionary containing configuration options. See
+ `MGLTileSourceOption` for available keys and values. Pass in `nil` to use
+ the default values.
+ @return An initialized tile source.
+ */
- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options NS_DESIGNATED_INITIALIZER;
@end
diff --git a/platform/darwin/src/MGLRasterSource.mm b/platform/darwin/src/MGLRasterSource.mm
index c73a824ea8..8fc18ba69d 100644
--- a/platform/darwin/src/MGLRasterSource.mm
+++ b/platform/darwin/src/MGLRasterSource.mm
@@ -15,15 +15,11 @@ static const CGFloat MGLRasterSourceRetinaTileSize = 512;
@interface MGLRasterSource ()
-- (instancetype)initWithRawSource:(mbgl::style::RasterSource *)rawSource NS_DESIGNATED_INITIALIZER;
-
-@property (nonatomic) mbgl::style::RasterSource *rawSource;
+@property (nonatomic, readonly) mbgl::style::RasterSource *rawSource;
@end
-@implementation MGLRasterSource {
- std::unique_ptr<mbgl::style::RasterSource> _pendingSource;
-}
+@implementation MGLRasterSource
- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL {
// The style specification default is 512, but 256 is the expected value for
@@ -37,76 +33,32 @@ static const CGFloat MGLRasterSourceRetinaTileSize = 512;
}
- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize {
- if (self = [super initWithIdentifier:identifier configurationURL:configurationURL]) {
- auto source = std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String,
- configurationURL.mgl_URLByStandardizingScheme.absoluteString.UTF8String,
- uint16_t(round(tileSize)));
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
- }
- return self;
+ auto source = std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String,
+ configurationURL.mgl_URLByStandardizingScheme.absoluteString.UTF8String,
+ uint16_t(round(tileSize)));
+ return self = [super initWithPendingSource:std::move(source)];
}
- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options {
- if (self = [super initWithIdentifier:identifier tileURLTemplates:tileURLTemplates options:options]) {
- mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options);
-
- uint16_t tileSize = MGLRasterSourceRetinaTileSize;
- if (NSNumber *tileSizeNumber = options[MGLTileSourceOptionTileSize]) {
- if (![tileSizeNumber isKindOfClass:[NSNumber class]]) {
- [NSException raise:NSInvalidArgumentException
- format:@"MGLTileSourceOptionTileSize must be set to an NSNumber."];
- }
- tileSize = static_cast<uint16_t>(round(tileSizeNumber.doubleValue));
- }
-
- auto source = std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String, tileSet, tileSize);
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
- }
- return self;
-}
-
-- (instancetype)initWithRawSource:(mbgl::style::RasterSource *)rawSource {
- return [super initWithRawSource:rawSource];
-}
-
-- (void)addToMapView:(MGLMapView *)mapView {
- if (_pendingSource == nullptr) {
- [NSException raise:@"MGLRedundantSourceException"
- format:@"This instance %@ was already added to %@. Adding the same source instance " \
- @"to the style more than once is invalid.", self, mapView.style];
- }
-
- mapView.mbglMap->addSource(std::move(_pendingSource));
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView {
- if (self.rawSource != mapView.mbglMap->getSource(self.identifier.UTF8String)) {
- return;
- }
+ mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options);
- auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
-
- mbgl::style::RasterSource *source = dynamic_cast<mbgl::style::RasterSource *>(removedSource.get());
- if (!source) {
- return;
+ uint16_t tileSize = MGLRasterSourceRetinaTileSize;
+ if (NSNumber *tileSizeNumber = options[MGLTileSourceOptionTileSize]) {
+ if (![tileSizeNumber isKindOfClass:[NSNumber class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLTileSourceOptionTileSize must be set to an NSNumber."];
+ }
+ tileSize = static_cast<uint16_t>(round(tileSizeNumber.doubleValue));
}
- removedSource.release();
-
- _pendingSource = std::unique_ptr<mbgl::style::RasterSource>(source);
- self.rawSource = _pendingSource.get();
+ auto source = std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String, tileSet, tileSize);
+ return self = [super initWithPendingSource:std::move(source)];
}
- (mbgl::style::RasterSource *)rawSource {
return (mbgl::style::RasterSource *)super.rawSource;
}
-- (void)setRawSource:(mbgl::style::RasterSource *)rawSource {
- super.rawSource = rawSource;
-}
-
- (NSURL *)configurationURL {
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
diff --git a/platform/darwin/src/MGLRasterSource_Private.h b/platform/darwin/src/MGLRasterSource_Private.h
index 47b1c13517..76790bd053 100644
--- a/platform/darwin/src/MGLRasterSource_Private.h
+++ b/platform/darwin/src/MGLRasterSource_Private.h
@@ -2,16 +2,7 @@
NS_ASSUME_NONNULL_BEGIN
-namespace mbgl {
- namespace style {
- class RasterSource;
- }
-}
-
@interface MGLRasterSource (Private)
-
-- (instancetype)initWithRawSource:(mbgl::style::RasterSource *)rawSource;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLRasterStyleLayer.h b/platform/darwin/src/MGLRasterStyleLayer.h
index 377b7f45cd..53a6a98b8a 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.h
+++ b/platform/darwin/src/MGLRasterStyleLayer.h
@@ -36,6 +36,21 @@ NS_ASSUME_NONNULL_BEGIN
MGL_EXPORT
@interface MGLRasterStyleLayer : MGLForegroundStyleLayer
+/**
+ Returns a raster style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
+
#pragma mark - Accessing the Paint Attributes
/**
diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm
index 80508e4e70..c63fd23529 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.mm
+++ b/platform/darwin/src/MGLRasterStyleLayer.mm
@@ -2,35 +2,27 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLRasterStyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
@interface MGLRasterStyleLayer ()
-@property (nonatomic) mbgl::style::RasterLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::RasterLayer *rawLayer;
@end
@implementation MGLRasterStyleLayer
-{
- std::unique_ptr<mbgl::style::RasterLayer> _pendingLayer;
-}
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super initWithIdentifier:identifier source:source]) {
- auto layer = std::make_unique<mbgl::style::RasterLayer>(identifier.UTF8String, source.identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::RasterLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::RasterLayer *)rawLayer
@@ -38,11 +30,6 @@
return (mbgl::style::RasterLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::RasterLayer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
- (NSString *)sourceIdentifier
{
MGLAssertStyleLayerIsValid();
@@ -50,46 +37,6 @@
return @(self.rawLayer->getSourceID().c_str());
}
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::RasterLayer *layer = dynamic_cast<mbgl::style::RasterLayer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::RasterLayer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
#pragma mark - Accessing the Paint Attributes
- (void)setMaximumRasterBrightness:(MGLStyleValue<NSNumber *> *)maximumRasterBrightness {
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index 7de2d69af3..023a81bba8 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -20,38 +20,26 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
@interface MGLShapeSource ()
-- (instancetype)initWithRawSource:(mbgl::style::GeoJSONSource *)rawSource NS_DESIGNATED_INITIALIZER;
-
@property (nonatomic, readwrite) NSDictionary *options;
-@property (nonatomic) mbgl::style::GeoJSONSource *rawSource;
+@property (nonatomic, readonly) mbgl::style::GeoJSONSource *rawSource;
@end
-@implementation MGLShapeSource {
- std::unique_ptr<mbgl::style::GeoJSONSource> _pendingSource;
-}
+@implementation MGLShapeSource
- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options {
- if (self = [super initWithIdentifier:identifier]) {
- auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options);
- auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, geoJSONOptions);
-
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
-
+ auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options);
+ auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, geoJSONOptions);
+ if (self = [super initWithPendingSource:std::move(source)]) {
self.URL = url;
}
return self;
}
- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(NS_DICTIONARY_OF(MGLShapeSourceOption, id) *)options {
- if (self = [super initWithIdentifier:identifier]) {
- auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options);
- auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, geoJSONOptions);
-
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
-
+ auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options);
+ auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, geoJSONOptions);
+ if (self = [super initWithPendingSource:std::move(source)]) {
self.shape = shape;
}
return self;
@@ -72,46 +60,10 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
return [self initWithIdentifier:identifier shape:shapeCollection options:options];
}
-- (instancetype)initWithRawSource:(mbgl::style::GeoJSONSource *)rawSource {
- return [super initWithRawSource:rawSource];
-}
-
-- (void)addToMapView:(MGLMapView *)mapView {
- if (_pendingSource == nullptr) {
- [NSException raise:@"MGLRedundantSourceException"
- format:@"This instance %@ was already added to %@. Adding the same source instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- mapView.mbglMap->addSource(std::move(_pendingSource));
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView {
- if (self.rawSource != mapView.mbglMap->getSource(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
-
- mbgl::style::GeoJSONSource *source = dynamic_cast<mbgl::style::GeoJSONSource *>(removedSource.get());
- if (!source) {
- return;
- }
-
- removedSource.release();
-
- _pendingSource = std::unique_ptr<mbgl::style::GeoJSONSource>(source);
- self.rawSource = _pendingSource.get();
-}
-
- (mbgl::style::GeoJSONSource *)rawSource {
return (mbgl::style::GeoJSONSource *)super.rawSource;
}
-- (void)setRawSource:(mbgl::style::GeoJSONSource *)rawSource {
- super.rawSource = rawSource;
-}
-
- (NSURL *)URL {
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
@@ -143,7 +95,10 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh
optionalFilter = predicate.mgl_filter;
}
- std::vector<mbgl::Feature> features = self.rawSource->querySourceFeatures({ {}, optionalFilter });
+ std::vector<mbgl::Feature> features;
+ if (self.mapView) {
+ features = self.mapView.mbglMap->querySourceFeatures(self.rawSource->getID(), { {}, optionalFilter });
+ }
return MGLFeaturesFromMBGLFeatures(features);
}
diff --git a/platform/darwin/src/MGLShapeSource_Private.h b/platform/darwin/src/MGLShapeSource_Private.h
index c14f4fbb59..84eb5deed4 100644
--- a/platform/darwin/src/MGLShapeSource_Private.h
+++ b/platform/darwin/src/MGLShapeSource_Private.h
@@ -6,14 +6,10 @@ NS_ASSUME_NONNULL_BEGIN
namespace mbgl {
namespace style {
class GeoJSONOptions;
- struct GeoJSONSource;
}
}
@interface MGLShapeSource (Private)
-
-- (instancetype)initWithRawSource:(mbgl::style::GeoJSONSource *)rawSource;
-
@end
MGL_EXPORT
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index c96b6c41c6..eb859ba2c0 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -1,16 +1,23 @@
#import "MGLSource_Private.h"
+#import "MGLMapView_Private.h"
+#include <mbgl/map/map.hpp>
#include <mbgl/style/source.hpp>
@interface MGLSource ()
// Even though this class is abstract, MGLStyle uses it to represent some
// special internal source types like mbgl::AnnotationSource.
-@property (nonatomic) mbgl::style::Source *rawSource;
+@property (nonatomic, readonly) mbgl::style::Source *rawSource;
+
+@property (nonatomic, readonly, weak) MGLMapView *mapView;
@end
-@implementation MGLSource
+@implementation MGLSource {
+ std::unique_ptr<mbgl::style::Source> _pendingSource;
+}
+
- (instancetype)initWithIdentifier:(NSString *)identifier
{
@@ -24,22 +31,34 @@
NSString *identifier = @(rawSource->getID().c_str());
if (self = [self initWithIdentifier:identifier]) {
_rawSource = rawSource;
+ _rawSource->peer = SourceWrapper { self };
+ }
+ return self;
+}
+
+- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource {
+ if (self = [self initWithRawSource:pendingSource.get()]) {
+ _pendingSource = std::move(pendingSource);
}
return self;
}
- (void)addToMapView:(MGLMapView *)mapView {
- [NSException raise:NSInvalidArgumentException format:
- @"The source %@ cannot be added to the style. "
- @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
- self];
+ if (_pendingSource == nullptr) {
+ [NSException raise:@"MGLRedundantSourceException"
+ format:@"This instance %@ was already added to %@. Adding the same source instance " \
+ "to the style more than once is invalid.", self, mapView.style];
+ }
+
+ _mapView = mapView;
+ mapView.mbglMap->addSource(std::move(_pendingSource));
}
- (void)removeFromMapView:(MGLMapView *)mapView {
- [NSException raise:NSInvalidArgumentException format:
- @"The source %@ cannot be removed from the style. "
- @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
- self];
+ if (self.rawSource == mapView.mbglMap->getSource(self.identifier.UTF8String)) {
+ _pendingSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
+ _mapView = nil;
+ }
}
- (NSString *)description {
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index acb325e2f3..91bfac6390 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -1,5 +1,7 @@
#import "MGLSource.h"
+#include <memory>
+
NS_ASSUME_NONNULL_BEGIN
namespace mbgl {
@@ -8,23 +10,46 @@ namespace mbgl {
}
}
+// A struct to be stored in the `peer` member of mbgl::style::Source, in order to implement
+// object identity. We don't store a MGLSource pointer directly because that doesn't
+// interoperate with ARC. The inner pointer is weak in order to avoid a reference cycle for
+// "pending" MGLSources, which have a strong owning pointer to the mbgl::style::Source.
+struct SourceWrapper {
+ __weak MGLSource *source;
+};
+
@class MGLMapView;
@interface MGLSource (Private)
/**
- Initializes and returns a source with a raw pointer to the backing store.
+ Initializes and returns a source with a raw pointer to the backing store,
+ associated with a style.
*/
- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource;
/**
+ Initializes and returns a source with an owning pointer to the backing store,
+ unassociated from a style.
+ */
+- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource;
+
+/**
A raw pointer to the mbgl object, which is always initialized, either to the
value returned by `mbgl::Map getSource`, or for independently created objects,
to the pointer value held in `pendingSource`. In the latter case, this raw
pointer value stays even after ownership of the object is transferred via
`mbgl::Map addSource`.
*/
-@property (nonatomic) mbgl::style::Source *rawSource;
+@property (nonatomic, readonly) mbgl::style::Source *rawSource;
+
+/**
+ The map view whose style currently contains the source.
+
+ If the source is not currently part of any map view’s style, this property is
+ set to `nil`.
+ */
+@property (nonatomic, readonly, weak) MGLMapView *mapView;
/**
Adds the mbgl source that this object represents to the mbgl map.
diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h
index bd17fdec44..ccec863236 100644
--- a/platform/darwin/src/MGLStyle.h
+++ b/platform/darwin/src/MGLStyle.h
@@ -10,9 +10,9 @@
NS_ASSUME_NONNULL_BEGIN
/**
- A version number identifying the default version of the suite of default styles
- provided by Mapbox. This version number may be passed into one of the
- “StyleURLWithVersion” class methods of MGLStyle.
+ A version number identifying the default version of the Mapbox Streets style
+ obtained through the `-streetsStyleURL` method. This version number may also be
+ passed into the `-streetsStyleURLWithVersion:` method.
The value of this constant generally corresponds to the latest released version
as of the date on which this SDK was published. You can use this constant to
@@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
the constant itself. Such details may change significantly from version to
version.
*/
-static MGL_EXPORT const NSInteger MGLStyleDefaultVersion = 9;
+static MGL_EXPORT const NSInteger MGLStyleDefaultVersion = 10;
/**
The proxy object for the current map style.
@@ -52,15 +52,22 @@ MGL_EXPORT
#pragma mark Accessing Default Styles
/**
- Returns the URL to version 8 of the
- <a href="https://www.mapbox.com/maps/streets/">Mapbox Streets</a> style.
+ Returns the URL to the current version of the
+ <a href="https://www.mapbox.com/maps/streets/">Mapbox Streets</a> style as of
+ publication.
Streets is a general-purpose style with detailed road and transit networks.
`MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style
is specified explicitly.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-streetsStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
*/
-+ (NSURL *)streetsStyleURL __attribute__((deprecated("Use -streetsStyleURLWithVersion:.")));
++ (NSURL *)streetsStyleURL;
/**
Returns the URL to the given version of the
@@ -71,8 +78,7 @@ MGL_EXPORT
`MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style
is specified explicitly.
- @param version The style’s latest released version. As of publication, the
- current version is `9`.
+ @param version A specific version of the style.
*/
+ (NSURL *)streetsStyleURLWithVersion:(NSInteger)version;
@@ -85,70 +91,102 @@ MGL_EXPORT
+ (NSURL *)emeraldStyleURL __attribute__((deprecated("Create an NSURL object with the string “mapbox://styles/mapbox/emerald-v8”.")));
/**
+ Returns the URL to the current version of the
+ <a href="https://www.mapbox.com/maps/outdoors/">Mapbox Outdoors</a> style as of
+ publication.
+
+ Outdoors is a general-purpose style tailored to outdoor activities.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-outdoorsStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
+ */
++ (NSURL *)outdoorsStyleURL;
+
+/**
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/outdoors/">Mapbox Outdoors</a> style.
Outdoors is a general-purpose style tailored to outdoor activities.
- @param version The style’s latest released version. As of publication, the
- current version is `9`.
+ @param version A specific version of the style.
*/
+ (NSURL *)outdoorsStyleURLWithVersion:(NSInteger)version;
/**
- Returns the URL to version 8 of the
+ Returns the URL to the current version of the
<a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style.
Light is a subtle, light-colored backdrop for data visualizations.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-lightStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
*/
-+ (NSURL *)lightStyleURL __attribute__((deprecated("Use -lightStyleURLWithVersion:.")));
++ (NSURL *)lightStyleURL;
/**
Returns the URL to the given version of the
- <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style.
+ <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style as of
+ publication.
Light is a subtle, light-colored backdrop for data visualizations.
- @param version The style’s latest released version. As of publication, the
- current version is `9`.
+ @param version A specific version of the style.
*/
+ (NSURL *)lightStyleURLWithVersion:(NSInteger)version;
/**
- Returns the URL to version 8 of the
+ Returns the URL to the current version of the
<a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style.
Dark is a subtle, dark-colored backdrop for data visualizations.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-darkStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
*/
-+ (NSURL *)darkStyleURL __attribute__((deprecated("Use -darkStyleURLWithVersion:.")));
++ (NSURL *)darkStyleURL;
/**
Returns the URL to the given version of the
- <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style.
+ <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style as of
+ publication.
Dark is a subtle, dark-colored backdrop for data visualizations.
- @param version The style’s latest released version. As of publication, the
- current version is `9`.
+ @param version A specific version of the style.
*/
+ (NSURL *)darkStyleURLWithVersion:(NSInteger)version;
/**
- Returns the URL to version 8 of the
+ Returns the URL to the current version of the
<a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style.
Satellite is high-resolution satellite and aerial imagery.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the raster tile sets included in the style – use the
+ `-satelliteStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
*/
-+ (NSURL *)satelliteStyleURL __attribute__((deprecated("Use -satelliteStyleURLWithVersion:.")));
++ (NSURL *)satelliteStyleURL;
/**
Returns the URL to the given version of the
- <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style.
+ <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style as
+ of publication.
Satellite is high-resolution satellite and aerial imagery.
- @param version The style’s latest released version. As of publication, the
- current version is `9`.
+ @param version A specific version of the style.
*/
+ (NSURL *)satelliteStyleURLWithVersion:(NSInteger)version;
@@ -161,7 +199,24 @@ MGL_EXPORT
Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox
Streets.
*/
-+ (NSURL *)hybridStyleURL __attribute__((deprecated("Use -satelliteStreetsStyleURLWithVersion:.")));
++ (NSURL *)hybridStyleURL __attribute__((deprecated("Use -satelliteStreetsStyleURL.")));
+
+/**
+ Returns the URL to the current version of the
+ <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite Streets</a>
+ style as of publication.
+
+ Satellite Streets combines the high-resolution satellite and aerial imagery of
+ Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox
+ Streets.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-satelliteStreetsStyleURLWithVersion:` method instead. Such details may
+ change significantly from version to version.
+ */
++ (NSURL *)satelliteStreetsStyleURL;
/**
Returns the URL to the given version of the
@@ -172,11 +227,72 @@ MGL_EXPORT
Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox
Streets.
- @param version The style’s latest released version. As of publication, the
- current version is `9`.
+ @param version A specific version of the style.
*/
+ (NSURL *)satelliteStreetsStyleURLWithVersion:(NSInteger)version;
+/**
+ Returns the URL to the current version of the
+ <a href="https://www.mapbox.com/blog/live-traffic-maps/">Mapbox Traffic Day</a>
+ style.
+
+ Traffic Day color-codes roads based on live traffic congestion data. Traffic
+ data is currently available in
+ <a href="https://www.mapbox.com/api-documentation/pages/traffic-countries.html">these select countries</a>.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-trafficDayStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
+ */
++ (NSURL *)trafficDayStyleURL;
+
+/**
+ Returns the URL to the given version of the
+ <a href="https://www.mapbox.com/blog/live-traffic-maps/">Mapbox Traffic Day</a>
+ style as of publication.
+
+ Traffic Day color-codes roads based on live traffic congestion data. Traffic
+ data is currently available in
+ <a href="https://www.mapbox.com/api-documentation/pages/traffic-countries.html">these select countries</a>.
+
+ @param version A specific version of the style.
+ */
++ (NSURL *)trafficDayStyleURLWithVersion:(NSInteger)version;
+
+/**
+ Returns the URL to the current version of the
+ <a href="https://www.mapbox.com/blog/live-traffic-maps/">Mapbox Traffic Night</a>
+ style.
+
+ Traffic Night color-codes roads based on live traffic congestion data and is
+ designed to maximize legibility in low-light situations. Traffic data is
+ currently available in
+ <a href="https://www.mapbox.com/api-documentation/pages/traffic-countries.html">these select countries</a>.
+
+ @warning The return value may change in a future release of the SDK. If you use
+ any feature that depends on a specific aspect of a default style – for
+ instance, the minimum zoom level that includes roads – use the
+ `-trafficNightStyleURLWithVersion:` method instead. Such details may change
+ significantly from version to version.
+ */
++ (NSURL *)trafficNightStyleURL;
+
+/**
+ Returns the URL to the given version of the
+ <a href="https://www.mapbox.com/blog/live-traffic-maps/">Mapbox Traffic Night</a>
+ style as of publication.
+
+ Traffic Night color-codes roads based on live traffic congestion data and is
+ designed to maximize legibility in low-light situations. Traffic data is
+ currently available in
+ <a href="https://www.mapbox.com/api-documentation/pages/traffic-countries.html">these select countries</a>.
+
+ @param version A specific version of the style.
+ */
++ (NSURL *)trafficNightStyleURLWithVersion:(NSInteger)version;
+
#pragma mark Accessing Metadata About the Style
/**
@@ -367,40 +483,24 @@ MGL_EXPORT
#pragma mark Managing Style Classes
/**
- Currently active style classes, represented as an array of string identifiers.
+ Support for style classes has been removed. This property always returns an empty array.
*/
-@property (nonatomic) NS_ARRAY_OF(NSString *) *styleClasses __attribute__((deprecated("This property will be removed in a future release.")));
+@property (nonatomic) NS_ARRAY_OF(NSString *) *styleClasses __attribute__((deprecated("This property is non-functional.")));
/**
- Returns a Boolean value indicating whether the style class with the given
- identifier is currently active.
-
- @param styleClass The style class to query for.
- @return Whether the style class is currently active.
+ Support for style classes has been removed. This method always returns NO.
*/
-- (BOOL)hasStyleClass:(NSString *)styleClass __attribute__((deprecated("This method will be removed in a future release.")));
+- (BOOL)hasStyleClass:(NSString *)styleClass __attribute__((deprecated("This method is non-functional.")));
/**
- Activates the style class with the given identifier.
-
- @param styleClass The style class to activate.
+ Support for style classes has been removed. This method is a no-op.
*/
-- (void)addStyleClass:(NSString *)styleClass __attribute__((deprecated("This method will be removed in a future release.")));
+- (void)addStyleClass:(NSString *)styleClass __attribute__((deprecated("This method is non-functional.")));
/**
- Deactivates the style class with the given identifier.
-
- @note Style class names are not guaranteed to exist across styles or different
- versions of the same style. Applications that use this API must first set the
- style URL to an explicitly versioned style using a convenience method like
- `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL”
- inspectable in Interface Builder, or a manually constructed `NSURL`. This
- approach also avoids style class name changes that will occur in the default
- style over time.
-
- @param styleClass The style class to deactivate.
+ Support for style classes has been removed. This method is a no-op.
*/
-- (void)removeStyleClass:(NSString *)styleClass __attribute__((deprecated("This method will be removed in a future release.")));
+- (void)removeStyleClass:(NSString *)styleClass __attribute__((deprecated("This method is non-functional.")));
#pragma mark Managing a Style’s Images
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index aa493d9ef7..5f26b4fed2 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -3,6 +3,7 @@
#import "MGLMapView_Private.h"
#import "MGLStyleLayer.h"
#import "MGLFillStyleLayer.h"
+#import "MGLFillExtrusionStyleLayer.h"
#import "MGLLineStyleLayer.h"
#import "MGLCircleStyleLayer.h"
#import "MGLSymbolStyleLayer.h"
@@ -26,8 +27,9 @@
#include <mbgl/map/map.hpp>
#include <mbgl/util/default_styles.hpp>
-#include <mbgl/sprite/sprite_image.hpp>
+#include <mbgl/style/image.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
@@ -56,8 +58,6 @@
#pragma mark Default style URLs
-static_assert(mbgl::util::default_styles::currentVersion == MGLStyleDefaultVersion, "mbgl::util::default_styles::currentVersion and MGLStyleDefaultVersion disagree.");
-
/// @param name The style’s marketing name, written in lower camelCase.
/// @param fileName The last path component in the style’s URL, excluding the version suffix.
#define MGL_DEFINE_STYLE(name, fileName) \
@@ -65,17 +65,13 @@ static_assert(mbgl::util::default_styles::currentVersion == MGLStyleDefaultVersi
+ (NSURL *)name##StyleURL { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
- MGLStyleURL_##name = [self name##StyleURLWithVersion:8]; \
+ MGLStyleURL_##name = [self name##StyleURLWithVersion:mbgl::util::default_styles::name.currentVersion]; \
}); \
return MGLStyleURL_##name; \
} \
\
+ (NSURL *)name##StyleURL##WithVersion:(NSInteger)version { \
- if (mbgl::util::default_styles::currentVersion == version) { \
- return [NSURL URLWithString:@(mbgl::util::default_styles::name.url)]; \
- } else { \
- return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \
- } \
+ return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \
}
MGL_DEFINE_STYLE(streets, streets)
@@ -84,10 +80,12 @@ MGL_DEFINE_STYLE(light, light)
MGL_DEFINE_STYLE(dark, dark)
MGL_DEFINE_STYLE(satellite, satellite)
MGL_DEFINE_STYLE(satelliteStreets, satellite-streets)
+MGL_DEFINE_STYLE(trafficDay, traffic-day)
+MGL_DEFINE_STYLE(trafficNight, traffic-night)
// Make sure all the styles listed in mbgl::util::default_styles::orderedStyles
// are defined above and also declared in MGLStyle.h.
-static_assert(6 == mbgl::util::default_styles::numOrderedStyles,
+static_assert(8 == mbgl::util::default_styles::numOrderedStyles,
"mbgl::util::default_styles::orderedStyles and MGLStyle have different numbers of styles.");
// Hybrid has been renamed Satellite Streets, so the last Hybrid version is hard-coded here.
@@ -165,17 +163,21 @@ static NSURL *MGLStyleURL_emerald;
return rawSource ? [self sourceFromMBGLSource:rawSource] : nil;
}
-- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)source {
+- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)rawSource {
+ if (MGLSource *source = rawSource->peer.empty() ? nil : mbgl::any_cast<SourceWrapper>(rawSource->peer).source) {
+ return source;
+ }
+
// TODO: Fill in options specific to the respective source classes
// https://github.com/mapbox/mapbox-gl-native/issues/6584
- if (auto vectorSource = source->as<mbgl::style::VectorSource>()) {
+ if (auto vectorSource = rawSource->as<mbgl::style::VectorSource>()) {
return [[MGLVectorSource alloc] initWithRawSource:vectorSource];
- } else if (auto geoJSONSource = source->as<mbgl::style::GeoJSONSource>()) {
+ } else if (auto geoJSONSource = rawSource->as<mbgl::style::GeoJSONSource>()) {
return [[MGLShapeSource alloc] initWithRawSource:geoJSONSource];
- } else if (auto rasterSource = source->as<mbgl::style::RasterSource>()) {
+ } else if (auto rasterSource = rawSource->as<mbgl::style::RasterSource>()) {
return [[MGLRasterSource alloc] initWithRawSource:rasterSource];
} else {
- return [[MGLSource alloc] initWithRawSource:source];
+ return [[MGLSource alloc] initWithRawSource:rawSource];
}
}
@@ -318,44 +320,34 @@ static NSURL *MGLStyleURL_emerald;
[styleLayer removeFromMapView:self.mapView];
}
-- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)mbglLayer
+- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)rawLayer
{
- NSParameterAssert(mbglLayer);
-
- NSString *identifier = @(mbglLayer->getID().c_str());
- MGLStyleLayer *styleLayer;
- if (auto fillLayer = mbglLayer->as<mbgl::style::FillLayer>()) {
- MGLSource *source = [self sourceWithIdentifier:@(fillLayer->getSourceID().c_str())];
- styleLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:identifier source:source];
- } else if (auto lineLayer = mbglLayer->as<mbgl::style::LineLayer>()) {
- MGLSource *source = [self sourceWithIdentifier:@(lineLayer->getSourceID().c_str())];
- styleLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:identifier source:source];
- } else if (auto symbolLayer = mbglLayer->as<mbgl::style::SymbolLayer>()) {
- MGLSource *source = [self sourceWithIdentifier:@(symbolLayer->getSourceID().c_str())];
- styleLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:identifier source:source];
- } else if (auto rasterLayer = mbglLayer->as<mbgl::style::RasterLayer>()) {
- MGLSource *source = [self sourceWithIdentifier:@(rasterLayer->getSourceID().c_str())];
- styleLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:identifier source:source];
- } else if (auto circleLayer = mbglLayer->as<mbgl::style::CircleLayer>()) {
- MGLSource *source = [self sourceWithIdentifier:@(circleLayer->getSourceID().c_str())];
- styleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:identifier source:source];
- } else if (mbglLayer->is<mbgl::style::BackgroundLayer>()) {
- styleLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:identifier];
- } else if (mbglLayer->is<mbgl::style::CustomLayer>()) {
- styleLayer = self.openGLLayers[identifier];
- if (styleLayer) {
- NSAssert(styleLayer.rawLayer == mbglLayer->as<mbgl::style::CustomLayer>(), @"%@ wraps a CustomLayer that differs from the one associated with the underlying style.", styleLayer);
- return styleLayer;
- }
- styleLayer = [[MGLOpenGLStyleLayer alloc] initWithIdentifier:identifier];
+ NSParameterAssert(rawLayer);
+
+ if (MGLStyleLayer *layer = rawLayer->peer.empty() ? nil : mbgl::any_cast<LayerWrapper>(rawLayer->peer).layer) {
+ return layer;
+ }
+
+ if (auto fillLayer = rawLayer->as<mbgl::style::FillLayer>()) {
+ return [[MGLFillStyleLayer alloc] initWithRawLayer:fillLayer];
+ } else if (auto fillExtrusionLayer = rawLayer->as<mbgl::style::FillExtrusionLayer>()) {
+ return [[MGLFillExtrusionStyleLayer alloc] initWithRawLayer:fillExtrusionLayer];
+ } else if (auto lineLayer = rawLayer->as<mbgl::style::LineLayer>()) {
+ return [[MGLLineStyleLayer alloc] initWithRawLayer:lineLayer];
+ } else if (auto symbolLayer = rawLayer->as<mbgl::style::SymbolLayer>()) {
+ return [[MGLSymbolStyleLayer alloc] initWithRawLayer:symbolLayer];
+ } else if (auto rasterLayer = rawLayer->as<mbgl::style::RasterLayer>()) {
+ return [[MGLRasterStyleLayer alloc] initWithRawLayer:rasterLayer];
+ } else if (auto circleLayer = rawLayer->as<mbgl::style::CircleLayer>()) {
+ return [[MGLCircleStyleLayer alloc] initWithRawLayer:circleLayer];
+ } else if (auto backgroundLayer = rawLayer->as<mbgl::style::BackgroundLayer>()) {
+ return [[MGLBackgroundStyleLayer alloc] initWithRawLayer:backgroundLayer];
+ } else if (auto customLayer = rawLayer->as<mbgl::style::CustomLayer>()) {
+ return [[MGLOpenGLStyleLayer alloc] initWithRawLayer:customLayer];
} else {
NSAssert(NO, @"Unrecognized layer type");
return nil;
}
-
- styleLayer.rawLayer = mbglLayer;
-
- return styleLayer;
}
- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
@@ -477,60 +469,32 @@ static NSURL *MGLStyleURL_emerald;
- (NS_ARRAY_OF(NSString *) *)styleClasses
{
- const std::vector<std::string> &appliedClasses = self.mapView.mbglMap->getClasses();
-
- NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:appliedClasses.size()];
-
- for (auto appliedClass : appliedClasses) {
- [returnArray addObject:@(appliedClass.c_str())];
- }
-
- return returnArray;
+ return @[];
}
- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses
{
- [self setStyleClasses:appliedClasses transitionDuration:0];
}
- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration
{
- std::vector<std::string> newAppliedClasses;
-
- for (NSString *appliedClass in appliedClasses)
- {
- newAppliedClasses.push_back([appliedClass UTF8String]);
- }
-
- mbgl::style::TransitionOptions transition { { MGLDurationFromTimeInterval(transitionDuration) } };
- self.mapView.mbglMap->setTransitionOptions(transition);
- self.mapView.mbglMap->setClasses(newAppliedClasses);
}
- (NSUInteger)countOfStyleClasses {
- const auto &classes = self.mapView.mbglMap->getClasses();
- return classes.size();
+ return 0;
}
- (BOOL)hasStyleClass:(NSString *)styleClass
{
- return styleClass && self.mapView.mbglMap->hasClass([styleClass UTF8String]);
+ return NO;
}
- (void)addStyleClass:(NSString *)styleClass
{
- if (styleClass)
- {
- self.mapView.mbglMap->addClass([styleClass UTF8String]);
- }
}
- (void)removeStyleClass:(NSString *)styleClass
{
- if (styleClass)
- {
- self.mapView.mbglMap->removeClass([styleClass UTF8String]);
- }
}
#pragma mark Style images
@@ -546,7 +510,7 @@ static NSURL *MGLStyleURL_emerald;
format:@"Cannot assign image %@ to a nil name.", image];
}
- self.mapView.mbglMap->addImage([name UTF8String], image.mgl_spriteImage);
+ self.mapView.mbglMap->addImage([image mgl_styleImageWithIdentifier:name]);
}
- (void)removeImageForName:(NSString *)name
@@ -566,8 +530,8 @@ static NSURL *MGLStyleURL_emerald;
format:@"Cannot get image with nil name."];
}
- auto spriteImage = self.mapView.mbglMap->getImage([name UTF8String]);
- return spriteImage ? [[MGLImage alloc] initWithMGLSpriteImage:spriteImage] : nil;
+ auto styleImage = self.mapView.mbglMap->getImage([name UTF8String]);
+ return styleImage ? [[MGLImage alloc] initWithMGLStyleImage:styleImage] : nil;
}
#pragma mark Style transitions
diff --git a/platform/darwin/src/MGLStyleLayer.h b/platform/darwin/src/MGLStyleLayer.h
index ac9b739c74..7d181667d6 100644
--- a/platform/darwin/src/MGLStyleLayer.h
+++ b/platform/darwin/src/MGLStyleLayer.h
@@ -27,25 +27,7 @@ MGL_EXPORT
#pragma mark Initializing a Style Layer
-- (instancetype)init __attribute__((unavailable("Use -initWithIdentifier: instead.")));
-
-/**
- Returns a style layer object initialized with the given identifier.
-
- The default implementation of this initializer in MGLStyleLayer creates an
- invalid style layer. Call this initializer on `MGLBackgroundStyleLayer` or one of
- the concrete subclasses of `MGLForegroundStyleLayer` to create a valid style
- layer.
-
- After initializing and configuring the style layer, add it to a map view’s
- style using the `-[MGLStyle addLayer:]` or
- `-[MGLStyle insertLayer:belowLayer:]` method.
-
- @param identifier A string that uniquely identifies the layer in the style to
- which it is added.
- @return An initialized style layer.
- */
-- (instancetype)initWithIdentifier:(NSString *)identifier;
+- (instancetype)init __attribute__((unavailable("Use -init methods of concrete subclasses instead.")));
#pragma mark Identifying a Style Layer
diff --git a/platform/darwin/src/MGLStyleLayer.h.ejs b/platform/darwin/src/MGLStyleLayer.h.ejs
index e6c60a76db..df42621c6d 100644
--- a/platform/darwin/src/MGLStyleLayer.h.ejs
+++ b/platform/darwin/src/MGLStyleLayer.h.ejs
@@ -84,7 +84,33 @@ MGL_EXPORT
%>StyleLayer
<% if (type === 'background') { -%>
-- (instancetype)initWithIdentifier:(NSString *)identifier NS_DESIGNATED_INITIALIZER;
+/**
+Returns a <%- type %> style layer initialized with an identifier.
+
+After initializing and configuring the style layer, add it to a map view’s
+style using the `-[MGLStyle addLayer:]` or
+`-[MGLStyle insertLayer:belowLayer:]` method.
+
+@param identifier A string that uniquely identifies the source in the style to
+which it is added.
+*/
+- (instancetype)initWithIdentifier:(NSString *)identifier;
+<% } else { -%>
+
+/**
+ Returns a <%- type %> style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
<% } -%>
<% if (layoutProperties.length) { -%>
@@ -135,7 +161,7 @@ MGL_EXPORT
*/
@interface NSValue (MGL<%- camelize(type) %>StyleLayerAdditions)
-#pragma mark Working with <%- camelize(type) %> Style Layer Attribute Values
+#pragma mark Working with <%- camelize(unhyphenate(type)) %> Style Layer Attribute Values
<% for (let property of enumProperties) { -%>
/**
diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm
index 47f41e0388..4bfaea934b 100644
--- a/platform/darwin/src/MGLStyleLayer.mm
+++ b/platform/darwin/src/MGLStyleLayer.mm
@@ -1,24 +1,58 @@
#import "MGLStyleLayer_Private.h"
#import "MGLMapView_Private.h"
+#include <mbgl/map/map.hpp>
#include <mbgl/style/layer.hpp>
@interface MGLStyleLayer ()
-@property (nonatomic) mbgl::style::Layer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::Layer *rawLayer;
@end
-@implementation MGLStyleLayer
+@implementation MGLStyleLayer {
+ std::unique_ptr<mbgl::style::Layer> _pendingLayer;
+}
-- (instancetype)initWithIdentifier:(NSString *)identifier
-{
+- (instancetype)initWithRawLayer:(mbgl::style::Layer *)rawLayer {
if (self = [super init]) {
- _identifier = identifier;
+ _identifier = @(rawLayer->getID().c_str());
+ _rawLayer = rawLayer;
+ _rawLayer->peer = LayerWrapper { self };
+ }
+ return self;
+}
+
+- (instancetype)initWithPendingLayer:(std::unique_ptr<mbgl::style::Layer>)pendingLayer {
+ if (self = [self initWithRawLayer:pendingLayer.get()]) {
+ _pendingLayer = std::move(pendingLayer);
}
return self;
}
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ if (_pendingLayer == nullptr) {
+ [NSException raise:@"MGLRedundantLayerException"
+ format:@"This instance %@ was already added to %@. Adding the same layer instance " \
+ "to the style more than once is invalid.", self, mapView.style];
+ }
+
+ if (otherLayer) {
+ const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
+ mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
+ } else {
+ mapView.mbglMap->addLayer(std::move(_pendingLayer));
+ }
+}
+
+- (void)removeFromMapView:(MGLMapView *)mapView
+{
+ if (self.rawLayer == mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
+ _pendingLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ }
+}
+
- (void)setVisible:(BOOL)visible
{
MGLAssertStyleLayerIsValid();
diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs
index 1e5f3df160..da67cbd633 100644
--- a/platform/darwin/src/MGLStyleLayer.mm.ejs
+++ b/platform/darwin/src/MGLStyleLayer.mm.ejs
@@ -8,14 +8,13 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGL<%- camelize(type) %>StyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
<% if (enumProperties) { -%>
@@ -50,35 +49,24 @@ namespace mbgl {
@interface MGL<%- camelize(type) %>StyleLayer ()
-@property (nonatomic) mbgl::style::<%- camelize(type) %>Layer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::<%- camelize(type) %>Layer *rawLayer;
@end
@implementation MGL<%- camelize(type) %>StyleLayer
-{
- std::unique_ptr<mbgl::style::<%- camelize(type) %>Layer> _pendingLayer;
-}
<% if (type == 'background') { -%>
- (instancetype)initWithIdentifier:(NSString *)identifier
{
- if (self = [super initWithIdentifier:identifier]) {
- auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
<% } else { -%>
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super initWithIdentifier:identifier source:source]) {
- auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String, source.identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
<% } -%>
@@ -87,11 +75,6 @@ namespace mbgl {
return (mbgl::style::<%- camelize(type) %>Layer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::<%- camelize(type) %>Layer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
<% if (type !== 'background') { -%>
- (NSString *)sourceIdentifier
{
@@ -131,46 +114,6 @@ namespace mbgl {
}
<% }} -%>
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::<%- camelize(type) %>Layer *layer = dynamic_cast<mbgl::style::<%- camelize(type) %>Layer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::<%- camelize(type) %>Layer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
<% if (layoutProperties.length) { -%>
#pragma mark - Accessing the Layout Attributes
diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h
index b5d709a7af..ed8ec31755 100644
--- a/platform/darwin/src/MGLStyleLayer_Private.h
+++ b/platform/darwin/src/MGLStyleLayer_Private.h
@@ -7,6 +7,14 @@
NS_ASSUME_NONNULL_BEGIN
+// A struct to be stored in the `peer` member of mbgl::style::Layer, in order to implement
+// object identity. We don't store a MGLStyleLayer pointer directly because that doesn't
+// interoperate with ARC. The inner pointer is weak in order to avoid a reference cycle for
+// "pending" MGLStyleLayers, which have a strong owning pointer to the mbgl::style::Layer.
+struct LayerWrapper {
+ __weak MGLStyleLayer *layer;
+};
+
/**
Assert that the style layer is valid.
@@ -30,6 +38,18 @@ NS_ASSUME_NONNULL_BEGIN
@interface MGLStyleLayer (Private)
+/**
+ Initializes and returns a layer with a raw pointer to the backing store,
+ associated with a style.
+ */
+- (instancetype)initWithRawLayer:(mbgl::style::Layer *)rawLayer;
+
+/**
+ Initializes and returns a layer with an owning pointer to the backing store,
+ unassociated from a style.
+ */
+- (instancetype)initWithPendingLayer:(std::unique_ptr<mbgl::style::Layer>)pendingLayer;
+
@property (nonatomic, readwrite, copy) NSString *identifier;
/**
@@ -39,7 +59,7 @@ NS_ASSUME_NONNULL_BEGIN
pointer value stays even after ownership of the object is transferred via
`mbgl::Map addLayer`.
*/
-@property (nonatomic) mbgl::style::Layer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::Layer *rawLayer;
/**
Adds the mbgl style layer that this object represents to the mbgl map below the
diff --git a/platform/darwin/src/MGLStyleValue_Private.h b/platform/darwin/src/MGLStyleValue_Private.h
index 90d6622c93..263b54d7e5 100644
--- a/platform/darwin/src/MGLStyleValue_Private.h
+++ b/platform/darwin/src/MGLStyleValue_Private.h
@@ -123,8 +123,9 @@ public:
return toMBGLConstantValue((MGLConstantStyleValue<ObjCType> *)value);
} else if ([value isKindOfClass:[MGLStyleFunction class]]) {
auto rawValue = toRawStyleSpecValue((MGLStyleFunction<ObjCType> *) value);
- auto result = mbgl::style::conversion::convert<mbgl::style::DataDrivenPropertyValue<MBGLType>>(rawValue);
- NSCAssert(result, @(result.error().message.c_str()));
+ mbgl::style::conversion::Error error;
+ auto result = mbgl::style::conversion::convert<mbgl::style::DataDrivenPropertyValue<MBGLType>>(rawValue, error);
+ NSCAssert(result, @(error.message.c_str()));
return *result;
} else {
return {};
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index c76efe2de7..b6c6372324 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -280,6 +280,21 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslationAnchor) {
MGL_EXPORT
@interface MGLSymbolStyleLayer : MGLVectorStyleLayer
+/**
+ Returns a symbol style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source;
+
#pragma mark - Accessing the Layout Attributes
/**
@@ -344,8 +359,18 @@ MGL_EXPORT
You can set this property to an instance of:
* `MGLConstantStyleValue`
- * `MGLCameraStyleFunction` with an interpolation mode of
- `MGLInterpolationModeInterval`
+ * `MGLCameraStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *iconImageName;
@@ -527,6 +552,15 @@ MGL_EXPORT
* `MGLCameraStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconScale;
@@ -909,6 +943,15 @@ MGL_EXPORT
* `MGLCameraStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textFontSize;
@@ -1026,6 +1069,15 @@ MGL_EXPORT
* `MGLCameraStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textOffset;
#else
@@ -1047,6 +1099,15 @@ MGL_EXPORT
* `MGLCameraStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textOffset;
#endif
@@ -1132,6 +1193,15 @@ MGL_EXPORT
* `MGLCameraStyleFunction` with an interpolation mode of:
* `MGLInterpolationModeExponential`
* `MGLInterpolationModeInterval`
+ * `MGLSourceStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
+ * `MGLInterpolationModeIdentity`
+ * `MGLCompositeStyleFunction` with an interpolation mode of:
+ * `MGLInterpolationModeExponential`
+ * `MGLInterpolationModeInterval`
+ * `MGLInterpolationModeCategorical`
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textRotation;
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm
index 8441931685..5a8f8c6084 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.mm
+++ b/platform/darwin/src/MGLSymbolStyleLayer.mm
@@ -2,14 +2,13 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLSource.h"
-#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLSymbolStyleLayer.h"
-#include <mbgl/map/map.hpp>
+#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
namespace mbgl {
@@ -82,23 +81,16 @@ namespace mbgl {
@interface MGLSymbolStyleLayer ()
-@property (nonatomic) mbgl::style::SymbolLayer *rawLayer;
+@property (nonatomic, readonly) mbgl::style::SymbolLayer *rawLayer;
@end
@implementation MGLSymbolStyleLayer
-{
- std::unique_ptr<mbgl::style::SymbolLayer> _pendingLayer;
-}
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super initWithIdentifier:identifier source:source]) {
- auto layer = std::make_unique<mbgl::style::SymbolLayer>(identifier.UTF8String, source.identifier.UTF8String);
- _pendingLayer = std::move(layer);
- self.rawLayer = _pendingLayer.get();
- }
- return self;
+ auto layer = std::make_unique<mbgl::style::SymbolLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ return self = [super initWithPendingLayer:std::move(layer)];
}
- (mbgl::style::SymbolLayer *)rawLayer
@@ -106,11 +98,6 @@ namespace mbgl {
return (mbgl::style::SymbolLayer *)super.rawLayer;
}
-- (void)setRawLayer:(mbgl::style::SymbolLayer *)rawLayer
-{
- super.rawLayer = rawLayer;
-}
-
- (NSString *)sourceIdentifier
{
MGLAssertStyleLayerIsValid();
@@ -147,46 +134,6 @@ namespace mbgl {
return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()];
}
-#pragma mark - Adding to and removing from a map view
-
-- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
-{
- if (_pendingLayer == nullptr) {
- [NSException raise:@"MGLRedundantLayerException"
- format:@"This instance %@ was already added to %@. Adding the same layer instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- if (otherLayer) {
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId);
- } else {
- mapView.mbglMap->addLayer(std::move(_pendingLayer));
- }
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView
-{
- if (self.rawLayer != mapView.mbglMap->getLayer(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
- if (!removedLayer) {
- return;
- }
-
- mbgl::style::SymbolLayer *layer = dynamic_cast<mbgl::style::SymbolLayer *>(removedLayer.get());
- if (!layer) {
- return;
- }
-
- removedLayer.release();
-
- _pendingLayer = std::unique_ptr<mbgl::style::SymbolLayer>(layer);
- self.rawLayer = _pendingLayer.get();
-}
-
#pragma mark - Accessing the Layout Attributes
- (void)setIconAllowsOverlap:(MGLStyleValue<NSNumber *> *)iconAllowsOverlap {
@@ -240,7 +187,7 @@ namespace mbgl {
- (void)setIconImageName:(MGLStyleValue<NSString *> *)iconImageName {
MGLAssertStyleLayerIsValid();
- auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(iconImageName);
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toDataDrivenPropertyValue(iconImageName);
self.rawLayer->setIconImage(mbglValue);
}
@@ -249,9 +196,9 @@ namespace mbgl {
auto propertyValue = self.rawLayer->getIconImage();
if (propertyValue.isUndefined()) {
- return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(self.rawLayer->getDefaultIconImage());
+ return MGLStyleValueTransformer<std::string, NSString *>().toDataDrivenStyleValue(self.rawLayer->getDefaultIconImage());
}
- return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
+ return MGLStyleValueTransformer<std::string, NSString *>().toDataDrivenStyleValue(propertyValue);
}
- (void)setIconImage:(MGLStyleValue<NSString *> *)iconImage {
@@ -356,7 +303,7 @@ namespace mbgl {
- (void)setIconScale:(MGLStyleValue<NSNumber *> *)iconScale {
MGLAssertStyleLayerIsValid();
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(iconScale);
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(iconScale);
self.rawLayer->setIconSize(mbglValue);
}
@@ -365,9 +312,9 @@ namespace mbgl {
auto propertyValue = self.rawLayer->getIconSize();
if (propertyValue.isUndefined()) {
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultIconSize());
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultIconSize());
}
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue);
}
- (void)setIconSize:(MGLStyleValue<NSNumber *> *)iconSize {
@@ -657,7 +604,7 @@ namespace mbgl {
- (void)setTextFontSize:(MGLStyleValue<NSNumber *> *)textFontSize {
MGLAssertStyleLayerIsValid();
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(textFontSize);
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(textFontSize);
self.rawLayer->setTextSize(mbglValue);
}
@@ -666,9 +613,9 @@ namespace mbgl {
auto propertyValue = self.rawLayer->getTextSize();
if (propertyValue.isUndefined()) {
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultTextSize());
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultTextSize());
}
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue);
}
- (void)setTextSize:(MGLStyleValue<NSNumber *> *)textSize {
@@ -763,7 +710,7 @@ namespace mbgl {
- (void)setTextOffset:(MGLStyleValue<NSValue *> *)textOffset {
MGLAssertStyleLayerIsValid();
- auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toInterpolatablePropertyValue(textOffset);
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toDataDrivenPropertyValue(textOffset);
self.rawLayer->setTextOffset(mbglValue);
}
@@ -772,9 +719,9 @@ namespace mbgl {
auto propertyValue = self.rawLayer->getTextOffset();
if (propertyValue.isUndefined()) {
- return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(self.rawLayer->getDefaultTextOffset());
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toDataDrivenStyleValue(self.rawLayer->getDefaultTextOffset());
}
- return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toDataDrivenStyleValue(propertyValue);
}
- (void)setTextOptional:(MGLStyleValue<NSNumber *> *)textOptional {
@@ -831,7 +778,7 @@ namespace mbgl {
- (void)setTextRotation:(MGLStyleValue<NSNumber *> *)textRotation {
MGLAssertStyleLayerIsValid();
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(textRotation);
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(textRotation);
self.rawLayer->setTextRotate(mbglValue);
}
@@ -840,9 +787,9 @@ namespace mbgl {
auto propertyValue = self.rawLayer->getTextRotate();
if (propertyValue.isUndefined()) {
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultTextRotate());
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultTextRotate());
}
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+ return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue);
}
- (void)setTextRotate:(MGLStyleValue<NSNumber *> *)textRotate {
diff --git a/platform/darwin/src/MGLTileSource.h b/platform/darwin/src/MGLTileSource.h
index 54c756332d..538b94037e 100644
--- a/platform/darwin/src/MGLTileSource.h
+++ b/platform/darwin/src/MGLTileSource.h
@@ -147,135 +147,6 @@ typedef NS_ENUM(NSUInteger, MGLTileCoordinateSystem) {
MGL_EXPORT
@interface MGLTileSource : MGLSource
-#pragma mark Initializing a Source
-
-- (instancetype)init __attribute__((unavailable("Use -initWithIdentifier:configurationURL: or -initWithIdentifier:tileURLTemplates:options: instead.")));
-- (instancetype)initWithIdentifier:(NSString *)identifier __attribute__((unavailable("Use -initWithIdentifier:configurationURL: or -initWithIdentifier:tileURLTemplates:options: instead.")));
-
-/**
- Returns a tile source initialized with an identifier and configuration URL.
-
- After initializing and configuring the source, add it to a map view’s style
- using the `-[MGLStyle addSource:]` method.
-
- The URL may be a full HTTP or HTTPS URL or, for tile sets hosted by Mapbox, a
- Mapbox URL indicating a map identifier (`mapbox://<mapid>`). The URL should
- point to a JSON file that conforms to the
- <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>.
-
- @param identifier A string that uniquely identifies the source in the style to
- which it is added.
- @param configurationURL A URL to a TileJSON configuration file describing the
- source’s contents and other metadata.
- @return An initialized tile source.
- */
-- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL;
-
-/**
- Returns a tile source initialized an identifier, tile URL templates, and
- options.
-
- After initializing and configuring the source, add it to a map view’s style
- using the `-[MGLStyle addSource:]` method.
-
- #### Tile URL templates
-
- Tile URL templates are strings that specify the URLs of the tile images to
- load. Each template resembles an absolute URL, but with any number of
- placeholder strings that the source evaluates based on the tile it needs to
- load. For example:
-
- <ul>
- <li><code>http://www.example.com/tiles/{z}/{x}/{y}.pbf</code> could be
- evaluated as <code>http://www.example.com/tiles/14/6/9.pbf</code>.</li>
- <li><code>http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png</code> could be
- evaluated as <code>http://www.example.com/tiles/14/6/9@2x.png</code>.</li>
- </ul>
-
- Tile sources support the following placeholder strings in tile URL templates,
- all of which are optional:
-
- <table>
- <thead>
- <tr><th>Placeholder string</th><th>Description</th></tr>
- </thead>
- <tbody>
- <tr>
- <td><code>{x}</code></td>
- <td>The index of the tile along the map’s x axis according to Spherical
- Mercator projection. If the value is 0, the tile’s left edge corresponds
- to the 180th meridian west. If the value is 2<sup><var>z</var></sup>−1,
- the tile’s right edge corresponds to the 180th meridian east.</td>
- </tr>
- <tr>
- <td><code>{y}</code></td>
- <td>The index of the tile along the map’s y axis according to Spherical
- Mercator projection. If the value is 0, the tile’s tile edge corresponds
- to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value
- is 2<sup><var>z</var></sup>−1, the tile’s bottom edge corresponds to
- −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is
- inverted if the <code>options</code> parameter contains
- <code>MGLTileSourceOptionTileCoordinateSystem</code> with a value of
- <code>MGLTileCoordinateSystemTMS</code>.</td>
- </tr>
- <tr>
- <td><code>{z}</code></td>
- <td>The tile’s zoom level. At zoom level 0, each tile covers the entire
- world map; at zoom level 1, it covers ¼ of the world; at zoom level 2,
- <sup>1</sup>⁄<sub>16</sub> of the world, and so on. For tiles loaded by
- a <code>MGLRasterSource</code> object, whether the tile zoom level
- matches the map’s current zoom level depends on the value of the
- source’s tile size as specified in the
- <code>MGLTileSourceOptionTileSize</code> key of the
- <code>options</code> parameter.</td>
- </tr>
- <tr>
- <td><code>{bbox-epsg-3857}</code></td>
- <td>The tile’s bounding box, expressed as a comma-separated list of the
- tile’s western, southern, eastern, and northern extents according to
- Spherical Mercator (EPSG:3857) projection. The bounding box is typically
- used with map services conforming to the
- <a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a>
- protocol.</td>
- </tr>
- <tr>
- <td><code>{quadkey}</code></td>
- <td>A quadkey indicating both the tile’s location and its zoom level. The
- quadkey is typically used with
- <a href="https://msdn.microsoft.com/en-us/library/bb259689.aspx">Bing Maps</a>.
- </td>
- </tr>
- <tr>
- <td><code>{ratio}</code></td>
- <td>A suffix indicating the resolution of the tile image. The suffix is the
- empty string for standard resolution displays and <code>@2x</code> for
- Retina displays, including displays for which
- <code>NSScreen.backingScaleFactor</code> or <code>UIScreen.scale</code>
- is 3.</td>
- </tr>
- <tr>
- <td><code>{prefix}</code></td>
- <td>Two hexadecimal digits chosen such that each visible tile has a
- different prefix. The prefix is typically used for domain sharding.</td>
- </tr>
- </tbody>
- </table>
-
- For more information about the `{x}`, `{y}`, and `{z}` placeholder strings,
- consult the
- <a href="https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames">OpenStreetMap Wiki</a>.
-
- @param identifier A string that uniquely identifies the source in the style to
- which it is added.
- @param tileURLTemplates An array of tile URL template strings. Only the first
- string is used; any additional strings are ignored.
- @param options A dictionary containing configuration options. See
- `MGLTileSourceOption` for available keys and values. Pass in `nil` to use
- the default values.
- @return An initialized tile source.
- */
-- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options;
-
#pragma mark Accessing a Source’s Content
/**
diff --git a/platform/darwin/src/MGLTileSource.mm b/platform/darwin/src/MGLTileSource.mm
index aa2a299a46..5644ad9a06 100644
--- a/platform/darwin/src/MGLTileSource.mm
+++ b/platform/darwin/src/MGLTileSource.mm
@@ -19,14 +19,6 @@ const MGLTileSourceOption MGLTileSourceOptionTileCoordinateSystem = @"MGLTileSou
@implementation MGLTileSource
-- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL {
- return [super initWithIdentifier:identifier];
-}
-
-- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options {
- return [super initWithIdentifier:identifier];
-}
-
- (NSURL *)configurationURL {
[NSException raise:@"MGLAbstractClassException"
format:@"MGLTileSource is an abstract class"];
diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h
index 5216e921f1..c06fd8b0e7 100644
--- a/platform/darwin/src/MGLTypes.h
+++ b/platform/darwin/src/MGLTypes.h
@@ -42,6 +42,10 @@ typedef NS_ENUM(NSInteger, MGLErrorCode) {
MGLErrorCodeBadServerResponse = 2,
/** An attempt to establish a connection failed. */
MGLErrorCodeConnectionFailed = 3,
+ /** A style parse error occurred while attempting to load the map. */
+ MGLErrorCodeParseStyleFailed = 4,
+ /** An attempt to load the style failed. */
+ MGLErrorCodeLoadStyleFailed = 5,
};
/** Options for enabling debugging features in an `MGLMapView` instance. */
diff --git a/platform/darwin/src/MGLVectorSource.h b/platform/darwin/src/MGLVectorSource.h
index 83926fd287..a48434f7a3 100644
--- a/platform/darwin/src/MGLVectorSource.h
+++ b/platform/darwin/src/MGLVectorSource.h
@@ -51,8 +51,128 @@ MGL_EXPORT
#pragma mark Initializing a Source
+/**
+ Returns a vector source initialized with an identifier and configuration URL.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ The URL may be a full HTTP or HTTPS URL or, for tile sets hosted by Mapbox, a
+ Mapbox URL indicating a map identifier (`mapbox://<mapid>`). The URL should
+ point to a JSON file that conforms to the
+ <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param configurationURL A URL to a TileJSON configuration file describing the
+ source’s contents and other metadata.
+ @return An initialized vector source.
+ */
- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL NS_DESIGNATED_INITIALIZER;
+/**
+ Returns a vector source initialized an identifier, tile URL templates, and
+ options.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ #### Tile URL templates
+
+ Tile URL templates are strings that specify the URLs of the tile images to
+ load. Each template resembles an absolute URL, but with any number of
+ placeholder strings that the source evaluates based on the tile it needs to
+ load. For example:
+
+ <ul>
+ <li><code>http://www.example.com/tiles/{z}/{x}/{y}.pbf</code> could be
+ evaluated as <code>http://www.example.com/tiles/14/6/9.pbf</code>.</li>
+ <li><code>http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png</code> could be
+ evaluated as <code>http://www.example.com/tiles/14/6/9@2x.png</code>.</li>
+ </ul>
+
+ Tile sources support the following placeholder strings in tile URL templates,
+ all of which are optional:
+
+ <table>
+ <thead>
+ <tr><th>Placeholder string</th><th>Description</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>{x}</code></td>
+ <td>The index of the tile along the map’s x axis according to Spherical
+ Mercator projection. If the value is 0, the tile’s left edge corresponds
+ to the 180th meridian west. If the value is 2<sup><var>z</var></sup>−1,
+ the tile’s right edge corresponds to the 180th meridian east.</td>
+ </tr>
+ <tr>
+ <td><code>{y}</code></td>
+ <td>The index of the tile along the map’s y axis according to Spherical
+ Mercator projection. If the value is 0, the tile’s tile edge corresponds
+ to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value
+ is 2<sup><var>z</var></sup>−1, the tile’s bottom edge corresponds to
+ −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is
+ inverted if the <code>options</code> parameter contains
+ <code>MGLTileSourceOptionTileCoordinateSystem</code> with a value of
+ <code>MGLTileCoordinateSystemTMS</code>.</td>
+ </tr>
+ <tr>
+ <td><code>{z}</code></td>
+ <td>The tile’s zoom level. At zoom level 0, each tile covers the entire
+ world map; at zoom level 1, it covers ¼ of the world; at zoom level 2,
+ <sup>1</sup>⁄<sub>16</sub> of the world, and so on. For tiles loaded by
+ a <code>MGLRasterSource</code> object, whether the tile zoom level
+ matches the map’s current zoom level depends on the value of the
+ source’s tile size as specified in the
+ <code>MGLTileSourceOptionTileSize</code> key of the
+ <code>options</code> parameter.</td>
+ </tr>
+ <tr>
+ <td><code>{bbox-epsg-3857}</code></td>
+ <td>The tile’s bounding box, expressed as a comma-separated list of the
+ tile’s western, southern, eastern, and northern extents according to
+ Spherical Mercator (EPSG:3857) projection. The bounding box is typically
+ used with map services conforming to the
+ <a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a>
+ protocol.</td>
+ </tr>
+ <tr>
+ <td><code>{quadkey}</code></td>
+ <td>A quadkey indicating both the tile’s location and its zoom level. The
+ quadkey is typically used with
+ <a href="https://msdn.microsoft.com/en-us/library/bb259689.aspx">Bing Maps</a>.
+ </td>
+ </tr>
+ <tr>
+ <td><code>{ratio}</code></td>
+ <td>A suffix indicating the resolution of the tile image. The suffix is the
+ empty string for standard resolution displays and <code>@2x</code> for
+ Retina displays, including displays for which
+ <code>NSScreen.backingScaleFactor</code> or <code>UIScreen.scale</code>
+ is 3.</td>
+ </tr>
+ <tr>
+ <td><code>{prefix}</code></td>
+ <td>Two hexadecimal digits chosen such that each visible tile has a
+ different prefix. The prefix is typically used for domain sharding.</td>
+ </tr>
+ </tbody>
+ </table>
+
+ For more information about the `{x}`, `{y}`, and `{z}` placeholder strings,
+ consult the
+ <a href="https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames">OpenStreetMap Wiki</a>.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param tileURLTemplates An array of tile URL template strings. Only the first
+ string is used; any additional strings are ignored.
+ @param options A dictionary containing configuration options. See
+ `MGLTileSourceOption` for available keys and values. Pass in `nil` to use
+ the default values.
+ @return An initialized tile source.
+ */
- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options NS_DESIGNATED_INITIALIZER;
#pragma mark Accessing a Source’s Content
diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm
index aeec2e40ac..5e9f4f4a6e 100644
--- a/platform/darwin/src/MGLVectorSource.mm
+++ b/platform/darwin/src/MGLVectorSource.mm
@@ -1,9 +1,9 @@
#import "MGLVectorSource_Private.h"
-#import "MGLMapView_Private.h"
#import "MGLFeature_Private.h"
#import "MGLSource_Private.h"
#import "MGLTileSource_Private.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "NSURL+MGLAdditions.h"
@@ -12,77 +12,28 @@
@interface MGLVectorSource ()
-- (instancetype)initWithRawSource:(mbgl::style::VectorSource *)rawSource NS_DESIGNATED_INITIALIZER;
-
-@property (nonatomic) mbgl::style::VectorSource *rawSource;
+@property (nonatomic, readonly) mbgl::style::VectorSource *rawSource;
@end
-@implementation MGLVectorSource {
- std::unique_ptr<mbgl::style::VectorSource> _pendingSource;
-}
+@implementation MGLVectorSource
- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL {
- if (self = [super initWithIdentifier:identifier configurationURL:configurationURL]) {
- auto source = std::make_unique<mbgl::style::VectorSource>(identifier.UTF8String,
- configurationURL.mgl_URLByStandardizingScheme.absoluteString.UTF8String);
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
- }
- return self;
+ auto source = std::make_unique<mbgl::style::VectorSource>(identifier.UTF8String,
+ configurationURL.mgl_URLByStandardizingScheme.absoluteString.UTF8String);
+ return self = [super initWithPendingSource:std::move(source)];
}
- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options {
- if (self = [super initWithIdentifier:identifier tileURLTemplates:tileURLTemplates options:options]) {
- mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options);
-
- auto source = std::make_unique<mbgl::style::VectorSource>(identifier.UTF8String, tileSet);
- _pendingSource = std::move(source);
- self.rawSource = _pendingSource.get();
- }
- return self;
-}
-
-- (instancetype)initWithRawSource:(mbgl::style::VectorSource *)rawSource {
- return [super initWithRawSource:rawSource];
-}
-
-- (void)addToMapView:(MGLMapView *)mapView {
- if (_pendingSource == nullptr) {
- [NSException raise:@"MGLRedundantSourceException"
- format:@"This instance %@ was already added to %@. Adding the same source instance " \
- "to the style more than once is invalid.", self, mapView.style];
- }
-
- mapView.mbglMap->addSource(std::move(_pendingSource));
-}
-
-- (void)removeFromMapView:(MGLMapView *)mapView {
- if (self.rawSource != mapView.mbglMap->getSource(self.identifier.UTF8String)) {
- return;
- }
-
- auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
-
- mbgl::style::VectorSource *source = dynamic_cast<mbgl::style::VectorSource *>(removedSource.get());
- if (!source) {
- return;
- }
-
- removedSource.release();
-
- _pendingSource = std::unique_ptr<mbgl::style::VectorSource>(source);
- self.rawSource = _pendingSource.get();
+ mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options);
+ auto source = std::make_unique<mbgl::style::VectorSource>(identifier.UTF8String, tileSet);
+ return self = [super initWithPendingSource:std::move(source)];
}
- (mbgl::style::VectorSource *)rawSource {
return (mbgl::style::VectorSource *)super.rawSource;
}
-- (void)setRawSource:(mbgl::style::VectorSource *)rawSource {
- super.rawSource = rawSource;
-}
-
- (NSURL *)configurationURL {
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
@@ -110,7 +61,10 @@
optionalFilter = predicate.mgl_filter;
}
- std::vector<mbgl::Feature> features = self.rawSource->querySourceFeatures({ optionalSourceLayerIDs, optionalFilter });
+ std::vector<mbgl::Feature> features;
+ if (self.mapView) {
+ features = self.mapView.mbglMap->querySourceFeatures(self.rawSource->getID(), { optionalSourceLayerIDs, optionalFilter });
+ }
return MGLFeaturesFromMBGLFeatures(features);
}
diff --git a/platform/darwin/src/MGLVectorSource_Private.h b/platform/darwin/src/MGLVectorSource_Private.h
index 12fcd82012..335743173e 100644
--- a/platform/darwin/src/MGLVectorSource_Private.h
+++ b/platform/darwin/src/MGLVectorSource_Private.h
@@ -2,16 +2,7 @@
NS_ASSUME_NONNULL_BEGIN
-namespace mbgl {
- namespace style {
- class VectorSource;
- }
-}
-
@interface MGLVectorSource (Private)
-
-- (instancetype)initWithRawSource:(mbgl::style::VectorSource *)rawSource;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/headless_backend_cgl.cpp b/platform/darwin/src/headless_backend_cgl.cpp
index 7069738fb1..6ad98f4326 100644
--- a/platform/darwin/src/headless_backend_cgl.cpp
+++ b/platform/darwin/src/headless_backend_cgl.cpp
@@ -36,7 +36,7 @@ struct CGLImpl : public HeadlessBackend::Impl {
CGLContextObj glContext = nullptr;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (!framework) {
throw std::runtime_error("Failed to load OpenGL framework.");
@@ -46,7 +46,7 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
void* symbol = CFBundleGetFunctionPointerForName(framework, str);
CFRelease(str);
- return reinterpret_cast<gl::glProc>(symbol);
+ return reinterpret_cast<gl::ProcAddress>(symbol);
}
bool HeadlessBackend::hasDisplay() {
diff --git a/platform/darwin/src/headless_backend_eagl.mm b/platform/darwin/src/headless_backend_eagl.mm
index bd4a202ec5..1daaeaf54c 100644
--- a/platform/darwin/src/headless_backend_eagl.mm
+++ b/platform/darwin/src/headless_backend_eagl.mm
@@ -1,7 +1,5 @@
#include <mbgl/gl/headless_backend.hpp>
-#include <mbgl/gl/extension.hpp>
-
#include <OpenGLES/EAGL.h>
#include <stdexcept>
@@ -29,7 +27,7 @@ struct EAGLImpl : public HeadlessBackend::Impl {
EAGLContext* glContext = nullptr;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
if (!framework) {
throw std::runtime_error("Failed to load OpenGL framework.");
@@ -39,7 +37,7 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
void* symbol = CFBundleGetFunctionPointerForName(framework, str);
CFRelease(str);
- return reinterpret_cast<gl::glProc>(symbol);
+ return reinterpret_cast<gl::ProcAddress>(symbol);
}
bool HeadlessBackend::hasDisplay() {