diff --git a/package.json b/package.json index 4037efe63..0f571c3dd 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "express": "^4.11.1", "lodash": "^4.16.4", "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#b51b85ffb8c512e228c36c5405293ce51d123519", - "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#deb30918f8637e7675a00731b799a5caec894b17", + "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#49e8b407bdbbe6f7c92dbcb56d3d51f425fc2653", "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#9252ffc5108131704b5acf52d78258ac05687871", "mkdirp": "^0.5.1", "node-cmake": "^1.2.1", diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java index 7df2421c5..d46414a35 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java @@ -196,6 +196,52 @@ public class CircleLayer extends Layer { return (PropertyValue) new PropertyValue(nativeGetCirclePitchScale()); } + /** + * Get the CircleStrokeWidth property + * + * @return property wrapper value around Float + */ + @SuppressWarnings("unchecked") + public PropertyValue getCircleStrokeWidth() { + return (PropertyValue) new PropertyValue(nativeGetCircleStrokeWidth()); + } + + /** + * Get the CircleStrokeColor property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue getCircleStrokeColor() { + return (PropertyValue) new PropertyValue(nativeGetCircleStrokeColor()); + } + /** + * The stroke color of the circle. + * + * @return int representation of a rgba string color + * @throws RuntimeException thrown if property isn't a value + */ + @ColorInt + public int getCircleStrokeColorAsInt() { + PropertyValue value = getCircleStrokeColor(); + if (value.isValue()) { + return rgbaToColor(value.getValue()); + } else { + throw new RuntimeException("circle-stroke-color was set as a Function"); + } + } + + + /** + * Get the CircleStrokeOpacity property + * + * @return property wrapper value around Float + */ + @SuppressWarnings("unchecked") + public PropertyValue getCircleStrokeOpacity() { + return (PropertyValue) new PropertyValue(nativeGetCircleStrokeOpacity()); + } + private native Object nativeGetCircleRadius(); private native Object nativeGetCircleColor(); @@ -210,6 +256,12 @@ public class CircleLayer extends Layer { private native Object nativeGetCirclePitchScale(); + private native Object nativeGetCircleStrokeWidth(); + + private native Object nativeGetCircleStrokeColor(); + + private native Object nativeGetCircleStrokeOpacity(); + @Override protected native void finalize() throws Throwable; 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 7a0b74f4f..d24dd541d 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 @@ -871,6 +871,76 @@ public class PropertyFactory { return new PaintProperty<>("circle-pitch-scale", function); } + /** + * The width of the circle's stroke. Strokes are placed outside of the "circle-radius". + * + * @param value a Float value + * @return property wrapper around Float + */ + public static Property circleStrokeWidth(Float value) { + return new PaintProperty<>("circle-stroke-width", value); + } + + /** + * The width of the circle's stroke. Strokes are placed outside of the "circle-radius". + * + * @param function a wrapper function for Float + * @return property wrapper around a Float function + */ + public static Property> circleStrokeWidth(Function function) { + return new PaintProperty<>("circle-stroke-width", function); + } + + /** + * The stroke color of the circle. + * + * @param value a int color value + * @return property wrapper around String color + */ + public static Property circleStrokeColor(@ColorInt int value) { + return new PaintProperty<>("circle-stroke-color", colorToRgbaString(value)); + } + + /** + * The stroke color of the circle. + * + * @param value a String value + * @return property wrapper around String + */ + public static Property circleStrokeColor(String value) { + return new PaintProperty<>("circle-stroke-color", value); + } + + /** + * The stroke color of the circle. + * + * @param function a wrapper function for String + * @return property wrapper around a String function + */ + public static Property> circleStrokeColor(Function function) { + return new PaintProperty<>("circle-stroke-color", function); + } + + /** + * The opacity of the circle's stroke. + * + * @param value a Float value + * @return property wrapper around Float + */ + public static Property circleStrokeOpacity(Float value) { + return new PaintProperty<>("circle-stroke-opacity", value); + } + + /** + * The opacity of the circle's stroke. + * + * @param function a wrapper function for Float + * @return property wrapper around a Float function + */ + public static Property> circleStrokeOpacity(Function function) { + return new PaintProperty<>("circle-stroke-opacity", function); + } + /** * The opacity at which the image will be drawn. * diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java index 8ee340b6b..e7be929d2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java @@ -245,6 +245,94 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP); } + @Test + public void testCircleStrokeWidth() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new CircleLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Timber.i("circle-stroke-width"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleStrokeWidth(0.3f)); + assertEquals((Float) layer.getCircleStrokeWidth().getValue(), (Float) 0.3f); + } + + @Test + public void testCircleStrokeColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new CircleLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Timber.i("circle-stroke-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleStrokeColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getCircleStrokeColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testCircleStrokeColorAsInt() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new CircleLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Timber.i("circle-stroke-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleStrokeColor(Color.RED)); + assertEquals(layer.getCircleStrokeColorAsInt(), Color.RED); + } + + @Test + public void testCircleStrokeOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new CircleLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Timber.i("circle-stroke-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleStrokeOpacity(0.3f)); + assertEquals((Float) layer.getCircleStrokeOpacity().getValue(), (Float) 0.3f); + } + @After public void unregisterIntentServiceIdlingResource() { diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index a19cc7c9b..bcfd6bc0d 100644 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -221,8 +221,8 @@ const layerJava = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidS const layerJavaUnitTests = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs', 'utf8'), {strict: true}); for (const layer of layers) { - writeIfModified(`platform/android/src/style/layers/${layer.type}_layer.hpp`, layerHpp(layer)); - writeIfModified(`platform/android/src/style/layers/${layer.type}_layer.cpp`, layerCpp(layer)); + writeIfModified(`platform/android/src/style/layers/${layer.type.replace('-', '_')}_layer.hpp`, layerHpp(layer)); + writeIfModified(`platform/android/src/style/layers/${layer.type.replace('-', '_')}_layer.cpp`, layerCpp(layer)); writeIfModified(`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/${camelize(layer.type)}Layer.java`, layerJava(layer)); writeIfModified(`platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/${camelize(layer.type)}LayerTest.java`, layerJavaUnitTests(layer)); } diff --git a/platform/android/src/style/layers/circle_layer.cpp b/platform/android/src/style/layers/circle_layer.cpp index 7320d8d04..4a6ba95d3 100644 --- a/platform/android/src/style/layers/circle_layer.cpp +++ b/platform/android/src/style/layers/circle_layer.cpp @@ -63,6 +63,24 @@ namespace android { return jni::Object(*converted); } + jni::Object CircleLayer::getCircleStrokeWidth(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleStrokeWidth()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleStrokeColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleStrokeColor()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleStrokeOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleStrokeOpacity()); + return jni::Object(*converted); + } + jni::Class CircleLayer::javaClass; jni::jobject* CircleLayer::createJavaPeer(jni::JNIEnv& env) { @@ -88,7 +106,10 @@ namespace android { METHOD(&CircleLayer::getCircleOpacity, "nativeGetCircleOpacity"), METHOD(&CircleLayer::getCircleTranslate, "nativeGetCircleTranslate"), METHOD(&CircleLayer::getCircleTranslateAnchor, "nativeGetCircleTranslateAnchor"), - METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale")); + METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale"), + METHOD(&CircleLayer::getCircleStrokeWidth, "nativeGetCircleStrokeWidth"), + METHOD(&CircleLayer::getCircleStrokeColor, "nativeGetCircleStrokeColor"), + METHOD(&CircleLayer::getCircleStrokeOpacity, "nativeGetCircleStrokeOpacity")); } } // namespace android diff --git a/platform/android/src/style/layers/circle_layer.hpp b/platform/android/src/style/layers/circle_layer.hpp index 072d0951b..d45984f23 100644 --- a/platform/android/src/style/layers/circle_layer.hpp +++ b/platform/android/src/style/layers/circle_layer.hpp @@ -39,6 +39,12 @@ public: jni::Object getCirclePitchScale(jni::JNIEnv&); + jni::Object getCircleStrokeWidth(jni::JNIEnv&); + + jni::Object getCircleStrokeColor(jni::JNIEnv&); + + jni::Object getCircleStrokeOpacity(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); }; // class CircleLayer diff --git a/platform/android/src/style/layers/layer.hpp.ejs b/platform/android/src/style/layers/layer.hpp.ejs index 004e5794a..3d715746f 100644 --- a/platform/android/src/style/layers/layer.hpp.ejs +++ b/platform/android/src/style/layers/layer.hpp.ejs @@ -7,7 +7,7 @@ #pragma once #include "layer.hpp" -#include _layer.hpp> +#include _layer.hpp> #include namespace mbgl { diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h index 2d88a664b..8c95b7212 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.h +++ b/platform/darwin/src/MGLCircleStyleLayer.h @@ -94,6 +94,38 @@ typedef NS_ENUM(NSUInteger, MGLCircleTranslateAnchor) { */ @property (nonatomic, null_resettable) MGLStyleValue *circleRadius; +#if TARGET_OS_IPHONE +/** + The stroke color of the circle. + + The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value. + */ +@property (nonatomic, null_resettable) MGLStyleValue *circleStrokeColor; +#else +/** + The stroke color of the circle. + + The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value. + */ +@property (nonatomic, null_resettable) MGLStyleValue *circleStrokeColor; +#endif + +/** + The opacity of the circle's stroke. + + 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 *circleStrokeOpacity; + +/** + The width of the circle's stroke. Strokes are placed outside of the `circleRadius`. + + 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. + */ +@property (nonatomic, null_resettable) MGLStyleValue *circleStrokeWidth; + /** The geometry's offset. diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm index 91f91a7bc..781682d4d 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ b/platform/darwin/src/MGLCircleStyleLayer.mm @@ -187,6 +187,48 @@ namespace mbgl { return MGLStyleValueTransformer().toStyleValue(propertyValue); } +- (void)setCircleStrokeColor:(MGLStyleValue *)circleStrokeColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer().toPropertyValue(circleStrokeColor); + _rawLayer->setCircleStrokeColor(mbglValue); +} + +- (MGLStyleValue *)circleStrokeColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = _rawLayer->getCircleStrokeColor() ?: _rawLayer->getDefaultCircleStrokeColor(); + return MGLStyleValueTransformer().toStyleValue(propertyValue); +} + +- (void)setCircleStrokeOpacity:(MGLStyleValue *)circleStrokeOpacity { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer().toPropertyValue(circleStrokeOpacity); + _rawLayer->setCircleStrokeOpacity(mbglValue); +} + +- (MGLStyleValue *)circleStrokeOpacity { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = _rawLayer->getCircleStrokeOpacity() ?: _rawLayer->getDefaultCircleStrokeOpacity(); + return MGLStyleValueTransformer().toStyleValue(propertyValue); +} + +- (void)setCircleStrokeWidth:(MGLStyleValue *)circleStrokeWidth { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer().toPropertyValue(circleStrokeWidth); + _rawLayer->setCircleStrokeWidth(mbglValue); +} + +- (MGLStyleValue *)circleStrokeWidth { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = _rawLayer->getCircleStrokeWidth() ?: _rawLayer->getDefaultCircleStrokeWidth(); + return MGLStyleValueTransformer().toStyleValue(propertyValue); +} + - (void)setCircleTranslate:(MGLStyleValue *)circleTranslate { MGLAssertStyleLayerIsValid(); diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs index c89912c1f..82d8a2561 100644 --- a/platform/darwin/src/MGLStyleLayer.mm.ejs +++ b/platform/darwin/src/MGLStyleLayer.mm.ejs @@ -14,7 +14,7 @@ #import "MGLStyleValue_Private.h" #import "MGL<%- camelize(type) %>StyleLayer.h" -#include _layer.hpp> +#include _layer.hpp> <% if (containsEnumerationProperties) { -%> namespace mbgl { diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.m b/platform/darwin/test/MGLCircleStyleLayerTests.m index 432d3ffa7..6f90f2c24 100644 --- a/platform/darwin/test/MGLCircleStyleLayerTests.m +++ b/platform/darwin/test/MGLCircleStyleLayerTests.m @@ -21,6 +21,9 @@ layer.circleOpacity = [MGLRuntimeStylingHelper testNumber]; layer.circlePitchScale = [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]; layer.circleRadius = [MGLRuntimeStylingHelper testNumber]; + layer.circleStrokeColor = [MGLRuntimeStylingHelper testColor]; + layer.circleStrokeOpacity = [MGLRuntimeStylingHelper testNumber]; + layer.circleStrokeWidth = [MGLRuntimeStylingHelper testNumber]; layer.circleTranslate = [MGLRuntimeStylingHelper testOffset]; layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]; @@ -32,6 +35,9 @@ XCTAssert([gLayer.circlePitchScale isKindOfClass:[MGLStyleConstantValue class]]); XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]); XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumber]); + XCTAssertEqualObjects(gLayer.circleStrokeColor, [MGLRuntimeStylingHelper testColor]); + XCTAssertEqualObjects(gLayer.circleStrokeOpacity, [MGLRuntimeStylingHelper testNumber]); + XCTAssertEqualObjects(gLayer.circleStrokeWidth, [MGLRuntimeStylingHelper testNumber]); XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffset]); XCTAssert([gLayer.circleTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]); XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]); @@ -41,6 +47,9 @@ layer.circleOpacity = [MGLRuntimeStylingHelper testNumberFunction]; layer.circlePitchScale = [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]; layer.circleRadius = [MGLRuntimeStylingHelper testNumberFunction]; + layer.circleStrokeColor = [MGLRuntimeStylingHelper testColorFunction]; + layer.circleStrokeOpacity = [MGLRuntimeStylingHelper testNumberFunction]; + layer.circleStrokeWidth = [MGLRuntimeStylingHelper testNumberFunction]; layer.circleTranslate = [MGLRuntimeStylingHelper testOffsetFunction]; layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]; @@ -49,6 +58,9 @@ XCTAssertEqualObjects(gLayer.circleOpacity, [MGLRuntimeStylingHelper testNumberFunction]); XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]); XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumberFunction]); + XCTAssertEqualObjects(gLayer.circleStrokeColor, [MGLRuntimeStylingHelper testColorFunction]); + XCTAssertEqualObjects(gLayer.circleStrokeOpacity, [MGLRuntimeStylingHelper testNumberFunction]); + XCTAssertEqualObjects(gLayer.circleStrokeWidth, [MGLRuntimeStylingHelper testNumberFunction]); XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffsetFunction]); XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]); }