diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-04-10 22:20:09 +0300 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-04-17 15:04:08 +0300 |
commit | 32376115c35567be9f0bfe4c9f7a6b3aef8b4f5b (patch) | |
tree | 9661ae7cf3dcd6c6eca1554c695b52f8007de4e8 | |
parent | d4149ea5f1d27685cbe2d19cccf67ff3ffdb613e (diff) | |
download | qtlocation-mapboxgl-32376115c35567be9f0bfe4c9f7a6b3aef8b4f5b.tar.gz |
[darwin] Generate style code for symbol-sort-key
-rw-r--r-- | platform/darwin/src/MGLSymbolStyleLayer.h | 28 | ||||
-rw-r--r-- | platform/darwin/src/MGLSymbolStyleLayer.mm | 19 | ||||
-rw-r--r-- | platform/darwin/test/MGLSymbolStyleLayerTests.mm | 71 |
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); |