diff options
author | Anand Thakker <anandthakker@users.noreply.github.com> | 2017-04-06 15:29:59 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-06 15:29:59 -0400 |
commit | 693c9f3641b3189b4cd439049904c95a516ae609 (patch) | |
tree | 8341a16f57ff184a2fe9e085c490e8762eb206ce /platform | |
parent | f9cc044357d60dd5cf15ba951384529f88802089 (diff) | |
download | qtlocation-mapboxgl-693c9f3641b3189b4cd439049904c95a516ae609.tar.gz |
[core] Add DDS support for {text,icon}-size (#8593)
* Update gl-js and generate style code
* Factor out packUint8Pair() helper function
* Draft implementation of DDS for {text,icon}-size
Ports https://github.com/mapbox/mapbox-gl-js/pull/4455
* Fix text-size/composite-function-line-placement test
* Refactor to PaintPropertyBinders-like strategy
* Dedupe gl::Program construction
* Use exponential function base for interpolation
* Dedupe coveringZoomStops method
* Fixup tests
* Fix CI errors (hidden within #if block)
Diffstat (limited to 'platform')
5 files changed, 294 insertions, 24 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java index 269a777050..e37245000e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java @@ -1526,11 +1526,11 @@ public class PropertyFactory { /** * Scale factor for icon. 1 is original size, 3 triples the size. * - * @param <Z> the zoom parameter type - * @param function a wrapper {@link CameraFunction} for Float + * @param <T> the function input type + * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> iconSize(CameraFunction<Z, Float> function) { + public static <T> PropertyValue<Function<T, Float>> iconSize(Function<T, Float> function) { return new LayoutPropertyValue<>("icon-size", function); } @@ -1802,11 +1802,11 @@ public class PropertyFactory { /** * Font size. * - * @param <Z> the zoom parameter type - * @param function a wrapper {@link CameraFunction} for Float + * @param <T> the function input type + * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textSize(CameraFunction<Z, Float> function) { + public static <T> PropertyValue<Function<T, Float>> textSize(Function<T, Float> function) { return new LayoutPropertyValue<>("text-size", function); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java index e8af375d66..d81965f2c9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java @@ -383,6 +383,114 @@ public class SymbolLayerTest extends BaseStyleTest { @Test + public void testIconSizeAsIdentitySourceFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("icon-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize(property("FeaturePropertyA", Stops.<Float>identity())) + ); + + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getIconSize().getFunction().getStops().getClass()); + } + + @Test + public void testIconSizeAsExponentialSourceFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("icon-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, iconSize(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); + } + + @Test + public void testIconSizeAsCategoricalSourceFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("icon-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, iconSize(0.3f)) + ) + ).withDefaultValue(iconSize(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(SourceFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getIconSize().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconSize().getFunction()).getDefaultValue().getValue()); + } + + @Test + public void testIconSizeAsCompositeFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("icon-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + iconSize( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, iconSize(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(iconSize(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getIconSize()); + assertNotNull(layer.getIconSize().getFunction()); + assertEquals(CompositeFunction.class, layer.getIconSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getIconSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getIconSize().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getIconSize().getFunction().getStops()).size()); + + ExponentialStops<Stop.CompositeValue<Float, Float>, Float> stops = + (ExponentialStops<Stop.CompositeValue<Float, Float>, Float>) layer.getIconSize().getFunction().getStops(); + Stop<Stop.CompositeValue<Float, Float>, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + + @Test public void testIconTextFitAsConstant() { checkViewIsDisplayed(R.id.mapView); Timber.i("icon-text-fit"); @@ -1075,6 +1183,114 @@ public class SymbolLayerTest extends BaseStyleTest { @Test + public void testTextSizeAsIdentitySourceFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("text-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + textSize(property("FeaturePropertyA", Stops.<Float>identity())) + ); + + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(IdentityStops.class, layer.getTextSize().getFunction().getStops().getClass()); + } + + @Test + public void testTextSizeAsExponentialSourceFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("text-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + property( + "FeaturePropertyA", + exponential( + stop(0.3f, textSize(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); + } + + @Test + public void testTextSizeAsCategoricalSourceFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("text-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + property( + "FeaturePropertyA", + categorical( + stop(1.0f, textSize(0.3f)) + ) + ).withDefaultValue(textSize(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(SourceFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(CategoricalStops.class, layer.getTextSize().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextSize().getFunction()).getDefaultValue().getValue()); + } + + @Test + public void testTextSizeAsCompositeFunction() { + checkViewIsDisplayed(R.id.mapView); + Timber.i("text-size"); + assertNotNull(layer); + + // Set + layer.setProperties( + textSize( + composite( + "FeaturePropertyA", + exponential( + stop(0, 0.3f, textSize(0.9f)) + ).withBase(0.5f) + ).withDefaultValue(textSize(0.3f)) + ) + ); + + // Verify + assertNotNull(layer.getTextSize()); + assertNotNull(layer.getTextSize().getFunction()); + assertEquals(CompositeFunction.class, layer.getTextSize().getFunction().getClass()); + assertEquals("FeaturePropertyA", ((CompositeFunction) layer.getTextSize().getFunction()).getProperty()); + assertEquals(ExponentialStops.class, layer.getTextSize().getFunction().getStops().getClass()); + assertEquals(1, ((ExponentialStops) layer.getTextSize().getFunction().getStops()).size()); + + ExponentialStops<Stop.CompositeValue<Float, Float>, Float> stops = + (ExponentialStops<Stop.CompositeValue<Float, Float>, Float>) layer.getTextSize().getFunction().getStops(); + Stop<Stop.CompositeValue<Float, Float>, Float> stop = stops.iterator().next(); + assertEquals(0f, stop.in.zoom, 0.001); + assertEquals(0.3f, stop.in.value, 0.001f); + assertEquals(0.9f, stop.out, 0.001f); + } + + @Test public void testTextMaxWidthAsConstant() { checkViewIsDisplayed(R.id.mapView); Timber.i("text-max-width"); diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h index 2c32b36c31..7040610093 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ b/platform/darwin/src/MGLSymbolStyleLayer.h @@ -537,6 +537,15 @@ MGL_EXPORT * `MGLCameraStyleFunction` with an interpolation mode of: * `MGLInterpolationModeExponential` * `MGLInterpolationModeInterval` + * `MGLSourceStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` + * `MGLInterpolationModeIdentity` + * `MGLCompositeStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` */ @property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconScale; @@ -919,6 +928,15 @@ MGL_EXPORT * `MGLCameraStyleFunction` with an interpolation mode of: * `MGLInterpolationModeExponential` * `MGLInterpolationModeInterval` + * `MGLSourceStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` + * `MGLInterpolationModeIdentity` + * `MGLCompositeStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + * `MGLInterpolationModeCategorical` */ @property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textFontSize; diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index c01877f8dc..0f7953311e 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -356,7 +356,7 @@ namespace mbgl { - (void)setIconScale:(MGLStyleValue<NSNumber *> *)iconScale { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(iconScale); + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(iconScale); self.rawLayer->setIconSize(mbglValue); } @@ -365,9 +365,9 @@ namespace mbgl { auto propertyValue = self.rawLayer->getIconSize(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultIconSize()); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultIconSize()); } - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue); } - (void)setIconSize:(MGLStyleValue<NSNumber *> *)iconSize { @@ -657,7 +657,7 @@ namespace mbgl { - (void)setTextFontSize:(MGLStyleValue<NSNumber *> *)textFontSize { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(textFontSize); + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenPropertyValue(textFontSize); self.rawLayer->setTextSize(mbglValue); } @@ -666,9 +666,9 @@ namespace mbgl { auto propertyValue = self.rawLayer->getTextSize(); if (propertyValue.isUndefined()) { - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultTextSize()); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(self.rawLayer->getDefaultTextSize()); } - return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); + return MGLStyleValueTransformer<float, NSNumber *>().toDataDrivenStyleValue(propertyValue); } - (void)setTextSize:(MGLStyleValue<NSNumber *> *)textSize { diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index eee61dd5d7..367ebf363c 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -405,7 +405,7 @@ MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.iconScale = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getIconSize(), propertyValue, @"Setting iconScale to a constant value should update icon-size."); XCTAssertEqualObjects(layer.iconScale, constantStyleValue, @@ -422,6 +422,29 @@ XCTAssertEqualObjects(layer.iconScale, functionStyleValue, @"iconScale should round-trip camera functions."); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.iconScale = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getIconSize(), propertyValue, + @"Setting iconScale to a source function should update icon-size."); + XCTAssertEqualObjects(layer.iconScale, functionStyleValue, + @"iconScale should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.iconScale = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getIconSize(), propertyValue, + @"Setting iconScale to a composite function should update icon-size."); + XCTAssertEqualObjects(layer.iconScale, functionStyleValue, + @"iconScale should round-trip composite functions."); layer.iconScale = nil; @@ -429,11 +452,6 @@ @"Unsetting iconScale should return icon-size to the default value."); XCTAssertEqualObjects(layer.iconScale, defaultStyleValue, @"iconScale should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.iconScale = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.iconScale = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // icon-text-fit @@ -952,7 +970,7 @@ MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.textFontSize = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getTextSize(), propertyValue, @"Setting textFontSize to a constant value should update text-size."); XCTAssertEqualObjects(layer.textFontSize, constantStyleValue, @@ -969,6 +987,29 @@ XCTAssertEqualObjects(layer.textFontSize, functionStyleValue, @"textFontSize should round-trip camera functions."); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.textFontSize = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getTextSize(), propertyValue, + @"Setting textFontSize to a source function should update text-size."); + XCTAssertEqualObjects(layer.textFontSize, functionStyleValue, + @"textFontSize should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.textFontSize = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getTextSize(), propertyValue, + @"Setting textFontSize to a composite function should update text-size."); + XCTAssertEqualObjects(layer.textFontSize, functionStyleValue, + @"textFontSize should round-trip composite functions."); layer.textFontSize = nil; @@ -976,11 +1017,6 @@ @"Unsetting textFontSize should return text-size to the default value."); XCTAssertEqualObjects(layer.textFontSize, defaultStyleValue, @"textFontSize should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textFontSize = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textFontSize = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-ignore-placement |