summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-04-10 22:20:09 +0300
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-04-17 15:04:08 +0300
commit32376115c35567be9f0bfe4c9f7a6b3aef8b4f5b (patch)
tree9661ae7cf3dcd6c6eca1554c695b52f8007de4e8
parentd4149ea5f1d27685cbe2d19cccf67ff3ffdb613e (diff)
downloadqtlocation-mapboxgl-32376115c35567be9f0bfe4c9f7a6b3aef8b4f5b.tar.gz
[darwin] Generate style code for symbol-sort-key
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h28
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.mm19
-rw-r--r--platform/darwin/test/MGLSymbolStyleLayerTests.mm71
3 files changed, 116 insertions, 2 deletions
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index 5c12b28544..f5047745f6 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -158,6 +158,11 @@ typedef NS_ENUM(NSUInteger, MGLSymbolPlacement) {
*/
typedef NS_ENUM(NSUInteger, MGLSymbolZOrder) {
/**
+ If `MGLSymbolStyleLayer.symbolSortKey` is set, sort based on that.
+ Otherwise sort symbols by their position relative to the viewport.
+ */
+ MGLSymbolZOrderAuto,
+ /**
Specify this z order if symbols’ appearance relies on lower features
overlapping higher features. For example, symbols with a pin-like
appearance would require this z order.
@@ -1019,6 +1024,23 @@ MGL_EXPORT
@property (nonatomic, null_resettable) NSExpression *symbolPlacement;
/**
+ Sorts features in ascending order based on this value. Features with a higher
+ sort key will appear above features with a lower sort key wehn they overlap.
+ Features with a lower sort key will have priority over other features when
+ doing placement.
+
+ You can set this property to an expression containing any of the following:
+
+ * Constant numeric values
+ * Predefined functions, including mathematical and string operators
+ * Conditional expressions
+ * Variable assignments and references to assigned variables
+ * Interpolation and step functions applied to the `$zoomLevel` variable and/or
+ feature attributes
+ */
+@property (nonatomic, null_resettable) NSExpression *symbolSortKey;
+
+/**
Distance between two symbol anchors.
This property is measured in points.
@@ -1045,13 +1067,15 @@ MGL_EXPORT
/**
Controls the order in which overlapping symbols in the same layer are rendered
- The default value of this property is an expression that evaluates to
- `viewport-y`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an expression that evaluates to `auto`.
+ Set this property to `nil` to reset it to the default value.
You can set this property to an expression containing any of the following:
* Constant `MGLSymbolZOrder` values
* Any of the following constant string values:
+ * `auto`: If `symbol-sort-key` is set, sort based on that. Otherwise sort
+ symbols by their position relative to the viewport.
* `viewport-y`: Specify this z order if symbols’ appearance relies on lower
features overlapping higher features. For example, symbols with a pin-like
appearance would require this z order.
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm
index 6d91bbe87f..e54a0b9a15 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.mm
+++ b/platform/darwin/src/MGLSymbolStyleLayer.mm
@@ -54,6 +54,7 @@ namespace mbgl {
});
MBGL_DEFINE_ENUM(MGLSymbolZOrder, {
+ { MGLSymbolZOrderAuto, "auto" },
{ MGLSymbolZOrderViewportY, "viewport-y" },
{ MGLSymbolZOrderSource, "source" },
});
@@ -587,6 +588,24 @@ namespace mbgl {
return MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *, mbgl::style::SymbolPlacementType, MGLSymbolPlacement>().toExpression(propertyValue);
}
+- (void)setSymbolSortKey:(NSExpression *)symbolSortKey {
+ MGLAssertStyleLayerIsValid();
+ MGLLogDebug(@"Setting symbolSortKey: %@", symbolSortKey);
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(symbolSortKey, true);
+ self.rawLayer->setSymbolSortKey(mbglValue);
+}
+
+- (NSExpression *)symbolSortKey {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getSymbolSortKey();
+ if (propertyValue.isUndefined()) {
+ propertyValue = self.rawLayer->getDefaultSymbolSortKey();
+ }
+ return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue);
+}
+
- (void)setSymbolSpacing:(NSExpression *)symbolSpacing {
MGLAssertStyleLayerIsValid();
MGLLogDebug(@"Setting symbolSpacing: %@", symbolSpacing);
diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm
index 083b12bcc3..87091acc1b 100644
--- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm
+++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm
@@ -1003,6 +1003,75 @@
XCTAssertThrowsSpecificNamed(layer.symbolPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes.");
}
+ // symbol-sort-key
+ {
+ XCTAssertTrue(rawLayer->getSymbolSortKey().isUndefined(),
+ @"symbol-sort-key should be unset initially.");
+ NSExpression *defaultExpression = layer.symbolSortKey;
+
+ NSExpression *constantExpression = [NSExpression expressionWithFormat:@"1"];
+ layer.symbolSortKey = constantExpression;
+ mbgl::style::PropertyValue<float> propertyValue = { 1.0 };
+ XCTAssertEqual(rawLayer->getSymbolSortKey(), propertyValue,
+ @"Setting symbolSortKey to a constant value expression should update symbol-sort-key.");
+ XCTAssertEqualObjects(layer.symbolSortKey, constantExpression,
+ @"symbolSortKey should round-trip constant value expressions.");
+
+ constantExpression = [NSExpression expressionWithFormat:@"1"];
+ NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}];
+ layer.symbolSortKey = functionExpression;
+
+ {
+ using namespace mbgl::style::expression::dsl;
+ propertyValue = mbgl::style::PropertyExpression<float>(
+ step(zoom(), literal(1.0), 18.0, literal(1.0))
+ );
+ }
+
+ XCTAssertEqual(rawLayer->getSymbolSortKey(), propertyValue,
+ @"Setting symbolSortKey to a camera expression should update symbol-sort-key.");
+ XCTAssertEqualObjects(layer.symbolSortKey, functionExpression,
+ @"symbolSortKey should round-trip camera expressions.");
+
+ functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}];
+ layer.symbolSortKey = functionExpression;
+
+ {
+ using namespace mbgl::style::expression::dsl;
+ propertyValue = mbgl::style::PropertyExpression<float>(
+ interpolate(linear(), number(get("keyName")), 18.0, literal(1.0))
+ );
+ }
+
+ XCTAssertEqual(rawLayer->getSymbolSortKey(), propertyValue,
+ @"Setting symbolSortKey to a data expression should update symbol-sort-key.");
+ NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}];
+ XCTAssertEqualObjects(layer.symbolSortKey, pedanticFunctionExpression,
+ @"symbolSortKey should round-trip data expressions.");
+
+ functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}];
+ layer.symbolSortKey = functionExpression;
+
+ {
+ using namespace mbgl::style::expression::dsl;
+ propertyValue = mbgl::style::PropertyExpression<float>(
+ interpolate(linear(), zoom(), 10.0, interpolate(linear(), number(get("keyName")), 18.0, literal(1.0)))
+ );
+ }
+
+ XCTAssertEqual(rawLayer->getSymbolSortKey(), propertyValue,
+ @"Setting symbolSortKey to a camera-data expression should update symbol-sort-key.");
+ pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}];
+ XCTAssertEqualObjects(layer.symbolSortKey, pedanticFunctionExpression,
+ @"symbolSortKey should round-trip camera-data expressions.");
+
+ layer.symbolSortKey = nil;
+ XCTAssertTrue(rawLayer->getSymbolSortKey().isUndefined(),
+ @"Unsetting symbolSortKey should return symbol-sort-key to the default value.");
+ XCTAssertEqualObjects(layer.symbolSortKey, defaultExpression,
+ @"symbolSortKey should return the default value after being unset.");
+ }
+
// symbol-spacing
{
XCTAssertTrue(rawLayer->getSymbolSpacing().isUndefined(),
@@ -2994,6 +3063,7 @@
[self testPropertyName:@"maximum-text-width" isBoolean:NO];
[self testPropertyName:@"symbol-avoids-edges" isBoolean:YES];
[self testPropertyName:@"symbol-placement" isBoolean:NO];
+ [self testPropertyName:@"symbol-sort-key" isBoolean:NO];
[self testPropertyName:@"symbol-spacing" isBoolean:NO];
[self testPropertyName:@"symbol-z-order" isBoolean:NO];
[self testPropertyName:@"text" isBoolean:NO];
@@ -3053,6 +3123,7 @@
XCTAssertEqual([NSValue valueWithMGLSymbolPlacement:MGLSymbolPlacementPoint].MGLSymbolPlacementValue, MGLSymbolPlacementPoint);
XCTAssertEqual([NSValue valueWithMGLSymbolPlacement:MGLSymbolPlacementLine].MGLSymbolPlacementValue, MGLSymbolPlacementLine);
XCTAssertEqual([NSValue valueWithMGLSymbolPlacement:MGLSymbolPlacementLineCenter].MGLSymbolPlacementValue, MGLSymbolPlacementLineCenter);
+ XCTAssertEqual([NSValue valueWithMGLSymbolZOrder:MGLSymbolZOrderAuto].MGLSymbolZOrderValue, MGLSymbolZOrderAuto);
XCTAssertEqual([NSValue valueWithMGLSymbolZOrder:MGLSymbolZOrderViewportY].MGLSymbolZOrderValue, MGLSymbolZOrderViewportY);
XCTAssertEqual([NSValue valueWithMGLSymbolZOrder:MGLSymbolZOrderSource].MGLSymbolZOrderValue, MGLSymbolZOrderSource);
XCTAssertEqual([NSValue valueWithMGLTextAnchor:MGLTextAnchorCenter].MGLTextAnchorValue, MGLTextAnchorCenter);