summaryrefslogtreecommitdiff
path: root/platform/darwin
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-12-03 15:36:42 -0800
committerMinh Nguyễn <mxn@1ec5.org>2016-12-03 15:36:42 -0800
commit3503c0e7679d5802068fc2ab2420b575a8ae2fc7 (patch)
treed1cfdd3ca2f2fb9761466a61e77d82d8f6b76002 /platform/darwin
parent84038832e45c2445b43b39ccb2f9e29c8646dac0 (diff)
parent9eb7f88b2c292d322a104c4580c3ef29958b628b (diff)
downloadqtlocation-mapboxgl-3503c0e7679d5802068fc2ab2420b575a8ae2fc7.tar.gz
Merge branch 'release-ios-v3.4.0' into 1ec5-release-ios-v3.4.0-beta.4-master
Diffstat (limited to 'platform/darwin')
-rw-r--r--platform/darwin/scripts/generate-style-code.js42
-rw-r--r--platform/darwin/scripts/style-spec-cocoa-conventions-v8.json9
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.h10
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.mm93
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.h64
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.mm174
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.h24
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.mm165
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.m7
-rw-r--r--platform/darwin/src/MGLGeoJSONSource.mm20
-rw-r--r--platform/darwin/src/MGLGeometry.h7
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.h70
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.mm273
-rw-r--r--platform/darwin/src/MGLMultiPoint.h25
-rw-r--r--platform/darwin/src/MGLMultiPoint.mm108
-rw-r--r--platform/darwin/src/MGLMultiPoint_Private.h2
-rw-r--r--platform/darwin/src/MGLPointCollection.h2
-rw-r--r--platform/darwin/src/MGLPointCollection.mm47
-rw-r--r--platform/darwin/src/MGLPointCollection_Private.h2
-rw-r--r--platform/darwin/src/MGLPolygon.h4
-rw-r--r--platform/darwin/src/MGLPolygon.mm6
-rw-r--r--platform/darwin/src/MGLPolyline.h2
-rw-r--r--platform/darwin/src/MGLPolyline.mm2
-rw-r--r--platform/darwin/src/MGLRasterSource.mm22
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.h42
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.mm152
-rw-r--r--platform/darwin/src/MGLRuntimeStylingTests.m.ejs4
-rw-r--r--platform/darwin/src/MGLSource.mm27
-rw-r--r--platform/darwin/src/MGLSource_Private.h9
-rw-r--r--platform/darwin/src/MGLStyle.h185
-rw-r--r--platform/darwin/src/MGLStyle.mm327
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm37
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm.ejs142
-rw-r--r--platform/darwin/src/MGLStyleLayer_Private.h58
-rw-r--r--platform/darwin/src/MGLStyleValue_Private.h100
-rw-r--r--platform/darwin/src/MGLStyle_Private.h5
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h402
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.mm772
-rw-r--r--platform/darwin/src/MGLTileSet.mm6
-rw-r--r--platform/darwin/src/MGLTypes.h13
-rw-r--r--platform/darwin/src/MGLVectorSource.mm22
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.h7
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.m9
-rw-r--r--platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm7
-rw-r--r--platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h232
-rw-r--r--platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h.ejs66
-rw-r--r--platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm169
-rw-r--r--platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm.ejs46
-rw-r--r--platform/darwin/test/MGLBackgroundStyleLayerTests.m12
-rw-r--r--platform/darwin/test/MGLCircleStyleLayerTests.m30
-rw-r--r--platform/darwin/test/MGLFillStyleLayerTests.m20
-rw-r--r--platform/darwin/test/MGLFilterTests.mm16
-rw-r--r--platform/darwin/test/MGLLineStyleLayerTests.m52
-rw-r--r--platform/darwin/test/MGLOfflineStorageTests.m1
-rw-r--r--platform/darwin/test/MGLRasterStyleLayerTests.m44
-rw-r--r--platform/darwin/test/MGLStyleLayerTests.h (renamed from platform/darwin/test/MGLMapViewTests.h)2
-rw-r--r--platform/darwin/test/MGLStyleLayerTests.m (renamed from platform/darwin/test/MGLMapViewTests.m)6
-rw-r--r--platform/darwin/test/MGLStyleLayerTests.xib (renamed from platform/darwin/test/MGLMapViewTests.xib)4
-rw-r--r--platform/darwin/test/MGLStyleTests.mm75
-rw-r--r--platform/darwin/test/MGLSymbolStyleLayerTests.m212
60 files changed, 3285 insertions, 1208 deletions
diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js
index c4652e4e9b..6b54b5219b 100644
--- a/platform/darwin/scripts/generate-style-code.js
+++ b/platform/darwin/scripts/generate-style-code.js
@@ -4,13 +4,23 @@ const fs = require('fs');
const ejs = require('ejs');
const _ = require('lodash');
const colorParser = require('csscolorparser');
-const spec = _.merge(require('mapbox-gl-style-spec').latest, require('./style-spec-overrides-v8.json'));
require('../../../scripts/style-code');
+const cocoaConventions = require('./style-spec-cocoa-conventions-v8.json');
+let spec = _.merge(require('mapbox-gl-style-spec').latest, require('./style-spec-overrides-v8.json'));
const prefix = 'MGL';
const suffix = 'StyleLayer';
+// Rename properties and keep `original` for use with setters and getters
+_.forOwn(cocoaConventions, function (properties, kind) {
+ _.forOwn(properties, function (newName, oldName) {
+ spec[kind][newName] = spec[kind][oldName];
+ spec[kind][newName].original = oldName;
+ delete spec[kind][oldName];
+ })
+});
+
global.objCName = function (property) {
return camelizeWithLeadingLowercase(property.name);
}
@@ -202,6 +212,10 @@ global.propertyDefault = function (property, layerType) {
return 'an `MGLStyleValue` object containing ' + describeValue(property.default, property, layerType);
};
+global.originalPropertyName = function (property) {
+ return property.original || property.name;
+}
+
global.propertyType = function (property) {
switch (property.type) {
case 'boolean':
@@ -291,6 +305,8 @@ global.mbglType = function(property) {
const layerH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.h.ejs', 'utf8'), { strict: true });
const layerM = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.mm.ejs', 'utf8'), { strict: true});
const testLayers = ejs.compile(fs.readFileSync('platform/darwin/src/MGLRuntimeStylingTests.m.ejs', 'utf8'), { strict: true});
+const categoryH = ejs.compile(fs.readFileSync('platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h.ejs', 'utf8'), { strict: true});
+const categoryM = ejs.compile(fs.readFileSync('platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm.ejs', 'utf8'), { strict: true});
const layers = Object.keys(spec.layer.type.values).map((type) => {
const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => {
@@ -309,8 +325,8 @@ const layers = Object.keys(spec.layer.type.values).map((type) => {
return {
type: type,
- layoutProperties: layoutProperties,
- paintProperties: paintProperties,
+ layoutProperties: _.sortBy(layoutProperties, ['name']),
+ paintProperties: _.sortBy(paintProperties, ['name']),
layoutPropertiesByName: spec[`layout_${type}`],
paintPropertiesByName: spec[`paint_${type}`],
};
@@ -335,8 +351,28 @@ ${macosComment}${decl}
});
}
+var allLayoutProperties = [];
+var allPaintProperties = [];
+var allTypes = [];
+
for (var layer of layers) {
+ allLayoutProperties.push(layer.layoutProperties);
+ allPaintProperties.push(layer.paintProperties);
+ allTypes.push(layer.type);
+ const containsEnumerationProperties = _.filter(layer.layoutProperties, function(property){ return property["type"] === "enum"; }).length || _.filter(layer.paintProperties, function(property){ return property["type"] === "enum"; }).length;
+ layer.containsEnumerationProperties = containsEnumerationProperties;
+
writeIfModified(`platform/darwin/src/${prefix}${camelize(layer.type)}${suffix}.h`, duplicatePlatformDecls(layerH(layer)));
writeIfModified(`platform/darwin/src/${prefix}${camelize(layer.type)}${suffix}.mm`, layerM(layer));
writeIfModified(`platform/darwin/test/${prefix}${camelize(layer.type)}${suffix}Tests.m`, testLayers(layer));
}
+
+fs.writeFileSync(`platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h`, categoryH({
+ layoutProperties: _.flatten(allLayoutProperties),
+ paintProperties: _.flatten(allPaintProperties),
+ types: allTypes
+}));
+fs.writeFileSync(`platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm`, categoryM({
+ layoutProperties: _.flatten(allLayoutProperties),
+ paintProperties: _.flatten(allPaintProperties)
+}));
diff --git a/platform/darwin/scripts/style-spec-cocoa-conventions-v8.json b/platform/darwin/scripts/style-spec-cocoa-conventions-v8.json
new file mode 100644
index 0000000000..e37598406b
--- /dev/null
+++ b/platform/darwin/scripts/style-spec-cocoa-conventions-v8.json
@@ -0,0 +1,9 @@
+{
+ "layout_symbol": {
+ "icon-image": "icon-image-name"
+ },
+ "paint_raster": {
+ "raster-brightness-min": "minimum-raster-brightness",
+ "raster-brightness-max": "maximum-raster-brightness"
+ }
+} \ No newline at end of file
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.h b/platform/darwin/src/MGLBackgroundStyleLayer.h
index a70383cc9c..656e104bbb 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.h
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.h
@@ -39,17 +39,17 @@ NS_ASSUME_NONNULL_BEGIN
#endif
/**
- Name of image in style images to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512).
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *backgroundPattern;
-
-/**
The opacity at which the background will be drawn.
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.
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *backgroundOpacity;
+/**
+ Name of image in style images to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512).
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *backgroundPattern;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm
index 33a105e5d5..253414852a 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.mm
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.mm
@@ -2,6 +2,7 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
@@ -11,50 +12,112 @@
@interface MGLBackgroundStyleLayer ()
-@property (nonatomic) mbgl::style::BackgroundLayer *layer;
+@property (nonatomic) mbgl::style::BackgroundLayer *rawLayer;
@end
@implementation MGLBackgroundStyleLayer
+{
+ std::unique_ptr<mbgl::style::BackgroundLayer> _pendingLayer;
+}
- (instancetype)initWithIdentifier:(NSString *)identifier
{
if (self = [super initWithIdentifier:identifier]) {
- _layer = new mbgl::style::BackgroundLayer(identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::BackgroundLayer>(identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
+#pragma mark - Adding to and removing from a map view
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
+
+ [self addToMapView:mapView belowLayer:nil];
+}
+
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
+
+ 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);
+ _rawLayer = _pendingLayer.get();
+}
+
#pragma mark - Accessing the Paint Attributes
- (void)setBackgroundColor:(MGLStyleValue<MGLColor *> *)backgroundColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(backgroundColor);
- self.layer->setBackgroundColor(mbglValue);
+ _rawLayer->setBackgroundColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)backgroundColor {
- auto propertyValue = self.layer->getBackgroundColor() ?: self.layer->getDefaultBackgroundColor();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getBackgroundColor() ?: _rawLayer->getDefaultBackgroundColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
+- (void)setBackgroundOpacity:(MGLStyleValue<NSNumber *> *)backgroundOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(backgroundOpacity);
+ _rawLayer->setBackgroundOpacity(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)backgroundOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getBackgroundOpacity() ?: _rawLayer->getDefaultBackgroundOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
- (void)setBackgroundPattern:(MGLStyleValue<NSString *> *)backgroundPattern {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(backgroundPattern);
- self.layer->setBackgroundPattern(mbglValue);
+ _rawLayer->setBackgroundPattern(mbglValue);
}
- (MGLStyleValue<NSString *> *)backgroundPattern {
- auto propertyValue = self.layer->getBackgroundPattern() ?: self.layer->getDefaultBackgroundPattern();
- return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
-}
+ MGLAssertStyleLayerIsValid();
-- (void)setBackgroundOpacity:(MGLStyleValue<NSNumber *> *)backgroundOpacity {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(backgroundOpacity);
- self.layer->setBackgroundOpacity(mbglValue);
+ auto propertyValue = _rawLayer->getBackgroundPattern() ?: _rawLayer->getDefaultBackgroundPattern();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
-- (MGLStyleValue<NSNumber *> *)backgroundOpacity {
- auto propertyValue = self.layer->getBackgroundOpacity() ?: self.layer->getDefaultBackgroundOpacity();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
-}
@end
diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h
index da7076e7d1..2d88a664ba 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.h
+++ b/platform/darwin/src/MGLCircleStyleLayer.h
@@ -7,35 +7,35 @@
NS_ASSUME_NONNULL_BEGIN
/**
- Controls the translation reference point.
+ Controls the scaling behavior of the circle when the map is pitched.
- Values of this type are used in the `circleTranslateAnchor` property of `MGLCircleStyleLayer`.
+ Values of this type are used in the `circlePitchScale` property of `MGLCircleStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLCircleTranslateAnchor) {
+typedef NS_ENUM(NSUInteger, MGLCirclePitchScale) {
/**
- The circle is translated relative to the map.
+ Circles are scaled according to their apparent distance to the camera.
*/
- MGLCircleTranslateAnchorMap,
+ MGLCirclePitchScaleMap,
/**
- The circle is translated relative to the viewport.
+ Circles are not scaled.
*/
- MGLCircleTranslateAnchorViewport,
+ MGLCirclePitchScaleViewport,
};
/**
- Controls the scaling behavior of the circle when the map is pitched.
+ Controls the translation reference point.
- Values of this type are used in the `circlePitchScale` property of `MGLCircleStyleLayer`.
+ Values of this type are used in the `circleTranslateAnchor` property of `MGLCircleStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLCirclePitchScale) {
+typedef NS_ENUM(NSUInteger, MGLCircleTranslateAnchor) {
/**
- Circles are scaled according to their apparent distance to the camera.
+ The circle is translated relative to the map.
*/
- MGLCirclePitchScaleMap,
+ MGLCircleTranslateAnchorMap,
/**
- Circles are not scaled.
+ The circle is translated relative to the viewport.
*/
- MGLCirclePitchScaleViewport,
+ MGLCircleTranslateAnchorViewport,
};
/**
@@ -49,13 +49,11 @@ typedef NS_ENUM(NSUInteger, MGLCirclePitchScale) {
#pragma mark - Accessing the Paint Attributes
/**
- Circle radius.
-
- This property is measured in points.
+ Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `5`. Set this property to `nil` to reset it to the default value.
+ 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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleRadius;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleBlur;
#if TARGET_OS_IPHONE
/**
@@ -74,18 +72,27 @@ typedef NS_ENUM(NSUInteger, MGLCirclePitchScale) {
#endif
/**
- Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
+ The opacity at which the circle will be drawn.
- 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.
+ 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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleOpacity;
/**
- The opacity at which the circle will be drawn.
+ Controls the scaling behavior of the circle when the map is pitched.
- 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.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLCirclePitchScaleMap`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *circlePitchScale;
+
+/**
+ Circle radius.
+
+ This property is measured in points.
+
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `5`. Set this property to `nil` to reset it to the default value.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleRadius;
/**
The geometry's offset.
@@ -105,13 +112,6 @@ typedef NS_ENUM(NSUInteger, MGLCirclePitchScale) {
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *circleTranslateAnchor;
-/**
- Controls the scaling behavior of the circle when the map is pitched.
-
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLCirclePitchScaleMap`. Set this property to `nil` to reset it to the default value.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *circlePitchScale;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm
index 8fe97a0537..91f91a7bcd 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.mm
+++ b/platform/darwin/src/MGLCircleStyleLayer.mm
@@ -2,120 +2,218 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLCircleStyleLayer.h"
#include <mbgl/style/layers/circle_layer.hpp>
+namespace mbgl {
+
+ MBGL_DEFINE_ENUM(MGLCirclePitchScale, {
+ { MGLCirclePitchScaleMap, "map" },
+ { MGLCirclePitchScaleViewport, "viewport" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLCircleTranslateAnchor, {
+ { MGLCircleTranslateAnchorMap, "map" },
+ { MGLCircleTranslateAnchorViewport, "viewport" },
+ });
+
+}
@interface MGLCircleStyleLayer ()
-@property (nonatomic) mbgl::style::CircleLayer *layer;
+@property (nonatomic) 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]) {
- _layer = new mbgl::style::CircleLayer(identifier.UTF8String, source.identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::CircleLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
-
- (NSString *)sourceLayerIdentifier
{
- auto layerID = self.layer->getSourceLayer();
+ MGLAssertStyleLayerIsValid();
+
+ auto layerID = _rawLayer->getSourceLayer();
return layerID.empty() ? nil : @(layerID.c_str());
}
- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
{
- self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
{
- self.layer->setFilter(predicate.mgl_filter);
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setFilter(predicate.mgl_filter);
}
- (NSPredicate *)predicate
{
- return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()];
+ MGLAssertStyleLayerIsValid();
+
+ return [NSPredicate mgl_predicateWithFilter:_rawLayer->getFilter()];
+}
+#pragma mark - Adding to and removing from a map view
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
+
+ [self addToMapView:mapView belowLayer:nil];
+}
+
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
+
+ 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);
+ _rawLayer = _pendingLayer.get();
}
#pragma mark - Accessing the Paint Attributes
-- (void)setCircleRadius:(MGLStyleValue<NSNumber *> *)circleRadius {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleRadius);
- self.layer->setCircleRadius(mbglValue);
+- (void)setCircleBlur:(MGLStyleValue<NSNumber *> *)circleBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleBlur);
+ _rawLayer->setCircleBlur(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)circleRadius {
- auto propertyValue = self.layer->getCircleRadius() ?: self.layer->getDefaultCircleRadius();
+- (MGLStyleValue<NSNumber *> *)circleBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getCircleBlur() ?: _rawLayer->getDefaultCircleBlur();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setCircleColor:(MGLStyleValue<MGLColor *> *)circleColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(circleColor);
- self.layer->setCircleColor(mbglValue);
+ _rawLayer->setCircleColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)circleColor {
- auto propertyValue = self.layer->getCircleColor() ?: self.layer->getDefaultCircleColor();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getCircleColor() ?: _rawLayer->getDefaultCircleColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setCircleBlur:(MGLStyleValue<NSNumber *> *)circleBlur {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleBlur);
- self.layer->setCircleBlur(mbglValue);
+- (void)setCircleOpacity:(MGLStyleValue<NSNumber *> *)circleOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleOpacity);
+ _rawLayer->setCircleOpacity(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)circleBlur {
- auto propertyValue = self.layer->getCircleBlur() ?: self.layer->getDefaultCircleBlur();
+- (MGLStyleValue<NSNumber *> *)circleOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getCircleOpacity() ?: _rawLayer->getDefaultCircleOpacity();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setCircleOpacity:(MGLStyleValue<NSNumber *> *)circleOpacity {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleOpacity);
- self.layer->setCircleOpacity(mbglValue);
+- (void)setCirclePitchScale:(MGLStyleValue<NSValue *> *)circlePitchScale {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *, mbgl::style::CirclePitchScaleType, MGLCirclePitchScale>().toEnumPropertyValue(circlePitchScale);
+ _rawLayer->setCirclePitchScale(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)circleOpacity {
- auto propertyValue = self.layer->getCircleOpacity() ?: self.layer->getDefaultCircleOpacity();
+- (MGLStyleValue<NSValue *> *)circlePitchScale {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getCirclePitchScale() ?: _rawLayer->getDefaultCirclePitchScale();
+ return MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *, mbgl::style::CirclePitchScaleType, MGLCirclePitchScale>().toEnumStyleValue(propertyValue);
+}
+
+- (void)setCircleRadius:(MGLStyleValue<NSNumber *> *)circleRadius {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleRadius);
+ _rawLayer->setCircleRadius(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)circleRadius {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getCircleRadius() ?: _rawLayer->getDefaultCircleRadius();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setCircleTranslate:(MGLStyleValue<NSValue *> *)circleTranslate {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(circleTranslate);
- self.layer->setCircleTranslate(mbglValue);
+ _rawLayer->setCircleTranslate(mbglValue);
}
- (MGLStyleValue<NSValue *> *)circleTranslate {
- auto propertyValue = self.layer->getCircleTranslate() ?: self.layer->getDefaultCircleTranslate();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getCircleTranslate() ?: _rawLayer->getDefaultCircleTranslate();
return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
- (void)setCircleTranslateAnchor:(MGLStyleValue<NSValue *> *)circleTranslateAnchor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(circleTranslateAnchor);
- self.layer->setCircleTranslateAnchor(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLCircleTranslateAnchor>().toEnumPropertyValue(circleTranslateAnchor);
+ _rawLayer->setCircleTranslateAnchor(mbglValue);
}
- (MGLStyleValue<NSValue *> *)circleTranslateAnchor {
- auto propertyValue = self.layer->getCircleTranslateAnchor() ?: self.layer->getDefaultCircleTranslateAnchor();
- return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
-}
+ MGLAssertStyleLayerIsValid();
-- (void)setCirclePitchScale:(MGLStyleValue<NSValue *> *)circlePitchScale {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *>().toPropertyValue(circlePitchScale);
- self.layer->setCirclePitchScale(mbglValue);
+ auto propertyValue = _rawLayer->getCircleTranslateAnchor() ?: _rawLayer->getDefaultCircleTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLCircleTranslateAnchor>().toEnumStyleValue(propertyValue);
}
-- (MGLStyleValue<NSValue *> *)circlePitchScale {
- auto propertyValue = self.layer->getCirclePitchScale() ?: self.layer->getDefaultCirclePitchScale();
- return MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *>().toStyleValue(propertyValue);
-}
@end
diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h
index 799fa380c0..9bbda26ce4 100644
--- a/platform/darwin/src/MGLFillStyleLayer.h
+++ b/platform/darwin/src/MGLFillStyleLayer.h
@@ -39,13 +39,6 @@ typedef NS_ENUM(NSUInteger, MGLFillTranslateAnchor) {
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillAntialias;
-/**
- The opacity of the entire fill layer. In contrast to the `fillColor`, this value will also affect the 1pt stroke around the fill, if the stroke is used.
-
- 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.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillOpacity;
-
#if TARGET_OS_IPHONE
/**
The color of the filled part of this layer.
@@ -67,6 +60,13 @@ typedef NS_ENUM(NSUInteger, MGLFillTranslateAnchor) {
#endif
/**
+ The opacity of the entire fill layer. In contrast to the `fillColor`, this value will also affect the 1pt stroke around the fill, if the stroke is used.
+
+ 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.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillOpacity;
+
+/**
The outline color of the fill. Matches the value of `fillColor` if unspecified.
This property is only applied to the style if `fillPattern` is set to `nil`, and `fillAntialias` is set to an `MGLStyleValue` object containing an `NSNumber` object containing `YES`. Otherwise, it is ignored.
@@ -74,6 +74,11 @@ typedef NS_ENUM(NSUInteger, MGLFillTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *fillOutlineColor;
/**
+ Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512).
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *fillPattern;
+
+/**
The geometry's offset.
This property is measured in points.
@@ -91,11 +96,6 @@ typedef NS_ENUM(NSUInteger, MGLFillTranslateAnchor) {
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillTranslateAnchor;
-/**
- Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512).
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *fillPattern;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm
index e16e3b2652..87a5144c6b 100644
--- a/platform/darwin/src/MGLFillStyleLayer.mm
+++ b/platform/darwin/src/MGLFillStyleLayer.mm
@@ -2,120 +2,213 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLFillStyleLayer.h"
#include <mbgl/style/layers/fill_layer.hpp>
+namespace mbgl {
+
+ MBGL_DEFINE_ENUM(MGLFillTranslateAnchor, {
+ { MGLFillTranslateAnchorMap, "map" },
+ { MGLFillTranslateAnchorViewport, "viewport" },
+ });
+
+}
@interface MGLFillStyleLayer ()
-@property (nonatomic) mbgl::style::FillLayer *layer;
+@property (nonatomic) 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]) {
- _layer = new mbgl::style::FillLayer(identifier.UTF8String, source.identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::FillLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
-
- (NSString *)sourceLayerIdentifier
{
- auto layerID = self.layer->getSourceLayer();
+ MGLAssertStyleLayerIsValid();
+
+ auto layerID = _rawLayer->getSourceLayer();
return layerID.empty() ? nil : @(layerID.c_str());
}
- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
{
- self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
{
- self.layer->setFilter(predicate.mgl_filter);
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setFilter(predicate.mgl_filter);
}
- (NSPredicate *)predicate
{
- return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()];
+ MGLAssertStyleLayerIsValid();
+
+ return [NSPredicate mgl_predicateWithFilter:_rawLayer->getFilter()];
+}
+#pragma mark - Adding to and removing from a map view
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
+
+ [self addToMapView:mapView belowLayer:nil];
+}
+
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
+
+ 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);
+ _rawLayer = _pendingLayer.get();
}
#pragma mark - Accessing the Paint Attributes
- (void)setFillAntialias:(MGLStyleValue<NSNumber *> *)fillAntialias {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(fillAntialias);
- self.layer->setFillAntialias(mbglValue);
+ _rawLayer->setFillAntialias(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)fillAntialias {
- auto propertyValue = self.layer->getFillAntialias() ?: self.layer->getDefaultFillAntialias();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getFillAntialias() ?: _rawLayer->getDefaultFillAntialias();
return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
+- (void)setFillColor:(MGLStyleValue<MGLColor *> *)fillColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(fillColor);
+ _rawLayer->setFillColor(mbglValue);
+}
+
+- (MGLStyleValue<MGLColor *> *)fillColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getFillColor() ?: _rawLayer->getDefaultFillColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
+}
+
- (void)setFillOpacity:(MGLStyleValue<NSNumber *> *)fillOpacity {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(fillOpacity);
- self.layer->setFillOpacity(mbglValue);
+ _rawLayer->setFillOpacity(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)fillOpacity {
- auto propertyValue = self.layer->getFillOpacity() ?: self.layer->getDefaultFillOpacity();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getFillOpacity() ?: _rawLayer->getDefaultFillOpacity();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setFillColor:(MGLStyleValue<MGLColor *> *)fillColor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(fillColor);
- self.layer->setFillColor(mbglValue);
+- (void)setFillOutlineColor:(MGLStyleValue<MGLColor *> *)fillOutlineColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(fillOutlineColor);
+ _rawLayer->setFillOutlineColor(mbglValue);
}
-- (MGLStyleValue<MGLColor *> *)fillColor {
- auto propertyValue = self.layer->getFillColor() ?: self.layer->getDefaultFillColor();
+- (MGLStyleValue<MGLColor *> *)fillOutlineColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getFillOutlineColor() ?: _rawLayer->getDefaultFillOutlineColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setFillOutlineColor:(MGLStyleValue<MGLColor *> *)fillOutlineColor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(fillOutlineColor);
- self.layer->setFillOutlineColor(mbglValue);
+- (void)setFillPattern:(MGLStyleValue<NSString *> *)fillPattern {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(fillPattern);
+ _rawLayer->setFillPattern(mbglValue);
}
-- (MGLStyleValue<MGLColor *> *)fillOutlineColor {
- auto propertyValue = self.layer->getFillOutlineColor() ?: self.layer->getDefaultFillOutlineColor();
- return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSString *> *)fillPattern {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getFillPattern() ?: _rawLayer->getDefaultFillPattern();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
- (void)setFillTranslate:(MGLStyleValue<NSValue *> *)fillTranslate {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(fillTranslate);
- self.layer->setFillTranslate(mbglValue);
+ _rawLayer->setFillTranslate(mbglValue);
}
- (MGLStyleValue<NSValue *> *)fillTranslate {
- auto propertyValue = self.layer->getFillTranslate() ?: self.layer->getDefaultFillTranslate();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getFillTranslate() ?: _rawLayer->getDefaultFillTranslate();
return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
- (void)setFillTranslateAnchor:(MGLStyleValue<NSValue *> *)fillTranslateAnchor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(fillTranslateAnchor);
- self.layer->setFillTranslateAnchor(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillTranslateAnchor>().toEnumPropertyValue(fillTranslateAnchor);
+ _rawLayer->setFillTranslateAnchor(mbglValue);
}
- (MGLStyleValue<NSValue *> *)fillTranslateAnchor {
- auto propertyValue = self.layer->getFillTranslateAnchor() ?: self.layer->getDefaultFillTranslateAnchor();
- return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
-}
+ MGLAssertStyleLayerIsValid();
-- (void)setFillPattern:(MGLStyleValue<NSString *> *)fillPattern {
- auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(fillPattern);
- self.layer->setFillPattern(mbglValue);
+ auto propertyValue = _rawLayer->getFillTranslateAnchor() ?: _rawLayer->getDefaultFillTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillTranslateAnchor>().toEnumStyleValue(propertyValue);
}
-- (MGLStyleValue<NSString *> *)fillPattern {
- auto propertyValue = self.layer->getFillPattern() ?: self.layer->getDefaultFillPattern();
- return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
-}
@end
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.m b/platform/darwin/src/MGLForegroundStyleLayer.m
index e3af963313..b7a0379af2 100644
--- a/platform/darwin/src/MGLForegroundStyleLayer.m
+++ b/platform/darwin/src/MGLForegroundStyleLayer.m
@@ -10,4 +10,11 @@
return self;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; sourceIdentifier = %@; visible = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ self.sourceIdentifier, self.visible ? @"YES" : @"NO"];
+}
+
@end
diff --git a/platform/darwin/src/MGLGeoJSONSource.mm b/platform/darwin/src/MGLGeoJSONSource.mm
index 0dbe1030c6..8b37ba47cd 100644
--- a/platform/darwin/src/MGLGeoJSONSource.mm
+++ b/platform/darwin/src/MGLGeoJSONSource.mm
@@ -61,9 +61,23 @@ const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionSimplificationTolerance = @"M
- (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
+{
+ auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
+
+ _pendingSource = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::GeoJSONSource> &>(removedSource));
+ self.rawSource = _pendingSource.get();
+}
+
- (void)commonInit
{
auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.identifier.UTF8String, self.geoJSONOptions);
@@ -184,4 +198,10 @@ const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionSimplificationTolerance = @"M
_features = MGLFeaturesFromMBGLFeatures(featureCollection);
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; geoJSONData = %@; features = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.geoJSONData, self.features];
+}
+
@end
diff --git a/platform/darwin/src/MGLGeometry.h b/platform/darwin/src/MGLGeometry.h
index 5fc927697b..e2a4d818b9 100644
--- a/platform/darwin/src/MGLGeometry.h
+++ b/platform/darwin/src/MGLGeometry.h
@@ -117,11 +117,4 @@ NS_INLINE CLLocationDegrees MGLDegreesFromRadians(CGFloat radians) {
return radians * 180 / M_PI;
}
-/**
- Methods for round-tripping Mapbox geometry structure values.
- */
-@interface NSValue (MGLGeometryAdditions)
-
-@end
-
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h
index 68b0a73a2e..74d8f7bfe9 100644
--- a/platform/darwin/src/MGLLineStyleLayer.h
+++ b/platform/darwin/src/MGLLineStyleLayer.h
@@ -107,11 +107,13 @@ typedef NS_ENUM(NSUInteger, MGLLineTranslateAnchor) {
#pragma mark - Accessing the Paint Attributes
/**
- The opacity at which the line will be drawn.
+ Blur applied to the line, in points.
+
+ This property is measured in points.
- 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.
+ 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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineBlur;
#if TARGET_OS_IPHONE
/**
@@ -134,31 +136,13 @@ typedef NS_ENUM(NSUInteger, MGLLineTranslateAnchor) {
#endif
/**
- 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 from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineTranslate;
-
-/**
- Controls the translation reference point.
-
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
-
- This property is only applied to the style if `lineTranslate` is non-`nil`. Otherwise, it is ignored.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineTranslateAnchor;
+ Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to points, multiply the length by the current line width.
-/**
- Stroke thickness.
+ This property is measured in line widths.
- This property is measured in points.
-
- 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.
+ This property is only applied to the style if `linePattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSArray<NSNumber *> *> *lineDasharray;
/**
Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.
@@ -179,27 +163,43 @@ typedef NS_ENUM(NSUInteger, MGLLineTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineOffset;
/**
- Blur applied to the line, in points.
+ The opacity at which the line will be drawn.
+
+ 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.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineOpacity;
+
+/**
+ Name of image in style images to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512).
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *linePattern;
+
+/**
+ The geometry's offset.
This property is measured in points.
- 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.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineTranslate;
/**
- Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to points, multiply the length by the current line width.
-
- This property is measured in line widths.
+ Controls the translation reference point.
+
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `linePattern` is set to `nil`. Otherwise, it is ignored.
+ This property is only applied to the style if `lineTranslate` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSArray<NSNumber *> *> *lineDasharray;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineTranslateAnchor;
/**
- Name of image in style images to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512).
+ Stroke thickness.
+
+ This property is measured in points.
+
+ 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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *linePattern;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineWidth;
@end
diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm
index 57724a0600..b155ec65d6 100644
--- a/platform/darwin/src/MGLLineStyleLayer.mm
+++ b/platform/darwin/src/MGLLineStyleLayer.mm
@@ -2,192 +2,325 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLLineStyleLayer.h"
#include <mbgl/style/layers/line_layer.hpp>
+namespace mbgl {
+
+ MBGL_DEFINE_ENUM(MGLLineCap, {
+ { MGLLineCapButt, "butt" },
+ { MGLLineCapRound, "round" },
+ { MGLLineCapSquare, "square" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLLineJoin, {
+ { MGLLineJoinBevel, "bevel" },
+ { MGLLineJoinRound, "round" },
+ { MGLLineJoinMiter, "miter" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLLineTranslateAnchor, {
+ { MGLLineTranslateAnchorMap, "map" },
+ { MGLLineTranslateAnchorViewport, "viewport" },
+ });
+
+}
@interface MGLLineStyleLayer ()
-@property (nonatomic) mbgl::style::LineLayer *layer;
+@property (nonatomic) 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]) {
- _layer = new mbgl::style::LineLayer(identifier.UTF8String, source.identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::LineLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
-
- (NSString *)sourceLayerIdentifier
{
- auto layerID = self.layer->getSourceLayer();
+ MGLAssertStyleLayerIsValid();
+
+ auto layerID = _rawLayer->getSourceLayer();
return layerID.empty() ? nil : @(layerID.c_str());
}
- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
{
- self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
{
- self.layer->setFilter(predicate.mgl_filter);
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setFilter(predicate.mgl_filter);
}
- (NSPredicate *)predicate
{
- return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()];
+ MGLAssertStyleLayerIsValid();
+
+ return [NSPredicate mgl_predicateWithFilter:_rawLayer->getFilter()];
+}
+#pragma mark - Adding to and removing from a map view
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
+
+ [self addToMapView:mapView belowLayer:nil];
+}
+
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
+
+ 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);
+ _rawLayer = _pendingLayer.get();
}
#pragma mark - Accessing the Layout Attributes
- (void)setLineCap:(MGLStyleValue<NSValue *> *)lineCap {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *>().toPropertyValue(lineCap);
- self.layer->setLineCap(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *, mbgl::style::LineCapType, MGLLineCap>().toEnumPropertyValue(lineCap);
+ _rawLayer->setLineCap(mbglValue);
}
- (MGLStyleValue<NSValue *> *)lineCap {
- auto propertyValue = self.layer->getLineCap() ?: self.layer->getDefaultLineCap();
- return MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *>().toStyleValue(propertyValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineCap() ?: _rawLayer->getDefaultLineCap();
+ return MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *, mbgl::style::LineCapType, MGLLineCap>().toEnumStyleValue(propertyValue);
}
- (void)setLineJoin:(MGLStyleValue<NSValue *> *)lineJoin {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *>().toPropertyValue(lineJoin);
- self.layer->setLineJoin(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *, mbgl::style::LineJoinType, MGLLineJoin>().toEnumPropertyValue(lineJoin);
+ _rawLayer->setLineJoin(mbglValue);
}
- (MGLStyleValue<NSValue *> *)lineJoin {
- auto propertyValue = self.layer->getLineJoin() ?: self.layer->getDefaultLineJoin();
- return MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *>().toStyleValue(propertyValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineJoin() ?: _rawLayer->getDefaultLineJoin();
+ return MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *, mbgl::style::LineJoinType, MGLLineJoin>().toEnumStyleValue(propertyValue);
}
- (void)setLineMiterLimit:(MGLStyleValue<NSNumber *> *)lineMiterLimit {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineMiterLimit);
- self.layer->setLineMiterLimit(mbglValue);
+ _rawLayer->setLineMiterLimit(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)lineMiterLimit {
- auto propertyValue = self.layer->getLineMiterLimit() ?: self.layer->getDefaultLineMiterLimit();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineMiterLimit() ?: _rawLayer->getDefaultLineMiterLimit();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setLineRoundLimit:(MGLStyleValue<NSNumber *> *)lineRoundLimit {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineRoundLimit);
- self.layer->setLineRoundLimit(mbglValue);
+ _rawLayer->setLineRoundLimit(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)lineRoundLimit {
- auto propertyValue = self.layer->getLineRoundLimit() ?: self.layer->getDefaultLineRoundLimit();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineRoundLimit() ?: _rawLayer->getDefaultLineRoundLimit();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
#pragma mark - Accessing the Paint Attributes
-- (void)setLineOpacity:(MGLStyleValue<NSNumber *> *)lineOpacity {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineOpacity);
- self.layer->setLineOpacity(mbglValue);
+- (void)setLineBlur:(MGLStyleValue<NSNumber *> *)lineBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineBlur);
+ _rawLayer->setLineBlur(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)lineOpacity {
- auto propertyValue = self.layer->getLineOpacity() ?: self.layer->getDefaultLineOpacity();
+- (MGLStyleValue<NSNumber *> *)lineBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineBlur() ?: _rawLayer->getDefaultLineBlur();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setLineColor:(MGLStyleValue<MGLColor *> *)lineColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(lineColor);
- self.layer->setLineColor(mbglValue);
+ _rawLayer->setLineColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)lineColor {
- auto propertyValue = self.layer->getLineColor() ?: self.layer->getDefaultLineColor();
- return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
-}
-
-- (void)setLineTranslate:(MGLStyleValue<NSValue *> *)lineTranslate {
- auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(lineTranslate);
- self.layer->setLineTranslate(mbglValue);
-}
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)lineTranslate {
- auto propertyValue = self.layer->getLineTranslate() ?: self.layer->getDefaultLineTranslate();
- return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getLineColor() ?: _rawLayer->getDefaultLineColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setLineTranslateAnchor:(MGLStyleValue<NSValue *> *)lineTranslateAnchor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(lineTranslateAnchor);
- self.layer->setLineTranslateAnchor(mbglValue);
-}
+- (void)setLineDasharray:(MGLStyleValue<NSArray<NSNumber *> *> *)lineDasharray {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)lineTranslateAnchor {
- auto propertyValue = self.layer->getLineTranslateAnchor() ?: self.layer->getDefaultLineTranslateAnchor();
- return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
+ auto mbglValue = MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toPropertyValue(lineDasharray);
+ _rawLayer->setLineDasharray(mbglValue);
}
-- (void)setLineWidth:(MGLStyleValue<NSNumber *> *)lineWidth {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineWidth);
- self.layer->setLineWidth(mbglValue);
-}
+- (MGLStyleValue<NSArray<NSNumber *> *> *)lineDasharray {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSNumber *> *)lineWidth {
- auto propertyValue = self.layer->getLineWidth() ?: self.layer->getDefaultLineWidth();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getLineDasharray() ?: _rawLayer->getDefaultLineDasharray();
+ return MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toStyleValue(propertyValue);
}
- (void)setLineGapWidth:(MGLStyleValue<NSNumber *> *)lineGapWidth {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineGapWidth);
- self.layer->setLineGapWidth(mbglValue);
+ _rawLayer->setLineGapWidth(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)lineGapWidth {
- auto propertyValue = self.layer->getLineGapWidth() ?: self.layer->getDefaultLineGapWidth();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineGapWidth() ?: _rawLayer->getDefaultLineGapWidth();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setLineOffset:(MGLStyleValue<NSNumber *> *)lineOffset {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineOffset);
- self.layer->setLineOffset(mbglValue);
+ _rawLayer->setLineOffset(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)lineOffset {
- auto propertyValue = self.layer->getLineOffset() ?: self.layer->getDefaultLineOffset();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineOffset() ?: _rawLayer->getDefaultLineOffset();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineBlur:(MGLStyleValue<NSNumber *> *)lineBlur {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineBlur);
- self.layer->setLineBlur(mbglValue);
-}
+- (void)setLineOpacity:(MGLStyleValue<NSNumber *> *)lineOpacity {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSNumber *> *)lineBlur {
- auto propertyValue = self.layer->getLineBlur() ?: self.layer->getDefaultLineBlur();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineOpacity);
+ _rawLayer->setLineOpacity(mbglValue);
}
-- (void)setLineDasharray:(MGLStyleValue<NSArray<NSNumber *> *> *)lineDasharray {
- auto mbglValue = MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toPropertyValue(lineDasharray);
- self.layer->setLineDasharray(mbglValue);
-}
+- (MGLStyleValue<NSNumber *> *)lineOpacity {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSArray<NSNumber *> *> *)lineDasharray {
- auto propertyValue = self.layer->getLineDasharray() ?: self.layer->getDefaultLineDasharray();
- return MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getLineOpacity() ?: _rawLayer->getDefaultLineOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setLinePattern:(MGLStyleValue<NSString *> *)linePattern {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(linePattern);
- self.layer->setLinePattern(mbglValue);
+ _rawLayer->setLinePattern(mbglValue);
}
- (MGLStyleValue<NSString *> *)linePattern {
- auto propertyValue = self.layer->getLinePattern() ?: self.layer->getDefaultLinePattern();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLinePattern() ?: _rawLayer->getDefaultLinePattern();
return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
+- (void)setLineTranslate:(MGLStyleValue<NSValue *> *)lineTranslate {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(lineTranslate);
+ _rawLayer->setLineTranslate(mbglValue);
+}
+
+- (MGLStyleValue<NSValue *> *)lineTranslate {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineTranslate() ?: _rawLayer->getDefaultLineTranslate();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+}
+
+- (void)setLineTranslateAnchor:(MGLStyleValue<NSValue *> *)lineTranslateAnchor {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLLineTranslateAnchor>().toEnumPropertyValue(lineTranslateAnchor);
+ _rawLayer->setLineTranslateAnchor(mbglValue);
+}
+
+- (MGLStyleValue<NSValue *> *)lineTranslateAnchor {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineTranslateAnchor() ?: _rawLayer->getDefaultLineTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLLineTranslateAnchor>().toEnumStyleValue(propertyValue);
+}
+
+- (void)setLineWidth:(MGLStyleValue<NSNumber *> *)lineWidth {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineWidth);
+ _rawLayer->setLineWidth(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)lineWidth {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getLineWidth() ?: _rawLayer->getDefaultLineWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
+
@end
diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h
index 69c7295842..3431fc2483 100644
--- a/platform/darwin/src/MGLMultiPoint.h
+++ b/platform/darwin/src/MGLMultiPoint.h
@@ -48,16 +48,25 @@ NS_ASSUME_NONNULL_BEGIN
cause the shape to be redrawn if it is currently visible on the map.
@param range The range of points to update. The `location` field indicates the
- first point you are replacing, with `0` being the first point, `1` being
- the second point, and so on. The `length` field indicates the number of
- points to update. You can append to an existing array of coordinates
- by specifying a range with a `location` at the end of the existing array
- and/or a `length` which extends past the end of the existing array. The array
- in _`coords`_ must be equal in number to the length of the range.
+ first point you are replacing, with `0` being the first point, `1` being
+ the second point, and so on. The `length` field indicates the number of
+ points to update. The array in _`coords`_ must be equal in number to the
+ length of the range. If you want to append to the existing coordinates
+ array use `-[MGLMultiPoint appendCoordinates:count:]`.
@param coords The array of coordinates defining the shape. The data in this
- array is copied to the object.
+ array is copied to the object.
+ */
+- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords;
+
+/**
+ Appends one or more coordinates for the shape, which will instantaneously
+ cause the shape to be redrawn if it is currently visible on the map.
+
+ @param coords The array of coordinates to add to the shape. The data in this
+ array is copied to the new object.
+ @param count The number of items in the `coords` array.
*/
-- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(CLLocationCoordinate2D *)coords;
+- (void)appendCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
@end
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm
index 17a61ed081..57b57889f3 100644
--- a/platform/darwin/src/MGLMultiPoint.mm
+++ b/platform/darwin/src/MGLMultiPoint.mm
@@ -14,55 +14,33 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
@implementation MGLMultiPoint
{
- size_t _count;
MGLCoordinateBounds _bounds;
+ std::vector<CLLocationCoordinate2D> _coordinates;
}
-- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
self = [super init];
if (self)
{
- [self setupWithCoordinates:coords count:count];
+ NSAssert(count > 0, @"A multipoint must have coordinates");
+ _coordinates = { coords, coords + count };
+ [self computeBounds];
}
return self;
}
-- (void)setupWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
-{
- if (_coordinates) free(_coordinates);
-
- _count = count;
- _coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));
-
- mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
-
- for (NSUInteger i = 0; i < _count; i++)
- {
- _coordinates[i] = coords[i];
- bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude));
- }
-
- _bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
-}
-
-- (void)dealloc
-{
- free(_coordinates);
-}
-
- (CLLocationCoordinate2D)coordinate
{
- assert(_count > 0);
-
- return CLLocationCoordinate2DMake(_coordinates[0].latitude, _coordinates[0].longitude);
+ NSAssert([self pointCount] > 0, @"A multipoint must have coordinates");
+ return _coordinates.at(0);
}
- (NSUInteger)pointCount
{
- return _count;
+ return _coordinates.size();
}
+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingPointCount
@@ -70,59 +48,59 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
return [NSSet setWithObjects:@"coordinates", nil];
}
+- (CLLocationCoordinate2D *)coordinates
+{
+ return _coordinates.data();
+}
+
- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
{
- if (range.location + range.length > _count)
+ if (range.location + range.length > [self pointCount])
{
[NSException raise:NSRangeException
- format:@"Invalid coordinate range %@ extends beyond current coordinate count of %zu",
- NSStringFromRange(range), _count];
+ format:@"Invalid coordinate range %@ extends beyond current coordinate count of %ld",
+ NSStringFromRange(range), (unsigned long)[self pointCount]];
}
- NSUInteger index = 0;
+ std::copy(_coordinates.begin() + range.location, _coordinates.begin() + NSMaxRange(range), coords);
+}
- for (NSUInteger i = range.location; i < range.location + range.length; i++)
- {
- coords[index] = _coordinates[i];
- index++;
- }
+- (void)appendCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count
+{
+ [self willChangeValueForKey:@"coordinates"];
+ _coordinates.insert(_coordinates.end(), count, *coords);
+ [self computeBounds];
+ [self didChangeValueForKey:@"coordinates"];
}
-- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(CLLocationCoordinate2D *)coords
+- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords
{
- if ((coords >= _coordinates && coords < _coordinates + _count) ||
- (coords + range.length >= _coordinates && coords + range.length < _coordinates + _count))
- {
- [NSException raise:NSRangeException format:@"Reuse of existing coordinates array %p not supported", coords];
- }
- else if (range.length == 0)
+ if (range.length == 0)
{
- [NSException raise:NSRangeException format:@"Empty coordinate range %@", NSStringFromRange(range)];
+ return;
}
- else if (range.location > _count)
+
+ if (NSMaxRange(range) > _coordinates.size())
{
[NSException raise:NSRangeException
- format:@"Invalid range %@ for existing coordinate count %zu",
- NSStringFromRange(range), _count];
+ format:@"Invalid range %@ for existing coordinate count %ld",
+ NSStringFromRange(range), (unsigned long)[self pointCount]];
}
[self willChangeValueForKey:@"coordinates"];
- if (NSMaxRange(range) <= _count)
- {
- // replacing existing coordinate(s)
- memcpy(_coordinates + range.location, coords, range.length * sizeof(CLLocationCoordinate2D));
- }
- else
+ std::copy(coords, coords + range.length, _coordinates.begin() + range.location);
+ [self computeBounds];
+ [self didChangeValueForKey:@"coordinates"];
+}
+
+- (void)computeBounds
+{
+ mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
+ for (auto coordinate : _coordinates)
{
- // appending new coordinate(s)
- NSUInteger newCount = NSMaxRange(range);
- CLLocationCoordinate2D *newCoordinates = (CLLocationCoordinate2D *)malloc(newCount * sizeof(CLLocationCoordinate2D));
- memcpy(newCoordinates, _coordinates, fmin(_count, range.location) * sizeof(CLLocationCoordinate2D));
- memcpy(newCoordinates + range.location, coords, range.length * sizeof(CLLocationCoordinate2D));
- [self setupWithCoordinates:newCoordinates count:newCount];
- free(newCoordinates);
+ bounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
}
- [self didChangeValueForKey:@"coordinates"];
+ _bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
}
- (MGLCoordinateBounds)overlayBounds
@@ -144,7 +122,7 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>",
- NSStringFromClass([self class]), (void *)self, (unsigned long)_count, MGLStringFromCoordinateBounds(_bounds)];
+ NSStringFromClass([self class]), (void *)self, (unsigned long)[self pointCount], MGLStringFromCoordinateBounds(_bounds)];
}
@end
diff --git a/platform/darwin/src/MGLMultiPoint_Private.h b/platform/darwin/src/MGLMultiPoint_Private.h
index 7bc3cae58a..a9b4b72ca5 100644
--- a/platform/darwin/src/MGLMultiPoint_Private.h
+++ b/platform/darwin/src/MGLMultiPoint_Private.h
@@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface MGLMultiPoint (Private)
-- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds;
/** Constructs a shape annotation object, asking the delegate for style values. */
diff --git a/platform/darwin/src/MGLPointCollection.h b/platform/darwin/src/MGLPointCollection.h
index db497d0a52..ce3e95a16d 100644
--- a/platform/darwin/src/MGLPointCollection.h
+++ b/platform/darwin/src/MGLPointCollection.h
@@ -26,7 +26,7 @@
@param count The number of items in the `coords` array.
@return A new point collection object.
*/
-+ (instancetype)pointCollectionWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
++ (instancetype)pointCollectionWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
/** The array of coordinates associated with the shape. */
@property (nonatomic, readonly) CLLocationCoordinate2D *coordinates NS_RETURNS_INNER_POINTER;
diff --git a/platform/darwin/src/MGLPointCollection.mm b/platform/darwin/src/MGLPointCollection.mm
index 5871915b5d..ab4a9c978e 100644
--- a/platform/darwin/src/MGLPointCollection.mm
+++ b/platform/darwin/src/MGLPointCollection.mm
@@ -8,31 +8,26 @@ NS_ASSUME_NONNULL_BEGIN
@implementation MGLPointCollection
{
- size_t _count;
MGLCoordinateBounds _bounds;
+ std::vector<CLLocationCoordinate2D> _coordinates;
}
-+ (instancetype)pointCollectionWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
++ (instancetype)pointCollectionWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
return [[self alloc] initWithCoordinates:coords count:count];
}
-- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
self = [super init];
if (self)
{
- _count = count;
- _coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));
-
+ _coordinates = { coords, coords + count };
mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
-
- for (NSUInteger i = 0; i < count; i++)
+ for (auto coordinate : _coordinates)
{
- _coordinates[i] = coords[i];
- bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude));
+ bounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
}
-
_bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
}
return self;
@@ -40,32 +35,30 @@ NS_ASSUME_NONNULL_BEGIN
- (NSUInteger)pointCount
{
- return _count;
+ return _coordinates.size();
+}
+
+- (CLLocationCoordinate2D *)coordinates
+{
+ return _coordinates.data();
}
- (CLLocationCoordinate2D)coordinate
{
- assert(_count > 0);
-
- return CLLocationCoordinate2DMake(_coordinates[0].latitude, _coordinates[0].longitude);
+ NSAssert([self pointCount] > 0, @"A multipoint must have coordinates");
+ return _coordinates.at(0);
}
- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
{
- if (range.location + range.length > _count)
+ if (range.location + range.length > [self pointCount])
{
[NSException raise:NSRangeException
- format:@"Invalid coordinate range %@ extends beyond current coordinate count of %zu",
- NSStringFromRange(range), _count];
- }
-
- NSUInteger index = 0;
-
- for (NSUInteger i = range.location; i < range.location + range.length; i++)
- {
- coords[index] = _coordinates[i];
- index++;
+ format:@"Invalid coordinate range %@ extends beyond current coordinate count of %ld",
+ NSStringFromRange(range), (unsigned long)[self pointCount]];
}
+
+ std::copy(_coordinates.begin() + range.location, _coordinates.begin() + NSMaxRange(range), coords);
}
- (MGLCoordinateBounds)overlayBounds
@@ -104,7 +97,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; count = %lu>",
- NSStringFromClass([self class]), (void *)self, (unsigned long)_count];
+ NSStringFromClass([self class]), (void *)self, (unsigned long)[self pointCount]];
}
@end
diff --git a/platform/darwin/src/MGLPointCollection_Private.h b/platform/darwin/src/MGLPointCollection_Private.h
index 039c1f18be..fc1c33fe4c 100644
--- a/platform/darwin/src/MGLPointCollection_Private.h
+++ b/platform/darwin/src/MGLPointCollection_Private.h
@@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface MGLPointCollection (Private)
-- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
@end
diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h
index 3d5b36abb6..b9ec6b8399 100644
--- a/platform/darwin/src/MGLPolygon.h
+++ b/platform/darwin/src/MGLPolygon.h
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polygon object.
*/
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
++ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
/**
Creates and returns an `MGLPolygon` object from the specified set of
@@ -50,7 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
is considered to have no interior polygons.
@return A new polygon object.
*/
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(nullable NS_ARRAY_OF(MGLPolygon *) *)interiorPolygons;
++ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(nullable NS_ARRAY_OF(MGLPolygon *) *)interiorPolygons;
@end
diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm
index eae2cfe75a..7562db6e61 100644
--- a/platform/darwin/src/MGLPolygon.mm
+++ b/platform/darwin/src/MGLPolygon.mm
@@ -9,15 +9,15 @@
@dynamic overlayBounds;
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count {
++ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count {
return [self polygonWithCoordinates:coords count:count interiorPolygons:nil];
}
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons {
++ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons {
return [[self alloc] initWithCoordinates:coords count:count interiorPolygons:interiorPolygons];
}
-- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons {
+- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons {
if (self = [super initWithCoordinates:coords count:count]) {
if (interiorPolygons.count) {
_interiorPolygons = interiorPolygons;
diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h
index d0274b44e3..cb98df9a1b 100644
--- a/platform/darwin/src/MGLPolyline.h
+++ b/platform/darwin/src/MGLPolyline.h
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polyline object.
*/
-+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
++ (instancetype)polylineWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count;
@end
diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm
index dd2fccf53d..1801dfd44e 100644
--- a/platform/darwin/src/MGLPolyline.mm
+++ b/platform/darwin/src/MGLPolyline.mm
@@ -9,7 +9,7 @@
@dynamic overlayBounds;
-+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords
++ (instancetype)polylineWithCoordinates:(const CLLocationCoordinate2D *)coords
count:(NSUInteger)count
{
return [[self alloc] initWithCoordinates:coords count:count];
diff --git a/platform/darwin/src/MGLRasterSource.mm b/platform/darwin/src/MGLRasterSource.mm
index fc47c23853..62472050e3 100644
--- a/platform/darwin/src/MGLRasterSource.mm
+++ b/platform/darwin/src/MGLRasterSource.mm
@@ -62,7 +62,29 @@
- (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
+{
+ auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
+
+ _pendingSource = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::RasterSource> &>(removedSource));
+ self.rawSource = _pendingSource.get();
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; URL = %@; tileSet = %@; tileSize = %lu>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.URL,
+ self.tileSet, (unsigned long)self.tileSize];
+}
+
@end
diff --git a/platform/darwin/src/MGLRasterStyleLayer.h b/platform/darwin/src/MGLRasterStyleLayer.h
index afae85001e..68b187a908 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.h
+++ b/platform/darwin/src/MGLRasterStyleLayer.h
@@ -17,57 +17,57 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Accessing the Paint Attributes
/**
- The opacity at which the image will be drawn.
+ Increase or reduce the brightness of the image. The value is the maximum brightness.
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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *maximumRasterBrightness;
/**
- Rotates hues around the color wheel.
-
- This property is measured in degrees.
+ Increase or reduce the brightness of the image. The value is the minimum brightness.
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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterHueRotate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *minimumRasterBrightness;
/**
- Increase or reduce the brightness of the image. The value is the minimum brightness.
+ Increase or reduce the contrast of the image.
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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterBrightnessMin;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterContrast;
/**
- Increase or reduce the brightness of the image. The value is the maximum brightness.
+ Fade duration when a new tile is added.
+
+ This property is measured in milliseconds.
- 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.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `300`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterBrightnessMax;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterFadeDuration;
/**
- Increase or reduce the saturation of the image.
+ Rotates hues around the color wheel.
+
+ This property is measured in degrees.
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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterSaturation;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterHueRotate;
/**
- Increase or reduce the contrast of the image.
+ The opacity at which the image will be drawn.
- 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.
+ 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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterContrast;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterOpacity;
/**
- Fade duration when a new tile is added.
-
- This property is measured in milliseconds.
+ Increase or reduce the saturation of the image.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `300`. Set this property to `nil` to reset it to the default value.
+ 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.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterFadeDuration;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterSaturation;
@end
diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm
index f616e89518..3b2c3bd83b 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.mm
+++ b/platform/darwin/src/MGLRasterStyleLayer.mm
@@ -2,6 +2,7 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
@@ -11,90 +12,167 @@
@interface MGLRasterStyleLayer ()
-@property (nonatomic) mbgl::style::RasterLayer *layer;
+@property (nonatomic) 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]) {
- _layer = new mbgl::style::RasterLayer(identifier.UTF8String, source.identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::RasterLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
+#pragma mark - Adding to and removing from a map view
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
+
+ [self addToMapView:mapView belowLayer:nil];
+}
+
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
+
+ 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);
+ _rawLayer = _pendingLayer.get();
+}
#pragma mark - Accessing the Paint Attributes
-- (void)setRasterOpacity:(MGLStyleValue<NSNumber *> *)rasterOpacity {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterOpacity);
- self.layer->setRasterOpacity(mbglValue);
+- (void)setMaximumRasterBrightness:(MGLStyleValue<NSNumber *> *)maximumRasterBrightness {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(maximumRasterBrightness);
+ _rawLayer->setRasterBrightnessMax(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterOpacity {
- auto propertyValue = self.layer->getRasterOpacity() ?: self.layer->getDefaultRasterOpacity();
+- (MGLStyleValue<NSNumber *> *)maximumRasterBrightness {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterBrightnessMax() ?: _rawLayer->getDefaultRasterBrightnessMax();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterHueRotate:(MGLStyleValue<NSNumber *> *)rasterHueRotate {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterHueRotate);
- self.layer->setRasterHueRotate(mbglValue);
+- (void)setMinimumRasterBrightness:(MGLStyleValue<NSNumber *> *)minimumRasterBrightness {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(minimumRasterBrightness);
+ _rawLayer->setRasterBrightnessMin(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterHueRotate {
- auto propertyValue = self.layer->getRasterHueRotate() ?: self.layer->getDefaultRasterHueRotate();
+- (MGLStyleValue<NSNumber *> *)minimumRasterBrightness {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterBrightnessMin() ?: _rawLayer->getDefaultRasterBrightnessMin();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterBrightnessMin:(MGLStyleValue<NSNumber *> *)rasterBrightnessMin {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterBrightnessMin);
- self.layer->setRasterBrightnessMin(mbglValue);
+- (void)setRasterContrast:(MGLStyleValue<NSNumber *> *)rasterContrast {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterContrast);
+ _rawLayer->setRasterContrast(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterBrightnessMin {
- auto propertyValue = self.layer->getRasterBrightnessMin() ?: self.layer->getDefaultRasterBrightnessMin();
+- (MGLStyleValue<NSNumber *> *)rasterContrast {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterContrast() ?: _rawLayer->getDefaultRasterContrast();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterBrightnessMax:(MGLStyleValue<NSNumber *> *)rasterBrightnessMax {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterBrightnessMax);
- self.layer->setRasterBrightnessMax(mbglValue);
+- (void)setRasterFadeDuration:(MGLStyleValue<NSNumber *> *)rasterFadeDuration {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterFadeDuration);
+ _rawLayer->setRasterFadeDuration(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterBrightnessMax {
- auto propertyValue = self.layer->getRasterBrightnessMax() ?: self.layer->getDefaultRasterBrightnessMax();
+- (MGLStyleValue<NSNumber *> *)rasterFadeDuration {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterFadeDuration() ?: _rawLayer->getDefaultRasterFadeDuration();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterSaturation:(MGLStyleValue<NSNumber *> *)rasterSaturation {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterSaturation);
- self.layer->setRasterSaturation(mbglValue);
+- (void)setRasterHueRotate:(MGLStyleValue<NSNumber *> *)rasterHueRotate {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterHueRotate);
+ _rawLayer->setRasterHueRotate(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterSaturation {
- auto propertyValue = self.layer->getRasterSaturation() ?: self.layer->getDefaultRasterSaturation();
+- (MGLStyleValue<NSNumber *> *)rasterHueRotate {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterHueRotate() ?: _rawLayer->getDefaultRasterHueRotate();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterContrast:(MGLStyleValue<NSNumber *> *)rasterContrast {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterContrast);
- self.layer->setRasterContrast(mbglValue);
+- (void)setRasterOpacity:(MGLStyleValue<NSNumber *> *)rasterOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterOpacity);
+ _rawLayer->setRasterOpacity(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterContrast {
- auto propertyValue = self.layer->getRasterContrast() ?: self.layer->getDefaultRasterContrast();
+- (MGLStyleValue<NSNumber *> *)rasterOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterOpacity() ?: _rawLayer->getDefaultRasterOpacity();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterFadeDuration:(MGLStyleValue<NSNumber *> *)rasterFadeDuration {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterFadeDuration);
- self.layer->setRasterFadeDuration(mbglValue);
+- (void)setRasterSaturation:(MGLStyleValue<NSNumber *> *)rasterSaturation {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterSaturation);
+ _rawLayer->setRasterSaturation(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)rasterFadeDuration {
- auto propertyValue = self.layer->getRasterFadeDuration() ?: self.layer->getDefaultRasterFadeDuration();
+- (MGLStyleValue<NSNumber *> *)rasterSaturation {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getRasterSaturation() ?: _rawLayer->getDefaultRasterSaturation();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
+
@end
diff --git a/platform/darwin/src/MGLRuntimeStylingTests.m.ejs b/platform/darwin/src/MGLRuntimeStylingTests.m.ejs
index c1492167b4..720ee4547e 100644
--- a/platform/darwin/src/MGLRuntimeStylingTests.m.ejs
+++ b/platform/darwin/src/MGLRuntimeStylingTests.m.ejs
@@ -6,9 +6,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGL<%- camelize(type) %>LayerTests : MGLMapViewTests
+@interface MGL<%- camelize(type) %>LayerTests : MGLStyleLayerTests
@end
@implementation MGL<%- camelize(type) %>LayerTests
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index 1b889d44d7..2fa580df89 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -2,6 +2,14 @@
#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;
+
+@end
+
@implementation MGLSource
- (instancetype)initWithIdentifier:(NSString *)identifier
@@ -12,4 +20,23 @@
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];
+}
+
+- (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];
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier];
+}
+
@end
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index 954dd5ae38..5f63f1fb1d 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -27,4 +27,13 @@
*/
- (void)addToMapView:(MGLMapView *)mapView;
+/**
+ Removes the mbgl source that this object represents from the mbgl map.
+
+ When a mbgl source is removed, ownership of the object is transferred back
+ to the `MGLSource` instance and the unique_ptr reference is valid again. It is
+ safe to add the source back to the style after it is removed.
+ */
+- (void)removeFromMapView:(MGLMapView *)mapView;
+
@end
diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h
index 7f01c230c5..54ca267bab 100644
--- a/platform/darwin/src/MGLStyle.h
+++ b/platform/darwin/src/MGLStyle.h
@@ -37,7 +37,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
*/
@interface MGLStyle : NSObject
-#pragma mark Default Style URLs
+#pragma mark Accessing Common Styles
/**
Returns the URL to version 8 of the
@@ -165,6 +165,8 @@ static const NSInteger MGLStyleDefaultVersion = 9;
*/
+ (NSURL *)satelliteStreetsStyleURLWithVersion:(NSInteger)version;
+#pragma mark Accessing Metadata About the Style
+
/**
The name of the style.
@@ -172,63 +174,164 @@ static const NSInteger MGLStyleDefaultVersion = 9;
*/
@property (readonly, copy, nullable) NSString *name;
-#pragma mark Runtime Styling
+#pragma mark Managing Sources
/**
- Returns a layer that conforms to `MGLStyleLayer` if any layer with the given
- identifier was found.
-
- @return An instance of a concrete subclass of `MGLStyleLayer` associated with
- the given identifier.
+ A set containing the style’s sources.
*/
-- (nullable MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier;
-
+@property (nonatomic, strong) NS_MUTABLE_SET_OF(MGLSource *) *sources;
/**
- Returns a source if any source with the given identifier was found.
+ Returns a source with the given identifier in the current style.
+
+ @note Source identifiers 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 source identifer name changes that will occur in the default
+ style’s sources over time.
@return An instance of a concrete subclass of `MGLSource` associated with the
- given identifier.
+ given identifier, or `nil` if the current style contains no such source.
*/
- (nullable MGLSource *)sourceWithIdentifier:(NSString *)identifier;
/**
+ Adds a new source to the current style.
+
+ @note Adding the same source instance more than once will result in a
+ `MGLRedundantSourceException`. Reusing the same source identifier, even with
+ different source instances, will result in a
+ `MGLRedundantSourceIdentiferException`.
+
+ @param source The source to add to the current style.
+ */
+- (void)addSource:(MGLSource *)source;
+
+/**
+ Removes a source from the current style.
+
+ @note Source identifiers 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 source identifer name changes that will occur in the default
+ style’s sources over time.
+
+ @param source The source to remove from the current style.
+ */
+- (void)removeSource:(MGLSource *)source;
+
+#pragma mark Managing Style Layers
+
+/**
+ The layers included in the style, arranged according to their front-to-back
+ ordering on the screen.
+ */
+@property (nonatomic, strong) NS_MUTABLE_ARRAY_OF(MGLStyleLayer *) *layers;
+
+/**
+ Returns a style layer with the given identifier in the current style.
+
+ @note Layer identifiers 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 layer identifer name changes that will occur in the default
+ style’s layers over time.
+
+ @return An instance of a concrete subclass of `MGLStyleLayer` associated with
+ the given identifier, or `nil` if the current style contains no such style
+ layer.
+ */
+- (nullable MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier;
+
+/**
Adds a new layer on top of existing layers.
+ @note Adding the same layer instance more than once will result in a
+ `MGLRedundantLayerException`. Reusing the same layer identifer, even with
+ different layer instances, will also result in an exception.
+
@param layer The layer object to add to the map view. This object must be an
instance of a concrete subclass of `MGLStyleLayer`.
*/
- (void)addLayer:(MGLStyleLayer *)layer;
/**
+ Inserts a new layer into the style at the given index.
+
+ @note Adding the same layer instance more than once will result in a
+ `MGLRedundantLayerException`. Reusing the same layer identifer, even with
+ different layer instances, will also result in an exception.
+
+ @param layer The layer to insert.
+ @param index The index at which to insert the layer. An index of 0 would send
+ the layer to the back; an index equal to the number of objects in the
+ `layers` property would bring the layer to the front.
+ */
+- (void)insertLayer:(MGLStyleLayer *)layer atIndex:(NSUInteger)index;
+
+/**
Inserts a new layer below another layer.
+
+ @note Layer identifiers 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 layer identifer name changes that will occur in the default
+ style’s layers over time.
+
+ Inserting the same layer instance more than once will result in a
+ `MGLRedundantLayerException`. Reusing the same layer identifer, even with
+ different layer instances, will also result in an exception.
+
+ @param layer The layer to insert.
+ @param sibling An existing layer in the style.
+ */
+- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling;
- @param layer Layer to be inserted.
- @param belowLayer A layer that's already on the map view.
+/**
+ Inserts a new layer above another layer.
+
+ @note Layer identifiers 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 layer identifer name changes that will occur in the default
+ style’s layers over time.
+
+ Inserting the same layer instance more than once will result in a
+ `MGLRedundantLayerException`. Reusing the same layer identifer, even with
+ different layer instances, will also result in an exception.
+
+ @param layer The layer to insert.
+ @param sibling An existing layer in the style.
*/
-- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer;
+- (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling;
/**
Removes a layer from the map view.
+
+ @note Layer identifiers 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 layer identifer name changes that will occur in the default
+ style’s layers over time.
@param layer The layer object to remove from the map view. This object
must conform to the `MGLStyleLayer` protocol.
*/
- (void)removeLayer:(MGLStyleLayer *)layer;
-/**
- Adds a new source to the map view.
-
- @param source The source to add to the map view.
- */
-- (void)addSource:(MGLSource *)source;
-
-/**
- Removes a source from the map view.
-
- @param source The source to remove.
- */
-- (void)removeSource:(MGLSource *)source;
+#pragma mark Managing Style Classes
/**
Currently active style classes, represented as an array of string identifiers.
@@ -253,17 +356,27 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
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.
*/
- (void)removeStyleClass:(NSString *)styleClass;
-/**
-Adds or overrides an image used by the style’s layers.
-
-To use an image in a style layer, give it a unique name using this method,
-then set the `iconImage` property of an `MGLSymbolStyleLayer` object to that name.
+#pragma mark Managing a Style’s Images
+/**
+ Adds or overrides an image used by the style’s layers.
+
+ To use an image in a style layer, give it a unique name using this method, then
+ set the `iconImage` property of an `MGLSymbolStyleLayer` object to that name.
+
@param image The image for the name.
@param name The name of the image to set to the style.
*/
@@ -271,6 +384,14 @@ then set the `iconImage` property of an `MGLSymbolStyleLayer` object to that nam
/**
Removes a name and its associated image from the style.
+
+ @note Names and their associated images 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 image name changes that will
+ occur in the default style over time.
@param name The name of the image to remove.
*/
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 6da3cae3df..6116f4df28 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -39,12 +39,16 @@
#endif
@interface MGLStyle()
-@property (nonatomic, weak) MGLMapView *mapView;
+
+@property (nonatomic, readwrite, weak) MGLMapView *mapView;
@property (readonly, copy, nullable) NSURL *URL;
+
@end
@implementation MGLStyle
+#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.
@@ -99,21 +103,197 @@ static NSURL *MGLStyleURL_emerald;
return MGLStyleURL_emerald;
}
-- (NSString *)name {
- return @(self.mapView.mbglMap->getStyleName().c_str());
+#pragma mark -
+
+- (instancetype)initWithMapView:(MGLMapView *)mapView {
+ if (self = [super init]) {
+ _mapView = mapView;
+ }
+ return self;
}
- (NSURL *)URL {
return [NSURL URLWithString:@(self.mapView.mbglMap->getStyleURL().c_str())];
}
-- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
+- (NSString *)name {
+ std::string name = self.mapView.mbglMap->getStyleName();
+ return name.empty() ? nil : @(name.c_str());
+}
+
+#pragma mark Sources
+
+- (NS_MUTABLE_SET_OF(MGLSource *) *)sources {
+ auto rawSources = self.mapView.mbglMap->getSources();
+ NSMutableSet *sources = [NSMutableSet setWithCapacity:rawSources.size()];
+ for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) {
+ MGLSource *source = [self sourceFromMBGLSource:*rawSource];
+ [sources addObject:source];
+ }
+ return sources;
+}
+
+- (void)setSources:(NS_MUTABLE_SET_OF(MGLSource *) *)sources {
+ for (MGLSource *source in self.sources) {
+ [self removeSource:source];
+ }
+ for (MGLSource *source in sources) {
+ [self addSource:source];
+ }
+}
+
+- (NSUInteger)countOfSources {
+ auto rawSources = self.mapView.mbglMap->getSources();
+ return rawSources.size();
+}
+
+- (MGLSource *)memberOfSources:(MGLSource *)object {
+ return [self sourceWithIdentifier:object.identifier];
+}
+
+- (MGLSource *)sourceWithIdentifier:(NSString *)identifier
{
- auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
- if (!mbglLayer) {
+ auto rawSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
+ return rawSource ? [self sourceFromMBGLSource:rawSource] : nil;
+}
+
+- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)mbglSource {
+ NSString *identifier = @(mbglSource->getID().c_str());
+
+ // TODO: Fill in options specific to the respective source classes
+ // https://github.com/mapbox/mapbox-gl-native/issues/6584
+ MGLSource *source;
+ if (mbglSource->is<mbgl::style::VectorSource>()) {
+ source = [[MGLVectorSource alloc] initWithIdentifier:identifier];
+ } else if (mbglSource->is<mbgl::style::GeoJSONSource>()) {
+ source = [[MGLGeoJSONSource alloc] initWithIdentifier:identifier];
+ } else if (mbglSource->is<mbgl::style::RasterSource>()) {
+ source = [[MGLRasterSource alloc] initWithIdentifier:identifier];
+ } else {
+ source = [[MGLSource alloc] initWithIdentifier:identifier];
+ }
+
+ source.rawSource = mbglSource;
+
+ return source;
+}
+
+- (void)addSource:(MGLSource *)source
+{
+ if (!source.rawSource) {
+ [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.",
+ source];
+ }
+
+ try {
+ [source addToMapView:self.mapView];
+ } catch (std::runtime_error & err) {
+ [NSException raise:@"MGLRedundantSourceIdentiferException" format:@"%s", err.what()];
+ }
+}
+
+- (void)removeSource:(MGLSource *)source
+{
+ if (!source.rawSource) {
+ [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.",
+ source];
+ }
+ [source removeFromMapView:self.mapView];
+}
+
+#pragma mark Style layers
+
+- (NS_MUTABLE_ARRAY_OF(MGLStyleLayer *) *)layers
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ NSMutableArray *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()];
+ for (auto layer = layers.rbegin(); layer != layers.rend(); ++layer) {
+ MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:*layer];
+ [styleLayers addObject:styleLayer];
+ }
+ return styleLayers;
+}
+
+- (void)setLayers:(NS_MUTABLE_ARRAY_OF(MGLStyleLayer *) *)layers {
+ for (MGLStyleLayer *layer in self.layers.reverseObjectEnumerator) {
+ [self removeLayer:layer];
+ }
+ for (MGLStyleLayer *layer in layers.reverseObjectEnumerator) {
+ [self addLayer:layer];
+ }
+}
+
+- (NSUInteger)countOfLayers
+{
+ return self.mapView.mbglMap->getLayers().size();
+}
+
+- (MGLStyleLayer *)objectInLayersAtIndex:(NSUInteger)index
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (index > layers.size() - 1) {
+ [NSException raise:NSRangeException
+ format:@"No style layer at index %lu.", (unsigned long)index];
return nil;
}
+ auto layer = layers.at(layers.size() - 1 - index);
+ return [self layerFromMBGLLayer:layer];
+}
+- (void)getLayers:(MGLStyleLayer **)buffer range:(NSRange)inRange
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (NSMaxRange(inRange) > layers.size()) {
+ [NSException raise:NSRangeException
+ format:@"Style layer range %@ is out of bounds.", NSStringFromRange(inRange)];
+ }
+ NSUInteger i = 0;
+ for (auto layer = *(layers.rbegin() + inRange.location); i < inRange.length; ++layer, ++i) {
+ MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
+ buffer[i] = styleLayer;
+ }
+}
+
+- (void)insertObject:(MGLStyleLayer *)styleLayer inLayersAtIndex:(NSUInteger)index
+{
+ if (!styleLayer.rawLayer) {
+ [NSException raise:NSInvalidArgumentException format:
+ @"The style layer %@ cannot be inserted into the style. "
+ @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
+ styleLayer];
+ }
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (index > layers.size()) {
+ [NSException raise:NSRangeException
+ format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index];
+ } else if (index == 0) {
+ [styleLayer addToMapView:self.mapView];
+ } else {
+ MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(layers.size() - index)];
+ [styleLayer addToMapView:self.mapView belowLayer:sibling];
+ }
+}
+
+- (void)removeObjectFromLayersAtIndex:(NSUInteger)index
+{
+ auto layers = self.mapView.mbglMap->getLayers();
+ if (index > layers.size() - 1) {
+ [NSException raise:NSRangeException
+ format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index];
+ }
+ auto layer = layers.at(layers.size() - 1 - index);
+ self.mapView.mbglMap->removeLayer(layer->getID());
+}
+
+- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)mbglLayer
+{
+ 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())];
@@ -137,116 +317,112 @@ static NSURL *MGLStyleURL_emerald;
return nil;
}
- styleLayer.layer = mbglLayer;
+ styleLayer.rawLayer = mbglLayer;
return styleLayer;
}
-- (MGLSource *)sourceWithIdentifier:(NSString *)identifier
+- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
{
- auto mbglSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
-
- if (!mbglSource) {
- return nil;
- }
-
- // TODO: Fill in options specific to the respective source classes
- // https://github.com/mapbox/mapbox-gl-native/issues/6584
- MGLSource *source;
- if (mbglSource->is<mbgl::style::VectorSource>()) {
- source = [[MGLVectorSource alloc] initWithIdentifier:identifier];
- } else if (mbglSource->is<mbgl::style::GeoJSONSource>()) {
- source = [[MGLGeoJSONSource alloc] initWithIdentifier:identifier];
- } else if (mbglSource->is<mbgl::style::RasterSource>()) {
- source = [[MGLRasterSource alloc] initWithIdentifier:identifier];
- } else {
- NSAssert(NO, @"Unrecognized source type");
- return nil;
- }
-
- source.rawSource = mbglSource;
-
- return source;
+ auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
+ return mbglLayer ? [self layerFromMBGLLayer:mbglLayer] : nil;
}
- (void)removeLayer:(MGLStyleLayer *)layer
{
- if (!layer.layer) {
+ if (!layer.rawLayer) {
[NSException raise:NSInvalidArgumentException format:
@"The style layer %@ cannot be removed from the style. "
@"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
layer];
}
-
- self.mapView.mbglMap->removeLayer(layer.identifier.UTF8String);
+ [self willChangeValueForKey:@"layers"];
+ [layer removeFromMapView:self.mapView];
+ [self didChangeValueForKey:@"layers"];
}
- (void)addLayer:(MGLStyleLayer *)layer
{
- if (!layer.layer) {
+ if (!layer.rawLayer) {
[NSException raise:NSInvalidArgumentException format:
@"The style layer %@ cannot be added to the style. "
@"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
layer];
}
+ [self willChangeValueForKey:@"layers"];
+ [layer addToMapView:self.mapView];
+ [self didChangeValueForKey:@"layers"];
+}
- self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer));
+- (void)insertLayer:(MGLStyleLayer *)layer atIndex:(NSUInteger)index {
+ [self insertObject:layer inLayersAtIndex:index];
}
-- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer
+- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling
{
- if (!layer.layer) {
+ if (!layer.rawLayer) {
[NSException raise:NSInvalidArgumentException
format:
@"The style layer %@ cannot be added to the style. "
@"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
layer];
}
- if (!otherLayer.layer) {
+ if (!sibling.rawLayer) {
[NSException raise:NSInvalidArgumentException
format:
- @"A style layer cannot be placed before %@ in the style. "
- @"Make sure otherLayer was obtained using -[MGLStyle layerWithIdentifier:].",
- otherLayer];
+ @"A style layer cannot be placed below %@ in the style. "
+ @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].",
+ sibling];
}
-
- const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
- self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer), belowLayerId);
+ [self willChangeValueForKey:@"layers"];
+ [layer addToMapView:self.mapView belowLayer:sibling];
+ [self didChangeValueForKey:@"layers"];
}
-- (void)addSource:(MGLSource *)source
-{
- if (!source.rawSource) {
- [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.",
- source];
+- (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling {
+ if (!layer.rawLayer) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"The style layer %@ cannot be added to the style. "
+ @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
+ layer];
}
-
- try {
- [source addToMapView:self.mapView];
- } catch (std::runtime_error & err) {
- [NSException raise:@"Could not add source" format:@"%s", err.what()];
+ if (!sibling.rawLayer) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"A style layer cannot be placed above %@ in the style. "
+ @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].",
+ sibling];
}
-}
-
-- (void)removeSource:(MGLSource *)source
-{
- if (!source.rawSource) {
- [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.",
- source];
+
+ auto layers = self.mapView.mbglMap->getLayers();
+ std::string siblingIdentifier = sibling.identifier.UTF8String;
+ NSUInteger index = 0;
+ for (auto layer : layers) {
+ if (layer->getID() == siblingIdentifier) {
+ break;
+ }
+ index++;
}
-
- self.mapView.mbglMap->removeSource(source.identifier.UTF8String);
- // Once a mbgl source is removed from the map, ownership does not return
- // to the MGL source. Therefore, the rawSource pointer is set to NULL
- // so that the implementation of MGL source can avoid using it again.
- source.rawSource = NULL;
+ [self willChangeValueForKey:@"layers"];
+ if (index + 1 > layers.size()) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"A style layer cannot be placed above %@ in the style. "
+ @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].",
+ sibling];
+ } else if (index + 1 == layers.size()) {
+ [layer addToMapView:self.mapView];
+ } else {
+ MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index + 1)];
+ [layer addToMapView:self.mapView belowLayer:sibling];
+ }
+ [self didChangeValueForKey:@"layers"];
}
+#pragma mark Style classes
+
- (NS_ARRAY_OF(NSString *) *)styleClasses
{
const std::vector<std::string> &appliedClasses = self.mapView.mbglMap->getClasses();
@@ -279,6 +455,11 @@ static NSURL *MGLStyleURL_emerald;
self.mapView.mbglMap->setClasses(newAppliedClasses);
}
+- (NSUInteger)countOfStyleClasses {
+ const auto &classes = self.mapView.mbglMap->getClasses();
+ return classes.size();
+}
+
- (BOOL)hasStyleClass:(NSString *)styleClass
{
return styleClass && self.mapView.mbglMap->hasClass([styleClass UTF8String]);
@@ -300,6 +481,8 @@ static NSURL *MGLStyleURL_emerald;
}
}
+#pragma mark Style images
+
- (void)setImage:(MGLImage *)image forName:(NSString *)name
{
NSAssert(image, @"image is null");
diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm
index 293aa54f30..6d9dabf25e 100644
--- a/platform/darwin/src/MGLStyleLayer.mm
+++ b/platform/darwin/src/MGLStyleLayer.mm
@@ -3,12 +3,6 @@
#include <mbgl/style/layer.hpp>
-@interface MGLStyleLayer ()
-
-@property (nonatomic) mbgl::style::Layer *layer;
-
-@end
-
@implementation MGLStyleLayer
- (instancetype)initWithIdentifier:(NSString *)identifier
@@ -21,36 +15,55 @@
- (void)setVisible:(BOOL)visible
{
+ MGLAssertStyleLayerIsValid();
+
mbgl::style::VisibilityType v = visible
? mbgl::style::VisibilityType::Visible
: mbgl::style::VisibilityType::None;
- self.layer->setVisibility(v);
+ self.rawLayer->setVisibility(v);
}
- (BOOL)isVisible
{
- mbgl::style::VisibilityType v = self.layer->getVisibility();
+ MGLAssertStyleLayerIsValid();
+
+ mbgl::style::VisibilityType v = self.rawLayer->getVisibility();
return (v == mbgl::style::VisibilityType::Visible);
}
- (void)setMaximumZoomLevel:(float)maximumZoomLevel
{
- self.layer->setMaxZoom(maximumZoomLevel);
+ MGLAssertStyleLayerIsValid();
+
+ self.rawLayer->setMaxZoom(maximumZoomLevel);
}
- (float)maximumZoomLevel
{
- return self.layer->getMaxZoom();
+ MGLAssertStyleLayerIsValid();
+
+ return self.rawLayer->getMaxZoom();
}
- (void)setMinimumZoomLevel:(float)minimumZoomLevel
{
- self.layer->setMinZoom(minimumZoomLevel);
+ MGLAssertStyleLayerIsValid();
+
+ self.rawLayer->setMinZoom(minimumZoomLevel);
}
- (float)minimumZoomLevel
{
- return self.layer->getMinZoom();
+ MGLAssertStyleLayerIsValid();
+
+ return self.rawLayer->getMinZoom();
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ self.visible ? @"YES" : @"NO"];
}
@end
diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs
index 3678e9ec52..c89912c1ff 100644
--- a/platform/darwin/src/MGLStyleLayer.mm.ejs
+++ b/platform/darwin/src/MGLStyleLayer.mm.ejs
@@ -2,79 +2,181 @@
const type = locals.type;
const layoutProperties = locals.layoutProperties;
const paintProperties = locals.paintProperties;
+ const containsEnumerationProperties = locals.containsEnumerationProperties;
-%>
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGL<%- camelize(type) %>StyleLayer.h"
#include <mbgl/style/layers/<%- type %>_layer.hpp>
+<% if (containsEnumerationProperties) { -%>
+namespace mbgl {
+
+<% if (layoutProperties.length) { -%>
+<% for (const property of layoutProperties) { -%>
+<% if (property.type == "enum") { -%>
+ MBGL_DEFINE_ENUM(MGL<%- camelize(originalPropertyName(property)) %>, {
+<% for (const value in property.values) { -%>
+ { MGL<%- camelize(originalPropertyName(property)) %><%- camelize(value) %>, "<%-value%>" },
+<% } -%>
+ });
+
+<% } -%>
+<% } -%>
+<% } -%>
+<% if (paintProperties.length) { -%>
+<% for (const property of paintProperties) { -%>
+<% if (property.type == "enum") { -%>
+ MBGL_DEFINE_ENUM(MGL<%- camelize(originalPropertyName(property)) %>, {
+<% for (const value in property.values) { -%>
+ { MGL<%- camelize(originalPropertyName(property)) %><%- camelize(value) %>, "<%-value%>" },
+<% } -%>
+ });
+
+<% } -%>
+<% } -%>
+<% } -%>
+}
+<% } -%>
@interface MGL<%- camelize(type) %>StyleLayer ()
-@property (nonatomic) mbgl::style::<%- camelize(type) %>Layer *layer;
+@property (nonatomic) 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]) {
- _layer = new mbgl::style::<%- camelize(type) %>Layer(identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
+
<% } else { -%>
- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
if (self = [super initWithIdentifier:identifier source:source]) {
- _layer = new mbgl::style::<%- camelize(type) %>Layer(identifier.UTF8String, source.identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String, source.identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
<% } -%>
-
<% if (type !== 'background' && type !== 'raster') { -%>
- (NSString *)sourceLayerIdentifier
{
- auto layerID = self.layer->getSourceLayer();
+ MGLAssertStyleLayerIsValid();
+
+ auto layerID = _rawLayer->getSourceLayer();
return layerID.empty() ? nil : @(layerID.c_str());
}
- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
{
- self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
{
- self.layer->setFilter(predicate.mgl_filter);
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setFilter(predicate.mgl_filter);
}
- (NSPredicate *)predicate
{
- return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()];
-}
+ MGLAssertStyleLayerIsValid();
+ return [NSPredicate mgl_predicateWithFilter:_rawLayer->getFilter()];
+}
<% } -%>
+#pragma mark - Adding to and removing from a map view
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
+
+ [self addToMapView:mapView belowLayer:nil];
+}
+
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
+
+ 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);
+ _rawLayer = _pendingLayer.get();
+}
+
<% if (layoutProperties.length) { -%>
#pragma mark - Accessing the Layout Attributes
<% for (const property of layoutProperties) { -%>
- (void)set<%- camelize(property.name) %>:(MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
+ MGLAssertStyleLayerIsValid();
+
+<% if (property.type == "enum") { -%>
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::<%- mbglType(property) %>, NSValue *, mbgl::style::<%- mbglType(property) %>, MGL<%- camelize(originalPropertyName(property)) %>>().toEnumPropertyValue(<%- objCName(property) %>);
+ _rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbglValue);
+<% } else { -%>
auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue(<%- objCName(property) %>);
- self.layer->set<%- camelize(property.name) %>(mbglValue);
+ _rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbglValue);
+<% } -%>
}
- (MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
- auto propertyValue = self.layer->get<%- camelize(property.name) %>() ?: self.layer->getDefault<%- camelize(property.name) %>();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->get<%- camelize(originalPropertyName(property)) %>() ?: _rawLayer->getDefault<%- camelize(originalPropertyName(property)) %>();
+<% if (property.type == "enum") { -%>
+ return MGLStyleValueTransformer<mbgl::style::<%- mbglType(property) %>, NSValue *, mbgl::style::<%- mbglType(property) %>, MGL<%- camelize(originalPropertyName(property)) %>>().toEnumStyleValue(propertyValue);
+<% } else { -%>
return MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toStyleValue(propertyValue);
+<% } -%>
}
<% } -%>
@@ -84,15 +186,29 @@
<% for (const property of paintProperties) { -%>
- (void)set<%- camelize(property.name) %>:(MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
+ MGLAssertStyleLayerIsValid();
+
+<% if (property.type == "enum") { -%>
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::<%- mbglType(property) %>, NSValue *, mbgl::style::<%- mbglType(property) %>, MGL<%- camelize(originalPropertyName(property)) %>>().toEnumPropertyValue(<%- objCName(property) %>);
+ _rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbglValue);
+<% } else { -%>
auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue(<%- objCName(property) %>);
- self.layer->set<%- camelize(property.name) %>(mbglValue);
+ _rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbglValue);
+<% } -%>
}
- (MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
- auto propertyValue = self.layer->get<%- camelize(property.name) %>() ?: self.layer->getDefault<%- camelize(property.name) %>();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->get<%- camelize(originalPropertyName(property)) %>() ?: _rawLayer->getDefault<%- camelize(originalPropertyName(property)) %>();
+<% if (property.type == "enum") { -%>
+ return MGLStyleValueTransformer<mbgl::style::<%- mbglType(property) %>, NSValue *, mbgl::style::<%- mbglType(property) %>, MGL<%- camelize(originalPropertyName(property)) %>>().toEnumStyleValue(propertyValue);
+<% } else { -%>
return MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toStyleValue(propertyValue);
+<% } -%>
}
<% } -%>
<% } -%>
+
@end
diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h
index 5fa01856ea..e723c8cf1b 100644
--- a/platform/darwin/src/MGLStyleLayer_Private.h
+++ b/platform/darwin/src/MGLStyleLayer_Private.h
@@ -5,9 +5,65 @@
#include <mbgl/style/layer.hpp>
+/**
+ Assert that the style layer is valid.
+
+ This macro should be used at the beginning of any public-facing instance method
+ of `MGLStyleLayer` and its subclasses. For private methods, an assertion is more appropriate.
+ */
+#define MGLAssertStyleLayerIsValid() \
+ do { \
+ if (!self.rawLayer) { \
+ [NSException raise:@"Invalid style layer" \
+ format: \
+ @"-[MGLStyle removeLayer:] has been called " \
+ @"with this instance but another style layer instance was added with the same identifer. It is an " \
+ @"error to send any message to this layer since it cannot be recovered after removal due to the " \
+ @"identifer collision. Use unique identifiers for all layer instances including layers of " \
+ @"different types."]; \
+ } \
+ } while (NO);
+
+@class MGLMapView;
+
@interface MGLStyleLayer (Private)
@property (nonatomic, readwrite, copy) NSString *identifier;
-@property (nonatomic) mbgl::style::Layer *layer;
+
+/**
+ A raw pointer to the mbgl object, which is always initialized, either to the
+ value returned by `mbgl::Map getLayer`, or for independently created objects,
+ to the pointer value held in `pendingLayer`. In the latter case, this raw
+ pointer value stays even after ownership of the object is transferred via
+ `mbgl::Map addLayer`.
+ */
+@property (nonatomic) mbgl::style::Layer *rawLayer;
+
+/**
+ Adds the mbgl style layer that this object represents to the mbgl map.
+
+ Once a mbgl style layer is added, ownership of the object is transferred to the
+ `mbgl::Map` and this object no longer has an active unique_ptr reference to the
+ `mbgl::style::Layer`.
+ */
+- (void)addToMapView:(MGLMapView *)mapView;
+
+/**
+ Removes the mbgl style layer that this object represents from the mbgl map.
+
+ When a mbgl style layer is removed, ownership of the object is transferred back
+ to the `MGLStyleLayer` instance and the unique_ptr reference is valid again. It
+ is safe to add the layer back to the style after it is removed.
+ */
+- (void)removeFromMapView:(MGLMapView *)mapView;
+
+/**
+ Adds the mbgl style layer that this object represents to the mbgl map below the specified `otherLayer`.
+
+ Once a mbgl style layer is added, ownership of the object is transferred to the
+ `mbgl::Map` and this object no longer has an active unique_ptr reference to the
+ `mbgl::style::Layer`.
+ */
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer;
@end
diff --git a/platform/darwin/src/MGLStyleValue_Private.h b/platform/darwin/src/MGLStyleValue_Private.h
index fdad07aafa..492ce20f1a 100644
--- a/platform/darwin/src/MGLStyleValue_Private.h
+++ b/platform/darwin/src/MGLStyleValue_Private.h
@@ -4,6 +4,8 @@
#import "NSValue+MGLStyleAttributeAdditions.h"
#import "MGLTypes.h"
+#import "MGLLineStyleLayer.h"
+#import <mbgl/util/enum.hpp>
#if TARGET_OS_IPHONE
#import "UIColor+MGLAdditions.h"
@@ -13,7 +15,7 @@
#include <array>
-template <typename MBGLType, typename ObjCType, typename MBGLElement = MBGLType>
+template <typename MBGLType, typename ObjCType, typename MBGLElement = MBGLType, typename ObjCEnum = ObjCType>
class MGLStyleValueTransformer {
public:
@@ -26,7 +28,26 @@ public:
return nil;
}
}
-
+
+ template <typename MBGLEnum = MBGLType,
+ class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type,
+ typename MGLEnum = ObjCEnum,
+ class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type>
+ MGLStyleValue<ObjCType> *toEnumStyleValue(const mbgl::style::PropertyValue<MBGLEnum> &mbglValue) {
+ if (mbglValue.isConstant()) {
+ return toEnumStyleConstantValue<>(mbglValue.asConstant());
+ } else if (mbglValue.isFunction()) {
+ const auto &mbglStops = mbglValue.asFunction().getStops();
+ NSMutableDictionary *stops = [NSMutableDictionary dictionaryWithCapacity:mbglStops.size()];
+ for (const auto &mbglStop : mbglStops) {
+ stops[@(mbglStop.first)] = toEnumStyleConstantValue<>(mbglStop.second);
+ }
+ return [MGLStyleFunction<NSValue *> functionWithBase:mbglValue.asFunction().getBase() stops:stops];
+ } else {
+ return nil;
+ }
+ }
+
mbgl::style::PropertyValue<MBGLType> toPropertyValue(MGLStyleValue<ObjCType> *value) {
if ([value isKindOfClass:[MGLStyleConstantValue class]]) {
MBGLType mbglValue;
@@ -52,9 +73,39 @@ public:
return {};
}
}
-
+
+ template <typename MBGLEnum = MBGLType,
+ class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type,
+ typename MGLEnum = ObjCEnum,
+ class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type>
+ mbgl::style::PropertyValue<MBGLEnum> toEnumPropertyValue(MGLStyleValue<ObjCType> *value) {
+ if ([value isKindOfClass:[MGLStyleConstantValue class]]) {
+ MBGLEnum mbglValue;
+ getMBGLValue([(MGLStyleConstantValue<ObjCType> *)value rawValue], mbglValue);
+ return mbglValue;
+ } else if ([value isKindOfClass:[MGLStyleFunction class]]) {
+ MGLStyleFunction<NSValue *> *function = (MGLStyleFunction<NSValue *> *)value;
+ __block std::vector<std::pair<float, MBGLEnum>> mbglStops;
+ [function.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, MGLStyleValue<NSValue *> * _Nonnull stopValue, BOOL * _Nonnull stop) {
+ NSCAssert([stopValue isKindOfClass:[MGLStyleValue class]], @"Stops should be MGLStyleValues");
+ auto mbglStopValue = toEnumPropertyValue(stopValue);
+ NSCAssert(mbglStopValue.isConstant(), @"Stops must be constant");
+ mbglStops.emplace_back(zoomKey.floatValue, mbglStopValue.asConstant());
+ }];
+ return mbgl::style::Function<MBGLEnum>({{mbglStops}}, function.base);
+ } else if (value) {
+ [NSException raise:@"MGLAbstractClassException" format:
+ @"The style value %@ cannot be applied to the style. "
+ @"Make sure the style value was created as a member of a concrete subclass of MGLStyleValue.",
+ NSStringFromClass([value class])];
+ return {};
+ } else {
+ return {};
+ }
+ }
+
private:
-
+
MGLStyleConstantValue<ObjCType> *toStyleConstantValue(const MBGLType mbglValue) {
auto rawValue = toMGLRawStyleValue(mbglValue);
return [MGLStyleConstantValue<ObjCType> valueWithRawValue:rawValue];
@@ -69,7 +120,17 @@ private:
}
return [MGLStyleFunction<ObjCType> functionWithBase:mbglFunction.getBase() stops:stops];
}
-
+
+ template <typename MBGLEnum = MBGLType,
+ class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type,
+ typename MGLEnum = ObjCEnum,
+ class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type>
+ MGLStyleConstantValue<ObjCType> *toEnumStyleConstantValue(const MBGLEnum mbglValue) {
+ auto str = mbgl::Enum<MBGLEnum>::toString(mbglValue);
+ MGLEnum mglType = *mbgl::Enum<MGLEnum>::toEnum(str);
+ return [MGLStyleConstantValue<ObjCType> valueWithRawValue:[NSValue value:&mglType withObjCType:@encode(MGLEnum)]];
+ }
+
NSNumber *toMGLRawStyleValue(const bool mbglStopValue) {
return @(mbglStopValue);
}
@@ -92,13 +153,6 @@ private:
return [NSValue mgl_valueWithPaddingArray:mbglStopValue];
}
- // Enumerations
- template <typename MBGLEnum = MBGLType, class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type>
- ObjCType toMGLRawStyleValue(const MBGLType &mbglStopValue) {
- NSUInteger rawValue = static_cast<NSUInteger>(mbglStopValue);
- return [NSValue value:&rawValue withObjCType:@encode(NSUInteger)];
- }
-
MGLColor *toMGLRawStyleValue(const mbgl::Color mbglStopValue) {
return [MGLColor mgl_colorWithColor:mbglStopValue];
}
@@ -110,9 +164,9 @@ private:
}
return array;
}
-
+
private:
-
+
void getMBGLValue(NSNumber *rawValue, bool &mbglValue) {
mbglValue = !!rawValue.boolValue;
}
@@ -135,12 +189,6 @@ private:
mbglValue = rawValue.mgl_paddingArrayValue;
}
- // Enumerations
- template <typename MBGLEnum = MBGLType, class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type>
- void getMBGLValue(ObjCType rawValue, MBGLType &mbglValue) {
- [rawValue getValue:&mbglValue];
- }
-
void getMBGLValue(MGLColor *rawValue, mbgl::Color &mbglValue) {
mbglValue = rawValue.mgl_color;
}
@@ -153,4 +201,16 @@ private:
mbglValue.push_back(mbglElement);
}
}
+
+ // Enumerations
+ template <typename MBGLEnum = MBGLType,
+ class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type,
+ typename MGLEnum = ObjCEnum,
+ class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type>
+ void getMBGLValue(ObjCType rawValue, MBGLEnum &mbglValue) {
+ MGLEnum mglEnum;
+ [rawValue getValue:&mglEnum];
+ auto str = mbgl::Enum<MGLEnum>::toString(mglEnum);
+ mbglValue = *mbgl::Enum<MBGLEnum>::toEnum(str);
+ }
};
diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h
index 6f52b67fa7..002be884e4 100644
--- a/platform/darwin/src/MGLStyle_Private.h
+++ b/platform/darwin/src/MGLStyle_Private.h
@@ -5,7 +5,10 @@
#import <mbgl/util/default_styles.hpp>
@interface MGLStyle (Private)
-@property (nonatomic, weak) MGLMapView *mapView;
+
+- (instancetype)initWithMapView:(MGLMapView *)mapView;
+
+@property (nonatomic, readonly, weak) MGLMapView *mapView;
- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration;
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index dc0cd236c8..dbb966b4e6 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -7,22 +7,6 @@
NS_ASSUME_NONNULL_BEGIN
/**
- Label placement relative to its geometry.
-
- Values of this type are used in the `symbolPlacement` property of `MGLSymbolStyleLayer`.
- */
-typedef NS_ENUM(NSUInteger, MGLSymbolPlacement) {
- /**
- The label is placed at the point where the geometry is located.
- */
- MGLSymbolPlacementPoint,
- /**
- The label is placed along the line of the geometry. Can only be used on `LineString` and `Polygon` geometries.
- */
- MGLSymbolPlacementLine,
-};
-
-/**
In combination with `symbolPlacement`, determines the rotation behavior of icons.
Values of this type are used in the `iconRotationAlignment` property of `MGLSymbolStyleLayer`.
@@ -67,43 +51,63 @@ typedef NS_ENUM(NSUInteger, MGLIconTextFit) {
};
/**
- Orientation of text when map is pitched.
+ Label placement relative to its geometry.
- Values of this type are used in the `textPitchAlignment` property of `MGLSymbolStyleLayer`.
+ Values of this type are used in the `symbolPlacement` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLTextPitchAlignment) {
- /**
- The text is aligned to the plane of the map.
- */
- MGLTextPitchAlignmentMap,
+typedef NS_ENUM(NSUInteger, MGLSymbolPlacement) {
/**
- The text is aligned to the plane of the viewport.
+ The label is placed at the point where the geometry is located.
*/
- MGLTextPitchAlignmentViewport,
+ MGLSymbolPlacementPoint,
/**
- Automatically matches the value of `textRotationAlignment`.
+ The label is placed along the line of the geometry. Can only be used on `LineString` and `Polygon` geometries.
*/
- MGLTextPitchAlignmentAuto,
+ MGLSymbolPlacementLine,
};
/**
- In combination with `symbolPlacement`, determines the rotation behavior of the individual glyphs forming the text.
+ Part of the text placed closest to the anchor.
- Values of this type are used in the `textRotationAlignment` property of `MGLSymbolStyleLayer`.
+ Values of this type are used in the `textAnchor` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLTextRotationAlignment) {
+typedef NS_ENUM(NSUInteger, MGLTextAnchor) {
/**
- When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, aligns text east-west. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, aligns text x-axes with the line.
+ The center of the text is placed closest to the anchor.
*/
- MGLTextRotationAlignmentMap,
+ MGLTextAnchorCenter,
/**
- Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbolPlacement`.
+ The left side of the text is placed closest to the anchor.
*/
- MGLTextRotationAlignmentViewport,
+ MGLTextAnchorLeft,
/**
- When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, this is equivalent to `MGLTextRotationAlignmentViewport`. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, this is equivalent to `MGLTextRotationAlignmentMap`.
+ The right side of the text is placed closest to the anchor.
*/
- MGLTextRotationAlignmentAuto,
+ MGLTextAnchorRight,
+ /**
+ The top of the text is placed closest to the anchor.
+ */
+ MGLTextAnchorTop,
+ /**
+ The bottom of the text is placed closest to the anchor.
+ */
+ MGLTextAnchorBottom,
+ /**
+ The top left corner of the text is placed closest to the anchor.
+ */
+ MGLTextAnchorTopLeft,
+ /**
+ The top right corner of the text is placed closest to the anchor.
+ */
+ MGLTextAnchorTopRight,
+ /**
+ The bottom left corner of the text is placed closest to the anchor.
+ */
+ MGLTextAnchorBottomLeft,
+ /**
+ The bottom right corner of the text is placed closest to the anchor.
+ */
+ MGLTextAnchorBottomRight,
};
/**
@@ -127,47 +131,43 @@ typedef NS_ENUM(NSUInteger, MGLTextJustify) {
};
/**
- Part of the text placed closest to the anchor.
+ Orientation of text when map is pitched.
- Values of this type are used in the `textAnchor` property of `MGLSymbolStyleLayer`.
+ Values of this type are used in the `textPitchAlignment` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLTextAnchor) {
- /**
- The center of the text is placed closest to the anchor.
- */
- MGLTextAnchorCenter,
- /**
- The left side of the text is placed closest to the anchor.
- */
- MGLTextAnchorLeft,
- /**
- The right side of the text is placed closest to the anchor.
- */
- MGLTextAnchorRight,
+typedef NS_ENUM(NSUInteger, MGLTextPitchAlignment) {
/**
- The top of the text is placed closest to the anchor.
+ The text is aligned to the plane of the map.
*/
- MGLTextAnchorTop,
+ MGLTextPitchAlignmentMap,
/**
- The bottom of the text is placed closest to the anchor.
+ The text is aligned to the plane of the viewport.
*/
- MGLTextAnchorBottom,
+ MGLTextPitchAlignmentViewport,
/**
- The top left corner of the text is placed closest to the anchor.
+ Automatically matches the value of `textRotationAlignment`.
*/
- MGLTextAnchorTopLeft,
+ MGLTextPitchAlignmentAuto,
+};
+
+/**
+ In combination with `symbolPlacement`, determines the rotation behavior of the individual glyphs forming the text.
+
+ Values of this type are used in the `textRotationAlignment` property of `MGLSymbolStyleLayer`.
+ */
+typedef NS_ENUM(NSUInteger, MGLTextRotationAlignment) {
/**
- The top right corner of the text is placed closest to the anchor.
+ When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, aligns text east-west. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, aligns text x-axes with the line.
*/
- MGLTextAnchorTopRight,
+ MGLTextRotationAlignmentMap,
/**
- The bottom left corner of the text is placed closest to the anchor.
+ Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbolPlacement`.
*/
- MGLTextAnchorBottomLeft,
+ MGLTextRotationAlignmentViewport,
/**
- The bottom right corner of the text is placed closest to the anchor.
+ When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, this is equivalent to `MGLTextRotationAlignmentViewport`. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, this is equivalent to `MGLTextRotationAlignmentMap`.
*/
- MGLTextAnchorBottomRight,
+ MGLTextRotationAlignmentAuto,
};
/**
@@ -233,47 +233,45 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
#pragma mark - Accessing the Layout Attributes
/**
- Label placement relative to its geometry.
+ If true, the icon will be visible even if it collides with other previously drawn symbols.
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementPoint`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+
+ This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *symbolPlacement;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconAllowOverlap;
/**
- Distance between two symbol anchors.
-
- This property is measured in points.
+ If true, other symbols can be visible even if they collide with the icon.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `250`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
+ This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *symbolSpacing;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconIgnorePlacement;
/**
- If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer.
-
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ A string with {tokens} replaced, referencing the data property to pull from.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *symbolAvoidEdges;
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *iconImageName;
/**
- If true, the icon will be visible even if it collides with other previously drawn symbols.
+ If true, the icon may be flipped to prevent it from being rendered upside-down.
The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
+ This property is only applied to the style if `iconImage` is non-`nil`, and `iconRotationAlignment` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconRotationAlignmentMap`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconAllowOverlap;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconKeepUpright;
/**
- If true, other symbols can be visible even if they collide with the icon.
+ Offset distance of icon from its anchor.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 from the left and 0 from the top. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconIgnorePlacement;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconOffset;
/**
If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not.
@@ -285,6 +283,28 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconOptional;
/**
+ Size of the additional area around the icon bounding box used for detecting symbol collisions.
+
+ This property is measured in points.
+
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
+
+ This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconPadding;
+
+/**
+ Rotates the icon clockwise.
+
+ This property is measured in degrees.
+
+ 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 `iconImage` is non-`nil`. Otherwise, it is ignored.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconRotate;
+
+/**
In combination with `symbolPlacement`, determines the rotation behavior of icons.
The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
@@ -323,67 +343,47 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconTextFitPadding;
/**
- A string with {tokens} replaced, referencing the data property to pull from.
+ If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer.
+
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *iconImage;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *symbolAvoidEdges;
/**
- Rotates the icon clockwise.
-
- This property is measured in degrees.
-
- 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.
+ Label placement relative to its geometry.
- This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementPoint`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconRotate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *symbolPlacement;
/**
- Size of the additional area around the icon bounding box used for detecting symbol collisions.
+ Distance between two symbol anchors.
This property is measured in points.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `250`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
+ This property is only applied to the style if `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconPadding;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *symbolSpacing;
/**
- If true, the icon may be flipped to prevent it from being rendered upside-down.
+ If true, the text will be visible even if it collides with other previously drawn symbols.
The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `iconImage` is non-`nil`, and `iconRotationAlignment` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconRotationAlignmentMap`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconKeepUpright;
-
-/**
- Offset distance of icon from its anchor.
-
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 from the left and 0 from the top. Set this property to `nil` to reset it to the default value.
-
- This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconOffset;
-
-/**
- Orientation of text when map is pitched.
-
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextPitchAlignmentAuto`. Set this property to `nil` to reset it to the default value.
-
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textPitchAlignment;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textAllowOverlap;
/**
- In combination with `symbolPlacement`, determines the rotation behavior of the individual glyphs forming the text.
+ Part of the text placed closest to the anchor.
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextAnchorCenter`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textRotationAlignment;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textAnchor;
/**
Value to use for a text label. Feature properties are specified using tokens like {field_name}.
@@ -402,37 +402,31 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSArray<NSString *> *> *textFont;
/**
- Font size.
-
- This property is measured in points.
+ If true, other symbols can be visible even if they collide with the text.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `16`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textSize;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textIgnorePlacement;
/**
- The maximum line width for text wrapping.
-
- This property is measured in ems.
+ Text justification options.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `10`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextJustifyCenter`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textMaxWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textJustify;
/**
- Text leading value for multi-line text.
-
- This property is measured in ems.
+ If true, the text may be flipped vertically to prevent it from being rendered upside-down.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1.2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `YES`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
+ This property is only applied to the style if `textField` is non-`nil`, and `textRotationAlignment` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextRotationAlignmentMap`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textLineHeight;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textKeepUpright;
/**
Text tracking amount.
@@ -446,22 +440,15 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textLetterSpacing;
/**
- Text justification options.
-
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextJustifyCenter`. Set this property to `nil` to reset it to the default value.
-
- This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textJustify;
+ Text leading value for multi-line text.
-/**
- Part of the text placed closest to the anchor.
+ This property is measured in ems.
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextAnchorCenter`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1.2`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textLineHeight;
/**
Maximum angle change between adjacent characters.
@@ -475,93 +462,97 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textMaxAngle;
/**
- Rotates the text clockwise.
+ The maximum line width for text wrapping.
- This property is measured in degrees.
+ This property is measured in ems.
- 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.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `10`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textRotate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textMaxWidth;
/**
- Size of the additional area around the text bounding box used for detecting symbol collisions.
+ Offset distance of text from its anchor.
- This property is measured in points.
+ This property is measured in ems.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 ems from the left and 0 ems from the top. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textPadding;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textOffset;
/**
- If true, the text may be flipped vertically to prevent it from being rendered upside-down.
+ If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `YES`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `textField` is non-`nil`, and `textRotationAlignment` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextRotationAlignmentMap`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
+ This property is only applied to the style if `textField` is non-`nil`, and `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textKeepUpright;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textOptional;
/**
- Specifies how to capitalize text.
+ Size of the additional area around the text bounding box used for detecting symbol collisions.
+
+ This property is measured in points.
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextTransformNone`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textTransform;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textPadding;
/**
- Offset distance of text from its anchor.
-
- This property is measured in ems.
+ Orientation of text when map is pitched.
- The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 ems from the left and 0 ems from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextPitchAlignmentAuto`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textOffset;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textPitchAlignment;
/**
- If true, the text will be visible even if it collides with other previously drawn symbols.
+ Rotates the text clockwise.
+
+ This property is measured in degrees.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ 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 `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textAllowOverlap;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textRotate;
/**
- If true, other symbols can be visible even if they collide with the text.
+ In combination with `symbolPlacement`, determines the rotation behavior of the individual glyphs forming the text.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textIgnorePlacement;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textRotationAlignment;
/**
- If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not.
+ Font size.
+
+ This property is measured in points.
- The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `16`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `textField` is non-`nil`, and `iconImage` is non-`nil`. Otherwise, it is ignored.
+ This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textOptional;
-
-#pragma mark - Accessing the Paint Attributes
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textSize;
/**
- The opacity at which the icon will be drawn.
+ Specifies how to capitalize text.
- 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.
-
- This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextTransformNone`. Set this property to `nil` to reset it to the default value.
+
+ This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textTransform;
+
+#pragma mark - Accessing the Paint Attributes
#if TARGET_OS_IPHONE
/**
@@ -583,6 +574,17 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *iconColor;
#endif
+/**
+ Fade out the halo towards the outside.
+
+ This property is measured in points.
+
+ 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 `iconImage` is non-`nil`. Otherwise, it is ignored.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconHaloBlur;
+
#if TARGET_OS_IPHONE
/**
The color of the icon's halo. Icon halos can only be used with SDF icons.
@@ -615,15 +617,13 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconHaloWidth;
/**
- Fade out the halo towards the outside.
-
- This property is measured in points.
+ The opacity at which the icon will be drawn.
- 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.
+ 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.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconHaloBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconOpacity;
/**
Distance that the icon's anchor is moved from its original placement.
@@ -645,15 +645,6 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconTranslateAnchor;
-/**
- The opacity at which the text will be drawn.
-
- 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.
-
- This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
- */
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textOpacity;
-
#if TARGET_OS_IPHONE
/**
The color with which the text will be drawn.
@@ -674,6 +665,17 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *textColor;
#endif
+/**
+ The halo's fadeout distance towards the outside.
+
+ This property is measured in points.
+
+ 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 `textField` is non-`nil`. Otherwise, it is ignored.
+ */
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textHaloBlur;
+
#if TARGET_OS_IPHONE
/**
The color of the text's halo, which helps it stand out from backgrounds.
@@ -706,15 +708,13 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textHaloWidth;
/**
- The halo's fadeout distance towards the outside.
-
- This property is measured in points.
+ The opacity at which the text will be drawn.
- 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.
+ 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.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textHaloBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textOpacity;
/**
Distance that the text's anchor is moved from its original placement.
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm
index a4c56fe297..d1d66f8ffb 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.mm
+++ b/platform/darwin/src/MGLSymbolStyleLayer.mm
@@ -2,532 +2,848 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
#import "MGLSource.h"
+#import "MGLMapView_Private.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
#import "MGLStyleValue_Private.h"
#import "MGLSymbolStyleLayer.h"
#include <mbgl/style/layers/symbol_layer.hpp>
+namespace mbgl {
+
+ MBGL_DEFINE_ENUM(MGLIconRotationAlignment, {
+ { MGLIconRotationAlignmentMap, "map" },
+ { MGLIconRotationAlignmentViewport, "viewport" },
+ { MGLIconRotationAlignmentAuto, "auto" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLIconTextFit, {
+ { MGLIconTextFitNone, "none" },
+ { MGLIconTextFitWidth, "width" },
+ { MGLIconTextFitHeight, "height" },
+ { MGLIconTextFitBoth, "both" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLSymbolPlacement, {
+ { MGLSymbolPlacementPoint, "point" },
+ { MGLSymbolPlacementLine, "line" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLTextAnchor, {
+ { MGLTextAnchorCenter, "center" },
+ { MGLTextAnchorLeft, "left" },
+ { MGLTextAnchorRight, "right" },
+ { MGLTextAnchorTop, "top" },
+ { MGLTextAnchorBottom, "bottom" },
+ { MGLTextAnchorTopLeft, "top-left" },
+ { MGLTextAnchorTopRight, "top-right" },
+ { MGLTextAnchorBottomLeft, "bottom-left" },
+ { MGLTextAnchorBottomRight, "bottom-right" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLTextJustify, {
+ { MGLTextJustifyLeft, "left" },
+ { MGLTextJustifyCenter, "center" },
+ { MGLTextJustifyRight, "right" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLTextPitchAlignment, {
+ { MGLTextPitchAlignmentMap, "map" },
+ { MGLTextPitchAlignmentViewport, "viewport" },
+ { MGLTextPitchAlignmentAuto, "auto" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLTextRotationAlignment, {
+ { MGLTextRotationAlignmentMap, "map" },
+ { MGLTextRotationAlignmentViewport, "viewport" },
+ { MGLTextRotationAlignmentAuto, "auto" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLTextTransform, {
+ { MGLTextTransformNone, "none" },
+ { MGLTextTransformUppercase, "uppercase" },
+ { MGLTextTransformLowercase, "lowercase" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLIconTranslateAnchor, {
+ { MGLIconTranslateAnchorMap, "map" },
+ { MGLIconTranslateAnchorViewport, "viewport" },
+ });
+
+ MBGL_DEFINE_ENUM(MGLTextTranslateAnchor, {
+ { MGLTextTranslateAnchorMap, "map" },
+ { MGLTextTranslateAnchorViewport, "viewport" },
+ });
+
+}
@interface MGLSymbolStyleLayer ()
-@property (nonatomic) mbgl::style::SymbolLayer *layer;
+@property (nonatomic) 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]) {
- _layer = new mbgl::style::SymbolLayer(identifier.UTF8String, source.identifier.UTF8String);
+ auto layer = std::make_unique<mbgl::style::SymbolLayer>(identifier.UTF8String, source.identifier.UTF8String);
+ _pendingLayer = std::move(layer);
+ _rawLayer = _pendingLayer.get();
}
return self;
}
-
- (NSString *)sourceLayerIdentifier
{
- auto layerID = self.layer->getSourceLayer();
+ MGLAssertStyleLayerIsValid();
+
+ auto layerID = _rawLayer->getSourceLayer();
return layerID.empty() ? nil : @(layerID.c_str());
}
- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
{
- self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
{
- self.layer->setFilter(predicate.mgl_filter);
+ MGLAssertStyleLayerIsValid();
+
+ _rawLayer->setFilter(predicate.mgl_filter);
}
- (NSPredicate *)predicate
{
- return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()];
+ MGLAssertStyleLayerIsValid();
+
+ return [NSPredicate mgl_predicateWithFilter:_rawLayer->getFilter()];
}
+#pragma mark - Adding to and removing from a map view
-#pragma mark - Accessing the Layout Attributes
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ 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];
+ }
-- (void)setSymbolPlacement:(MGLStyleValue<NSValue *> *)symbolPlacement {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *>().toPropertyValue(symbolPlacement);
- self.layer->setSymbolPlacement(mbglValue);
+ [self addToMapView:mapView belowLayer:nil];
}
-- (MGLStyleValue<NSValue *> *)symbolPlacement {
- auto propertyValue = self.layer->getSymbolPlacement() ?: self.layer->getDefaultSymbolPlacement();
- return MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *>().toStyleValue(propertyValue);
+- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer
+{
+ 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)setSymbolSpacing:(MGLStyleValue<NSNumber *> *)symbolSpacing {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(symbolSpacing);
- self.layer->setSymbolSpacing(mbglValue);
-}
+- (void)removeFromMapView:(MGLMapView *)mapView
+{
+ _pendingLayer = nullptr;
+ _rawLayer = nullptr;
-- (MGLStyleValue<NSNumber *> *)symbolSpacing {
- auto propertyValue = self.layer->getSymbolSpacing() ?: self.layer->getDefaultSymbolSpacing();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
-}
+ auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String);
+ if (!removedLayer) {
+ return;
+ }
-- (void)setSymbolAvoidEdges:(MGLStyleValue<NSNumber *> *)symbolAvoidEdges {
- auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(symbolAvoidEdges);
- self.layer->setSymbolAvoidEdges(mbglValue);
-}
+ mbgl::style::SymbolLayer *layer = dynamic_cast<mbgl::style::SymbolLayer *>(removedLayer.get());
+ if (!layer) {
+ return;
+ }
-- (MGLStyleValue<NSNumber *> *)symbolAvoidEdges {
- auto propertyValue = self.layer->getSymbolAvoidEdges() ?: self.layer->getDefaultSymbolAvoidEdges();
- return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
+ removedLayer.release();
+
+ _pendingLayer = std::unique_ptr<mbgl::style::SymbolLayer>(layer);
+ _rawLayer = _pendingLayer.get();
}
+#pragma mark - Accessing the Layout Attributes
+
- (void)setIconAllowOverlap:(MGLStyleValue<NSNumber *> *)iconAllowOverlap {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconAllowOverlap);
- self.layer->setIconAllowOverlap(mbglValue);
+ _rawLayer->setIconAllowOverlap(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)iconAllowOverlap {
- auto propertyValue = self.layer->getIconAllowOverlap() ?: self.layer->getDefaultIconAllowOverlap();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconAllowOverlap() ?: _rawLayer->getDefaultIconAllowOverlap();
return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setIconIgnorePlacement:(MGLStyleValue<NSNumber *> *)iconIgnorePlacement {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconIgnorePlacement);
- self.layer->setIconIgnorePlacement(mbglValue);
+ _rawLayer->setIconIgnorePlacement(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)iconIgnorePlacement {
- auto propertyValue = self.layer->getIconIgnorePlacement() ?: self.layer->getDefaultIconIgnorePlacement();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconIgnorePlacement() ?: _rawLayer->getDefaultIconIgnorePlacement();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
+}
+
+- (void)setIconImageName:(MGLStyleValue<NSString *> *)iconImageName {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(iconImageName);
+ _rawLayer->setIconImage(mbglValue);
+}
+
+- (MGLStyleValue<NSString *> *)iconImageName {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconImage() ?: _rawLayer->getDefaultIconImage();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
+}
+
+- (void)setIconKeepUpright:(MGLStyleValue<NSNumber *> *)iconKeepUpright {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconKeepUpright);
+ _rawLayer->setIconKeepUpright(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)iconKeepUpright {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconKeepUpright() ?: _rawLayer->getDefaultIconKeepUpright();
return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
+- (void)setIconOffset:(MGLStyleValue<NSValue *> *)iconOffset {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(iconOffset);
+ _rawLayer->setIconOffset(mbglValue);
+}
+
+- (MGLStyleValue<NSValue *> *)iconOffset {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconOffset() ?: _rawLayer->getDefaultIconOffset();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+}
+
- (void)setIconOptional:(MGLStyleValue<NSNumber *> *)iconOptional {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconOptional);
- self.layer->setIconOptional(mbglValue);
+ _rawLayer->setIconOptional(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)iconOptional {
- auto propertyValue = self.layer->getIconOptional() ?: self.layer->getDefaultIconOptional();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconOptional() ?: _rawLayer->getDefaultIconOptional();
return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
+- (void)setIconPadding:(MGLStyleValue<NSNumber *> *)iconPadding {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconPadding);
+ _rawLayer->setIconPadding(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)iconPadding {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconPadding() ?: _rawLayer->getDefaultIconPadding();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
+- (void)setIconRotate:(MGLStyleValue<NSNumber *> *)iconRotate {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconRotate);
+ _rawLayer->setIconRotate(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)iconRotate {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconRotate() ?: _rawLayer->getDefaultIconRotate();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
- (void)setIconRotationAlignment:(MGLStyleValue<NSValue *> *)iconRotationAlignment {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toPropertyValue(iconRotationAlignment);
- self.layer->setIconRotationAlignment(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLIconRotationAlignment>().toEnumPropertyValue(iconRotationAlignment);
+ _rawLayer->setIconRotationAlignment(mbglValue);
}
- (MGLStyleValue<NSValue *> *)iconRotationAlignment {
- auto propertyValue = self.layer->getIconRotationAlignment() ?: self.layer->getDefaultIconRotationAlignment();
- return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toStyleValue(propertyValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconRotationAlignment() ?: _rawLayer->getDefaultIconRotationAlignment();
+ return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLIconRotationAlignment>().toEnumStyleValue(propertyValue);
}
- (void)setIconSize:(MGLStyleValue<NSNumber *> *)iconSize {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconSize);
- self.layer->setIconSize(mbglValue);
+ _rawLayer->setIconSize(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)iconSize {
- auto propertyValue = self.layer->getIconSize() ?: self.layer->getDefaultIconSize();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconSize() ?: _rawLayer->getDefaultIconSize();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setIconTextFit:(MGLStyleValue<NSValue *> *)iconTextFit {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *>().toPropertyValue(iconTextFit);
- self.layer->setIconTextFit(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *, mbgl::style::IconTextFitType, MGLIconTextFit>().toEnumPropertyValue(iconTextFit);
+ _rawLayer->setIconTextFit(mbglValue);
}
- (MGLStyleValue<NSValue *> *)iconTextFit {
- auto propertyValue = self.layer->getIconTextFit() ?: self.layer->getDefaultIconTextFit();
- return MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *>().toStyleValue(propertyValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconTextFit() ?: _rawLayer->getDefaultIconTextFit();
+ return MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *, mbgl::style::IconTextFitType, MGLIconTextFit>().toEnumStyleValue(propertyValue);
}
- (void)setIconTextFitPadding:(MGLStyleValue<NSValue *> *)iconTextFitPadding {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::array<float, 4>, NSValue *>().toPropertyValue(iconTextFitPadding);
- self.layer->setIconTextFitPadding(mbglValue);
+ _rawLayer->setIconTextFitPadding(mbglValue);
}
- (MGLStyleValue<NSValue *> *)iconTextFitPadding {
- auto propertyValue = self.layer->getIconTextFitPadding() ?: self.layer->getDefaultIconTextFitPadding();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconTextFitPadding() ?: _rawLayer->getDefaultIconTextFitPadding();
return MGLStyleValueTransformer<std::array<float, 4>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setIconImage:(MGLStyleValue<NSString *> *)iconImage {
- auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(iconImage);
- self.layer->setIconImage(mbglValue);
+- (void)setSymbolAvoidEdges:(MGLStyleValue<NSNumber *> *)symbolAvoidEdges {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(symbolAvoidEdges);
+ _rawLayer->setSymbolAvoidEdges(mbglValue);
}
-- (MGLStyleValue<NSString *> *)iconImage {
- auto propertyValue = self.layer->getIconImage() ?: self.layer->getDefaultIconImage();
- return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSNumber *> *)symbolAvoidEdges {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getSymbolAvoidEdges() ?: _rawLayer->getDefaultSymbolAvoidEdges();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconRotate:(MGLStyleValue<NSNumber *> *)iconRotate {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconRotate);
- self.layer->setIconRotate(mbglValue);
+- (void)setSymbolPlacement:(MGLStyleValue<NSValue *> *)symbolPlacement {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *, mbgl::style::SymbolPlacementType, MGLSymbolPlacement>().toEnumPropertyValue(symbolPlacement);
+ _rawLayer->setSymbolPlacement(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)iconRotate {
- auto propertyValue = self.layer->getIconRotate() ?: self.layer->getDefaultIconRotate();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSValue *> *)symbolPlacement {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getSymbolPlacement() ?: _rawLayer->getDefaultSymbolPlacement();
+ return MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *, mbgl::style::SymbolPlacementType, MGLSymbolPlacement>().toEnumStyleValue(propertyValue);
}
-- (void)setIconPadding:(MGLStyleValue<NSNumber *> *)iconPadding {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconPadding);
- self.layer->setIconPadding(mbglValue);
+- (void)setSymbolSpacing:(MGLStyleValue<NSNumber *> *)symbolSpacing {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(symbolSpacing);
+ _rawLayer->setSymbolSpacing(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)iconPadding {
- auto propertyValue = self.layer->getIconPadding() ?: self.layer->getDefaultIconPadding();
+- (MGLStyleValue<NSNumber *> *)symbolSpacing {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getSymbolSpacing() ?: _rawLayer->getDefaultSymbolSpacing();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconKeepUpright:(MGLStyleValue<NSNumber *> *)iconKeepUpright {
- auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconKeepUpright);
- self.layer->setIconKeepUpright(mbglValue);
-}
+- (void)setTextAllowOverlap:(MGLStyleValue<NSNumber *> *)textAllowOverlap {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSNumber *> *)iconKeepUpright {
- auto propertyValue = self.layer->getIconKeepUpright() ?: self.layer->getDefaultIconKeepUpright();
- return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textAllowOverlap);
+ _rawLayer->setTextAllowOverlap(mbglValue);
}
-- (void)setIconOffset:(MGLStyleValue<NSValue *> *)iconOffset {
- auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(iconOffset);
- self.layer->setIconOffset(mbglValue);
-}
+- (MGLStyleValue<NSNumber *> *)textAllowOverlap {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)iconOffset {
- auto propertyValue = self.layer->getIconOffset() ?: self.layer->getDefaultIconOffset();
- return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getTextAllowOverlap() ?: _rawLayer->getDefaultTextAllowOverlap();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextPitchAlignment:(MGLStyleValue<NSValue *> *)textPitchAlignment {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toPropertyValue(textPitchAlignment);
- self.layer->setTextPitchAlignment(mbglValue);
-}
+- (void)setTextAnchor:(MGLStyleValue<NSValue *> *)textAnchor {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)textPitchAlignment {
- auto propertyValue = self.layer->getTextPitchAlignment() ?: self.layer->getDefaultTextPitchAlignment();
- return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toStyleValue(propertyValue);
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextAnchorType, NSValue *, mbgl::style::TextAnchorType, MGLTextAnchor>().toEnumPropertyValue(textAnchor);
+ _rawLayer->setTextAnchor(mbglValue);
}
-- (void)setTextRotationAlignment:(MGLStyleValue<NSValue *> *)textRotationAlignment {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toPropertyValue(textRotationAlignment);
- self.layer->setTextRotationAlignment(mbglValue);
-}
+- (MGLStyleValue<NSValue *> *)textAnchor {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)textRotationAlignment {
- auto propertyValue = self.layer->getTextRotationAlignment() ?: self.layer->getDefaultTextRotationAlignment();
- return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getTextAnchor() ?: _rawLayer->getDefaultTextAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TextAnchorType, NSValue *, mbgl::style::TextAnchorType, MGLTextAnchor>().toEnumStyleValue(propertyValue);
}
- (void)setTextField:(MGLStyleValue<NSString *> *)textField {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(textField);
- self.layer->setTextField(mbglValue);
+ _rawLayer->setTextField(mbglValue);
}
- (MGLStyleValue<NSString *> *)textField {
- auto propertyValue = self.layer->getTextField() ?: self.layer->getDefaultTextField();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextField() ?: _rawLayer->getDefaultTextField();
return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
- (void)setTextFont:(MGLStyleValue<NSArray<NSString *> *> *)textFont {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::vector<std::string>, NSArray<NSString *> *, std::string>().toPropertyValue(textFont);
- self.layer->setTextFont(mbglValue);
+ _rawLayer->setTextFont(mbglValue);
}
- (MGLStyleValue<NSArray<NSString *> *> *)textFont {
- auto propertyValue = self.layer->getTextFont() ?: self.layer->getDefaultTextFont();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextFont() ?: _rawLayer->getDefaultTextFont();
return MGLStyleValueTransformer<std::vector<std::string>, NSArray<NSString *> *, std::string>().toStyleValue(propertyValue);
}
-- (void)setTextSize:(MGLStyleValue<NSNumber *> *)textSize {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textSize);
- self.layer->setTextSize(mbglValue);
+- (void)setTextIgnorePlacement:(MGLStyleValue<NSNumber *> *)textIgnorePlacement {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textIgnorePlacement);
+ _rawLayer->setTextIgnorePlacement(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textSize {
- auto propertyValue = self.layer->getTextSize() ?: self.layer->getDefaultTextSize();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSNumber *> *)textIgnorePlacement {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextIgnorePlacement() ?: _rawLayer->getDefaultTextIgnorePlacement();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextMaxWidth:(MGLStyleValue<NSNumber *> *)textMaxWidth {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textMaxWidth);
- self.layer->setTextMaxWidth(mbglValue);
+- (void)setTextJustify:(MGLStyleValue<NSValue *> *)textJustify {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *, mbgl::style::TextJustifyType, MGLTextJustify>().toEnumPropertyValue(textJustify);
+ _rawLayer->setTextJustify(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textMaxWidth {
- auto propertyValue = self.layer->getTextMaxWidth() ?: self.layer->getDefaultTextMaxWidth();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSValue *> *)textJustify {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextJustify() ?: _rawLayer->getDefaultTextJustify();
+ return MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *, mbgl::style::TextJustifyType, MGLTextJustify>().toEnumStyleValue(propertyValue);
}
-- (void)setTextLineHeight:(MGLStyleValue<NSNumber *> *)textLineHeight {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textLineHeight);
- self.layer->setTextLineHeight(mbglValue);
+- (void)setTextKeepUpright:(MGLStyleValue<NSNumber *> *)textKeepUpright {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textKeepUpright);
+ _rawLayer->setTextKeepUpright(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textLineHeight {
- auto propertyValue = self.layer->getTextLineHeight() ?: self.layer->getDefaultTextLineHeight();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSNumber *> *)textKeepUpright {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextKeepUpright() ?: _rawLayer->getDefaultTextKeepUpright();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setTextLetterSpacing:(MGLStyleValue<NSNumber *> *)textLetterSpacing {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textLetterSpacing);
- self.layer->setTextLetterSpacing(mbglValue);
+ _rawLayer->setTextLetterSpacing(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)textLetterSpacing {
- auto propertyValue = self.layer->getTextLetterSpacing() ?: self.layer->getDefaultTextLetterSpacing();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextLetterSpacing() ?: _rawLayer->getDefaultTextLetterSpacing();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextJustify:(MGLStyleValue<NSValue *> *)textJustify {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *>().toPropertyValue(textJustify);
- self.layer->setTextJustify(mbglValue);
-}
+- (void)setTextLineHeight:(MGLStyleValue<NSNumber *> *)textLineHeight {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)textJustify {
- auto propertyValue = self.layer->getTextJustify() ?: self.layer->getDefaultTextJustify();
- return MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *>().toStyleValue(propertyValue);
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textLineHeight);
+ _rawLayer->setTextLineHeight(mbglValue);
}
-- (void)setTextAnchor:(MGLStyleValue<NSValue *> *)textAnchor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextAnchorType, NSValue *>().toPropertyValue(textAnchor);
- self.layer->setTextAnchor(mbglValue);
-}
+- (MGLStyleValue<NSNumber *> *)textLineHeight {
+ MGLAssertStyleLayerIsValid();
-- (MGLStyleValue<NSValue *> *)textAnchor {
- auto propertyValue = self.layer->getTextAnchor() ?: self.layer->getDefaultTextAnchor();
- return MGLStyleValueTransformer<mbgl::style::TextAnchorType, NSValue *>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getTextLineHeight() ?: _rawLayer->getDefaultTextLineHeight();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setTextMaxAngle:(MGLStyleValue<NSNumber *> *)textMaxAngle {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textMaxAngle);
- self.layer->setTextMaxAngle(mbglValue);
+ _rawLayer->setTextMaxAngle(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)textMaxAngle {
- auto propertyValue = self.layer->getTextMaxAngle() ?: self.layer->getDefaultTextMaxAngle();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextMaxAngle() ?: _rawLayer->getDefaultTextMaxAngle();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextRotate:(MGLStyleValue<NSNumber *> *)textRotate {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textRotate);
- self.layer->setTextRotate(mbglValue);
+- (void)setTextMaxWidth:(MGLStyleValue<NSNumber *> *)textMaxWidth {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textMaxWidth);
+ _rawLayer->setTextMaxWidth(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textRotate {
- auto propertyValue = self.layer->getTextRotate() ?: self.layer->getDefaultTextRotate();
+- (MGLStyleValue<NSNumber *> *)textMaxWidth {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextMaxWidth() ?: _rawLayer->getDefaultTextMaxWidth();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextPadding:(MGLStyleValue<NSNumber *> *)textPadding {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textPadding);
- self.layer->setTextPadding(mbglValue);
+- (void)setTextOffset:(MGLStyleValue<NSValue *> *)textOffset {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(textOffset);
+ _rawLayer->setTextOffset(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textPadding {
- auto propertyValue = self.layer->getTextPadding() ?: self.layer->getDefaultTextPadding();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSValue *> *)textOffset {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextOffset() ?: _rawLayer->getDefaultTextOffset();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextKeepUpright:(MGLStyleValue<NSNumber *> *)textKeepUpright {
- auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textKeepUpright);
- self.layer->setTextKeepUpright(mbglValue);
+- (void)setTextOptional:(MGLStyleValue<NSNumber *> *)textOptional {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textOptional);
+ _rawLayer->setTextOptional(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textKeepUpright {
- auto propertyValue = self.layer->getTextKeepUpright() ?: self.layer->getDefaultTextKeepUpright();
+- (MGLStyleValue<NSNumber *> *)textOptional {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextOptional() ?: _rawLayer->getDefaultTextOptional();
return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextTransform:(MGLStyleValue<NSValue *> *)textTransform {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *>().toPropertyValue(textTransform);
- self.layer->setTextTransform(mbglValue);
+- (void)setTextPadding:(MGLStyleValue<NSNumber *> *)textPadding {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textPadding);
+ _rawLayer->setTextPadding(mbglValue);
}
-- (MGLStyleValue<NSValue *> *)textTransform {
- auto propertyValue = self.layer->getTextTransform() ?: self.layer->getDefaultTextTransform();
- return MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSNumber *> *)textPadding {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextPadding() ?: _rawLayer->getDefaultTextPadding();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextOffset:(MGLStyleValue<NSValue *> *)textOffset {
- auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(textOffset);
- self.layer->setTextOffset(mbglValue);
+- (void)setTextPitchAlignment:(MGLStyleValue<NSValue *> *)textPitchAlignment {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextPitchAlignment>().toEnumPropertyValue(textPitchAlignment);
+ _rawLayer->setTextPitchAlignment(mbglValue);
}
-- (MGLStyleValue<NSValue *> *)textOffset {
- auto propertyValue = self.layer->getTextOffset() ?: self.layer->getDefaultTextOffset();
- return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSValue *> *)textPitchAlignment {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextPitchAlignment() ?: _rawLayer->getDefaultTextPitchAlignment();
+ return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextPitchAlignment>().toEnumStyleValue(propertyValue);
}
-- (void)setTextAllowOverlap:(MGLStyleValue<NSNumber *> *)textAllowOverlap {
- auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textAllowOverlap);
- self.layer->setTextAllowOverlap(mbglValue);
+- (void)setTextRotate:(MGLStyleValue<NSNumber *> *)textRotate {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textRotate);
+ _rawLayer->setTextRotate(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textAllowOverlap {
- auto propertyValue = self.layer->getTextAllowOverlap() ?: self.layer->getDefaultTextAllowOverlap();
- return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSNumber *> *)textRotate {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextRotate() ?: _rawLayer->getDefaultTextRotate();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextIgnorePlacement:(MGLStyleValue<NSNumber *> *)textIgnorePlacement {
- auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textIgnorePlacement);
- self.layer->setTextIgnorePlacement(mbglValue);
+- (void)setTextRotationAlignment:(MGLStyleValue<NSValue *> *)textRotationAlignment {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextRotationAlignment>().toEnumPropertyValue(textRotationAlignment);
+ _rawLayer->setTextRotationAlignment(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textIgnorePlacement {
- auto propertyValue = self.layer->getTextIgnorePlacement() ?: self.layer->getDefaultTextIgnorePlacement();
- return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSValue *> *)textRotationAlignment {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextRotationAlignment() ?: _rawLayer->getDefaultTextRotationAlignment();
+ return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextRotationAlignment>().toEnumStyleValue(propertyValue);
}
-- (void)setTextOptional:(MGLStyleValue<NSNumber *> *)textOptional {
- auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textOptional);
- self.layer->setTextOptional(mbglValue);
+- (void)setTextSize:(MGLStyleValue<NSNumber *> *)textSize {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textSize);
+ _rawLayer->setTextSize(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textOptional {
- auto propertyValue = self.layer->getTextOptional() ?: self.layer->getDefaultTextOptional();
- return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSNumber *> *)textSize {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextSize() ?: _rawLayer->getDefaultTextSize();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-#pragma mark - Accessing the Paint Attributes
+- (void)setTextTransform:(MGLStyleValue<NSValue *> *)textTransform {
+ MGLAssertStyleLayerIsValid();
-- (void)setIconOpacity:(MGLStyleValue<NSNumber *> *)iconOpacity {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconOpacity);
- self.layer->setIconOpacity(mbglValue);
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *, mbgl::style::TextTransformType, MGLTextTransform>().toEnumPropertyValue(textTransform);
+ _rawLayer->setTextTransform(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)iconOpacity {
- auto propertyValue = self.layer->getIconOpacity() ?: self.layer->getDefaultIconOpacity();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+- (MGLStyleValue<NSValue *> *)textTransform {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextTransform() ?: _rawLayer->getDefaultTextTransform();
+ return MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *, mbgl::style::TextTransformType, MGLTextTransform>().toEnumStyleValue(propertyValue);
}
+#pragma mark - Accessing the Paint Attributes
+
- (void)setIconColor:(MGLStyleValue<MGLColor *> *)iconColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(iconColor);
- self.layer->setIconColor(mbglValue);
+ _rawLayer->setIconColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)iconColor {
- auto propertyValue = self.layer->getIconColor() ?: self.layer->getDefaultIconColor();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconColor() ?: _rawLayer->getDefaultIconColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
+- (void)setIconHaloBlur:(MGLStyleValue<NSNumber *> *)iconHaloBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconHaloBlur);
+ _rawLayer->setIconHaloBlur(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)iconHaloBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconHaloBlur() ?: _rawLayer->getDefaultIconHaloBlur();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
- (void)setIconHaloColor:(MGLStyleValue<MGLColor *> *)iconHaloColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(iconHaloColor);
- self.layer->setIconHaloColor(mbglValue);
+ _rawLayer->setIconHaloColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)iconHaloColor {
- auto propertyValue = self.layer->getIconHaloColor() ?: self.layer->getDefaultIconHaloColor();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconHaloColor() ?: _rawLayer->getDefaultIconHaloColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
- (void)setIconHaloWidth:(MGLStyleValue<NSNumber *> *)iconHaloWidth {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconHaloWidth);
- self.layer->setIconHaloWidth(mbglValue);
+ _rawLayer->setIconHaloWidth(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)iconHaloWidth {
- auto propertyValue = self.layer->getIconHaloWidth() ?: self.layer->getDefaultIconHaloWidth();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconHaloWidth() ?: _rawLayer->getDefaultIconHaloWidth();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconHaloBlur:(MGLStyleValue<NSNumber *> *)iconHaloBlur {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconHaloBlur);
- self.layer->setIconHaloBlur(mbglValue);
+- (void)setIconOpacity:(MGLStyleValue<NSNumber *> *)iconOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconOpacity);
+ _rawLayer->setIconOpacity(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)iconHaloBlur {
- auto propertyValue = self.layer->getIconHaloBlur() ?: self.layer->getDefaultIconHaloBlur();
+- (MGLStyleValue<NSNumber *> *)iconOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconOpacity() ?: _rawLayer->getDefaultIconOpacity();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setIconTranslate:(MGLStyleValue<NSValue *> *)iconTranslate {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(iconTranslate);
- self.layer->setIconTranslate(mbglValue);
+ _rawLayer->setIconTranslate(mbglValue);
}
- (MGLStyleValue<NSValue *> *)iconTranslate {
- auto propertyValue = self.layer->getIconTranslate() ?: self.layer->getDefaultIconTranslate();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getIconTranslate() ?: _rawLayer->getDefaultIconTranslate();
return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
- (void)setIconTranslateAnchor:(MGLStyleValue<NSValue *> *)iconTranslateAnchor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(iconTranslateAnchor);
- self.layer->setIconTranslateAnchor(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLIconTranslateAnchor>().toEnumPropertyValue(iconTranslateAnchor);
+ _rawLayer->setIconTranslateAnchor(mbglValue);
}
- (MGLStyleValue<NSValue *> *)iconTranslateAnchor {
- auto propertyValue = self.layer->getIconTranslateAnchor() ?: self.layer->getDefaultIconTranslateAnchor();
- return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
-}
+ MGLAssertStyleLayerIsValid();
-- (void)setTextOpacity:(MGLStyleValue<NSNumber *> *)textOpacity {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textOpacity);
- self.layer->setTextOpacity(mbglValue);
-}
-
-- (MGLStyleValue<NSNumber *> *)textOpacity {
- auto propertyValue = self.layer->getTextOpacity() ?: self.layer->getDefaultTextOpacity();
- return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+ auto propertyValue = _rawLayer->getIconTranslateAnchor() ?: _rawLayer->getDefaultIconTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLIconTranslateAnchor>().toEnumStyleValue(propertyValue);
}
- (void)setTextColor:(MGLStyleValue<MGLColor *> *)textColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(textColor);
- self.layer->setTextColor(mbglValue);
+ _rawLayer->setTextColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)textColor {
- auto propertyValue = self.layer->getTextColor() ?: self.layer->getDefaultTextColor();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextColor() ?: _rawLayer->getDefaultTextColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
+- (void)setTextHaloBlur:(MGLStyleValue<NSNumber *> *)textHaloBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textHaloBlur);
+ _rawLayer->setTextHaloBlur(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)textHaloBlur {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextHaloBlur() ?: _rawLayer->getDefaultTextHaloBlur();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
- (void)setTextHaloColor:(MGLStyleValue<MGLColor *> *)textHaloColor {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(textHaloColor);
- self.layer->setTextHaloColor(mbglValue);
+ _rawLayer->setTextHaloColor(mbglValue);
}
- (MGLStyleValue<MGLColor *> *)textHaloColor {
- auto propertyValue = self.layer->getTextHaloColor() ?: self.layer->getDefaultTextHaloColor();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextHaloColor() ?: _rawLayer->getDefaultTextHaloColor();
return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
- (void)setTextHaloWidth:(MGLStyleValue<NSNumber *> *)textHaloWidth {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textHaloWidth);
- self.layer->setTextHaloWidth(mbglValue);
+ _rawLayer->setTextHaloWidth(mbglValue);
}
- (MGLStyleValue<NSNumber *> *)textHaloWidth {
- auto propertyValue = self.layer->getTextHaloWidth() ?: self.layer->getDefaultTextHaloWidth();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextHaloWidth() ?: _rawLayer->getDefaultTextHaloWidth();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextHaloBlur:(MGLStyleValue<NSNumber *> *)textHaloBlur {
- auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textHaloBlur);
- self.layer->setTextHaloBlur(mbglValue);
+- (void)setTextOpacity:(MGLStyleValue<NSNumber *> *)textOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textOpacity);
+ _rawLayer->setTextOpacity(mbglValue);
}
-- (MGLStyleValue<NSNumber *> *)textHaloBlur {
- auto propertyValue = self.layer->getTextHaloBlur() ?: self.layer->getDefaultTextHaloBlur();
+- (MGLStyleValue<NSNumber *> *)textOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextOpacity() ?: _rawLayer->getDefaultTextOpacity();
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
- (void)setTextTranslate:(MGLStyleValue<NSValue *> *)textTranslate {
+ MGLAssertStyleLayerIsValid();
+
auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(textTranslate);
- self.layer->setTextTranslate(mbglValue);
+ _rawLayer->setTextTranslate(mbglValue);
}
- (MGLStyleValue<NSValue *> *)textTranslate {
- auto propertyValue = self.layer->getTextTranslate() ?: self.layer->getDefaultTextTranslate();
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextTranslate() ?: _rawLayer->getDefaultTextTranslate();
return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
- (void)setTextTranslateAnchor:(MGLStyleValue<NSValue *> *)textTranslateAnchor {
- auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(textTranslateAnchor);
- self.layer->setTextTranslateAnchor(mbglValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLTextTranslateAnchor>().toEnumPropertyValue(textTranslateAnchor);
+ _rawLayer->setTextTranslateAnchor(mbglValue);
}
- (MGLStyleValue<NSValue *> *)textTranslateAnchor {
- auto propertyValue = self.layer->getTextTranslateAnchor() ?: self.layer->getDefaultTextTranslateAnchor();
- return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = _rawLayer->getTextTranslateAnchor() ?: _rawLayer->getDefaultTextTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLTextTranslateAnchor>().toEnumStyleValue(propertyValue);
}
+
@end
diff --git a/platform/darwin/src/MGLTileSet.mm b/platform/darwin/src/MGLTileSet.mm
index b2359bb92d..f795545eed 100644
--- a/platform/darwin/src/MGLTileSet.mm
+++ b/platform/darwin/src/MGLTileSet.mm
@@ -84,4 +84,10 @@
return tileset;
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; tileURLTemplates = %@>",
+ NSStringFromClass([self class]), (void *)self, self.tileURLTemplates];
+}
+
@end
diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h
index e9e05bc684..a6b7254b58 100644
--- a/platform/darwin/src/MGLTypes.h
+++ b/platform/darwin/src/MGLTypes.h
@@ -20,6 +20,13 @@
NS_ASSUME_NONNULL_BEGIN
+#ifndef NS_STRING_ENUM
+ #define NS_STRING_ENUM
+ #define NS_EXTENSIBLE_STRING_ENUM
+ typedef NSString *NSErrorDomain;
+ typedef NSString *NSNotificationName;
+#endif
+
/** Indicates an error occurred in the Mapbox SDK. */
extern NSErrorDomain const MGLErrorDomain;
@@ -97,9 +104,3 @@ NS_ASSUME_NONNULL_END
#define NS_MUTABLE_DICTIONARY_OF(ObjectClass...) NSMutableDictionary
#endif
#endif
-
-#if !defined(FOUNDATION_SWIFT_SDK_EPOCH_LESS_THAN) || FOUNDATION_SWIFT_SDK_EPOCH_LESS_THAN(8)
- #define NS_STRING_ENUM
- #define NS_EXTENSIBLE_STRING_ENUM
- #define NSNotificationName NSString *
-#endif
diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm
index 995565419f..ab68d45ba1 100644
--- a/platform/darwin/src/MGLVectorSource.mm
+++ b/platform/darwin/src/MGLVectorSource.mm
@@ -18,8 +18,6 @@
std::unique_ptr<mbgl::style::VectorSource> _pendingSource;
}
-static NSString *MGLVectorSourceType = @"vector";
-
- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url
{
if (self = [super initWithIdentifier:identifier])
@@ -61,7 +59,27 @@ static NSString *MGLVectorSourceType = @"vector";
- (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
+{
+ auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
+
+ _pendingSource = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::VectorSource> &>(removedSource));
+ self.rawSource = _pendingSource.get();
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; tileSet = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.tileSet];
+}
+
@end
diff --git a/platform/darwin/src/MGLVectorStyleLayer.h b/platform/darwin/src/MGLVectorStyleLayer.h
index 13bb9e79a9..e2a755083f 100644
--- a/platform/darwin/src/MGLVectorStyleLayer.h
+++ b/platform/darwin/src/MGLVectorStyleLayer.h
@@ -52,10 +52,11 @@ NS_ASSUME_NONNULL_BEGIN
<li><code>NSNotPredicateType</code> (<code>NOT</code>, <code>!</code>)</li>
</ul>
- The following aggregate operator is supported:
+ The following aggregate operators are supported:
<ul>
<li><code>NSInPredicateOperatorType</code> (<code>IN</code>)</li>
+ <li><code>NSContainsPredicateOperatorType</code> (<code>CONTAINS</code>)</li>
</ul>
To test whether a feature has or lacks a specific attribute, compare the attribute to `NULL` or `NIL`. Predicates created using the `+[NSPredicate predicateWithValue:]` method are also supported. String operators and custom operators are not supported.
@@ -118,7 +119,9 @@ NS_ASSUME_NONNULL_BEGIN
Automatic type casting is not performed. Therefore, a feature only matches this
predicate if its value for the attribute in question is of the same type as the
- value specified in the predicate.
+ value specified in the predicate. Also, operator modifiers `c`, `d`, and the
+ combined `cd` for case and diacritic insensitivity are unsupported for
+ comparison and aggregate operators that are used in the predicate.
*/
@property (nonatomic, nullable) NSPredicate *predicate;
diff --git a/platform/darwin/src/MGLVectorStyleLayer.m b/platform/darwin/src/MGLVectorStyleLayer.m
index 174256cbdd..d8146f4246 100644
--- a/platform/darwin/src/MGLVectorStyleLayer.m
+++ b/platform/darwin/src/MGLVectorStyleLayer.m
@@ -13,4 +13,13 @@
return nil;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:
+ @"<%@: %p; identifier = %@; sourceIdentifier = %@; "
+ @"sourceLayerIdentifier = %@; predicate = %@; visible = %@>",
+ NSStringFromClass([self class]), (void *)self, self.identifier,
+ self.sourceIdentifier, self.sourceLayerIdentifier, self.predicate,
+ self.visible ? @"YES" : @"NO"];
+}
+
@end
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
index aa0e456bb1..19c264aa40 100644
--- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
@@ -68,6 +68,12 @@
filter.values = self.rightExpression.mgl_filterValues;
return filter;
}
+ case NSContainsPredicateOperatorType: {
+ auto filter = mbgl::style::InFilter();
+ filter.key = [self.rightExpression.constantValue UTF8String];
+ filter.values = self.leftExpression.mgl_filterValues;
+ return filter;
+ }
case NSBetweenPredicateOperatorType: {
auto filter = mbgl::style::AllFilter();
auto gteFilter = mbgl::style::GreaterThanEqualsFilter();
@@ -85,7 +91,6 @@
case NSBeginsWithPredicateOperatorType:
case NSEndsWithPredicateOperatorType:
case NSCustomSelectorPredicateOperatorType:
- case NSContainsPredicateOperatorType:
[NSException raise:@"Unsupported operator type"
format:@"NSPredicateOperatorType:%lu is not supported.", (unsigned long)self.predicateOperatorType];
}
diff --git a/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h
new file mode 100644
index 0000000000..8aa07b2a0c
--- /dev/null
+++ b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h
@@ -0,0 +1,232 @@
+// This file is generated.
+// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
+
+#import <Foundation/Foundation.h>
+
+#import "MGLFillStyleLayer.h"
+#import "MGLLineStyleLayer.h"
+#import "MGLSymbolStyleLayer.h"
+#import "MGLCircleStyleLayer.h"
+#import "MGLRasterStyleLayer.h"
+#import "MGLBackgroundStyleLayer.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Methods for round-tripping values for Mapbox style layer enumeration values.
+*/
+@interface NSValue (MGLStyleEnumAttributeAdditions)
+
+#pragma mark Working with Style Layer Enumeration Attribute Values
+
+/**
+ Creates a new value object containing the given `MGLLineCap` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLLineCap:(MGLLineCap)lineCap;
+
+/**
+ The `MGLLineCap` enumeration representation of the value.
+*/
+@property (readonly) MGLLineCap MGLLineCapValue;
+
+/**
+ Creates a new value object containing the given `MGLLineJoin` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLLineJoin:(MGLLineJoin)lineJoin;
+
+/**
+ The `MGLLineJoin` enumeration representation of the value.
+*/
+@property (readonly) MGLLineJoin MGLLineJoinValue;
+
+/**
+ Creates a new value object containing the given `MGLIconRotationAlignment` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLIconRotationAlignment:(MGLIconRotationAlignment)iconRotationAlignment;
+
+/**
+ The `MGLIconRotationAlignment` enumeration representation of the value.
+*/
+@property (readonly) MGLIconRotationAlignment MGLIconRotationAlignmentValue;
+
+/**
+ Creates a new value object containing the given `MGLIconTextFit` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLIconTextFit:(MGLIconTextFit)iconTextFit;
+
+/**
+ The `MGLIconTextFit` enumeration representation of the value.
+*/
+@property (readonly) MGLIconTextFit MGLIconTextFitValue;
+
+/**
+ Creates a new value object containing the given `MGLSymbolPlacement` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLSymbolPlacement:(MGLSymbolPlacement)symbolPlacement;
+
+/**
+ The `MGLSymbolPlacement` enumeration representation of the value.
+*/
+@property (readonly) MGLSymbolPlacement MGLSymbolPlacementValue;
+
+/**
+ Creates a new value object containing the given `MGLTextAnchor` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLTextAnchor:(MGLTextAnchor)textAnchor;
+
+/**
+ The `MGLTextAnchor` enumeration representation of the value.
+*/
+@property (readonly) MGLTextAnchor MGLTextAnchorValue;
+
+/**
+ Creates a new value object containing the given `MGLTextJustify` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLTextJustify:(MGLTextJustify)textJustify;
+
+/**
+ The `MGLTextJustify` enumeration representation of the value.
+*/
+@property (readonly) MGLTextJustify MGLTextJustifyValue;
+
+/**
+ Creates a new value object containing the given `MGLTextPitchAlignment` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLTextPitchAlignment:(MGLTextPitchAlignment)textPitchAlignment;
+
+/**
+ The `MGLTextPitchAlignment` enumeration representation of the value.
+*/
+@property (readonly) MGLTextPitchAlignment MGLTextPitchAlignmentValue;
+
+/**
+ Creates a new value object containing the given `MGLTextRotationAlignment` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLTextRotationAlignment:(MGLTextRotationAlignment)textRotationAlignment;
+
+/**
+ The `MGLTextRotationAlignment` enumeration representation of the value.
+*/
+@property (readonly) MGLTextRotationAlignment MGLTextRotationAlignmentValue;
+
+/**
+ Creates a new value object containing the given `MGLTextTransform` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLTextTransform:(MGLTextTransform)textTransform;
+
+/**
+ The `MGLTextTransform` enumeration representation of the value.
+*/
+@property (readonly) MGLTextTransform MGLTextTransformValue;
+
+/**
+ Creates a new value object containing the given `MGLFillTranslateAnchor` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLFillTranslateAnchor:(MGLFillTranslateAnchor)fillTranslateAnchor;
+
+/**
+ The `MGLFillTranslateAnchor` enumeration representation of the value.
+*/
+@property (readonly) MGLFillTranslateAnchor MGLFillTranslateAnchorValue;
+
+/**
+ Creates a new value object containing the given `MGLLineTranslateAnchor` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLLineTranslateAnchor:(MGLLineTranslateAnchor)lineTranslateAnchor;
+
+/**
+ The `MGLLineTranslateAnchor` enumeration representation of the value.
+*/
+@property (readonly) MGLLineTranslateAnchor MGLLineTranslateAnchorValue;
+
+/**
+ Creates a new value object containing the given `MGLIconTranslateAnchor` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLIconTranslateAnchor:(MGLIconTranslateAnchor)iconTranslateAnchor;
+
+/**
+ The `MGLIconTranslateAnchor` enumeration representation of the value.
+*/
+@property (readonly) MGLIconTranslateAnchor MGLIconTranslateAnchorValue;
+
+/**
+ Creates a new value object containing the given `MGLTextTranslateAnchor` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLTextTranslateAnchor:(MGLTextTranslateAnchor)textTranslateAnchor;
+
+/**
+ The `MGLTextTranslateAnchor` enumeration representation of the value.
+*/
+@property (readonly) MGLTextTranslateAnchor MGLTextTranslateAnchorValue;
+
+/**
+ Creates a new value object containing the given `MGLCirclePitchScale` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLCirclePitchScale:(MGLCirclePitchScale)circlePitchScale;
+
+/**
+ The `MGLCirclePitchScale` enumeration representation of the value.
+*/
+@property (readonly) MGLCirclePitchScale MGLCirclePitchScaleValue;
+
+/**
+ Creates a new value object containing the given `MGLCircleTranslateAnchor` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGLCircleTranslateAnchor:(MGLCircleTranslateAnchor)circleTranslateAnchor;
+
+/**
+ The `MGLCircleTranslateAnchor` enumeration representation of the value.
+*/
+@property (readonly) MGLCircleTranslateAnchor MGLCircleTranslateAnchorValue;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h.ejs b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h.ejs
new file mode 100644
index 0000000000..c078ac7d02
--- /dev/null
+++ b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h.ejs
@@ -0,0 +1,66 @@
+// This file is generated.
+// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
+
+<%
+const types = locals.types;
+const layoutProperties = locals.layoutProperties;
+const paintProperties = locals.paintProperties;
+-%>
+#import <Foundation/Foundation.h>
+
+<% if (types) { -%>
+<% for (const type of types) { -%>
+#import "MGL<%- camelize(type) %>StyleLayer.h"
+<% } -%>
+<% } -%>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Methods for round-tripping values for Mapbox style layer enumeration values.
+*/
+@interface NSValue (MGLStyleEnumAttributeAdditions)
+
+#pragma mark Working with Style Layer Enumeration Attribute Values
+
+<% if (layoutProperties.length) { -%>
+<% for (const property of layoutProperties) { -%>
+<% if (property.type == "enum") { -%>
+/**
+ Creates a new value object containing the given `MGL<%- camelize(property.name) %>` enumeration.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGL<%- camelize(property.name) %>:(MGL<%- camelize(property.name) %>)<%- objCName(property) %>;
+
+/**
+ The `MGL<%- camelize(property.name) %>` enumeration representation of the value.
+*/
+@property (readonly) MGL<%- camelize(property.name) %> MGL<%- camelize(property.name) %>Value;
+
+<% } -%>
+<% } -%>
+<% } -%>
+<% if (paintProperties.length) { -%>
+<% for (const property of paintProperties) { -%>
+<% if (property.type == "enum") { -%>
+/**
+ Creates a new value object containing the given `MGL<%- camelize(property.name) %>` structure.
+
+ @param type The value for the new object.
+ @return A new value object that contains the style enumeration type.
+*/
++ (instancetype)valueWithMGL<%- camelize(property.name) %>:(MGL<%- camelize(property.name) %>)<%- objCName(property) %>;
+
+/**
+ The `MGL<%- camelize(property.name) %>` enumeration representation of the value.
+*/
+@property (readonly) MGL<%- camelize(property.name) %> MGL<%- camelize(property.name) %>Value;
+
+<% } -%>
+<% } -%>
+<% } -%>
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm
new file mode 100644
index 0000000000..89f0c07a5a
--- /dev/null
+++ b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm
@@ -0,0 +1,169 @@
+// This file is generated.
+// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
+
+#import "NSValue+MGLStyleEnumAttributeAdditions.h"
+
+@implementation NSValue (MGLStyleEnumAttributeAdditions)
+
++ (NSValue *)valueWithMGLLineCap:(MGLLineCap)lineCap {
+ return [NSValue value:&lineCap withObjCType:@encode(MGLLineCap)];
+}
+
+- (MGLLineCap)MGLLineCapValue {
+ MGLLineCap value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLLineJoin:(MGLLineJoin)lineJoin {
+ return [NSValue value:&lineJoin withObjCType:@encode(MGLLineJoin)];
+}
+
+- (MGLLineJoin)MGLLineJoinValue {
+ MGLLineJoin value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLIconRotationAlignment:(MGLIconRotationAlignment)iconRotationAlignment {
+ return [NSValue value:&iconRotationAlignment withObjCType:@encode(MGLIconRotationAlignment)];
+}
+
+- (MGLIconRotationAlignment)MGLIconRotationAlignmentValue {
+ MGLIconRotationAlignment value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLIconTextFit:(MGLIconTextFit)iconTextFit {
+ return [NSValue value:&iconTextFit withObjCType:@encode(MGLIconTextFit)];
+}
+
+- (MGLIconTextFit)MGLIconTextFitValue {
+ MGLIconTextFit value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLSymbolPlacement:(MGLSymbolPlacement)symbolPlacement {
+ return [NSValue value:&symbolPlacement withObjCType:@encode(MGLSymbolPlacement)];
+}
+
+- (MGLSymbolPlacement)MGLSymbolPlacementValue {
+ MGLSymbolPlacement value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLTextAnchor:(MGLTextAnchor)textAnchor {
+ return [NSValue value:&textAnchor withObjCType:@encode(MGLTextAnchor)];
+}
+
+- (MGLTextAnchor)MGLTextAnchorValue {
+ MGLTextAnchor value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLTextJustify:(MGLTextJustify)textJustify {
+ return [NSValue value:&textJustify withObjCType:@encode(MGLTextJustify)];
+}
+
+- (MGLTextJustify)MGLTextJustifyValue {
+ MGLTextJustify value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLTextPitchAlignment:(MGLTextPitchAlignment)textPitchAlignment {
+ return [NSValue value:&textPitchAlignment withObjCType:@encode(MGLTextPitchAlignment)];
+}
+
+- (MGLTextPitchAlignment)MGLTextPitchAlignmentValue {
+ MGLTextPitchAlignment value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLTextRotationAlignment:(MGLTextRotationAlignment)textRotationAlignment {
+ return [NSValue value:&textRotationAlignment withObjCType:@encode(MGLTextRotationAlignment)];
+}
+
+- (MGLTextRotationAlignment)MGLTextRotationAlignmentValue {
+ MGLTextRotationAlignment value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLTextTransform:(MGLTextTransform)textTransform {
+ return [NSValue value:&textTransform withObjCType:@encode(MGLTextTransform)];
+}
+
+- (MGLTextTransform)MGLTextTransformValue {
+ MGLTextTransform value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLFillTranslateAnchor:(MGLFillTranslateAnchor)fillTranslateAnchor {
+return [NSValue value:&fillTranslateAnchor withObjCType:@encode(MGLFillTranslateAnchor)];
+}
+
+- (MGLFillTranslateAnchor)MGLFillTranslateAnchorValue {
+ MGLFillTranslateAnchor value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLLineTranslateAnchor:(MGLLineTranslateAnchor)lineTranslateAnchor {
+return [NSValue value:&lineTranslateAnchor withObjCType:@encode(MGLLineTranslateAnchor)];
+}
+
+- (MGLLineTranslateAnchor)MGLLineTranslateAnchorValue {
+ MGLLineTranslateAnchor value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLIconTranslateAnchor:(MGLIconTranslateAnchor)iconTranslateAnchor {
+return [NSValue value:&iconTranslateAnchor withObjCType:@encode(MGLIconTranslateAnchor)];
+}
+
+- (MGLIconTranslateAnchor)MGLIconTranslateAnchorValue {
+ MGLIconTranslateAnchor value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLTextTranslateAnchor:(MGLTextTranslateAnchor)textTranslateAnchor {
+return [NSValue value:&textTranslateAnchor withObjCType:@encode(MGLTextTranslateAnchor)];
+}
+
+- (MGLTextTranslateAnchor)MGLTextTranslateAnchorValue {
+ MGLTextTranslateAnchor value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLCirclePitchScale:(MGLCirclePitchScale)circlePitchScale {
+return [NSValue value:&circlePitchScale withObjCType:@encode(MGLCirclePitchScale)];
+}
+
+- (MGLCirclePitchScale)MGLCirclePitchScaleValue {
+ MGLCirclePitchScale value;
+ [self getValue:&value];
+ return value;
+}
+
++ (NSValue *)valueWithMGLCircleTranslateAnchor:(MGLCircleTranslateAnchor)circleTranslateAnchor {
+return [NSValue value:&circleTranslateAnchor withObjCType:@encode(MGLCircleTranslateAnchor)];
+}
+
+- (MGLCircleTranslateAnchor)MGLCircleTranslateAnchorValue {
+ MGLCircleTranslateAnchor value;
+ [self getValue:&value];
+ return value;
+}
+
+
+@end
diff --git a/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm.ejs b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm.ejs
new file mode 100644
index 0000000000..fab278aac8
--- /dev/null
+++ b/platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.mm.ejs
@@ -0,0 +1,46 @@
+// This file is generated.
+// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
+<%
+const type = locals.type;
+const layoutProperties = locals.layoutProperties;
+const paintProperties = locals.paintProperties;
+-%>
+
+#import "NSValue+MGLStyleEnumAttributeAdditions.h"
+
+@implementation NSValue (MGLStyleEnumAttributeAdditions)
+
+<% if (layoutProperties.length) { -%>
+<% for (const property of layoutProperties) { -%>
+<% if (property.type == "enum") { -%>
++ (NSValue *)valueWithMGL<%- camelize(property.name) %>:(MGL<%- camelize(property.name) %>)<%- objCName(property) %> {
+ return [NSValue value:&<%- objCName(property) %> withObjCType:@encode(MGL<%- camelize(property.name) %>)];
+}
+
+- (MGL<%- camelize(property.name) %>)MGL<%- camelize(property.name) %>Value {
+ MGL<%- camelize(property.name) %> value;
+ [self getValue:&value];
+ return value;
+}
+
+<% } -%>
+<% } -%>
+<% } -%>
+<% if (paintProperties.length) { -%>
+<% for (const property of paintProperties) { -%>
+<% if (property.type == "enum") { -%>
++ (NSValue *)valueWithMGL<%- camelize(property.name) %>:(MGL<%- camelize(property.name) %>)<%- objCName(property) %> {
+return [NSValue value:&<%- objCName(property) %> withObjCType:@encode(MGL<%- camelize(property.name) %>)];
+}
+
+- (MGL<%- camelize(property.name) %>)MGL<%- camelize(property.name) %>Value {
+ MGL<%- camelize(property.name) %> value;
+ [self getValue:&value];
+ return value;
+}
+
+<% } -%>
+<% } -%>
+<% } -%>
+
+@end
diff --git a/platform/darwin/test/MGLBackgroundStyleLayerTests.m b/platform/darwin/test/MGLBackgroundStyleLayerTests.m
index 75181cdf0c..09bed76654 100644
--- a/platform/darwin/test/MGLBackgroundStyleLayerTests.m
+++ b/platform/darwin/test/MGLBackgroundStyleLayerTests.m
@@ -1,9 +1,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGLBackgroundLayerTests : MGLMapViewTests
+@interface MGLBackgroundLayerTests : MGLStyleLayerTests
@end
@implementation MGLBackgroundLayerTests
@@ -13,22 +13,22 @@
[self.mapView.style addLayer:layer];
layer.backgroundColor = [MGLRuntimeStylingHelper testColor];
- layer.backgroundPattern = [MGLRuntimeStylingHelper testString];
layer.backgroundOpacity = [MGLRuntimeStylingHelper testNumber];
+ layer.backgroundPattern = [MGLRuntimeStylingHelper testString];
MGLBackgroundStyleLayer *gLayer = (MGLBackgroundStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
XCTAssertTrue([gLayer isKindOfClass:[MGLBackgroundStyleLayer class]]);
XCTAssertEqualObjects(gLayer.backgroundColor, [MGLRuntimeStylingHelper testColor]);
- XCTAssertEqualObjects(gLayer.backgroundPattern, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.backgroundOpacity, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.backgroundPattern, [MGLRuntimeStylingHelper testString]);
layer.backgroundColor = [MGLRuntimeStylingHelper testColorFunction];
- layer.backgroundPattern = [MGLRuntimeStylingHelper testStringFunction];
layer.backgroundOpacity = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.backgroundPattern = [MGLRuntimeStylingHelper testStringFunction];
XCTAssertEqualObjects(gLayer.backgroundColor, [MGLRuntimeStylingHelper testColorFunction]);
- XCTAssertEqualObjects(gLayer.backgroundPattern, [MGLRuntimeStylingHelper testStringFunction]);
XCTAssertEqualObjects(gLayer.backgroundOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.backgroundPattern, [MGLRuntimeStylingHelper testStringFunction]);
}
@end
diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.m b/platform/darwin/test/MGLCircleStyleLayerTests.m
index eb175de621..432d3ffa79 100644
--- a/platform/darwin/test/MGLCircleStyleLayerTests.m
+++ b/platform/darwin/test/MGLCircleStyleLayerTests.m
@@ -1,9 +1,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGLCircleLayerTests : MGLMapViewTests
+@interface MGLCircleLayerTests : MGLStyleLayerTests
@end
@implementation MGLCircleLayerTests
@@ -16,41 +16,41 @@
MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
- layer.circleRadius = [MGLRuntimeStylingHelper testNumber];
- layer.circleColor = [MGLRuntimeStylingHelper testColor];
layer.circleBlur = [MGLRuntimeStylingHelper testNumber];
+ layer.circleColor = [MGLRuntimeStylingHelper testColor];
layer.circleOpacity = [MGLRuntimeStylingHelper testNumber];
+ layer.circlePitchScale = [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
+ layer.circleRadius = [MGLRuntimeStylingHelper testNumber];
layer.circleTranslate = [MGLRuntimeStylingHelper testOffset];
layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)];
- layer.circlePitchScale = [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
MGLCircleStyleLayer *gLayer = (MGLCircleStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
XCTAssertTrue([gLayer isKindOfClass:[MGLCircleStyleLayer class]]);
- XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.circleColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.circleBlur, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.circleColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.circleOpacity, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssert([gLayer.circlePitchScale isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
+ XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffset]);
XCTAssert([gLayer.circleTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]);
- XCTAssert([gLayer.circlePitchScale isKindOfClass:[MGLStyleConstantValue class]]);
- XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
- layer.circleRadius = [MGLRuntimeStylingHelper testNumberFunction];
- layer.circleColor = [MGLRuntimeStylingHelper testColorFunction];
layer.circleBlur = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.circleColor = [MGLRuntimeStylingHelper testColorFunction];
layer.circleOpacity = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.circlePitchScale = [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
+ layer.circleRadius = [MGLRuntimeStylingHelper testNumberFunction];
layer.circleTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)];
- layer.circlePitchScale = [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
- XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.circleColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.circleBlur, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.circleColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.circleOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
+ XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
}
@end
diff --git a/platform/darwin/test/MGLFillStyleLayerTests.m b/platform/darwin/test/MGLFillStyleLayerTests.m
index ca8015ecfd..87846302ea 100644
--- a/platform/darwin/test/MGLFillStyleLayerTests.m
+++ b/platform/darwin/test/MGLFillStyleLayerTests.m
@@ -1,9 +1,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGLFillLayerTests : MGLMapViewTests
+@interface MGLFillLayerTests : MGLStyleLayerTests
@end
@implementation MGLFillLayerTests
@@ -17,39 +17,39 @@
[self.mapView.style addLayer:layer];
layer.fillAntialias = [MGLRuntimeStylingHelper testBool];
- layer.fillOpacity = [MGLRuntimeStylingHelper testNumber];
layer.fillColor = [MGLRuntimeStylingHelper testColor];
+ layer.fillOpacity = [MGLRuntimeStylingHelper testNumber];
layer.fillOutlineColor = [MGLRuntimeStylingHelper testColor];
+ layer.fillPattern = [MGLRuntimeStylingHelper testString];
layer.fillTranslate = [MGLRuntimeStylingHelper testOffset];
layer.fillTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)];
- layer.fillPattern = [MGLRuntimeStylingHelper testString];
MGLFillStyleLayer *gLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
XCTAssertTrue([gLayer isKindOfClass:[MGLFillStyleLayer class]]);
XCTAssertEqualObjects(gLayer.fillAntialias, [MGLRuntimeStylingHelper testBool]);
- XCTAssertEqualObjects(gLayer.fillOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.fillColor, [MGLRuntimeStylingHelper testColor]);
+ XCTAssertEqualObjects(gLayer.fillOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.fillOutlineColor, [MGLRuntimeStylingHelper testColor]);
+ XCTAssertEqualObjects(gLayer.fillPattern, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.fillTranslate, [MGLRuntimeStylingHelper testOffset]);
XCTAssert([gLayer.fillTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.fillTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.fillPattern, [MGLRuntimeStylingHelper testString]);
layer.fillAntialias = [MGLRuntimeStylingHelper testBoolFunction];
- layer.fillOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.fillColor = [MGLRuntimeStylingHelper testColorFunction];
+ layer.fillOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.fillOutlineColor = [MGLRuntimeStylingHelper testColorFunction];
+ layer.fillPattern = [MGLRuntimeStylingHelper testStringFunction];
layer.fillTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
layer.fillTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)];
- layer.fillPattern = [MGLRuntimeStylingHelper testStringFunction];
XCTAssertEqualObjects(gLayer.fillAntialias, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.fillOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.fillColor, [MGLRuntimeStylingHelper testColorFunction]);
+ XCTAssertEqualObjects(gLayer.fillOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.fillOutlineColor, [MGLRuntimeStylingHelper testColorFunction]);
+ XCTAssertEqualObjects(gLayer.fillPattern, [MGLRuntimeStylingHelper testStringFunction]);
XCTAssertEqualObjects(gLayer.fillTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.fillTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.fillPattern, [MGLRuntimeStylingHelper testStringFunction]);
}
@end
diff --git a/platform/darwin/test/MGLFilterTests.mm b/platform/darwin/test/MGLFilterTests.mm
index 72927df0a1..b18400f83a 100644
--- a/platform/darwin/test/MGLFilterTests.mm
+++ b/platform/darwin/test/MGLFilterTests.mm
@@ -1,10 +1,10 @@
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLValueEvaluator.h"
-@interface MGLFilterTests : MGLMapViewTests {
+@interface MGLFilterTests : MGLStyleLayerTests {
MGLGeoJSONSource *source;
MGLLineStyleLayer *layer;
}
@@ -74,6 +74,18 @@
[self.mapView.style addLayer:layer];
}
+- (void)testContainsPredicate
+{
+ // core does not have a "contains" filter but we can achieve the equivalent by creating an `mbgl::style::InFilter`
+ // and searching the value for the key
+ NSPredicate *expectedPredicate = [NSPredicate predicateWithFormat:@"park IN %@", @[@"park", @"neighbourhood"]];
+ NSPredicate *containsPredicate = [NSPredicate predicateWithFormat:@"%@ CONTAINS %@", @[@"park", @"neighbourhood"], @"park"];
+
+ layer.predicate = containsPredicate;
+ XCTAssertEqualObjects(layer.predicate, expectedPredicate);
+ [self.mapView.style addLayer:layer];
+}
+
- (void)testBetweenPredicate
{
// core does not have a "between" filter but we can achieve the equivalent by creating a set of greater than or equal / less than or equal
diff --git a/platform/darwin/test/MGLLineStyleLayerTests.m b/platform/darwin/test/MGLLineStyleLayerTests.m
index d368451562..95983b1f52 100644
--- a/platform/darwin/test/MGLLineStyleLayerTests.m
+++ b/platform/darwin/test/MGLLineStyleLayerTests.m
@@ -1,9 +1,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGLLineLayerTests : MGLMapViewTests
+@interface MGLLineLayerTests : MGLStyleLayerTests
@end
@implementation MGLLineLayerTests
@@ -20,16 +20,16 @@
layer.lineJoin = [MGLRuntimeStylingHelper testEnum:MGLLineJoinMiter type:@encode(MGLLineJoin)];
layer.lineMiterLimit = [MGLRuntimeStylingHelper testNumber];
layer.lineRoundLimit = [MGLRuntimeStylingHelper testNumber];
- layer.lineOpacity = [MGLRuntimeStylingHelper testNumber];
+ layer.lineBlur = [MGLRuntimeStylingHelper testNumber];
layer.lineColor = [MGLRuntimeStylingHelper testColor];
- layer.lineTranslate = [MGLRuntimeStylingHelper testOffset];
- layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)];
- layer.lineWidth = [MGLRuntimeStylingHelper testNumber];
+ layer.lineDasharray = [MGLRuntimeStylingHelper testDashArray];
layer.lineGapWidth = [MGLRuntimeStylingHelper testNumber];
layer.lineOffset = [MGLRuntimeStylingHelper testNumber];
- layer.lineBlur = [MGLRuntimeStylingHelper testNumber];
- layer.lineDasharray = [MGLRuntimeStylingHelper testDashArray];
+ layer.lineOpacity = [MGLRuntimeStylingHelper testNumber];
layer.linePattern = [MGLRuntimeStylingHelper testString];
+ layer.lineTranslate = [MGLRuntimeStylingHelper testOffset];
+ layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)];
+ layer.lineWidth = [MGLRuntimeStylingHelper testNumber];
MGLLineStyleLayer *gLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
XCTAssertTrue([gLayer isKindOfClass:[MGLLineStyleLayer class]]);
@@ -39,47 +39,47 @@
XCTAssertEqualObjects(gLayer.lineJoin, [MGLRuntimeStylingHelper testEnum:MGLLineJoinMiter type:@encode(MGLLineJoin)]);
XCTAssertEqualObjects(gLayer.lineMiterLimit, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineRoundLimit, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.lineOpacity, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.lineBlur, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineColor, [MGLRuntimeStylingHelper testColor]);
+ XCTAssertEqualObjects(gLayer.lineDasharray, [MGLRuntimeStylingHelper testDashArray]);
+ XCTAssertEqualObjects(gLayer.lineGapWidth, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.lineOffset, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.lineOpacity, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.linePattern, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.lineTranslate, [MGLRuntimeStylingHelper testOffset]);
XCTAssert([gLayer.lineTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.lineWidth, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.lineGapWidth, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.lineOffset, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.lineBlur, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.lineDasharray, [MGLRuntimeStylingHelper testDashArray]);
- XCTAssertEqualObjects(gLayer.linePattern, [MGLRuntimeStylingHelper testString]);
layer.lineCap = [MGLRuntimeStylingHelper testEnumFunction:MGLLineCapSquare type:@encode(MGLLineCap)];
layer.lineJoin = [MGLRuntimeStylingHelper testEnumFunction:MGLLineJoinMiter type:@encode(MGLLineJoin)];
layer.lineMiterLimit = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineRoundLimit = [MGLRuntimeStylingHelper testNumberFunction];
- layer.lineOpacity = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.lineBlur = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineColor = [MGLRuntimeStylingHelper testColorFunction];
- layer.lineTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)];
- layer.lineWidth = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.lineDasharray = [MGLRuntimeStylingHelper testDashArrayFunction];
layer.lineGapWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineOffset = [MGLRuntimeStylingHelper testNumberFunction];
- layer.lineBlur = [MGLRuntimeStylingHelper testNumberFunction];
- layer.lineDasharray = [MGLRuntimeStylingHelper testDashArrayFunction];
+ layer.lineOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.linePattern = [MGLRuntimeStylingHelper testStringFunction];
+ layer.lineTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
+ layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)];
+ layer.lineWidth = [MGLRuntimeStylingHelper testNumberFunction];
XCTAssertEqualObjects(gLayer.lineCap, [MGLRuntimeStylingHelper testEnumFunction:MGLLineCapSquare type:@encode(MGLLineCap)]);
XCTAssertEqualObjects(gLayer.lineJoin, [MGLRuntimeStylingHelper testEnumFunction:MGLLineJoinMiter type:@encode(MGLLineJoin)]);
XCTAssertEqualObjects(gLayer.lineMiterLimit, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineRoundLimit, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.lineOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.lineBlur, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineColor, [MGLRuntimeStylingHelper testColorFunction]);
- XCTAssertEqualObjects(gLayer.lineTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.lineWidth, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.lineDasharray, [MGLRuntimeStylingHelper testDashArrayFunction]);
XCTAssertEqualObjects(gLayer.lineGapWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineOffset, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.lineBlur, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.lineDasharray, [MGLRuntimeStylingHelper testDashArrayFunction]);
+ XCTAssertEqualObjects(gLayer.lineOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.linePattern, [MGLRuntimeStylingHelper testStringFunction]);
+ XCTAssertEqualObjects(gLayer.lineTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
+ XCTAssertEqualObjects(gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)]);
+ XCTAssertEqualObjects(gLayer.lineWidth, [MGLRuntimeStylingHelper testNumberFunction]);
}
@end
diff --git a/platform/darwin/test/MGLOfflineStorageTests.m b/platform/darwin/test/MGLOfflineStorageTests.m
index cd13a9262e..07540b5645 100644
--- a/platform/darwin/test/MGLOfflineStorageTests.m
+++ b/platform/darwin/test/MGLOfflineStorageTests.m
@@ -19,6 +19,7 @@
}];
if ([MGLOfflineStorage sharedOfflineStorage].packs) {
[expectation fulfill];
+ [self waitForExpectationsWithTimeout:0 handler:nil];
} else {
[self waitForExpectationsWithTimeout:2 handler:nil];
}
diff --git a/platform/darwin/test/MGLRasterStyleLayerTests.m b/platform/darwin/test/MGLRasterStyleLayerTests.m
index ef7ab0263f..84fd0fe3e5 100644
--- a/platform/darwin/test/MGLRasterStyleLayerTests.m
+++ b/platform/darwin/test/MGLRasterStyleLayerTests.m
@@ -1,9 +1,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGLRasterLayerTests : MGLMapViewTests
+@interface MGLRasterLayerTests : MGLStyleLayerTests
@end
@implementation MGLRasterLayerTests
@@ -16,39 +16,39 @@
MGLRasterStyleLayer *layer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
- layer.rasterOpacity = [MGLRuntimeStylingHelper testNumber];
- layer.rasterHueRotate = [MGLRuntimeStylingHelper testNumber];
- layer.rasterBrightnessMin = [MGLRuntimeStylingHelper testNumber];
- layer.rasterBrightnessMax = [MGLRuntimeStylingHelper testNumber];
- layer.rasterSaturation = [MGLRuntimeStylingHelper testNumber];
+ layer.maximumRasterBrightness = [MGLRuntimeStylingHelper testNumber];
+ layer.minimumRasterBrightness = [MGLRuntimeStylingHelper testNumber];
layer.rasterContrast = [MGLRuntimeStylingHelper testNumber];
layer.rasterFadeDuration = [MGLRuntimeStylingHelper testNumber];
+ layer.rasterHueRotate = [MGLRuntimeStylingHelper testNumber];
+ layer.rasterOpacity = [MGLRuntimeStylingHelper testNumber];
+ layer.rasterSaturation = [MGLRuntimeStylingHelper testNumber];
MGLRasterStyleLayer *gLayer = (MGLRasterStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
XCTAssertTrue([gLayer isKindOfClass:[MGLRasterStyleLayer class]]);
- XCTAssertEqualObjects(gLayer.rasterOpacity, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.rasterHueRotate, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.rasterBrightnessMin, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.rasterBrightnessMax, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.rasterSaturation, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.maximumRasterBrightness, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.minimumRasterBrightness, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.rasterContrast, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.rasterFadeDuration, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.rasterHueRotate, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.rasterOpacity, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.rasterSaturation, [MGLRuntimeStylingHelper testNumber]);
- layer.rasterOpacity = [MGLRuntimeStylingHelper testNumberFunction];
- layer.rasterHueRotate = [MGLRuntimeStylingHelper testNumberFunction];
- layer.rasterBrightnessMin = [MGLRuntimeStylingHelper testNumberFunction];
- layer.rasterBrightnessMax = [MGLRuntimeStylingHelper testNumberFunction];
- layer.rasterSaturation = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.maximumRasterBrightness = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.minimumRasterBrightness = [MGLRuntimeStylingHelper testNumberFunction];
layer.rasterContrast = [MGLRuntimeStylingHelper testNumberFunction];
layer.rasterFadeDuration = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.rasterHueRotate = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.rasterOpacity = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.rasterSaturation = [MGLRuntimeStylingHelper testNumberFunction];
- XCTAssertEqualObjects(gLayer.rasterOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.rasterHueRotate, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.rasterBrightnessMin, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.rasterBrightnessMax, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.rasterSaturation, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.maximumRasterBrightness, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.minimumRasterBrightness, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.rasterContrast, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.rasterFadeDuration, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.rasterHueRotate, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.rasterOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.rasterSaturation, [MGLRuntimeStylingHelper testNumberFunction]);
}
@end
diff --git a/platform/darwin/test/MGLMapViewTests.h b/platform/darwin/test/MGLStyleLayerTests.h
index da94281165..f81e075e03 100644
--- a/platform/darwin/test/MGLMapViewTests.h
+++ b/platform/darwin/test/MGLStyleLayerTests.h
@@ -2,7 +2,7 @@
#import "MGLRuntimeStylingHelper.h"
#import <XCTest/XCTest.h>
-@interface MGLMapViewTests : XCTestCase <MGLMapViewDelegate>
+@interface MGLStyleLayerTests : XCTestCase <MGLMapViewDelegate>
@property (nonatomic) IBOutlet MGLMapView *mapView;
@property (nonatomic) XCTestExpectation *expectation;
diff --git a/platform/darwin/test/MGLMapViewTests.m b/platform/darwin/test/MGLStyleLayerTests.m
index 63ff3501ca..74c6b2f906 100644
--- a/platform/darwin/test/MGLMapViewTests.m
+++ b/platform/darwin/test/MGLStyleLayerTests.m
@@ -1,6 +1,6 @@
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@implementation MGLMapViewTests
+@implementation MGLStyleLayerTests
- (void)setUp {
[super setUp];
@@ -14,7 +14,7 @@
_mapView.delegate = self;
#else
[MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
- NSWindowController *windowController = [[NSWindowController alloc] initWithWindowNibName:@"MGLMapViewTests" owner:self];
+ NSWindowController *windowController = [[NSWindowController alloc] initWithWindowNibName:@"MGLStyleLayerTests" owner:self];
[windowController showWindow:nil];
#endif
}
diff --git a/platform/darwin/test/MGLMapViewTests.xib b/platform/darwin/test/MGLStyleLayerTests.xib
index cc336191ef..23ad22e7e3 100644
--- a/platform/darwin/test/MGLMapViewTests.xib
+++ b/platform/darwin/test/MGLStyleLayerTests.xib
@@ -4,14 +4,14 @@
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
- <customObject id="-2" userLabel="File's Owner" customClass="MGLMapViewTests">
+ <customObject id="-2" userLabel="File's Owner" customClass="MGLStyleLayerTests">
<connections>
<outlet property="mapView" destination="6RL-d9-juy" id="0ch-aR-Um6"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
- <window title="MGLMapViewTests" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
+ <window title="MGLStyleLayerTests" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="256" height="256"/>
diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm
index 07e012edc6..4c0c163b38 100644
--- a/platform/darwin/test/MGLStyleTests.mm
+++ b/platform/darwin/test/MGLStyleTests.mm
@@ -1,4 +1,16 @@
-#import "MGLStyle.h"
+#import "MGLMapView.h"
+#import "MGLStyle_Private.h"
+
+#import "MGLGeoJSONSource.h"
+#import "MGLRasterSource.h"
+#import "MGLVectorSource.h"
+
+#import "MGLBackgroundStyleLayer.h"
+#import "MGLCircleStyleLayer.h"
+#import "MGLFillStyleLayer.h"
+#import "MGLLineStyleLayer.h"
+#import "MGLRasterStyleLayer.h"
+#import "MGLSymbolStyleLayer.h"
#import "NSBundle+MGLAdditions.h"
@@ -8,10 +20,21 @@
#import <objc/runtime.h>
@interface MGLStyleTests : XCTestCase
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) MGLStyle *style;
+
@end
@implementation MGLStyleTests
+- (void)setUp {
+ [super setUp];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
+ self.style = [[MGLStyle alloc] initWithMapView:self.mapView];
+}
+
- (void)testUnversionedStyleURLs {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -92,6 +115,56 @@
}];
}
+- (void)testAddingSourcesTwice {
+ MGLGeoJSONSource *geoJSONSource = [[MGLGeoJSONSource alloc] initWithIdentifier:@"geoJSONSource" features:@[] options:nil];
+ [self.style addSource:geoJSONSource];
+ XCTAssertThrowsSpecificNamed([self.style addSource:geoJSONSource], NSException, @"MGLRedundantSourceException");
+
+ MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"rasterSource" URL:[NSURL new] tileSize:42];
+ [self.style addSource:rasterSource];
+ XCTAssertThrowsSpecificNamed([self.style addSource:rasterSource], NSException, @"MGLRedundantSourceException");
+
+ MGLVectorSource *vectorSource = [[MGLVectorSource alloc] initWithIdentifier:@"vectorSource" URL:[NSURL new]];
+ [self.style addSource:vectorSource];
+ XCTAssertThrowsSpecificNamed([self.style addSource:vectorSource], NSException, @"MGLRedundantSourceException");
+}
+
+- (void)testAddingSourcesWithDuplicateIdentifiers {
+ MGLVectorSource *source1 = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" URL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]];
+ MGLVectorSource *source2 = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" URL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]];
+
+ [self.style addSource: source1];
+ XCTAssertThrowsSpecificNamed([self.style addSource: source2], NSException, @"MGLRedundantSourceIdentiferException");
+}
+
+- (void)testAddingLayersTwice {
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"geoJSONSource" features:@[] options:nil];
+
+ MGLBackgroundStyleLayer *backgroundLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:@"backgroundLayer"];
+ [self.style addLayer:backgroundLayer];
+ XCTAssertThrowsSpecificNamed([self.style addLayer:backgroundLayer], NSException, @"MGLRedundantLayerException");
+
+ MGLCircleStyleLayer *circleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"circleLayer" source:source];
+ [self.style addLayer:circleLayer];
+ XCTAssertThrowsSpecificNamed([self.style addLayer:circleLayer], NSException, @"MGLRedundantLayerException");
+
+ MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:source];
+ [self.style addLayer:fillLayer];
+ XCTAssertThrowsSpecificNamed([self.style addLayer:fillLayer], NSException, @"MGLRedundantLayerException");
+
+ MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"lineLayer" source:source];
+ [self.style addLayer:lineLayer];
+ XCTAssertThrowsSpecificNamed([self.style addLayer:lineLayer], NSException, @"MGLRedundantLayerException");
+
+ MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"rasterLayer" source:source];
+ [self.style addLayer:rasterLayer];
+ XCTAssertThrowsSpecificNamed([self.style addLayer:rasterLayer], NSException, @"MGLRedundantLayerException");
+
+ MGLSymbolStyleLayer *symbolLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"symbolLayer" source:source];
+ [self.style addLayer:symbolLayer];
+ XCTAssertThrowsSpecificNamed([self.style addLayer:symbolLayer], NSException, @"MGLRedundantLayerException");
+}
+
- (NSString *)stringWithContentsOfStyleHeader {
NSURL *styleHeaderURL = [[[NSBundle mgl_frameworkBundle].bundleURL
URLByAppendingPathComponent:@"Headers" isDirectory:YES]
diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.m b/platform/darwin/test/MGLSymbolStyleLayerTests.m
index 1761a71e0c..e77c4f6f39 100644
--- a/platform/darwin/test/MGLSymbolStyleLayerTests.m
+++ b/platform/darwin/test/MGLSymbolStyleLayerTests.m
@@ -1,9 +1,9 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLMapViewTests.h"
+#import "MGLStyleLayerTests.h"
-@interface MGLSymbolLayerTests : MGLMapViewTests
+@interface MGLSymbolLayerTests : MGLStyleLayerTests
@end
@implementation MGLSymbolLayerTests
@@ -16,211 +16,211 @@
MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
- layer.symbolPlacement = [MGLRuntimeStylingHelper testEnum:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)];
- layer.symbolSpacing = [MGLRuntimeStylingHelper testNumber];
- layer.symbolAvoidEdges = [MGLRuntimeStylingHelper testBool];
layer.iconAllowOverlap = [MGLRuntimeStylingHelper testBool];
layer.iconIgnorePlacement = [MGLRuntimeStylingHelper testBool];
+ layer.iconImageName = [MGLRuntimeStylingHelper testString];
+ layer.iconKeepUpright = [MGLRuntimeStylingHelper testBool];
+ layer.iconOffset = [MGLRuntimeStylingHelper testOffset];
layer.iconOptional = [MGLRuntimeStylingHelper testBool];
+ layer.iconPadding = [MGLRuntimeStylingHelper testNumber];
+ layer.iconRotate = [MGLRuntimeStylingHelper testNumber];
layer.iconRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)];
layer.iconSize = [MGLRuntimeStylingHelper testNumber];
layer.iconTextFit = [MGLRuntimeStylingHelper testEnum:MGLIconTextFitBoth type:@encode(MGLIconTextFit)];
layer.iconTextFitPadding = [MGLRuntimeStylingHelper testPadding];
- layer.iconImage = [MGLRuntimeStylingHelper testString];
- layer.iconRotate = [MGLRuntimeStylingHelper testNumber];
- layer.iconPadding = [MGLRuntimeStylingHelper testNumber];
- layer.iconKeepUpright = [MGLRuntimeStylingHelper testBool];
- layer.iconOffset = [MGLRuntimeStylingHelper testOffset];
- layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnum:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)];
- layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)];
+ layer.symbolAvoidEdges = [MGLRuntimeStylingHelper testBool];
+ layer.symbolPlacement = [MGLRuntimeStylingHelper testEnum:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)];
+ layer.symbolSpacing = [MGLRuntimeStylingHelper testNumber];
+ layer.textAllowOverlap = [MGLRuntimeStylingHelper testBool];
+ layer.textAnchor = [MGLRuntimeStylingHelper testEnum:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)];
layer.textField = [MGLRuntimeStylingHelper testString];
layer.textFont = [MGLRuntimeStylingHelper testFont];
- layer.textSize = [MGLRuntimeStylingHelper testNumber];
- layer.textMaxWidth = [MGLRuntimeStylingHelper testNumber];
- layer.textLineHeight = [MGLRuntimeStylingHelper testNumber];
- layer.textLetterSpacing = [MGLRuntimeStylingHelper testNumber];
+ layer.textIgnorePlacement = [MGLRuntimeStylingHelper testBool];
layer.textJustify = [MGLRuntimeStylingHelper testEnum:MGLTextJustifyRight type:@encode(MGLTextJustify)];
- layer.textAnchor = [MGLRuntimeStylingHelper testEnum:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)];
- layer.textMaxAngle = [MGLRuntimeStylingHelper testNumber];
- layer.textRotate = [MGLRuntimeStylingHelper testNumber];
- layer.textPadding = [MGLRuntimeStylingHelper testNumber];
layer.textKeepUpright = [MGLRuntimeStylingHelper testBool];
- layer.textTransform = [MGLRuntimeStylingHelper testEnum:MGLTextTransformLowercase type:@encode(MGLTextTransform)];
+ layer.textLetterSpacing = [MGLRuntimeStylingHelper testNumber];
+ layer.textLineHeight = [MGLRuntimeStylingHelper testNumber];
+ layer.textMaxAngle = [MGLRuntimeStylingHelper testNumber];
+ layer.textMaxWidth = [MGLRuntimeStylingHelper testNumber];
layer.textOffset = [MGLRuntimeStylingHelper testOffset];
- layer.textAllowOverlap = [MGLRuntimeStylingHelper testBool];
- layer.textIgnorePlacement = [MGLRuntimeStylingHelper testBool];
layer.textOptional = [MGLRuntimeStylingHelper testBool];
- layer.iconOpacity = [MGLRuntimeStylingHelper testNumber];
+ layer.textPadding = [MGLRuntimeStylingHelper testNumber];
+ layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnum:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)];
+ layer.textRotate = [MGLRuntimeStylingHelper testNumber];
+ layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)];
+ layer.textSize = [MGLRuntimeStylingHelper testNumber];
+ layer.textTransform = [MGLRuntimeStylingHelper testEnum:MGLTextTransformLowercase type:@encode(MGLTextTransform)];
layer.iconColor = [MGLRuntimeStylingHelper testColor];
+ layer.iconHaloBlur = [MGLRuntimeStylingHelper testNumber];
layer.iconHaloColor = [MGLRuntimeStylingHelper testColor];
layer.iconHaloWidth = [MGLRuntimeStylingHelper testNumber];
- layer.iconHaloBlur = [MGLRuntimeStylingHelper testNumber];
+ layer.iconOpacity = [MGLRuntimeStylingHelper testNumber];
layer.iconTranslate = [MGLRuntimeStylingHelper testOffset];
layer.iconTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)];
- layer.textOpacity = [MGLRuntimeStylingHelper testNumber];
layer.textColor = [MGLRuntimeStylingHelper testColor];
+ layer.textHaloBlur = [MGLRuntimeStylingHelper testNumber];
layer.textHaloColor = [MGLRuntimeStylingHelper testColor];
layer.textHaloWidth = [MGLRuntimeStylingHelper testNumber];
- layer.textHaloBlur = [MGLRuntimeStylingHelper testNumber];
+ layer.textOpacity = [MGLRuntimeStylingHelper testNumber];
layer.textTranslate = [MGLRuntimeStylingHelper testOffset];
layer.textTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)];
MGLSymbolStyleLayer *gLayer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
XCTAssertTrue([gLayer isKindOfClass:[MGLSymbolStyleLayer class]]);
- XCTAssert([gLayer.symbolPlacement isKindOfClass:[MGLStyleConstantValue class]]);
- XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnum:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)]);
- XCTAssertEqualObjects(gLayer.symbolSpacing, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.symbolAvoidEdges, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.iconAllowOverlap, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.iconIgnorePlacement, [MGLRuntimeStylingHelper testBool]);
+ XCTAssertEqualObjects(gLayer.iconImageName, [MGLRuntimeStylingHelper testString]);
+ XCTAssertEqualObjects(gLayer.iconKeepUpright, [MGLRuntimeStylingHelper testBool]);
+ XCTAssertEqualObjects(gLayer.iconOffset, [MGLRuntimeStylingHelper testOffset]);
XCTAssertEqualObjects(gLayer.iconOptional, [MGLRuntimeStylingHelper testBool]);
+ XCTAssertEqualObjects(gLayer.iconPadding, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.iconRotate, [MGLRuntimeStylingHelper testNumber]);
XCTAssert([gLayer.iconRotationAlignment isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.iconRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)]);
XCTAssertEqualObjects(gLayer.iconSize, [MGLRuntimeStylingHelper testNumber]);
XCTAssert([gLayer.iconTextFit isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.iconTextFit, [MGLRuntimeStylingHelper testEnum:MGLIconTextFitBoth type:@encode(MGLIconTextFit)]);
XCTAssertEqualObjects(gLayer.iconTextFitPadding, [MGLRuntimeStylingHelper testPadding]);
- XCTAssertEqualObjects(gLayer.iconImage, [MGLRuntimeStylingHelper testString]);
- XCTAssertEqualObjects(gLayer.iconRotate, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.iconPadding, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.iconKeepUpright, [MGLRuntimeStylingHelper testBool]);
- XCTAssertEqualObjects(gLayer.iconOffset, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([gLayer.textPitchAlignment isKindOfClass:[MGLStyleConstantValue class]]);
- XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnum:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)]);
- XCTAssert([gLayer.textRotationAlignment isKindOfClass:[MGLStyleConstantValue class]]);
- XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)]);
+ XCTAssertEqualObjects(gLayer.symbolAvoidEdges, [MGLRuntimeStylingHelper testBool]);
+ XCTAssert([gLayer.symbolPlacement isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnum:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)]);
+ XCTAssertEqualObjects(gLayer.symbolSpacing, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.textAllowOverlap, [MGLRuntimeStylingHelper testBool]);
+ XCTAssert([gLayer.textAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnum:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)]);
XCTAssertEqualObjects(gLayer.textField, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.textFont, [MGLRuntimeStylingHelper testFont]);
- XCTAssertEqualObjects(gLayer.textSize, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.textMaxWidth, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.textLineHeight, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.textLetterSpacing, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.textIgnorePlacement, [MGLRuntimeStylingHelper testBool]);
XCTAssert([gLayer.textJustify isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.textJustify, [MGLRuntimeStylingHelper testEnum:MGLTextJustifyRight type:@encode(MGLTextJustify)]);
- XCTAssert([gLayer.textAnchor isKindOfClass:[MGLStyleConstantValue class]]);
- XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnum:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)]);
+ XCTAssertEqualObjects(gLayer.textKeepUpright, [MGLRuntimeStylingHelper testBool]);
+ XCTAssertEqualObjects(gLayer.textLetterSpacing, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.textLineHeight, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textMaxAngle, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.textRotate, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.textMaxWidth, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.textOffset, [MGLRuntimeStylingHelper testOffset]);
+ XCTAssertEqualObjects(gLayer.textOptional, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.textPadding, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.textKeepUpright, [MGLRuntimeStylingHelper testBool]);
+ XCTAssert([gLayer.textPitchAlignment isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnum:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)]);
+ XCTAssertEqualObjects(gLayer.textRotate, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssert([gLayer.textRotationAlignment isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)]);
+ XCTAssertEqualObjects(gLayer.textSize, [MGLRuntimeStylingHelper testNumber]);
XCTAssert([gLayer.textTransform isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.textTransform, [MGLRuntimeStylingHelper testEnum:MGLTextTransformLowercase type:@encode(MGLTextTransform)]);
- XCTAssertEqualObjects(gLayer.textOffset, [MGLRuntimeStylingHelper testOffset]);
- XCTAssertEqualObjects(gLayer.textAllowOverlap, [MGLRuntimeStylingHelper testBool]);
- XCTAssertEqualObjects(gLayer.textIgnorePlacement, [MGLRuntimeStylingHelper testBool]);
- XCTAssertEqualObjects(gLayer.textOptional, [MGLRuntimeStylingHelper testBool]);
- XCTAssertEqualObjects(gLayer.iconOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconColor, [MGLRuntimeStylingHelper testColor]);
+ XCTAssertEqualObjects(gLayer.iconHaloBlur, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconHaloColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.iconHaloWidth, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.iconHaloBlur, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.iconOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconTranslate, [MGLRuntimeStylingHelper testOffset]);
XCTAssert([gLayer.iconTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.iconTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.textOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textColor, [MGLRuntimeStylingHelper testColor]);
+ XCTAssertEqualObjects(gLayer.textHaloBlur, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textHaloColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.textHaloWidth, [MGLRuntimeStylingHelper testNumber]);
- XCTAssertEqualObjects(gLayer.textHaloBlur, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.textOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textTranslate, [MGLRuntimeStylingHelper testOffset]);
XCTAssert([gLayer.textTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.textTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)]);
- layer.symbolPlacement = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)];
- layer.symbolSpacing = [MGLRuntimeStylingHelper testNumberFunction];
- layer.symbolAvoidEdges = [MGLRuntimeStylingHelper testBoolFunction];
layer.iconAllowOverlap = [MGLRuntimeStylingHelper testBoolFunction];
layer.iconIgnorePlacement = [MGLRuntimeStylingHelper testBoolFunction];
+ layer.iconImageName = [MGLRuntimeStylingHelper testStringFunction];
+ layer.iconKeepUpright = [MGLRuntimeStylingHelper testBoolFunction];
+ layer.iconOffset = [MGLRuntimeStylingHelper testOffsetFunction];
layer.iconOptional = [MGLRuntimeStylingHelper testBoolFunction];
+ layer.iconPadding = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.iconRotate = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)];
layer.iconSize = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconTextFit = [MGLRuntimeStylingHelper testEnumFunction:MGLIconTextFitBoth type:@encode(MGLIconTextFit)];
layer.iconTextFitPadding = [MGLRuntimeStylingHelper testPaddingFunction];
- layer.iconImage = [MGLRuntimeStylingHelper testStringFunction];
- layer.iconRotate = [MGLRuntimeStylingHelper testNumberFunction];
- layer.iconPadding = [MGLRuntimeStylingHelper testNumberFunction];
- layer.iconKeepUpright = [MGLRuntimeStylingHelper testBoolFunction];
- layer.iconOffset = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)];
- layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)];
+ layer.symbolAvoidEdges = [MGLRuntimeStylingHelper testBoolFunction];
+ layer.symbolPlacement = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)];
+ layer.symbolSpacing = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textAllowOverlap = [MGLRuntimeStylingHelper testBoolFunction];
+ layer.textAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)];
layer.textField = [MGLRuntimeStylingHelper testStringFunction];
layer.textFont = [MGLRuntimeStylingHelper testFontFunction];
- layer.textSize = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textMaxWidth = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textLineHeight = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textLetterSpacing = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textIgnorePlacement = [MGLRuntimeStylingHelper testBoolFunction];
layer.textJustify = [MGLRuntimeStylingHelper testEnumFunction:MGLTextJustifyRight type:@encode(MGLTextJustify)];
- layer.textAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)];
- layer.textMaxAngle = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textRotate = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textPadding = [MGLRuntimeStylingHelper testNumberFunction];
layer.textKeepUpright = [MGLRuntimeStylingHelper testBoolFunction];
- layer.textTransform = [MGLRuntimeStylingHelper testEnumFunction:MGLTextTransformLowercase type:@encode(MGLTextTransform)];
+ layer.textLetterSpacing = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textLineHeight = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textMaxAngle = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textMaxWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.textOffset = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.textAllowOverlap = [MGLRuntimeStylingHelper testBoolFunction];
- layer.textIgnorePlacement = [MGLRuntimeStylingHelper testBoolFunction];
layer.textOptional = [MGLRuntimeStylingHelper testBoolFunction];
- layer.iconOpacity = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textPadding = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)];
+ layer.textRotate = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)];
+ layer.textSize = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textTransform = [MGLRuntimeStylingHelper testEnumFunction:MGLTextTransformLowercase type:@encode(MGLTextTransform)];
layer.iconColor = [MGLRuntimeStylingHelper testColorFunction];
+ layer.iconHaloBlur = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconHaloColor = [MGLRuntimeStylingHelper testColorFunction];
layer.iconHaloWidth = [MGLRuntimeStylingHelper testNumberFunction];
- layer.iconHaloBlur = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.iconOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
layer.iconTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)];
- layer.textOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.textColor = [MGLRuntimeStylingHelper testColorFunction];
+ layer.textHaloBlur = [MGLRuntimeStylingHelper testNumberFunction];
layer.textHaloColor = [MGLRuntimeStylingHelper testColorFunction];
layer.textHaloWidth = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textHaloBlur = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.textOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.textTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
layer.textTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)];
- XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)]);
- XCTAssertEqualObjects(gLayer.symbolSpacing, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.symbolAvoidEdges, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.iconAllowOverlap, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.iconIgnorePlacement, [MGLRuntimeStylingHelper testBoolFunction]);
+ XCTAssertEqualObjects(gLayer.iconImageName, [MGLRuntimeStylingHelper testStringFunction]);
+ XCTAssertEqualObjects(gLayer.iconKeepUpright, [MGLRuntimeStylingHelper testBoolFunction]);
+ XCTAssertEqualObjects(gLayer.iconOffset, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.iconOptional, [MGLRuntimeStylingHelper testBoolFunction]);
+ XCTAssertEqualObjects(gLayer.iconPadding, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.iconRotate, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)]);
XCTAssertEqualObjects(gLayer.iconSize, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconTextFit, [MGLRuntimeStylingHelper testEnumFunction:MGLIconTextFitBoth type:@encode(MGLIconTextFit)]);
XCTAssertEqualObjects(gLayer.iconTextFitPadding, [MGLRuntimeStylingHelper testPaddingFunction]);
- XCTAssertEqualObjects(gLayer.iconImage, [MGLRuntimeStylingHelper testStringFunction]);
- XCTAssertEqualObjects(gLayer.iconRotate, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.iconPadding, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.iconKeepUpright, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.iconOffset, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)]);
- XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)]);
+ XCTAssertEqualObjects(gLayer.symbolAvoidEdges, [MGLRuntimeStylingHelper testBoolFunction]);
+ XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)]);
+ XCTAssertEqualObjects(gLayer.symbolSpacing, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textAllowOverlap, [MGLRuntimeStylingHelper testBoolFunction]);
+ XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)]);
XCTAssertEqualObjects(gLayer.textField, [MGLRuntimeStylingHelper testStringFunction]);
XCTAssertEqualObjects(gLayer.textFont, [MGLRuntimeStylingHelper testFontFunction]);
- XCTAssertEqualObjects(gLayer.textSize, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textMaxWidth, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textLineHeight, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textLetterSpacing, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textIgnorePlacement, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.textJustify, [MGLRuntimeStylingHelper testEnumFunction:MGLTextJustifyRight type:@encode(MGLTextJustify)]);
- XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)]);
- XCTAssertEqualObjects(gLayer.textMaxAngle, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textRotate, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textPadding, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textKeepUpright, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.textTransform, [MGLRuntimeStylingHelper testEnumFunction:MGLTextTransformLowercase type:@encode(MGLTextTransform)]);
+ XCTAssertEqualObjects(gLayer.textLetterSpacing, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textLineHeight, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textMaxAngle, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textMaxWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textOffset, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.textAllowOverlap, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.textIgnorePlacement, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.textOptional, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.iconOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textPadding, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)]);
+ XCTAssertEqualObjects(gLayer.textRotate, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)]);
+ XCTAssertEqualObjects(gLayer.textSize, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textTransform, [MGLRuntimeStylingHelper testEnumFunction:MGLTextTransformLowercase type:@encode(MGLTextTransform)]);
XCTAssertEqualObjects(gLayer.iconColor, [MGLRuntimeStylingHelper testColorFunction]);
+ XCTAssertEqualObjects(gLayer.iconHaloBlur, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconHaloColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.iconHaloWidth, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.iconHaloBlur, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.iconOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.iconTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.textOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textColor, [MGLRuntimeStylingHelper testColorFunction]);
+ XCTAssertEqualObjects(gLayer.textHaloBlur, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textHaloColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.textHaloWidth, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textHaloBlur, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.textOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.textTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)]);
}