From 10b2cc60a7b274f71b46976b1e9e89031b9e44ca Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Tue, 26 Jul 2016 17:02:52 -0400 Subject: [android] #5610 - Runtime style api - part 2 --- .../com/mapbox/mapboxsdk/layers/CustomLayer.java | 23 - .../com/mapbox/mapboxsdk/layers/package-info.java | 4 - .../java/com/mapbox/mapboxsdk/maps/MapView.java | 29 - .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 45 +- .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 14 +- .../mapboxsdk/style/layers/BackgroundLayer.java | 27 + .../mapbox/mapboxsdk/style/layers/CircleLayer.java | 62 ++ .../mapbox/mapboxsdk/style/layers/CustomLayer.java | 30 + .../mapbox/mapboxsdk/style/layers/FillLayer.java | 62 ++ .../mapbox/mapboxsdk/style/layers/Function.java | 85 ++ .../com/mapbox/mapboxsdk/style/layers/Layer.java | 64 +- .../mapbox/mapboxsdk/style/layers/LineLayer.java | 118 ++ .../mapbox/mapboxsdk/style/layers/Property.java | 11 + .../mapboxsdk/style/layers/PropertyFactory.java | 903 +++++++++++++++- .../mapboxsdk/style/layers/PropertyValue.java | 56 + .../mapbox/mapboxsdk/style/layers/RasterLayer.java | 60 ++ .../mapbox/mapboxsdk/style/layers/SymbolLayer.java | 390 +++++++ .../mapbox/mapboxsdk/style/layers/layer.java.ejs | 63 ++ .../mapboxsdk/style/layers/property.java.ejs | 53 + .../style/layers/property_factory.java.ejs | 78 ++ .../mapboxsdk/style/sources/RasterSource.java | 16 + .../mapbox/mapboxsdk/style/sources/TileSet.java | 290 +++++ .../mapboxsdk/style/sources/VectorSource.java | 6 +- .../mapboxsdk/style/BackgroundLayerTest.java | 120 +++ .../mapbox/mapboxsdk/style/CircleLayerTest.java | 232 ++++ .../com/mapbox/mapboxsdk/style/FillLayerTest.java | 232 ++++ .../com/mapbox/mapboxsdk/style/LineLayerTest.java | 386 +++++++ .../mapbox/mapboxsdk/style/RasterLayerTest.java | 232 ++++ .../style/RuntimeStyleBackgroundLayerTest.java | 61 ++ .../mapbox/mapboxsdk/style/RuntimeStyleTests.java | 91 ++ .../mapboxsdk/style/RuntimeStyleTimingTests.java | 54 + .../mapbox/mapboxsdk/style/SymbolLayerTest.java | 1134 ++++++++++++++++++++ .../com/mapbox/mapboxsdk/style/layer.junit.ejs | 116 ++ .../espresso/utils/OnMapReadyIdlingResource.java | 51 + .../src/main/AndroidManifest.xml | 5 + .../testapp/activity/FeatureOverviewActivity.java | 12 +- .../activity/customlayer/CustomLayerActivity.java | 13 +- .../activity/style/RuntimeStyleActivity.java | 86 +- .../activity/style/RuntimeStyleTestActivity.java | 69 ++ .../style/RuntimeStyleTimingTestActivity.java | 87 ++ .../src/main/res/menu/menu_runtime_style.xml | 8 + .../mapboxsdk/style/layers/FunctionTest.java | 29 + platform/android/platform.gyp | 1 + platform/android/scripts/generate-style-code.js | 124 ++- platform/android/scripts/layer.cpp.ejs | 64 -- platform/android/scripts/layer.hpp.ejs | 38 - platform/android/scripts/layer.java.ejs | 44 - platform/android/scripts/layer_property.java.ejs | 42 - .../scripts/layer_property_factory.java.ejs | 45 - platform/android/src/conversion/constant.hpp | 95 ++ platform/android/src/conversion/conversion.hpp | 50 + platform/android/src/jni.cpp | 38 - platform/android/src/style/android_conversion.hpp | 8 +- platform/android/src/style/conversion/function.hpp | 52 + .../src/style/conversion/property_value.hpp | 38 + platform/android/src/style/conversion/types.hpp | 98 ++ .../android/src/style/conversion/types.hpp.ejs | 40 + .../src/style/conversion/types_string_values.hpp | 209 ++++ .../style/conversion/types_string_values.hpp.ejs | 48 + .../android/src/style/layers/background_layer.cpp | 35 +- .../android/src/style/layers/background_layer.hpp | 10 +- platform/android/src/style/layers/circle_layer.cpp | 63 +- platform/android/src/style/layers/circle_layer.hpp | 18 +- platform/android/src/style/layers/custom_layer.cpp | 57 + platform/android/src/style/layers/custom_layer.hpp | 32 + platform/android/src/style/layers/fill_layer.cpp | 63 +- platform/android/src/style/layers/fill_layer.hpp | 18 +- platform/android/src/style/layers/layer.cpp | 59 +- platform/android/src/style/layers/layer.cpp.ejs | 69 ++ platform/android/src/style/layers/layer.hpp | 14 + platform/android/src/style/layers/layer.hpp.ejs | 45 + platform/android/src/style/layers/layers.cpp | 10 +- platform/android/src/style/layers/line_layer.cpp | 112 +- platform/android/src/style/layers/line_layer.hpp | 32 +- platform/android/src/style/layers/raster_layer.cpp | 63 +- platform/android/src/style/layers/raster_layer.hpp | 18 +- platform/android/src/style/layers/symbol_layer.cpp | 350 +++++- platform/android/src/style/layers/symbol_layer.hpp | 100 +- 78 files changed, 7193 insertions(+), 516 deletions(-) delete mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/CustomLayer.java delete mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/package-info.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/BackgroundLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/CircleLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/FillLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/LineLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RasterLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleBackgroundLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTests.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTimingTests.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/SymbolLayerTest.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/layer.junit.ejs create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/espresso/utils/OnMapReadyIdlingResource.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java delete mode 100644 platform/android/scripts/layer.cpp.ejs delete mode 100644 platform/android/scripts/layer.hpp.ejs delete mode 100644 platform/android/scripts/layer.java.ejs delete mode 100644 platform/android/scripts/layer_property.java.ejs delete mode 100644 platform/android/scripts/layer_property_factory.java.ejs create mode 100644 platform/android/src/conversion/constant.hpp create mode 100644 platform/android/src/conversion/conversion.hpp create mode 100644 platform/android/src/style/conversion/function.hpp create mode 100644 platform/android/src/style/conversion/property_value.hpp create mode 100644 platform/android/src/style/conversion/types.hpp create mode 100644 platform/android/src/style/conversion/types.hpp.ejs create mode 100644 platform/android/src/style/conversion/types_string_values.hpp create mode 100644 platform/android/src/style/conversion/types_string_values.hpp.ejs create mode 100644 platform/android/src/style/layers/custom_layer.cpp create mode 100644 platform/android/src/style/layers/custom_layer.hpp create mode 100644 platform/android/src/style/layers/layer.cpp.ejs create mode 100644 platform/android/src/style/layers/layer.hpp.ejs diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/CustomLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/CustomLayer.java deleted file mode 100644 index 30efd59a6e..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/CustomLayer.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mapbox.mapboxsdk.layers; - -public class CustomLayer { - - public String mID; - public long mContext; - public long mInitializeFunction; - public long mRenderFunction; - public long mDeinitializeFunction; - - public CustomLayer(String id, - long context, - long initializeFunction, - long renderFunction, - long deinitializeFunction) { - this.mID = id; - this.mContext = context; - this.mInitializeFunction = initializeFunction; - this.mRenderFunction = renderFunction; - this.mDeinitializeFunction = deinitializeFunction; - } - -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/package-info.java deleted file mode 100644 index 4c58308c47..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/layers/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Do not use this package. Experimental feature. - */ -package com.mapbox.mapboxsdk.layers; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index dafece6641..c4cf0b3efc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -78,7 +78,6 @@ import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; -import com.mapbox.mapboxsdk.layers.CustomLayer; import com.mapbox.mapboxsdk.location.LocationListener; import com.mapbox.mapboxsdk.location.LocationServices; import com.mapbox.mapboxsdk.maps.widgets.CompassView; @@ -2604,34 +2603,6 @@ public class MapView extends FrameLayout { return mMapboxMap.getUiSettings().getAttributionTintColor(); } - // - // Custom layer - // - - @UiThread - void addCustomLayer(CustomLayer customLayer, String before) { - if (mDestroyed) { - return; - } - mNativeMapView.addCustomLayer(customLayer, before); - } - - @UiThread - void removeCustomLayer(String id) { - if (mDestroyed) { - return; - } - mNativeMapView.removeCustomLayer(id); - } - - @UiThread - void invalidateCustomLayers() { - if (mDestroyed) { - return; - } - mNativeMapView.update(); - } - /** * Sets a callback object which will be triggered when the {@link MapboxMap} instance is ready to be used. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 85287a62c1..275cc2aeab 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -38,7 +38,6 @@ import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.layers.CustomLayer; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; @@ -59,6 +58,7 @@ import java.util.concurrent.TimeUnit; *

*/ public class MapboxMap { + private static final String TAG = MapboxMap.class.getSimpleName(); private MapView mMapView; private UiSettings mUiSettings; @@ -114,6 +114,21 @@ public class MapboxMap { return getMapView().getNativeMapView().getLayer(layerId); } + /** + * Tries to cast the Layer to T, returns null if it's another type + */ + @Nullable + @UiThread + public T getLayerAs(@NonNull String layerId) { + try { + //noinspection unchecked + return (T) getMapView().getNativeMapView().getLayer(layerId); + } catch (ClassCastException e) { + Log.e(TAG, String.format("Layer: %s is a different type: %s", layerId, e.getMessage())); + return null; + } + } + @UiThread public void addLayer(@NonNull Layer layer) { addLayer(layer, null); @@ -1621,34 +1636,6 @@ public class MapboxMap { return mOnMyBearingTrackingModeChangeListener; } - // - // Custom layer - // - - /** - * Do not use this method, experimental feature. - */ - @UiThread - public void addCustomLayer(CustomLayer customLayer, String before) { - mMapView.addCustomLayer(customLayer, before); - } - - /** - * Do not use this method, experimental feature. - */ - @UiThread - public void removeCustomLayer(String id) { - mMapView.removeCustomLayer(id); - } - - /** - * Do not use this method, experimental feature. - */ - @UiThread - public void invalidateCustomLayers() { - mMapView.invalidateCustomLayers(); - } - MapView getMapView() { return mMapView; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index c6cb48fdc3..973fa8b5e1 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -16,7 +16,6 @@ import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.geometry.ProjectedMeters; -import com.mapbox.mapboxsdk.layers.CustomLayer; import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; @@ -463,14 +462,6 @@ final class NativeMapView { nativeFlyTo(mNativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom); } - public void addCustomLayer(CustomLayer customLayer, String before) { - nativeAddCustomLayer(mNativeMapViewPtr, customLayer, before); - } - - public void removeCustomLayer(String id) { - nativeRemoveCustomLayer(mNativeMapViewPtr, id); - } - public double[] getCameraValues() { return nativeGetCameraValues(mNativeMapViewPtr); } @@ -483,6 +474,7 @@ final class NativeMapView { public void addLayer(@NonNull Layer layer, @Nullable String before) { nativeAddLayer(mNativeMapViewPtr, layer.getNativePtr(), before); + layer.invalidate(); } public void removeLayer(@NonNull String layerId) throws NoSuchLayerException { @@ -667,10 +659,6 @@ final class NativeMapView { private native void nativeFlyTo(long nativeMapViewPtr, double angle, double latitude, double longitude, long duration, double pitch, double zoom); - private native void nativeAddCustomLayer(long nativeMapViewPtr, CustomLayer customLayer, String before); - - private native void nativeRemoveCustomLayer(long nativeMapViewPtr, String id); - private native double[] nativeGetCameraValues(long mNativeMapViewPtr); private native Layer nativeGetLayer(long nativeMapViewPtr, String layerId); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java index 7dcd9eee46..f7a71155ad 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java @@ -16,4 +16,31 @@ public class BackgroundLayer extends Layer { protected native void initialize(String layerId); + + // Property getters + + @SuppressWarnings("unchecked") + public PropertyValue getBackgroundColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetBackgroundColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getBackgroundPattern() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetBackgroundPattern()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getBackgroundOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetBackgroundOpacity()); + } + + private native Object nativeGetBackgroundColor(); + + private native Object nativeGetBackgroundPattern(); + + private native Object nativeGetBackgroundOpacity(); + } 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 8562ef1bf4..6628fee47a 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 @@ -17,15 +17,77 @@ public class CircleLayer extends Layer { protected native void initialize(String layerId, String sourceId); public void setSourceLayer(String sourceLayer) { + checkValidity(); nativeSetSourceLayer(sourceLayer); } public void setFilter(Filter.Statement filter) { + checkValidity(); this.setFilter(filter.toArray()); } public void setFilter(Object[] filter) { + checkValidity(); nativeSetFilter(filter); } + + // Property getters + + @SuppressWarnings("unchecked") + public PropertyValue getCircleRadius() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCircleRadius()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getCircleColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCircleColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getCircleBlur() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCircleBlur()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getCircleOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCircleOpacity()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getCircleTranslate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCircleTranslate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getCircleTranslateAnchor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCircleTranslateAnchor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getCirclePitchScale() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetCirclePitchScale()); + } + + private native Object nativeGetCircleRadius(); + + private native Object nativeGetCircleColor(); + + private native Object nativeGetCircleBlur(); + + private native Object nativeGetCircleOpacity(); + + private native Object nativeGetCircleTranslate(); + + private native Object nativeGetCircleTranslateAnchor(); + + private native Object nativeGetCirclePitchScale(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java new file mode 100644 index 0000000000..f25d46dba9 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java @@ -0,0 +1,30 @@ +package com.mapbox.mapboxsdk.style.layers; + +/** + * Custom layer. + *

+ * Experimental feature. Do not use. + */ +public class CustomLayer extends Layer { + + public CustomLayer(String id, + long context, + long initializeFunction, + long renderFunction, + long deinitializeFunction) { + initialize(id, initializeFunction, renderFunction, deinitializeFunction, context); + } + + public CustomLayer(long nativePtr) { + super(nativePtr); + } + + public void invalidate() { + nativeUpdate(); + } + + protected native void initialize(String id, long initializeFunction, long renderFunction, long deinitializeFunction, long context); + + protected native void nativeUpdate(); + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java index b3eb5a39c1..7938af3c80 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java @@ -17,15 +17,77 @@ public class FillLayer extends Layer { protected native void initialize(String layerId, String sourceId); public void setSourceLayer(String sourceLayer) { + checkValidity(); nativeSetSourceLayer(sourceLayer); } public void setFilter(Filter.Statement filter) { + checkValidity(); this.setFilter(filter.toArray()); } public void setFilter(Object[] filter) { + checkValidity(); nativeSetFilter(filter); } + + // Property getters + + @SuppressWarnings("unchecked") + public PropertyValue getFillAntialias() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillAntialias()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getFillOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillOpacity()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getFillColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getFillOutlineColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillOutlineColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getFillTranslate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillTranslate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getFillTranslateAnchor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillTranslateAnchor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getFillPattern() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetFillPattern()); + } + + private native Object nativeGetFillAntialias(); + + private native Object nativeGetFillOpacity(); + + private native Object nativeGetFillColor(); + + private native Object nativeGetFillOutlineColor(); + + private native Object nativeGetFillTranslate(); + + private native Object nativeGetFillTranslateAnchor(); + + private native Object nativeGetFillPattern(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java new file mode 100644 index 0000000000..c776f9ff23 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java @@ -0,0 +1,85 @@ +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.FloatRange; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.Size; + +import java.util.HashMap; +import java.util.Map; + +/** + * Representation of Function in the Mapbox style specification + * + * @param the target property's value type. Make sure it matches. + */ +public class Function { + + public static class Stop { + public final I in; + public final O out; + + Stop(I in, O out) { + this.in = in; + this.out = out; + } + + Object[] toValueObject() { + return new Object[]{in, out}; + } + } + + @SafeVarargs + public static Function zoom(@NonNull @Size(min = 1) Stop... stops) { + return new Function(stops); + } + + @SafeVarargs + public static Function zoom( + @FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base, + @NonNull @Size(min = 1) Stop... stops) { + return new Function(stops) + .withBase(base); + } + + public static Stop stop(float in, Property output) { + return new Stop<>(in, output.value); + } + + private final Stop[] stops; + private Float base; + + Function(@NonNull @Size(min = 1) Stop[] stops) { + this.stops = stops; + } + + Function withBase(float base) { + this.base = base; + return this; + } + + @Nullable + public Float getBase() { + return base; + } + + public Stop[] getStops() { + return stops; + } + + Map toValueObject() { + Object[] stopsValue = new Object[stops.length]; + + for (int i = 0; i < stopsValue.length; i++) { + Stop stop = stops[i]; + stopsValue[i] = stop.toValueObject(); + } + + Map value = new HashMap<>(); + if (base != null) { + value.put("base", base); + } + value.put("stops", stopsValue); + return value; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java index eb316658ce..387cedbd6c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java @@ -1,7 +1,6 @@ package com.mapbox.mapboxsdk.style.layers; import android.support.annotation.NonNull; -import android.util.Log; /** * Base class for the different Layer types @@ -9,17 +8,18 @@ import android.util.Log; public abstract class Layer { private long nativePtr; + private boolean invalidated; public Layer(long nativePtr) { - Log.i(Layer.class.getSimpleName(), "Native pointer constructor: " + nativePtr); this.nativePtr = nativePtr; } public Layer() { - Log.i(Layer.class.getSimpleName(), "Default constructor"); } - public void set(@NonNull Property... properties) { + public void setProperties(@NonNull Property... properties) { + checkValidity(); + if (properties.length == 0) { return; } @@ -28,9 +28,9 @@ public abstract class Layer { for (Property property : properties) { if (property instanceof PaintProperty) { updateClasses = true; - nativeSetPaintProperty(property.name, property.value); + nativeSetPaintProperty(property.name, convertValue(property.value)); } else { - nativeSetLayoutProperty(property.name, property.value); + nativeSetLayoutProperty(property.name, convertValue(property.value)); } } @@ -38,14 +38,42 @@ public abstract class Layer { } public String getId() { + checkValidity(); return nativeGetId(); } + public PropertyValue getVisibility() { + checkValidity(); + return new PropertyValue<>(nativeGetVisibility()); + } + + public float getMinZoom() { + checkValidity(); + return nativeGetMinZoom(); + } + + public float getMaxZoom() { + checkValidity(); + return nativeGetMaxZoom(); + } + + public void setMinZoom(float zoom) { + checkValidity(); + nativeSetMinZoom(zoom); + } + + public void setMaxZoom(float zoom) { + checkValidity(); + nativeSetMaxZoom(zoom); + } + @Override protected native void finalize() throws Throwable; protected native String nativeGetId(); + protected native Object nativeGetVisibility(); + protected native void nativeSetLayoutProperty(String name, Object value); protected native void nativeSetPaintProperty(String name, Object value); @@ -56,13 +84,29 @@ public abstract class Layer { protected native void nativeUpdateStyle(boolean updateClasses); - @Override - public String toString() { - return "Layer: " + getId(); - } + protected native float nativeGetMinZoom(); + + protected native float nativeGetMaxZoom(); + + protected native void nativeSetMinZoom(float zoom); + + protected native void nativeSetMaxZoom(float zoom); public long getNativePtr() { return nativePtr; } + private Object convertValue(Object value) { + return value != null && value instanceof Function ? ((Function) value).toValueObject() : value; + } + + protected void checkValidity() { + if (invalidated) { + throw new RuntimeException("Layer has been invalidated. Request a new reference after adding"); + } + } + + public void invalidate() { + this.invalidated = true; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java index 36c9d53d20..11cd709f49 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java @@ -17,15 +17,133 @@ public class LineLayer extends Layer { protected native void initialize(String layerId, String sourceId); public void setSourceLayer(String sourceLayer) { + checkValidity(); nativeSetSourceLayer(sourceLayer); } public void setFilter(Filter.Statement filter) { + checkValidity(); this.setFilter(filter.toArray()); } public void setFilter(Object[] filter) { + checkValidity(); nativeSetFilter(filter); } + + // Property getters + + @SuppressWarnings("unchecked") + public PropertyValue getLineCap() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineCap()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineJoin() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineJoin()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineMiterLimit() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineMiterLimit()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineRoundLimit() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineRoundLimit()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineOpacity()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineTranslate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineTranslate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineTranslateAnchor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineTranslateAnchor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineWidth() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineWidth()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineGapWidth() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineGapWidth()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineOffset() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineOffset()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineBlur() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineBlur()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLineDasharray() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLineDasharray()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getLinePattern() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetLinePattern()); + } + + private native Object nativeGetLineCap(); + + private native Object nativeGetLineJoin(); + + private native Object nativeGetLineMiterLimit(); + + private native Object nativeGetLineRoundLimit(); + + private native Object nativeGetLineOpacity(); + + private native Object nativeGetLineColor(); + + private native Object nativeGetLineTranslate(); + + private native Object nativeGetLineTranslateAnchor(); + + private native Object nativeGetLineWidth(); + + private native Object nativeGetLineGapWidth(); + + private native Object nativeGetLineOffset(); + + private native Object nativeGetLineBlur(); + + private native Object nativeGetLineDasharray(); + + private native Object nativeGetLinePattern(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java index 66cc7df111..a31f1adb54 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java @@ -11,6 +11,17 @@ import java.lang.annotation.RetentionPolicy; */ public abstract class Property { + //visibility + public static final String VISIBLE = "visible"; + public static final String NONE = "none"; + + @StringDef({ + VISIBLE, + NONE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface VISIBILITY {} + //line-cap public static final String LINE_CAP_BUTT = "butt"; public static final String LINE_CAP_ROUND = "round"; 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 4dcec0d9b3..88587dbb5b 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 @@ -6,395 +6,1292 @@ import android.support.annotation.ColorInt; /** * Constructs paint/layout properties for Layers - * @see Layer style documentation */ public class PropertyFactory { - public static Property visibility(Boolean visible) { - return new LayoutProperty<>("visibility", visible? "visible": "none"); + /** + * Set visibility + */ + public static Property visibility(@Property.VISIBILITY String value) { + return new LayoutProperty<>("visibility", value); + } + + /** + * Set visibility + */ + public static Property> visibility(Function function) { + return new LayoutProperty<>("visibility", function); } + /** + * Whether or not the fill should be antialiased. + */ public static Property fillAntialias(Boolean value) { return new PaintProperty<>("fill-antialias", value); } + /** + * Whether or not the fill should be antialiased. + */ + public static Property> fillAntialias(Function function) { + return new PaintProperty<>("fill-antialias", function); + } + + /** + * The opacity of the entire fill layer. In contrast to the fill-color, this value will also affect the 1px stroke around the fill, if the stroke is used. + */ public static Property fillOpacity(Float value) { return new PaintProperty<>("fill-opacity", value); } + /** + * The opacity of the entire fill layer. In contrast to the fill-color, this value will also affect the 1px stroke around the fill, if the stroke is used. + */ + public static Property> fillOpacity(Function function) { + return new PaintProperty<>("fill-opacity", function); + } + + /** + * The color of the filled part of this layer. This color can be specified as rgba with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. + */ public static Property fillColor(@ColorInt int value) { return new PaintProperty<>("fill-color", colorToRgbaString(value)); } + /** + * The color of the filled part of this layer. This color can be specified as rgba with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. + */ public static Property fillColor(String value) { return new PaintProperty<>("fill-color", value); } + /** + * The color of the filled part of this layer. This color can be specified as rgba with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. + */ + public static Property> fillColor(Function function) { + return new PaintProperty<>("fill-color", function); + } + + /** + * The outline color of the fill. Matches the value of `fill-color` if unspecified. + */ public static Property fillOutlineColor(@ColorInt int value) { return new PaintProperty<>("fill-outline-color", colorToRgbaString(value)); } + /** + * The outline color of the fill. Matches the value of `fill-color` if unspecified. + */ public static Property fillOutlineColor(String value) { return new PaintProperty<>("fill-outline-color", value); } + /** + * The outline color of the fill. Matches the value of `fill-color` if unspecified. + */ + public static Property> fillOutlineColor(Function function) { + return new PaintProperty<>("fill-outline-color", function); + } + + /** + * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. + */ public static Property fillTranslate(Float[] value) { return new PaintProperty<>("fill-translate", value); } + /** + * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. + */ + public static Property> fillTranslate(Function function) { + return new PaintProperty<>("fill-translate", function); + } + + /** + * Control whether the translation is relative to the map (north) or viewport (screen) + */ public static Property fillTranslateAnchor(@Property.FILL_TRANSLATE_ANCHOR String value) { return new PaintProperty<>("fill-translate-anchor", value); } + /** + * Control whether the translation is relative to the map (north) or viewport (screen) + */ + public static Property> fillTranslateAnchor(Function function) { + return new PaintProperty<>("fill-translate-anchor", function); + } + + /** + * 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). + */ public static Property fillPattern(String value) { return new PaintProperty<>("fill-pattern", value); } + /** + * 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). + */ + public static Property> fillPattern(Function function) { + return new PaintProperty<>("fill-pattern", function); + } + + /** + * The opacity at which the line will be drawn. + */ public static Property lineOpacity(Float value) { return new PaintProperty<>("line-opacity", value); } + /** + * The opacity at which the line will be drawn. + */ + public static Property> lineOpacity(Function function) { + return new PaintProperty<>("line-opacity", function); + } + + /** + * The color with which the line will be drawn. + */ public static Property lineColor(@ColorInt int value) { return new PaintProperty<>("line-color", colorToRgbaString(value)); } + /** + * The color with which the line will be drawn. + */ public static Property lineColor(String value) { return new PaintProperty<>("line-color", value); } + /** + * The color with which the line will be drawn. + */ + public static Property> lineColor(Function function) { + return new PaintProperty<>("line-color", function); + } + + /** + * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. + */ public static Property lineTranslate(Float[] value) { return new PaintProperty<>("line-translate", value); } + /** + * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. + */ + public static Property> lineTranslate(Function function) { + return new PaintProperty<>("line-translate", function); + } + + /** + * Control whether the translation is relative to the map (north) or viewport (screen) + */ public static Property lineTranslateAnchor(@Property.LINE_TRANSLATE_ANCHOR String value) { return new PaintProperty<>("line-translate-anchor", value); } + /** + * Control whether the translation is relative to the map (north) or viewport (screen) + */ + public static Property> lineTranslateAnchor(Function function) { + return new PaintProperty<>("line-translate-anchor", function); + } + + /** + * Stroke thickness. + */ public static Property lineWidth(Float value) { return new PaintProperty<>("line-width", value); } + /** + * Stroke thickness. + */ + public static Property> lineWidth(Function function) { + return new PaintProperty<>("line-width", function); + } + + /** + * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap. + */ public static Property lineGapWidth(Float value) { return new PaintProperty<>("line-gap-width", value); } + /** + * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap. + */ + public static Property> lineGapWidth(Function function) { + return new PaintProperty<>("line-gap-width", function); + } + + /** + * The line's offset perpendicular to its direction. Values may be positive or negative, where positive indicates "rightwards" (if you were moving in the direction of the line) and negative indicates "leftwards." + */ public static Property lineOffset(Float value) { return new PaintProperty<>("line-offset", value); } + /** + * The line's offset perpendicular to its direction. Values may be positive or negative, where positive indicates "rightwards" (if you were moving in the direction of the line) and negative indicates "leftwards." + */ + public static Property> lineOffset(Function function) { + return new PaintProperty<>("line-offset", function); + } + + /** + * Blur applied to the line, in pixels. + */ public static Property lineBlur(Float value) { return new PaintProperty<>("line-blur", value); } + /** + * Blur applied to the line, in pixels. + */ + public static Property> lineBlur(Function function) { + return new PaintProperty<>("line-blur", function); + } + + /** + * 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 pixels, multiply the length by the current line width. + */ public static Property lineDasharray(Float[] value) { return new PaintProperty<>("line-dasharray", value); } + /** + * 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 pixels, multiply the length by the current line width. + */ + public static Property> lineDasharray(Function function) { + return new PaintProperty<>("line-dasharray", function); + } + + /** + * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). + */ public static Property linePattern(String value) { return new PaintProperty<>("line-pattern", value); } + /** + * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). + */ + public static Property> linePattern(Function function) { + return new PaintProperty<>("line-pattern", function); + } + + /** + * The opacity at which the icon will be drawn. + */ public static Property iconOpacity(Float value) { return new PaintProperty<>("icon-opacity", value); } + /** + * The opacity at which the icon will be drawn. + */ + public static Property> iconOpacity(Function function) { + return new PaintProperty<>("icon-opacity", function); + } + + /** + * The color of the icon. This can only be used with sdf icons. + */ public static Property iconColor(@ColorInt int value) { return new PaintProperty<>("icon-color", colorToRgbaString(value)); } + /** + * The color of the icon. This can only be used with sdf icons. + */ public static Property iconColor(String value) { return new PaintProperty<>("icon-color", value); } + /** + * The color of the icon. This can only be used with sdf icons. + */ + public static Property> iconColor(Function function) { + return new PaintProperty<>("icon-color", function); + } + + /** + * The color of the icon's halo. Icon halos can only be used with sdf icons. + */ public static Property iconHaloColor(@ColorInt int value) { return new PaintProperty<>("icon-halo-color", colorToRgbaString(value)); } + /** + * The color of the icon's halo. Icon halos can only be used with sdf icons. + */ public static Property iconHaloColor(String value) { return new PaintProperty<>("icon-halo-color", value); } + /** + * The color of the icon's halo. Icon halos can only be used with sdf icons. + */ + public static Property> iconHaloColor(Function function) { + return new PaintProperty<>("icon-halo-color", function); + } + + /** + * Distance of halo to the icon outline. + */ public static Property iconHaloWidth(Float value) { return new PaintProperty<>("icon-halo-width", value); } + /** + * Distance of halo to the icon outline. + */ + public static Property> iconHaloWidth(Function function) { + return new PaintProperty<>("icon-halo-width", function); + } + + /** + * Fade out the halo towards the outside. + */ public static Property iconHaloBlur(Float value) { return new PaintProperty<>("icon-halo-blur", value); } + /** + * Fade out the halo towards the outside. + */ + public static Property> iconHaloBlur(Function function) { + return new PaintProperty<>("icon-halo-blur", function); + } + + /** + * Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. + */ public static Property iconTranslate(Float[] value) { return new PaintProperty<>("icon-translate", value); } + /** + * Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. + */ + public static Property> iconTranslate(Function function) { + return new PaintProperty<>("icon-translate", function); + } + + /** + * Control whether the translation is relative to the map (north) or viewport (screen). + */ public static Property iconTranslateAnchor(@Property.ICON_TRANSLATE_ANCHOR String value) { return new PaintProperty<>("icon-translate-anchor", value); } + /** + * Control whether the translation is relative to the map (north) or viewport (screen). + */ + public static Property> iconTranslateAnchor(Function function) { + return new PaintProperty<>("icon-translate-anchor", function); + } + + /** + * The opacity at which the text will be drawn. + */ public static Property textOpacity(Float value) { return new PaintProperty<>("text-opacity", value); } + /** + * The opacity at which the text will be drawn. + */ + public static Property> textOpacity(Function function) { + return new PaintProperty<>("text-opacity", function); + } + + /** + * The color with which the text will be drawn. + */ public static Property textColor(@ColorInt int value) { return new PaintProperty<>("text-color", colorToRgbaString(value)); } + /** + * The color with which the text will be drawn. + */ public static Property textColor(String value) { return new PaintProperty<>("text-color", value); } + /** + * The color with which the text will be drawn. + */ + public static Property> textColor(Function function) { + return new PaintProperty<>("text-color", function); + } + + /** + * The color of the text's halo, which helps it stand out from backgrounds. + */ public static Property textHaloColor(@ColorInt int value) { return new PaintProperty<>("text-halo-color", colorToRgbaString(value)); } + /** + * The color of the text's halo, which helps it stand out from backgrounds. + */ public static Property textHaloColor(String value) { return new PaintProperty<>("text-halo-color", value); } + /** + * The color of the text's halo, which helps it stand out from backgrounds. + */ + public static Property> textHaloColor(Function function) { + return new PaintProperty<>("text-halo-color", function); + } + + /** + * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size. + */ public static Property textHaloWidth(Float value) { return new PaintProperty<>("text-halo-width", value); } + /** + * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size. + */ + public static Property> textHaloWidth(Function function) { + return new PaintProperty<>("text-halo-width", function); + } + + /** + * The halo's fadeout distance towards the outside. + */ public static Property textHaloBlur(Float value) { return new PaintProperty<>("text-halo-blur", value); } + /** + * The halo's fadeout distance towards the outside. + */ + public static Property> textHaloBlur(Function function) { + return new PaintProperty<>("text-halo-blur", function); + } + + /** + * Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. + */ public static Property textTranslate(Float[] value) { return new PaintProperty<>("text-translate", value); } + /** + * Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. + */ + public static Property> textTranslate(Function function) { + return new PaintProperty<>("text-translate", function); + } + + /** + * Control whether the translation is relative to the map (north) or viewport (screen). + */ public static Property textTranslateAnchor(@Property.TEXT_TRANSLATE_ANCHOR String value) { return new PaintProperty<>("text-translate-anchor", value); } + /** + * Control whether the translation is relative to the map (north) or viewport (screen). + */ + public static Property> textTranslateAnchor(Function function) { + return new PaintProperty<>("text-translate-anchor", function); + } + + /** + * Circle radius. + */ public static Property circleRadius(Float value) { return new PaintProperty<>("circle-radius", value); } + /** + * Circle radius. + */ + public static Property> circleRadius(Function function) { + return new PaintProperty<>("circle-radius", function); + } + + /** + * The color of the circle. + */ public static Property circleColor(@ColorInt int value) { return new PaintProperty<>("circle-color", colorToRgbaString(value)); } + /** + * The color of the circle. + */ public static Property circleColor(String value) { return new PaintProperty<>("circle-color", value); } + /** + * The color of the circle. + */ + public static Property> circleColor(Function function) { + return new PaintProperty<>("circle-color", function); + } + + /** + * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity. + */ public static Property circleBlur(Float value) { return new PaintProperty<>("circle-blur", value); } + /** + * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity. + */ + public static Property> circleBlur(Function function) { + return new PaintProperty<>("circle-blur", function); + } + + /** + * The opacity at which the circle will be drawn. + */ public static Property circleOpacity(Float value) { return new PaintProperty<>("circle-opacity", value); } + /** + * The opacity at which the circle will be drawn. + */ + public static Property> circleOpacity(Function function) { + return new PaintProperty<>("circle-opacity", function); + } + + /** + * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. + */ public static Property circleTranslate(Float[] value) { return new PaintProperty<>("circle-translate", value); } + /** + * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. + */ + public static Property> circleTranslate(Function function) { + return new PaintProperty<>("circle-translate", function); + } + + /** + * Control whether the translation is relative to the map (north) or viewport (screen) + */ public static Property circleTranslateAnchor(@Property.CIRCLE_TRANSLATE_ANCHOR String value) { return new PaintProperty<>("circle-translate-anchor", value); } + /** + * Control whether the translation is relative to the map (north) or viewport (screen) + */ + public static Property> circleTranslateAnchor(Function function) { + return new PaintProperty<>("circle-translate-anchor", function); + } + + /** + * Controls the scaling behavior of the circle when the map is pitched. The value `map` scales circles according to their apparent distance to the camera. The value `viewport` results in no pitch-related scaling. + */ public static Property circlePitchScale(@Property.CIRCLE_PITCH_SCALE String value) { return new PaintProperty<>("circle-pitch-scale", value); } + /** + * Controls the scaling behavior of the circle when the map is pitched. The value `map` scales circles according to their apparent distance to the camera. The value `viewport` results in no pitch-related scaling. + */ + public static Property> circlePitchScale(Function function) { + return new PaintProperty<>("circle-pitch-scale", function); + } + + /** + * The opacity at which the image will be drawn. + */ public static Property rasterOpacity(Float value) { return new PaintProperty<>("raster-opacity", value); } + /** + * The opacity at which the image will be drawn. + */ + public static Property> rasterOpacity(Function function) { + return new PaintProperty<>("raster-opacity", function); + } + + /** + * Rotates hues around the color wheel. + */ public static Property rasterHueRotate(Float value) { return new PaintProperty<>("raster-hue-rotate", value); } + /** + * Rotates hues around the color wheel. + */ + public static Property> rasterHueRotate(Function function) { + return new PaintProperty<>("raster-hue-rotate", function); + } + + /** + * Increase or reduce the brightness of the image. The value is the minimum brightness. + */ public static Property rasterBrightnessMin(Float value) { return new PaintProperty<>("raster-brightness-min", value); } + /** + * Increase or reduce the brightness of the image. The value is the minimum brightness. + */ + public static Property> rasterBrightnessMin(Function function) { + return new PaintProperty<>("raster-brightness-min", function); + } + + /** + * Increase or reduce the brightness of the image. The value is the maximum brightness. + */ public static Property rasterBrightnessMax(Float value) { return new PaintProperty<>("raster-brightness-max", value); } + /** + * Increase or reduce the brightness of the image. The value is the maximum brightness. + */ + public static Property> rasterBrightnessMax(Function function) { + return new PaintProperty<>("raster-brightness-max", function); + } + + /** + * Increase or reduce the saturation of the image. + */ public static Property rasterSaturation(Float value) { return new PaintProperty<>("raster-saturation", value); } + /** + * Increase or reduce the saturation of the image. + */ + public static Property> rasterSaturation(Function function) { + return new PaintProperty<>("raster-saturation", function); + } + + /** + * Increase or reduce the contrast of the image. + */ public static Property rasterContrast(Float value) { return new PaintProperty<>("raster-contrast", value); } + /** + * Increase or reduce the contrast of the image. + */ + public static Property> rasterContrast(Function function) { + return new PaintProperty<>("raster-contrast", function); + } + + /** + * Fade duration when a new tile is added. + */ public static Property rasterFadeDuration(Float value) { return new PaintProperty<>("raster-fade-duration", value); } + /** + * Fade duration when a new tile is added. + */ + public static Property> rasterFadeDuration(Function function) { + return new PaintProperty<>("raster-fade-duration", function); + } + + /** + * The color with which the background will be drawn. + */ public static Property backgroundColor(@ColorInt int value) { return new PaintProperty<>("background-color", colorToRgbaString(value)); } + /** + * The color with which the background will be drawn. + */ public static Property backgroundColor(String value) { return new PaintProperty<>("background-color", value); } + /** + * The color with which the background will be drawn. + */ + public static Property> backgroundColor(Function function) { + return new PaintProperty<>("background-color", function); + } + + /** + * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + */ public static Property backgroundPattern(String value) { return new PaintProperty<>("background-pattern", value); } + /** + * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). + */ + public static Property> backgroundPattern(Function function) { + return new PaintProperty<>("background-pattern", function); + } + + /** + * The opacity at which the background will be drawn. + */ public static Property backgroundOpacity(Float value) { return new PaintProperty<>("background-opacity", value); } + /** + * The opacity at which the background will be drawn. + */ + public static Property> backgroundOpacity(Function function) { + return new PaintProperty<>("background-opacity", function); + } + + /** + * The display of line endings. + */ public static Property lineCap(@Property.LINE_CAP String value) { return new LayoutProperty<>("line-cap", value); } + /** + * The display of line endings. + */ + public static Property> lineCap(Function function) { + return new LayoutProperty<>("line-cap", function); + } + + /** + * The display of lines when joining. + */ public static Property lineJoin(@Property.LINE_JOIN String value) { return new LayoutProperty<>("line-join", value); } + /** + * The display of lines when joining. + */ + public static Property> lineJoin(Function function) { + return new LayoutProperty<>("line-join", function); + } + + /** + * Used to automatically convert miter joins to bevel joins for sharp angles. + */ public static Property lineMiterLimit(Float value) { return new LayoutProperty<>("line-miter-limit", value); } + /** + * Used to automatically convert miter joins to bevel joins for sharp angles. + */ + public static Property> lineMiterLimit(Function function) { + return new LayoutProperty<>("line-miter-limit", function); + } + + /** + * Used to automatically convert round joins to miter joins for shallow angles. + */ public static Property lineRoundLimit(Float value) { return new LayoutProperty<>("line-round-limit", value); } + /** + * Used to automatically convert round joins to miter joins for shallow angles. + */ + public static Property> lineRoundLimit(Function function) { + return new LayoutProperty<>("line-round-limit", function); + } + + /** + * Label placement relative to its geometry. `line` can only be used on LineStrings and Polygons. + */ public static Property symbolPlacement(@Property.SYMBOL_PLACEMENT String value) { return new LayoutProperty<>("symbol-placement", value); } + /** + * Label placement relative to its geometry. `line` can only be used on LineStrings and Polygons. + */ + public static Property> symbolPlacement(Function function) { + return new LayoutProperty<>("symbol-placement", function); + } + + /** + * Distance between two symbol anchors. + */ public static Property symbolSpacing(Float value) { return new LayoutProperty<>("symbol-spacing", value); } + /** + * Distance between two symbol anchors. + */ + public static Property> symbolSpacing(Function function) { + return new LayoutProperty<>("symbol-spacing", function); + } + + /** + * 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. + */ public static Property symbolAvoidEdges(Boolean value) { return new LayoutProperty<>("symbol-avoid-edges", value); } + /** + * 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. + */ + public static Property> symbolAvoidEdges(Function function) { + return new LayoutProperty<>("symbol-avoid-edges", function); + } + + /** + * If true, the icon will be visible even if it collides with other previously drawn symbols. + */ public static Property iconAllowOverlap(Boolean value) { return new LayoutProperty<>("icon-allow-overlap", value); } + /** + * If true, the icon will be visible even if it collides with other previously drawn symbols. + */ + public static Property> iconAllowOverlap(Function function) { + return new LayoutProperty<>("icon-allow-overlap", function); + } + + /** + * If true, other symbols can be visible even if they collide with the icon. + */ public static Property iconIgnorePlacement(Boolean value) { return new LayoutProperty<>("icon-ignore-placement", value); } + /** + * If true, other symbols can be visible even if they collide with the icon. + */ + public static Property> iconIgnorePlacement(Function function) { + return new LayoutProperty<>("icon-ignore-placement", function); + } + + /** + * If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not. + */ public static Property iconOptional(Boolean value) { return new LayoutProperty<>("icon-optional", value); } + /** + * If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not. + */ + public static Property> iconOptional(Function function) { + return new LayoutProperty<>("icon-optional", function); + } + + /** + * Orientation of icon when map is rotated. + */ public static Property iconRotationAlignment(@Property.ICON_ROTATION_ALIGNMENT String value) { return new LayoutProperty<>("icon-rotation-alignment", value); } + /** + * Orientation of icon when map is rotated. + */ + public static Property> iconRotationAlignment(Function function) { + return new LayoutProperty<>("icon-rotation-alignment", function); + } + + /** + * Scale factor for icon. 1 is original size, 3 triples the size. + */ public static Property iconSize(Float value) { return new LayoutProperty<>("icon-size", value); } + /** + * Scale factor for icon. 1 is original size, 3 triples the size. + */ + public static Property> iconSize(Function function) { + return new LayoutProperty<>("icon-size", function); + } + + /** + * Position and scale an icon by the its corresponding text. + */ public static Property iconTextFit(@Property.ICON_TEXT_FIT String value) { return new LayoutProperty<>("icon-text-fit", value); } + /** + * Position and scale an icon by the its corresponding text. + */ + public static Property> iconTextFit(Function function) { + return new LayoutProperty<>("icon-text-fit", function); + } + + /** + * Size of padding area around the text-fit size in clockwise order: top, right, bottom, left. + */ public static Property iconTextFitPadding(Float[] value) { return new LayoutProperty<>("icon-text-fit-padding", value); } + /** + * Size of padding area around the text-fit size in clockwise order: top, right, bottom, left. + */ + public static Property> iconTextFitPadding(Function function) { + return new LayoutProperty<>("icon-text-fit-padding", function); + } + + /** + * A string with {tokens} replaced, referencing the data property to pull from. + */ public static Property iconImage(String value) { return new LayoutProperty<>("icon-image", value); } + /** + * A string with {tokens} replaced, referencing the data property to pull from. + */ + public static Property> iconImage(Function function) { + return new LayoutProperty<>("icon-image", function); + } + + /** + * Rotates the icon clockwise. + */ public static Property iconRotate(Float value) { return new LayoutProperty<>("icon-rotate", value); } + /** + * Rotates the icon clockwise. + */ + public static Property> iconRotate(Function function) { + return new LayoutProperty<>("icon-rotate", function); + } + + /** + * Size of the additional area around the icon bounding box used for detecting symbol collisions. + */ public static Property iconPadding(Float value) { return new LayoutProperty<>("icon-padding", value); } + /** + * Size of the additional area around the icon bounding box used for detecting symbol collisions. + */ + public static Property> iconPadding(Function function) { + return new LayoutProperty<>("icon-padding", function); + } + + /** + * If true, the icon may be flipped to prevent it from being rendered upside-down. + */ public static Property iconKeepUpright(Boolean value) { return new LayoutProperty<>("icon-keep-upright", value); } + /** + * If true, the icon may be flipped to prevent it from being rendered upside-down. + */ + public static Property> iconKeepUpright(Function function) { + return new LayoutProperty<>("icon-keep-upright", function); + } + + /** + * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up. + */ public static Property iconOffset(Float[] value) { return new LayoutProperty<>("icon-offset", value); } + /** + * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up. + */ + public static Property> iconOffset(Function function) { + return new LayoutProperty<>("icon-offset", function); + } + + /** + * Aligns text to the plane of the `viewport` or the `map` when the map is pitched. Matches `text-rotation-alignment` if unspecified. + */ public static Property textPitchAlignment(@Property.TEXT_PITCH_ALIGNMENT String value) { return new LayoutProperty<>("text-pitch-alignment", value); } + /** + * Aligns text to the plane of the `viewport` or the `map` when the map is pitched. Matches `text-rotation-alignment` if unspecified. + */ + public static Property> textPitchAlignment(Function function) { + return new LayoutProperty<>("text-pitch-alignment", function); + } + + /** + * Orientation of text when map is rotated. + */ public static Property textRotationAlignment(@Property.TEXT_ROTATION_ALIGNMENT String value) { return new LayoutProperty<>("text-rotation-alignment", value); } + /** + * Orientation of text when map is rotated. + */ + public static Property> textRotationAlignment(Function function) { + return new LayoutProperty<>("text-rotation-alignment", function); + } + + /** + * Value to use for a text label. Feature properties are specified using tokens like {field_name}. + */ public static Property textField(String value) { return new LayoutProperty<>("text-field", value); } + /** + * Value to use for a text label. Feature properties are specified using tokens like {field_name}. + */ + public static Property> textField(Function function) { + return new LayoutProperty<>("text-field", function); + } + + /** + * Font stack to use for displaying text. + */ public static Property textFont(String[] value) { return new LayoutProperty<>("text-font", value); } + /** + * Font stack to use for displaying text. + */ + public static Property> textFont(Function function) { + return new LayoutProperty<>("text-font", function); + } + + /** + * Font size. + */ public static Property textSize(Float value) { return new LayoutProperty<>("text-size", value); } + /** + * Font size. + */ + public static Property> textSize(Function function) { + return new LayoutProperty<>("text-size", function); + } + + /** + * The maximum line width for text wrapping. + */ public static Property textMaxWidth(Float value) { return new LayoutProperty<>("text-max-width", value); } + /** + * The maximum line width for text wrapping. + */ + public static Property> textMaxWidth(Function function) { + return new LayoutProperty<>("text-max-width", function); + } + + /** + * Text leading value for multi-line text. + */ public static Property textLineHeight(Float value) { return new LayoutProperty<>("text-line-height", value); } + /** + * Text leading value for multi-line text. + */ + public static Property> textLineHeight(Function function) { + return new LayoutProperty<>("text-line-height", function); + } + + /** + * Text tracking amount. + */ public static Property textLetterSpacing(Float value) { return new LayoutProperty<>("text-letter-spacing", value); } + /** + * Text tracking amount. + */ + public static Property> textLetterSpacing(Function function) { + return new LayoutProperty<>("text-letter-spacing", function); + } + + /** + * Text justification options. + */ public static Property textJustify(@Property.TEXT_JUSTIFY String value) { return new LayoutProperty<>("text-justify", value); } + /** + * Text justification options. + */ + public static Property> textJustify(Function function) { + return new LayoutProperty<>("text-justify", function); + } + + /** + * Part of the text placed closest to the anchor. + */ public static Property textAnchor(@Property.TEXT_ANCHOR String value) { return new LayoutProperty<>("text-anchor", value); } + /** + * Part of the text placed closest to the anchor. + */ + public static Property> textAnchor(Function function) { + return new LayoutProperty<>("text-anchor", function); + } + + /** + * Maximum angle change between adjacent characters. + */ public static Property textMaxAngle(Float value) { return new LayoutProperty<>("text-max-angle", value); } + /** + * Maximum angle change between adjacent characters. + */ + public static Property> textMaxAngle(Function function) { + return new LayoutProperty<>("text-max-angle", function); + } + + /** + * Rotates the text clockwise. + */ public static Property textRotate(Float value) { return new LayoutProperty<>("text-rotate", value); } + /** + * Rotates the text clockwise. + */ + public static Property> textRotate(Function function) { + return new LayoutProperty<>("text-rotate", function); + } + + /** + * Size of the additional area around the text bounding box used for detecting symbol collisions. + */ public static Property textPadding(Float value) { return new LayoutProperty<>("text-padding", value); } + /** + * Size of the additional area around the text bounding box used for detecting symbol collisions. + */ + public static Property> textPadding(Function function) { + return new LayoutProperty<>("text-padding", function); + } + + /** + * If true, the text may be flipped vertically to prevent it from being rendered upside-down. + */ public static Property textKeepUpright(Boolean value) { return new LayoutProperty<>("text-keep-upright", value); } + /** + * If true, the text may be flipped vertically to prevent it from being rendered upside-down. + */ + public static Property> textKeepUpright(Function function) { + return new LayoutProperty<>("text-keep-upright", function); + } + + /** + * Specifies how to capitalize text, similar to the CSS `text-transform` property. + */ public static Property textTransform(@Property.TEXT_TRANSFORM String value) { return new LayoutProperty<>("text-transform", value); } + /** + * Specifies how to capitalize text, similar to the CSS `text-transform` property. + */ + public static Property> textTransform(Function function) { + return new LayoutProperty<>("text-transform", function); + } + + /** + * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. + */ public static Property textOffset(Float[] value) { return new LayoutProperty<>("text-offset", value); } + /** + * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. + */ + public static Property> textOffset(Function function) { + return new LayoutProperty<>("text-offset", function); + } + + /** + * If true, the text will be visible even if it collides with other previously drawn symbols. + */ public static Property textAllowOverlap(Boolean value) { return new LayoutProperty<>("text-allow-overlap", value); } + /** + * If true, the text will be visible even if it collides with other previously drawn symbols. + */ + public static Property> textAllowOverlap(Function function) { + return new LayoutProperty<>("text-allow-overlap", function); + } + + /** + * If true, other symbols can be visible even if they collide with the text. + */ public static Property textIgnorePlacement(Boolean value) { return new LayoutProperty<>("text-ignore-placement", value); } + /** + * If true, other symbols can be visible even if they collide with the text. + */ + public static Property> textIgnorePlacement(Function function) { + return new LayoutProperty<>("text-ignore-placement", function); + } + + /** + * If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not. + */ public static Property textOptional(Boolean value) { return new LayoutProperty<>("text-optional", value); } + /** + * If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not. + */ + public static Property> textOptional(Function function) { + return new LayoutProperty<>("text-optional", function); + } + @SuppressLint("DefaultLocale") static String colorToRgbaString(@ColorInt int value) { return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java new file mode 100644 index 0000000000..204c154743 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java @@ -0,0 +1,56 @@ +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.Nullable; +import android.util.Log; + +/** + * Properties for Layer + */ +public class PropertyValue { + private static final String TAG = PropertyValue.class.getSimpleName(); + + private final Object value; + + /* package */ PropertyValue(Object value) { + this.value = value; + } + + public boolean isNull() { + return value == null; + } + + public boolean isFunction() { + return !isNull() && value instanceof Function; + } + + public boolean isValue() { + return !isNull() && !isFunction(); + } + + @Nullable + public Function getFunction() { + if (isFunction()) { + //noinspection unchecked + return (Function) value; + } else { + Log.w(TAG, "not a function, try value"); + return null; + } + } + + @Nullable + public T getValue() { + if (isValue()) { + //noinspection unchecked + return (T) value; + } else { + Log.w(TAG, "not a value, try function"); + return null; + } + } + + @Override + public String toString() { + return String.format("%s (%s)", getClass().getSimpleName(), value != null ? value.getClass().getSimpleName() : null); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java index 8e0817fe94..1cbe5fb387 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java @@ -17,7 +17,67 @@ public class RasterLayer extends Layer { protected native void initialize(String layerId, String sourceId); public void setSourceLayer(String sourceLayer) { + checkValidity(); nativeSetSourceLayer(sourceLayer); } + + // Property getters + + @SuppressWarnings("unchecked") + public PropertyValue getRasterOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterOpacity()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getRasterHueRotate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterHueRotate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getRasterBrightnessMin() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterBrightnessMin()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getRasterBrightnessMax() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterBrightnessMax()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getRasterSaturation() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterSaturation()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getRasterContrast() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterContrast()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getRasterFadeDuration() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetRasterFadeDuration()); + } + + private native Object nativeGetRasterOpacity(); + + private native Object nativeGetRasterHueRotate(); + + private native Object nativeGetRasterBrightnessMin(); + + private native Object nativeGetRasterBrightnessMax(); + + private native Object nativeGetRasterSaturation(); + + private native Object nativeGetRasterContrast(); + + private native Object nativeGetRasterFadeDuration(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java index 52f42f72d5..281b4fc028 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java @@ -17,15 +17,405 @@ public class SymbolLayer extends Layer { protected native void initialize(String layerId, String sourceId); public void setSourceLayer(String sourceLayer) { + checkValidity(); nativeSetSourceLayer(sourceLayer); } public void setFilter(Filter.Statement filter) { + checkValidity(); this.setFilter(filter.toArray()); } public void setFilter(Object[] filter) { + checkValidity(); nativeSetFilter(filter); } + + // Property getters + + @SuppressWarnings("unchecked") + public PropertyValue getSymbolPlacement() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetSymbolPlacement()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getSymbolSpacing() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetSymbolSpacing()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getSymbolAvoidEdges() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetSymbolAvoidEdges()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconAllowOverlap() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconAllowOverlap()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconIgnorePlacement() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconIgnorePlacement()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconOptional() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconOptional()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconRotationAlignment() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconRotationAlignment()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconSize() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconSize()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconTextFit() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconTextFit()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconTextFitPadding() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconTextFitPadding()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconImage() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconImage()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconRotate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconRotate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconPadding() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconPadding()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconKeepUpright() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconKeepUpright()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconOffset() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconOffset()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextPitchAlignment() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextPitchAlignment()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextRotationAlignment() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextRotationAlignment()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextField() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextField()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextFont() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextFont()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextSize() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextSize()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextMaxWidth() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextMaxWidth()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextLineHeight() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextLineHeight()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextLetterSpacing() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextLetterSpacing()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextJustify() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextJustify()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextAnchor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextAnchor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextMaxAngle() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextMaxAngle()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextRotate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextRotate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextPadding() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextPadding()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextKeepUpright() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextKeepUpright()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextTransform() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextTransform()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextOffset() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextOffset()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextAllowOverlap() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextAllowOverlap()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextIgnorePlacement() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextIgnorePlacement()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextOptional() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextOptional()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconOpacity()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconHaloColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconHaloColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconHaloWidth() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconHaloWidth()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconHaloBlur() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconHaloBlur()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconTranslate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconTranslate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getIconTranslateAnchor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetIconTranslateAnchor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextOpacity() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextOpacity()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextHaloColor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextHaloColor()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextHaloWidth() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextHaloWidth()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextHaloBlur() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextHaloBlur()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextTranslate() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextTranslate()); + } + + @SuppressWarnings("unchecked") + public PropertyValue getTextTranslateAnchor() { + checkValidity(); + return (PropertyValue) new PropertyValue(nativeGetTextTranslateAnchor()); + } + + private native Object nativeGetSymbolPlacement(); + + private native Object nativeGetSymbolSpacing(); + + private native Object nativeGetSymbolAvoidEdges(); + + private native Object nativeGetIconAllowOverlap(); + + private native Object nativeGetIconIgnorePlacement(); + + private native Object nativeGetIconOptional(); + + private native Object nativeGetIconRotationAlignment(); + + private native Object nativeGetIconSize(); + + private native Object nativeGetIconTextFit(); + + private native Object nativeGetIconTextFitPadding(); + + private native Object nativeGetIconImage(); + + private native Object nativeGetIconRotate(); + + private native Object nativeGetIconPadding(); + + private native Object nativeGetIconKeepUpright(); + + private native Object nativeGetIconOffset(); + + private native Object nativeGetTextPitchAlignment(); + + private native Object nativeGetTextRotationAlignment(); + + private native Object nativeGetTextField(); + + private native Object nativeGetTextFont(); + + private native Object nativeGetTextSize(); + + private native Object nativeGetTextMaxWidth(); + + private native Object nativeGetTextLineHeight(); + + private native Object nativeGetTextLetterSpacing(); + + private native Object nativeGetTextJustify(); + + private native Object nativeGetTextAnchor(); + + private native Object nativeGetTextMaxAngle(); + + private native Object nativeGetTextRotate(); + + private native Object nativeGetTextPadding(); + + private native Object nativeGetTextKeepUpright(); + + private native Object nativeGetTextTransform(); + + private native Object nativeGetTextOffset(); + + private native Object nativeGetTextAllowOverlap(); + + private native Object nativeGetTextIgnorePlacement(); + + private native Object nativeGetTextOptional(); + + private native Object nativeGetIconOpacity(); + + private native Object nativeGetIconColor(); + + private native Object nativeGetIconHaloColor(); + + private native Object nativeGetIconHaloWidth(); + + private native Object nativeGetIconHaloBlur(); + + private native Object nativeGetIconTranslate(); + + private native Object nativeGetIconTranslateAnchor(); + + private native Object nativeGetTextOpacity(); + + private native Object nativeGetTextColor(); + + private native Object nativeGetTextHaloColor(); + + private native Object nativeGetTextHaloWidth(); + + private native Object nativeGetTextHaloBlur(); + + private native Object nativeGetTextTranslate(); + + private native Object nativeGetTextTranslateAnchor(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs new file mode 100644 index 0000000000..79bf98d389 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs @@ -0,0 +1,63 @@ +<% + const type = locals.type; + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style.layers; + +/** + * <%- camelize(type) %> Layer + */ +public class <%- camelize(type) %>Layer extends Layer { + + public <%- camelize(type) %>Layer(long nativePtr) { + super(nativePtr); + } + +<% if (type === 'background') { -%> + public <%- camelize(type) %>Layer(String layerId) { + initialize(layerId); + } + + protected native void initialize(String layerId); +<% } else { -%> + public <%- camelize(type) %>Layer(String layerId, String sourceId) { + initialize(layerId, sourceId); + } + + protected native void initialize(String layerId, String sourceId); + + public void setSourceLayer(String sourceLayer) { + checkValidity(); + nativeSetSourceLayer(sourceLayer); + } +<% } -%> + +<% if (type !== 'background' && type !== 'raster') { -%> + public void setFilter(Filter.Statement filter) { + checkValidity(); + this.setFilter(filter.toArray()); + } + + public void setFilter(Object[] filter) { + checkValidity(); + nativeSetFilter(filter); + } + +<% } -%> + + // Property getters + +<% for (const property of properties) { -%> + @SuppressWarnings("unchecked") + public PropertyValue<<%- propertyType(property) %>> get<%- camelize(property.name) %>() { + checkValidity(); + return (PropertyValue<<%- propertyType(property) %>>) new PropertyValue(nativeGet<%- camelize(property.name) %>()); + } + +<% } -%> +<% for (const property of properties) { -%> + private native Object nativeGet<%- camelize(property.name) %>(); + +<% } -%> +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs new file mode 100644 index 0000000000..e734a9ff11 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs @@ -0,0 +1,53 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.StringDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Paint/Layout properties for Layer + */ +public abstract class Property { + + //visibility + public static final String VISIBLE = "visible"; + public static final String NONE = "none"; + + @StringDef({ + VISIBLE, + NONE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface VISIBILITY {} + +<% for (const property of properties) { -%> + //<%- property.name %> +<% for (const value of property.values) { -%> + public static final String <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %> = "<%- value %>"; +<% } -%> + + @StringDef({ + <% for (const value of property.values) { -%> + <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %>, + <% } -%> + }) + @Retention(RetentionPolicy.SOURCE) + public @interface <%- snakeCaseUpper(property.name) %> {} + +<% } -%> + + //Class definition + public final String name; + public final T value; + + /* package */ Property(String name, T value) { + this.name = name; + this.value = value; + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs new file mode 100644 index 0000000000..c7424bc31e --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs @@ -0,0 +1,78 @@ +<% + const paintProperties = locals.paintProperties; + const layoutProperties = locals.layoutProperties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style.layers; + +import android.annotation.SuppressLint; +import android.support.annotation.ColorInt; + +/** + * Constructs paint/layout properties for Layers + * + * @see > visibility(Function function) { + return new LayoutProperty<>("visibility", function); + } + +<% for (const property of paintProperties) { -%> +<% if (property.type == 'color') { -%> + /** + * <%- property.doc %> + */ + public static Property <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) { + return new PaintProperty<>("<%- property.name %>", colorToRgbaString(value)); + } + +<% } -%> + /** + * <%- property.doc %> + */ + public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { + return new PaintProperty<>("<%- property.name %>", value); + } + + /** + * <%- property.doc %> + */ + public static Property>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<<%- propertyType(property) %>> function) { + return new PaintProperty<>("<%- property.name %>", function); + } + +<% } -%> +<% for (const property of layoutProperties) { -%> + /** + * <%- property.doc %> + */ + public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { + return new LayoutProperty<>("<%- property.name %>", value); + } + + /** + * <%- property.doc %> + */ + public static Property>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<<%- propertyType(property) %>> function) { + return new LayoutProperty<>("<%- property.name %>", function); + } + +<% } -%> + @SuppressLint("DefaultLocale") + static String colorToRgbaString(@ColorInt int value) { + return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java index d0bc7ca2fe..f5db6f2a37 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java @@ -2,9 +2,15 @@ package com.mapbox.mapboxsdk.style.sources; import java.net.URL; +/** + * Construct a Raster Source. + * + * @see The style specificition + */ public class RasterSource extends Source { public static final String TYPE = "raster"; private static final String URL_KEY = "url"; + private static final String TILE_SIZE_KEY = "tileSize"; public RasterSource(String id, URL url) { this(id, url.toExternalForm()); @@ -14,4 +20,14 @@ public class RasterSource extends Source { super(id, TYPE); this.put(URL_KEY, url); } + + public RasterSource(String id, TileSet tileSet) { + super(id, TYPE); + this.putAll(tileSet.toValueObject()); + } + + public RasterSource withTileSize(int tileSize) { + this.put(TILE_SIZE_KEY, (float) tileSize); + return this; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java new file mode 100644 index 0000000000..1da8827d72 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java @@ -0,0 +1,290 @@ +package com.mapbox.mapboxsdk.style.sources; + +import android.support.annotation.Size; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +import java.util.HashMap; +import java.util.Map; + +/** + * Tile set + * + * @see The tileset specification + */ +public class TileSet { + private final String tilejson; + private String name; + private String description; + private String version; + private String attribution; + private String template; + private String legend; + private String scheme; + private final String[] tiles; + private String[] grids; + private String[] data; + private Float minZoom; + private Float maxZoom; + private Float[] bounds; + private Float[] center; + + /** + * @param tilejson A semver.org style version number. Describes the version of the TileJSON spec that is implemented by this JSON object. + * @param tiles An array of tile endpoints. {z}, {x} and {y}, if present, are replaced with the corresponding integers. + * If multiple endpoints are specified, clients may use any combination of endpoints. All endpoints MUST return the same + * content for the same URL. The array MUST contain at least one endpoint. + * Example: "http:localhost:8888/admin/1.0.0/world-light,broadband/{z}/{x}/{y}.png" + */ + public TileSet(String tilejson, String... tiles) { + this.tilejson = tilejson; + this.tiles = tiles; + } + + public String getTilejson() { + return tilejson; + } + + public String getName() { + return name; + } + + /** + * A name describing the tileset. The name can + * contain any legal character. Implementations SHOULD NOT interpret the + * name as HTML. + * "name": "compositing", + */ + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + /** + * A text description of the tileset. The + * description can contain any legal character. + * Implementations SHOULD NOT + * interpret the description as HTML. + * "description": "A simple, light grey world." + */ + public void setDescription(String description) { + this.description = description; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getAttribution() { + return attribution; + } + + /** + * Default: null. Contains an attribution to be displayed + * when the map is shown to a user. Implementations MAY decide to treat this + * as HTML or literal text. For security reasons, make absolutely sure that + * this field can't be abused as a vector for XSS or beacon tracking. + * "attribution": "OSM contributors", + */ + public void setAttribution(String attribution) { + this.attribution = attribution; + } + + public String getTemplate() { + return template; + } + + /** + * Contains a mustache template to be used to + * format data from grids for interaction. + * See https:github.com/mapbox/utfgrid-spec/tree/master/1.2 + * for the interactivity specification. + * "template": "{{#__teaser__}}{{NAME}}{{/__teaser__}}" + */ + public void setTemplate(String template) { + this.template = template; + } + + public String getLegend() { + return legend; + } + + /** + * Contains a legend to be displayed with the map. + * Implementations MAY decide to treat this as HTML or literal text. + * For security reasons, make absolutely sure that this field can't be + * abused as a vector for XSS or beacon tracking. + * "legend": "Dangerous zones are red, safe zones are green" + */ + public void setLegend(String legend) { + this.legend = legend; + } + + public String getScheme() { + return scheme; + } + + /** + * Default: "xyz". Either "xyz" or "tms". Influences the y + * direction of the tile coordinates. + * The global-mercator (aka Spherical Mercator) profile is assumed. + * "scheme": "xyz" + */ + public void setScheme(String scheme) { + this.scheme = scheme; + } + + public String[] getTiles() { + return tiles; + } + + public String[] getGrids() { + return grids; + } + + /** + * An array of interactivity endpoints. {z}, {x} + * and {y}, if present, are replaced with the corresponding integers. If multiple + * endpoints are specified, clients may use any combination of endpoints. + * All endpoints MUST return the same content for the same URL. + * If the array doesn't contain any entries, interactivity is not supported + * for this tileset. See https:github.com/mapbox/utfgrid-spec/tree/master/1.2 + * for the interactivity specification. + *

+ * Example: "http:localhost:8888/admin/1.0.0/broadband/{z}/{x}/{y}.grid.json" + */ + public void setGrids(String... grids) { + this.grids = grids; + } + + public String[] getData() { + return data; + } + + /** + * An array of data files in GeoJSON format. + * {z}, {x} and {y}, if present, + * are replaced with the corresponding integers. If multiple + * endpoints are specified, clients may use any combination of endpoints. + * All endpoints MUST return the same content for the same URL. + * If the array doesn't contain any entries, then no data is present in + * the map. + *

+ * "http:localhost:8888/admin/data.geojson" + */ + public void setData(String... data) { + this.data = data; + } + + public float getMinZoom() { + return minZoom; + } + + /** + * 0. >= 0, <= 22. An integer specifying the minimum zoom level. + */ + public void setMinZoom(float minZoom) { + this.minZoom = minZoom; + } + + public float getMaxZoom() { + return maxZoom; + } + + /** + * 0. >= 0, <= 22. An integer specifying the maximum zoom level. + */ + public void setMaxZoom(float maxZoom) { + this.maxZoom = maxZoom; + } + + public Float[] getBounds() { + return bounds; + } + + /** + * Default: [-180, -90, 180, 90]. The maximum extent of available map tiles. Bounds MUST define an area + * covered by all zoom levels. The bounds are represented in WGS:84 + * latitude and longitude values, in the order left, bottom, right, top. + * Values may be integers or floating point numbers. + */ + public void setBounds(@Size(value = 4) Float... bounds) { + this.bounds = bounds; + } + + public Float[] getCenter() { + return center; + } + + /** + * The first value is the longitude, the second is latitude (both in + * WGS:84 values), the third value is the zoom level as an integer. + * Longitude and latitude MUST be within the specified bounds. + * The zoom level MUST be between minzoom and maxzoom. + * Implementations can use this value to set the default location. If the + * value is null, implementations may use their own algorithm for + * determining a default location. + */ + public void setCenter(@Size(value = 2) Float... center) { + this.center = center; + } + + public void setCenter(LatLng center) { + this.center = new Float[]{(float) center.getLongitude(), (float) center.getLatitude()}; + } + + Map toValueObject() { + Map result = new HashMap<>(); + result.put("tilejson", tilejson); + result.put("tiles", tiles); + + if (name != null) { + result.put("name", name); + } + if (description != null) { + result.put("description", description); + } + if (version != null) { + result.put("version", version); + } + if (attribution != null) { + result.put("attribution", attribution); + } + if (template != null) { + result.put("template", template); + } + if (legend != null) { + result.put("legend", legend); + } + if (scheme != null) { + result.put("scheme", scheme); + } + if (grids != null) { + result.put("grids", grids); + } + if (data != null) { + result.put("data", data); + } + if (minZoom != null) { + result.put("minzoom", minZoom); + } + if (maxZoom != null) { + result.put("maxzoom", maxZoom); + } + if (bounds != null) { + result.put("bounds", bounds); + } + if (center != null) { + result.put("center", center); + } + + return result; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java index 9fc6acba3f..df3b73368c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java @@ -1,7 +1,6 @@ package com.mapbox.mapboxsdk.style.sources; import java.net.URL; -import java.util.HashMap; public class VectorSource extends Source { public static final String TYPE = "vector"; @@ -15,4 +14,9 @@ public class VectorSource extends Source { super(id, TYPE); this.put(URL_KEY, url); } + + public VectorSource(String id, TileSet tileSet) { + super(id, TYPE); + this.putAll(tileSet.toValueObject()); + } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/BackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/BackgroundLayerTest.java new file mode 100644 index 0000000000..9f61b290db --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/BackgroundLayerTest.java @@ -0,0 +1,120 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.BackgroundLayer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for BackgroundLayer + */ +@RunWith(AndroidJUnit4.class) +public class BackgroundLayerTest extends BaseTest { + private static final String TAG = BackgroundLayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private BackgroundLayer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + Log.i(TAG, "Retrieving layer"); + layer = mapboxMap.getLayerAs("background"); + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + public void testBackgroundColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + Log.i(TAG, "Retrieving layer"); + layer = mapboxMap.getLayerAs("background"); + Log.i(TAG, "background-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testBackgroundPattern() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + Log.i(TAG, "Retrieving layer"); + layer = mapboxMap.getLayerAs("background"); + Log.i(TAG, "background-pattern"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(backgroundPattern("pedestrian-polygon")); + assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon"); + } + + @Test + public void testBackgroundOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + Log.i(TAG, "Retrieving layer"); + layer = mapboxMap.getLayerAs("background"); + Log.i(TAG, "background-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(backgroundOpacity(0.3f)); + assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f); + } + + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/CircleLayerTest.java new file mode 100644 index 0000000000..0ea2ad6d12 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/CircleLayerTest.java @@ -0,0 +1,232 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.CircleLayer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for CircleLayer + */ +@RunWith(AndroidJUnit4.class) +public class CircleLayerTest extends BaseTest { + private static final String TAG = CircleLayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private CircleLayer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + public void testCircleRadius() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-radius"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleRadius(0.3f)); + assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f); + } + + @Test + public void testCircleColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testCircleBlur() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-blur"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleBlur(0.3f)); + assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f); + } + + @Test + public void testCircleOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleOpacity(0.3f)); + assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f); + } + + @Test + public void testCircleTranslate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-translate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleTranslate(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testCircleTranslateAnchor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-translate-anchor"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP); + } + + @Test + public void testCirclePitchScale() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "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"); + } + Log.i(TAG, "circle-pitch-scale"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP)); + assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP); + } + + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/FillLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/FillLayerTest.java new file mode 100644 index 0000000000..32ddc408c4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/FillLayerTest.java @@ -0,0 +1,232 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for FillLayer + */ +@RunWith(AndroidJUnit4.class) +public class FillLayerTest extends BaseTest { + private static final String TAG = FillLayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private FillLayer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + public void testFillAntialias() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-antialias"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillAntialias(true)); + assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true); + } + + @Test + public void testFillOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillOpacity(0.3f)); + assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f); + } + + @Test + public void testFillColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testFillOutlineColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-outline-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testFillTranslate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-translate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillTranslate(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testFillTranslateAnchor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-translate-anchor"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP); + } + + @Test + public void testFillPattern() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new FillLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "fill-pattern"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(fillPattern("pedestrian-polygon")); + assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon"); + } + + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/LineLayerTest.java new file mode 100644 index 0000000000..7e6f22b330 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/LineLayerTest.java @@ -0,0 +1,386 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.LineLayer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for LineLayer + */ +@RunWith(AndroidJUnit4.class) +public class LineLayerTest extends BaseTest { + private static final String TAG = LineLayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private LineLayer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + public void testLineCap() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-cap"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineCap(LINE_CAP_BUTT)); + assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT); + } + + @Test + public void testLineJoin() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-join"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineJoin(LINE_JOIN_BEVEL)); + assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL); + } + + @Test + public void testLineMiterLimit() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-miter-limit"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineMiterLimit(0.3f)); + assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f); + } + + @Test + public void testLineRoundLimit() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-round-limit"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineRoundLimit(0.3f)); + assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f); + } + + @Test + public void testLineOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineOpacity(0.3f)); + assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f); + } + + @Test + public void testLineColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testLineTranslate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-translate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineTranslate(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testLineTranslateAnchor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-translate-anchor"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP); + } + + @Test + public void testLineWidth() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-width"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineWidth(0.3f)); + assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f); + } + + @Test + public void testLineGapWidth() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-gap-width"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineGapWidth(0.3f)); + assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f); + } + + @Test + public void testLineOffset() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-offset"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineOffset(0.3f)); + assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f); + } + + @Test + public void testLineBlur() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-blur"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineBlur(0.3f)); + assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f); + } + + @Test + public void testLineDasharray() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-dasharray"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(lineDasharray(new Float[]{})); + assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[]{}); + } + + @Test + public void testLinePattern() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new LineLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "line-pattern"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(linePattern("pedestrian-polygon")); + assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon"); + } + + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RasterLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RasterLayerTest.java new file mode 100644 index 0000000000..b6cebc15a9 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RasterLayerTest.java @@ -0,0 +1,232 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.RasterLayer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for RasterLayer + */ +@RunWith(AndroidJUnit4.class) +public class RasterLayerTest extends BaseTest { + private static final String TAG = RasterLayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private RasterLayer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + public void testRasterOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterOpacity(0.3f)); + assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f); + } + + @Test + public void testRasterHueRotate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-hue-rotate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterHueRotate(0.3f)); + assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f); + } + + @Test + public void testRasterBrightnessMin() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-brightness-min"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterBrightnessMin(0.3f)); + assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f); + } + + @Test + public void testRasterBrightnessMax() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-brightness-max"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterBrightnessMax(0.3f)); + assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f); + } + + @Test + public void testRasterSaturation() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-saturation"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterSaturation(0.3f)); + assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f); + } + + @Test + public void testRasterContrast() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-contrast"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterContrast(0.3f)); + assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f); + } + + @Test + public void testRasterFadeDuration() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new RasterLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "raster-fade-duration"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(rasterFadeDuration(0.3f)); + assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f); + } + + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleBackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleBackgroundLayerTest.java new file mode 100644 index 0000000000..70ebf78556 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleBackgroundLayerTest.java @@ -0,0 +1,61 @@ +package com.mapbox.mapboxsdk.style; + +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.style.layers.BackgroundLayer; +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Basic smoke tests for BackgroundLayer + */ +@RunWith(AndroidJUnit4.class) +public class RuntimeStyleBackgroundLayerTest + extends ActivityInstrumentationTestCase2 { + private static final String TAG = RuntimeStyleBackgroundLayerTest.class.getSimpleName(); + + public RuntimeStyleBackgroundLayerTest() { + super(RuntimeStyleTestActivity.class); + } + + @Before + public void setUp() throws Exception { + super.setUp(); + injectInstrumentation(InstrumentationRegistry.getInstrumentation()); + } + + @Test + public void testSetVisibility() { + getActivity().mapView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(MapboxMap mapboxMap) { + Log.i(TAG, "visibility"); + BackgroundLayer layer = mapboxMap.getLayerAs("background"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), Property.VISIBLE); + + //Set + layer.setProperties(PropertyFactory.visibility(Property.NONE)); + assertEquals(layer.getVisibility().getValue(), Property.NONE); + } + }); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTests.java new file mode 100644 index 0000000000..4f570a0f50 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTests.java @@ -0,0 +1,91 @@ +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.sources.VectorSource; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * Basic smoke tests for Layer and Source + */ +@RunWith(AndroidJUnit4.class) +public class RuntimeStyleTests extends BaseTest { + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private OnMapReadyIdlingResource idlingResource; + + @Before + public void registerIdlingResource() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testGetAddRemoveLayer() { + checkViewIsDisplayed(R.id.mapView); + + MapboxMap mapboxMap = rule.getActivity().getMapboxMap(); + + //Get initial + assertNotNull(mapboxMap.getLayer("building")); + + //Remove + try { + mapboxMap.removeLayer("building"); + } catch (NoSuchLayerException e) { + assertFalse(true); + } + assertNull(mapboxMap.getLayer("building")); + + //Add + FillLayer layer = new FillLayer("building", "composite"); + layer.setSourceLayer("building"); + mapboxMap.addLayer(layer); + + assertNotNull(mapboxMap.getLayer("building")); + + try { + layer.setProperties(PropertyFactory.visibility(Property.VISIBLE)); + assertTrue("Never reached as the reference is invalid after adding", false); + } catch (Exception e) { + //Expected, reference is no longer valid + } + } + + @Test + public void testAddRemoveSource() { + checkViewIsDisplayed(R.id.mapView); + + MapboxMap mapboxMap = rule.getActivity().getMapboxMap(); + mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2")); + mapboxMap.removeSource("my-source"); + } + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTimingTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTimingTests.java new file mode 100644 index 0000000000..0f638002c6 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/RuntimeStyleTimingTests.java @@ -0,0 +1,54 @@ +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.sources.VectorSource; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTimingTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Basic smoke tests for adding Layer and Source as early as possible (in onCreate) + */ +@RunWith(AndroidJUnit4.class) +public class RuntimeStyleTimingTests extends BaseTest { + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTimingTestActivity.class); + + private OnMapReadyIdlingResource idlingResource; + + @Before + public void registerIdlingResource() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testGetAddRemoveLayer() { + checkViewIsDisplayed(R.id.mapView); + //We're good if it didn't crash + } + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/SymbolLayerTest.java new file mode 100644 index 0000000000..3c93c00503 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/SymbolLayerTest.java @@ -0,0 +1,1134 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for SymbolLayer + */ +@RunWith(AndroidJUnit4.class) +public class SymbolLayerTest extends BaseTest { + private static final String TAG = SymbolLayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private SymbolLayer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + + @Test + public void testSymbolPlacement() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "symbol-placement"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT)); + assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT); + } + + @Test + public void testSymbolSpacing() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "symbol-spacing"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(symbolSpacing(0.3f)); + assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f); + } + + @Test + public void testSymbolAvoidEdges() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "symbol-avoid-edges"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(symbolAvoidEdges(true)); + assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true); + } + + @Test + public void testIconAllowOverlap() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-allow-overlap"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconAllowOverlap(true)); + assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true); + } + + @Test + public void testIconIgnorePlacement() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-ignore-placement"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconIgnorePlacement(true)); + assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true); + } + + @Test + public void testIconOptional() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-optional"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconOptional(true)); + assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true); + } + + @Test + public void testIconRotationAlignment() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-rotation-alignment"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); + assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP); + } + + @Test + public void testIconSize() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-size"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconSize(0.3f)); + assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f); + } + + @Test + public void testIconTextFit() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-text-fit"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE)); + assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE); + } + + @Test + public void testIconTextFitPadding() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-text-fit-padding"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconTextFitPadding(new Float[]{0f,0f,0f,0f})); + assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[]{0f,0f,0f,0f}); + } + + @Test + public void testIconImage() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-image"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconImage("undefined")); + assertEquals((String) layer.getIconImage().getValue(), (String) "undefined"); + } + + @Test + public void testIconRotate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-rotate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconRotate(0.3f)); + assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f); + } + + @Test + public void testIconPadding() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-padding"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconPadding(0.3f)); + assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f); + } + + @Test + public void testIconKeepUpright() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-keep-upright"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconKeepUpright(true)); + assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true); + } + + @Test + public void testIconOffset() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-offset"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconOffset(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testTextPitchAlignment() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-pitch-alignment"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP)); + assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP); + } + + @Test + public void testTextRotationAlignment() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-rotation-alignment"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP)); + assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP); + } + + @Test + public void testTextField() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-field"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textField("")); + assertEquals((String) layer.getTextField().getValue(), (String) ""); + } + + @Test + public void testTextFont() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-font"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"})); + assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}); + } + + @Test + public void testTextSize() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-size"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textSize(0.3f)); + assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f); + } + + @Test + public void testTextMaxWidth() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-max-width"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textMaxWidth(0.3f)); + assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f); + } + + @Test + public void testTextLineHeight() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-line-height"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textLineHeight(0.3f)); + assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f); + } + + @Test + public void testTextLetterSpacing() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-letter-spacing"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textLetterSpacing(0.3f)); + assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f); + } + + @Test + public void testTextJustify() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-justify"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT)); + assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT); + } + + @Test + public void testTextAnchor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-anchor"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER)); + assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER); + } + + @Test + public void testTextMaxAngle() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-max-angle"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textMaxAngle(0.3f)); + assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f); + } + + @Test + public void testTextRotate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-rotate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textRotate(0.3f)); + assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f); + } + + @Test + public void testTextPadding() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-padding"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textPadding(0.3f)); + assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f); + } + + @Test + public void testTextKeepUpright() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-keep-upright"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textKeepUpright(true)); + assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true); + } + + @Test + public void testTextTransform() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-transform"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textTransform(TEXT_TRANSFORM_NONE)); + assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE); + } + + @Test + public void testTextOffset() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-offset"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textOffset(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testTextAllowOverlap() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-allow-overlap"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textAllowOverlap(true)); + assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true); + } + + @Test + public void testTextIgnorePlacement() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-ignore-placement"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textIgnorePlacement(true)); + assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true); + } + + @Test + public void testTextOptional() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-optional"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textOptional(true)); + assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true); + } + + @Test + public void testIconOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconOpacity(0.3f)); + assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f); + } + + @Test + public void testIconColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testIconHaloColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-halo-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testIconHaloWidth() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-halo-width"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconHaloWidth(0.3f)); + assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f); + } + + @Test + public void testIconHaloBlur() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-halo-blur"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconHaloBlur(0.3f)); + assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f); + } + + @Test + public void testIconTranslate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-translate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconTranslate(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testIconTranslateAnchor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "icon-translate-anchor"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP); + } + + @Test + public void testTextOpacity() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-opacity"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textOpacity(0.3f)); + assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f); + } + + @Test + public void testTextColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testTextHaloColor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-halo-color"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + + @Test + public void testTextHaloWidth() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-halo-width"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textHaloWidth(0.3f)); + assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f); + } + + @Test + public void testTextHaloBlur() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-halo-blur"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textHaloBlur(0.3f)); + assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f); + } + + @Test + public void testTextTranslate() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-translate"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textTranslate(new Float[]{0f,0f})); + assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[]{0f,0f}); + } + + @Test + public void testTextTranslateAnchor() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new SymbolLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + Log.i(TAG, "text-translate-anchor"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP)); + assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP); + } + + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/layer.junit.ejs new file mode 100644 index 0000000000..b818aac179 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/layer.junit.ejs @@ -0,0 +1,116 @@ +<% + const type = locals.type; + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +package com.mapbox.mapboxsdk.style; + +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.layers.<%- camelize(type) %>Layer; +import com.mapbox.mapboxsdk.testapp.R; +import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity; +import com.mapbox.mapboxsdk.testapp.espresso.BaseTest; +import com.mapbox.mapboxsdk.testapp.espresso.utils.OnMapReadyIdlingResource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Basic smoke tests for <%- camelize(type) %>Layer + */ +@RunWith(AndroidJUnit4.class) +public class <%- camelize(type) %>LayerTest extends BaseTest { + private static final String TAG = <%- camelize(type) %>LayerTest.class.getSimpleName(); + + @Rule + public final ActivityTestRule rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class); + + private <%- camelize(type) %>Layer layer; + + private OnMapReadyIdlingResource idlingResource; + + private MapboxMap mapboxMap; + + @Before + public void setup() { + idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); + Espresso.registerIdlingResources(idlingResource); + } + + @Test + public void testSetVisibility() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + +<% if (type === 'background') { -%> + Log.i(TAG, "Retrieving layer"); + layer = mapboxMap.getLayerAs("background"); +<% } else { -%> + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new <%- camelize(type) %>Layer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } +<% } -%> + Log.i(TAG, "visibility"); + assertNotNull(layer); + + //Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + //Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + +<% for (const property of properties) { -%> + @Test + public void test<%- camelize(property.name) %>() { + checkViewIsDisplayed(R.id.mapView); + + mapboxMap = rule.getActivity().getMapboxMap(); + +<% if (type === 'background') { -%> + Log.i(TAG, "Retrieving layer"); + layer = mapboxMap.getLayerAs("background"); +<% } else { -%> + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Log.i(TAG, "Adding layer"); + layer = new <%- camelize(type) %>Layer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + //Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } +<% } -%> + Log.i(TAG, "<%- property.name %>"); + assertNotNull(layer); + + //Set and Get + layer.setProperties(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)); + assertEquals((<%- propertyType(property) %>) layer.get<%- camelize(property.name) %>().getValue(), (<%- propertyType(property) %>) <%- defaultValueJava(property) %>); + } + +<% } -%> + + @After + public void unregisterIntentServiceIdlingResource() { + Espresso.unregisterIdlingResources(idlingResource); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/espresso/utils/OnMapReadyIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/espresso/utils/OnMapReadyIdlingResource.java new file mode 100644 index 0000000000..cb046c58bb --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/espresso/utils/OnMapReadyIdlingResource.java @@ -0,0 +1,51 @@ +package com.mapbox.mapboxsdk.testapp.espresso.utils; + +import android.app.Activity; +import android.support.test.espresso.IdlingResource; +import android.util.Log; + +import com.mapbox.mapboxsdk.constants.MapboxConstants; + +import java.lang.reflect.Field; + +public class OnMapReadyIdlingResource implements IdlingResource { + + private final Activity activity; + private IdlingResource.ResourceCallback resourceCallback; + + public OnMapReadyIdlingResource(Activity activity) { + this.activity = activity; + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public boolean isIdleNow() { + boolean idle = isMapboxMapReady(); + if (idle && resourceCallback != null) { + resourceCallback.onTransitionToIdle(); + } + return idle; + } + + @Override + public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { + this.resourceCallback = resourceCallback; + } + + private boolean isMapboxMapReady() { + try { + Field field = activity.getClass().getDeclaredField("mapboxMap"); + field.setAccessible(true); + Object value = field.get(activity); + Log.e(MapboxConstants.TAG, "isMapboxReady called with value " + (value != null)); + return value != null; + } catch (Exception e) { + Log.e(MapboxConstants.TAG, "could not reflect", e); + return false; + } + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index 584969229f..9dc2037238 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -317,6 +317,11 @@ android:value="@string/category_imagegenerator" /> + + + + + 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startFeature(features.get(requestCode)); - }else{ - Snackbar.make(findViewById(android.R.id.content),"Can't open without the location permission.",Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(findViewById(android.R.id.content), "Can't open without the location permission.", Snackbar.LENGTH_SHORT).show(); } } @@ -147,7 +147,7 @@ public class FeatureOverviewActivity extends AppCompatActivity { String packageName = getApplicationContext().getPackageName(); String metaDataKey = getString(R.string.category); for (ActivityInfo info : app.activities) { - if (info.name.startsWith(packageName) && !info.name.equals(FeatureOverviewActivity.class.getName())) { + if (info.labelRes != 0 && info.name.startsWith(packageName) && !info.name.equals(FeatureOverviewActivity.class.getName())) { String label = getString(info.labelRes); String description = resolveString(info.descriptionRes); String category = resolveMetaData(info.metaData, metaDataKey); @@ -176,10 +176,10 @@ public class FeatureOverviewActivity extends AppCompatActivity { return category; } - private String resolveString(@StringRes int stringRes){ - try{ + private String resolveString(@StringRes int stringRes) { + try { return getString(stringRes); - }catch (Resources.NotFoundException e){ + } catch (Resources.NotFoundException e) { return "-"; } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java index 98c86d4313..4070216537 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java @@ -6,18 +6,21 @@ import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.MenuItem; import android.view.View; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.layers.CustomLayer; +import com.mapbox.mapboxsdk.style.layers.CustomLayer; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.model.customlayer.ExampleCustomLayer; public class CustomLayerActivity extends AppCompatActivity { + private static final String TAG = CustomLayerActivity.class.getSimpleName(); private MapboxMap mapboxMap; private MapView mapView; @@ -66,10 +69,14 @@ public class CustomLayerActivity extends AppCompatActivity { private void swapCustomLayer() { if (isShowingCustomLayer) { - mapboxMap.removeCustomLayer("custom"); + try { + mapboxMap.removeLayer("custom"); + } catch (NoSuchLayerException e) { + Log.e(TAG, "No custom layer to remove"); + } fab.setImageResource(R.drawable.ic_layers_24dp); } else { - mapboxMap.addCustomLayer(new CustomLayer("custom", + mapboxMap.addLayer(new CustomLayer("custom", ExampleCustomLayer.createContext(), ExampleCustomLayer.InitializeFunction, ExampleCustomLayer.RenderFunction, diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java index d0049eeb31..b104f9ea03 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java @@ -6,6 +6,7 @@ import android.support.annotation.RawRes; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; @@ -16,14 +17,17 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.Function; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.LineLayer; import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyValue; import com.mapbox.mapboxsdk.style.layers.RasterLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import com.mapbox.mapboxsdk.style.sources.RasterSource; import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.mapboxsdk.style.sources.TileSet; import com.mapbox.mapboxsdk.style.sources.VectorSource; import com.mapbox.mapboxsdk.testapp.R; @@ -36,6 +40,7 @@ import java.io.StringWriter; import java.io.Writer; import static com.mapbox.mapboxsdk.style.layers.Filter.*; +import static com.mapbox.mapboxsdk.style.layers.Function.*; import static com.mapbox.mapboxsdk.style.layers.Property.*; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; @@ -138,6 +143,12 @@ public class RuntimeStyleActivity extends AppCompatActivity { case R.id.action_add_satellite_layer: addSatelliteLayer(); return true; + case R.id.action_update_water_color_on_zoom: + updateWaterColorOnZoom(); + return true; + case R.id.action_add_custom_tiles: + addCustomTileSource(); + return true; default: return super.onOptionsItemSelected(item); } @@ -148,7 +159,7 @@ public class RuntimeStyleActivity extends AppCompatActivity { for (String roadLayer : roadLayers) { Layer layer = mapboxMap.getLayer(roadLayer); if (layer != null) { - layer.set(visibility(false)); + layer.setProperties(visibility(VISIBLE)); } } } @@ -162,7 +173,7 @@ public class RuntimeStyleActivity extends AppCompatActivity { for (String roadLayer : roadLayers) { Layer layer = mapboxMap.getLayer(roadLayer); if (layer != null) { - layer.set(symbolPlacement(SYMBOL_PLACEMENT_POINT)); + layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT)); } } } @@ -172,16 +183,16 @@ public class RuntimeStyleActivity extends AppCompatActivity { private void setBackgroundOpacity() { Layer background = mapboxMap.getLayer("background"); if (background != null) { - background.set(backgroundOpacity(0.2f)); + background.setProperties(backgroundOpacity(0.2f)); } } private void setWaterColor() { Layer water = mapboxMap.getLayer("water"); if (water != null) { - water.set( - visibility(true), - fillColor(Color.RED) + water.setProperties( + visibility(VISIBLE), + fillColor(Color.RED) ); } else { Toast.makeText(RuntimeStyleActivity.this, "No water layer in this style", Toast.LENGTH_SHORT).show(); @@ -210,7 +221,7 @@ public class RuntimeStyleActivity extends AppCompatActivity { mapboxMap.addSource(source); FillLayer layer = new FillLayer("parksLayer", "amsterdam-spots"); - layer.set( + layer.setProperties( fillColor(Color.RED), fillOutlineColor(Color.BLUE), fillOpacity(0.3f), @@ -224,7 +235,18 @@ public class RuntimeStyleActivity extends AppCompatActivity { //layer.setPaintProperty(fillColor(Color.RED)); //XXX But not after the object is attached //Or get the object later and set it. It's all good. - mapboxMap.getLayer("parksLayer").set(fillColor(Color.RED)); + mapboxMap.getLayer("parksLayer").setProperties(fillColor(Color.RED)); + + //You can get a typed layer, if you're sure it's of that type. Use with care + layer = mapboxMap.getLayerAs("parksLayer"); + //And get some properties + PropertyValue fillAntialias = layer.getFillAntialias(); + Log.d(TAG, "Fill anti alias: " + fillAntialias.getValue()); + layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)); + PropertyValue fillTranslateAnchor = layer.getFillTranslateAnchor(); + Log.d(TAG, "Fill translate anchor: " + fillTranslateAnchor.getValue()); + PropertyValue visibility = layer.getVisibility(); + Log.d(TAG, "Visibility: " + visibility.getValue()); //Get a good look at it all mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12)); @@ -237,7 +259,7 @@ public class RuntimeStyleActivity extends AppCompatActivity { LineLayer layer = new LineLayer("terrainLayer", "my-terrain-source"); layer.setSourceLayer("contour"); - layer.set( + layer.setProperties( lineJoin(Property.LINE_JOIN_ROUND), lineCap(Property.LINE_CAP_ROUND), lineColor(Color.RED), @@ -245,17 +267,50 @@ public class RuntimeStyleActivity extends AppCompatActivity { ); mapboxMap.addLayer(layer); + + //Need to get a fresh handle + layer = mapboxMap.getLayerAs("terrainLayer"); + + //Make sure it's also applied after the fact + layer.setMinZoom(10); + layer.setMaxZoom(15); + + layer = (LineLayer) mapboxMap.getLayer("terrainLayer"); + Toast.makeText(this, String.format("Set min/max zoom to %s - %s", layer.getMinZoom(), layer.getMaxZoom()), Toast.LENGTH_SHORT).show(); } private void addSatelliteLayer() { //Add a source - Source source = new RasterSource("my-raster-source", "mapbox://mapbox.satellite"); + Source source = new RasterSource("my-raster-source", "mapbox://mapbox.satellite").withTileSize(512); mapboxMap.addSource(source); //Add a layer mapboxMap.addLayer(new RasterLayer("satellite-layer", "my-raster-source")); } + private void updateWaterColorOnZoom() { + FillLayer layer = mapboxMap.getLayerAs("water"); + if (layer == null) { + return; + } + + //Set a zoom function to update the color of the water + layer.setProperties(fillColor(zoom(0.8f, + stop(1, fillColor(Color.GREEN)), + stop(4, fillColor(Color.BLUE)), + stop(12, fillColor(Color.RED)), + stop(20, fillColor(Color.BLACK)) + ))); + + //do some animations to show it off properly + mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1), 1500); + + PropertyValue fillColor = layer.getFillColor(); + Function function = fillColor.getFunction(); + Log.d(TAG, "Fill color base: " + function.getBase()); + Log.d(TAG, "Fill color #stops: " + function.getStops().length); + } + private String readRawResource(@RawRes int rawResource) throws IOException { InputStream is = getResources().openRawResource(rawResource); Writer writer = new StringWriter(); @@ -284,6 +339,17 @@ public class RuntimeStyleActivity extends AppCompatActivity { } } + private void addCustomTileSource() { + //Add a source + Source source = new VectorSource("custom-tile-source", new TileSet("2.1.0", "https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-LM25tq4")); + mapboxMap.addSource(source); + + //Add a layer + FillLayer layer = new FillLayer("custom-tile-layers", "custom-tile-source"); + layer.setSourceLayer("water"); + mapboxMap.addLayer(layer); + } + private static class DefaultCallback implements MapboxMap.CancelableCallback { @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java new file mode 100644 index 0000000000..6f04852ca1 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java @@ -0,0 +1,69 @@ +package com.mapbox.mapboxsdk.testapp.activity.style; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.testapp.R; + +/** + * Test activity for unit test execution + */ +public class RuntimeStyleTestActivity extends AppCompatActivity { + private static final String TAG = RuntimeStyleTestActivity.class.getSimpleName(); + + public MapView mapView; + private MapboxMap mapboxMap; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_runtime_style); + + //Initialize map as normal + mapView = (MapView) findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(MapboxMap mapboxMap) { + RuntimeStyleTestActivity.this.mapboxMap = mapboxMap; + } + }); + } + + public MapboxMap getMapboxMap() { + return mapboxMap; + } + + @Override + public void onResume() { + super.onResume(); + mapView.onResume(); + } + + @Override + public void onPause() { + super.onPause(); + mapView.onPause(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java new file mode 100644 index 0000000000..9463cfcf08 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java @@ -0,0 +1,87 @@ +package com.mapbox.mapboxsdk.testapp.activity.style; + +import android.graphics.Color; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.style.layers.CircleLayer; +import com.mapbox.mapboxsdk.style.sources.VectorSource; +import com.mapbox.mapboxsdk.testapp.R; + +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +/** + * Test activity for unit test execution + */ +public class RuntimeStyleTimingTestActivity extends AppCompatActivity { + private static final String TAG = RuntimeStyleTimingTestActivity.class.getSimpleName(); + + public MapView mapView; + private MapboxMap mapboxMap; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_runtime_style); + + //Initialize map as normal + mapView = (MapView) findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(MapboxMap mapboxMap) { + RuntimeStyleTimingTestActivity.this.mapboxMap = mapboxMap; + VectorSource museums = new VectorSource("museums_source", "mapbox://mapbox.2opop9hr"); + mapboxMap.addSource(museums); + + CircleLayer museumsLayer = new CircleLayer("museums", "museums_source"); + museumsLayer.setSourceLayer("museum-cusco"); + museumsLayer.setProperties( + visibility(VISIBLE), + circleRadius(8f), + circleColor(Color.argb(1, 55, 148, 179)) + ); + + mapboxMap.addLayer(museumsLayer); + } + }); + } + + public MapboxMap getMapboxMap() { + return mapboxMap; + } + + @Override + public void onResume() { + super.onResume(); + mapView.onResume(); + } + + @Override + public void onPause() { + super.onPause(); + mapView.onPause(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_runtime_style.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_runtime_style.xml index 69784584c0..189a33708f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_runtime_style.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_runtime_style.xml @@ -34,4 +34,12 @@ android:id="@+id/action_add_satellite_layer" android:title="Add a satellite layer" mapbox:showAsAction="never"/> + + \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java new file mode 100644 index 0000000000..1106009ea8 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java @@ -0,0 +1,29 @@ +package com.mapbox.mapboxsdk.style.layers; + +import org.junit.Test; + +import static com.mapbox.mapboxsdk.style.layers.Function.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import static org.junit.Assert.*; + +/** + * Tests Function + */ +public class FunctionTest { + + @Test + public void testZoomFunction() { + Function zoomF = zoom( + stop(1f, lineBlur(1f)), + stop(10f, lineBlur(20f)) + ); + + assertNotNull(zoomF.toValueObject()); + assertArrayEquals( + new Object[]{new Object[]{1f, 1f}, new Object[]{10f, 20f}}, + (Object[]) zoomF.toValueObject().get("stops") + ); + } + +} diff --git a/platform/android/platform.gyp b/platform/android/platform.gyp index cd49dc25d8..f8e8b33b08 100644 --- a/platform/android/platform.gyp +++ b/platform/android/platform.gyp @@ -43,6 +43,7 @@ 'src/style/layers/line_layer.cpp', 'src/style/layers/raster_layer.cpp', 'src/style/layers/symbol_layer.cpp', + 'src/style/layers/custom_layer.cpp', '../default/string_stdlib.cpp', '../default/image.cpp', '../default/png_reader.cpp', diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index 03bfac8067..0abc4969be 100644 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -22,18 +22,11 @@ global.camelizeWithLeadingLowercase = function (str) { }); } -global.snakeCaseUpper = function (str) { +global.snakeCaseUpper = function snakeCaseUpper(str) { return str.replace(/-/g, "_").toUpperCase(); } global.propertyType = function propertyType(property) { -//TODO: Doe we want these exceptions? -// if (/-translate-anchor$/.test(property.name)) { - // return 'TranslateAnchorType'; - // } - // if (/-(rotation|pitch)-alignment$/.test(property.name)) { - // return 'AlignmentType'; - // } switch (property.type) { case 'boolean': return 'Boolean'; @@ -42,9 +35,9 @@ global.propertyType = function propertyType(property) { case 'string': return 'String'; case 'enum': - return `String`; + return 'String'; case 'color': - return `String`; + return 'String'; case 'array': return `${propertyType({type:property.value})}[]`; default: @@ -52,6 +45,53 @@ global.propertyType = function propertyType(property) { } } +global.propertyJNIType = function propertyJNIType(property) { + switch (property.type) { + case 'boolean': + return 'jboolean'; + case 'jfloat': + return 'Float'; + case 'String': + return 'String'; + case 'enum': + return 'String'; + case 'color': + return 'String'; + case 'array': + return `jarray<${propertyType({type:property.value})}[]>`; + default: + return 'jobject*'; + } +} + +global.propertyNativeType = function (property) { + if (/-translate-anchor$/.test(property.name)) { + return 'TranslateAnchorType'; + } + if (/-(rotation|pitch)-alignment$/.test(property.name)) { + return 'AlignmentType'; + } + switch (property.type) { + case 'boolean': + return 'bool'; + case 'number': + return 'float'; + case 'string': + return 'std::string'; + case 'enum': + return `${camelize(property.name)}Type`; + case 'color': + return `Color`; + case 'array': + if (property.length) { + return `std::array<${propertyType({type: property.value})}, ${property.length}>`; + } else { + return `std::vector<${propertyType({type: property.value})}>`; + } + default: throw new Error(`unknown type for ${property.name}`) + } +} + global.propertyTypeAnnotation = function propertyTypeAnnotation(property) { switch (property.type) { case 'enum': @@ -61,6 +101,42 @@ global.propertyTypeAnnotation = function propertyTypeAnnotation(property) { } }; +global.defaultValueJava = function(property) { + if(property.name.endsWith("-pattern")) { + return '"pedestrian-polygon"'; + } + if(property.name.endsWith("-font")) { + return 'new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}'; + } + switch (property.type) { + case 'boolean': + return 'true'; + case 'number': + return '0.3f'; + case 'string': + return '"' + property['default'] + '"'; + case 'enum': + return snakeCaseUpper(property.name) + "_" + snakeCaseUpper(property.values[0]); + case 'color': + return '"rgba(0, 0, 0, 1)"'; + case 'array': + switch (property.value) { + case 'string': + return '[' + property['default'] + "]"; + case 'number': + var result ='new Float[]{'; + for (var i = 0; i < property.length; i++) { + result += "0f"; + if (i +1 != property.length) { + result += ","; + } + } + return result + "}"; + } + default: throw new Error(`unknown type for ${property.name}`) + } +} + //Process Layers const layers = spec.layer.type.values.map((type) => { const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => { @@ -81,24 +157,27 @@ const layers = spec.layer.type.values.map((type) => { type: type, layoutProperties: layoutProperties, paintProperties: paintProperties, + properties: layoutProperties.concat(paintProperties) }; }); -const layerHpp = ejs.compile(fs.readFileSync('platform/android/scripts/layer.hpp.ejs', 'utf8'), {strict: true}); -const layerCpp = ejs.compile(fs.readFileSync('platform/android/scripts/layer.cpp.ejs', 'utf8'), {strict: true}); -const layerJava = ejs.compile(fs.readFileSync('platform/android/scripts/layer.java.ejs', 'utf8'), {strict: true}); +const layerHpp = ejs.compile(fs.readFileSync('platform/android/src/style/layers/layer.hpp.ejs', 'utf8'), {strict: true}); +const layerCpp = ejs.compile(fs.readFileSync('platform/android/src/style/layers/layer.cpp.ejs', 'utf8'), {strict: true}); +const layerJava = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs', 'utf8'), {strict: true}); +const layerJavaUnitTests = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/layer.junit.ejs', 'utf8'), {strict: true}); for (const layer of layers) { fs.writeFileSync(`platform/android/src/style/layers/${layer.type}_layer.hpp`, layerHpp(layer)); fs.writeFileSync(`platform/android/src/style/layers/${layer.type}_layer.cpp`, layerCpp(layer)); fs.writeFileSync(`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/${camelize(layer.type)}Layer.java`, layerJava(layer)); + fs.writeFileSync(`platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/style/${camelize(layer.type)}LayerTest.java`, layerJavaUnitTests(layer)); } //Process all layer properties const layoutProperties = _(layers).map('layoutProperties').flatten().value(); const paintProperties = _(layers).map('paintProperties').flatten().value(); -const propertiesTemplate = ejs.compile(fs.readFileSync('platform/android/scripts/layer_property_factory.java.ejs', 'utf8'), {strict: true}); +const propertiesTemplate = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs', 'utf8'), {strict: true}); fs.writeFileSync( `platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java`, propertiesTemplate({layoutProperties: layoutProperties, paintProperties: paintProperties}) @@ -106,9 +185,22 @@ fs.writeFileSync( //Create types for the enum properties const enumProperties = _(layoutProperties).union(paintProperties).filter({'type': 'enum'}).value(); -const enumPropertyTemplate = ejs.compile(fs.readFileSync('platform/android/scripts/layer_property.java.ejs', 'utf8'), {strict: true}); +const enumPropertyJavaTemplate = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs', 'utf8'), {strict: true}); fs.writeFileSync( `platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java`, - enumPropertyTemplate({properties: enumProperties}) + enumPropertyJavaTemplate({properties: enumProperties}) ); +//De-dup types before generating cpp headers +const enumPropertiesDeDup = _(enumProperties).uniq(global.propertyNativeType).value(); +const enumPropertyHppTypeStringValueTemplate = ejs.compile(fs.readFileSync('platform/android/src/style/conversion/types_string_values.hpp.ejs', 'utf8'), {strict: true}); +fs.writeFileSync( + `platform/android/src/style/conversion/types_string_values.hpp`, + enumPropertyHppTypeStringValueTemplate({properties: enumPropertiesDeDup}) +); + +const enumPropertyHppTypeTemplate = ejs.compile(fs.readFileSync('platform/android/src/style/conversion/types.hpp.ejs', 'utf8'), {strict: true}); +fs.writeFileSync( + `platform/android/src/style/conversion/types.hpp`, + enumPropertyHppTypeTemplate({properties: enumPropertiesDeDup}) +); diff --git a/platform/android/scripts/layer.cpp.ejs b/platform/android/scripts/layer.cpp.ejs deleted file mode 100644 index b53bc3c4d6..0000000000 --- a/platform/android/scripts/layer.cpp.ejs +++ /dev/null @@ -1,64 +0,0 @@ -<% - const type = locals.type; --%> -// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. - -#include "<%- type %>_layer.hpp" - -#include - -//XXX -#include - -namespace mbgl { -namespace android { - -<% if (type === 'background') { -%> - <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(jni::JNIEnv& env, jni::String layerId) - : Layer(env, std::make_uniqueLayer>(jni::Make(env, layerId))) { -<% } else { -%> - <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) - : Layer(env, std::make_uniqueLayer>(jni::Make(env, layerId), jni::Make(env, sourceId))) { -<% } -%> - mbgl::Log::Debug(mbgl::Event::JNI, "<%- camelize(type) %>Layer constructed, owning reference"); - } - - <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(mbgl::Map& map, mbgl::style::<%- camelize(type) %>Layer& coreLayer) - : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "<%- camelize(type) %>Layer Non-owning reference constructor"); - } - - <%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default; - - jni::Class<<%- camelize(type) %>Layer> <%- camelize(type) %>Layer::javaClass; - - jni::jobject* <%- camelize(type) %>Layer::createJavaPeer(jni::JNIEnv& env) { - static auto constructor = <%- camelize(type) %>Layer::javaClass.template GetConstructor(env); - return <%- camelize(type) %>Layer::javaClass.New(env, constructor, reinterpret_cast(this)); - } - - void <%- camelize(type) %>Layer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - - //Lookup the class - <%- camelize(type) %>Layer::javaClass = *jni::Class<<%- camelize(type) %>Layer>::Find(env).NewGlobalRef(env).release(); - - #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) - - //Register the peer - jni::RegisterNativePeer<<%- camelize(type) %>Layer>( - env, <%- camelize(type) %>Layer::javaClass, "nativePtr", -<% if (type === 'background') { -%> - std::make_unique<<%- camelize(type) %>Layer, JNIEnv&, jni::String>, -<% } else { -%> - std::make_unique<<%- camelize(type) %>Layer, JNIEnv&, jni::String, jni::String>, -<% } -%> - "initialize", - "finalize" - ); - - } - -} // namespace android -} // namespace mbgl diff --git a/platform/android/scripts/layer.hpp.ejs b/platform/android/scripts/layer.hpp.ejs deleted file mode 100644 index f735e3e35c..0000000000 --- a/platform/android/scripts/layer.hpp.ejs +++ /dev/null @@ -1,38 +0,0 @@ -<% - const type = locals.type; --%> -// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. - -#pragma once - -#include "layer.hpp" -#include _layer.hpp> -#include - -namespace mbgl { -namespace android { - -class <%- camelize(type) %>Layer : public Layer { -public: - - static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/layers/<%- camelize(type) %>Layer"; }; - - static jni::Class<<%- camelize(type) %>Layer> javaClass; - - static void registerNative(jni::JNIEnv&); - -<% if (type === 'background') { -%> - <%- camelize(type) %>Layer(jni::JNIEnv&, jni::String); -<% } else { -%> - <%- camelize(type) %>Layer(jni::JNIEnv&, jni::String, jni::String); -<% } -%> - - <%- camelize(type) %>Layer(mbgl::Map&, mbgl::style::<%- camelize(type) %>Layer&); - - ~<%- camelize(type) %>Layer(); - - jni::jobject* createJavaPeer(jni::JNIEnv&); -}; - -} // namespace android -} // namespace mbgl diff --git a/platform/android/scripts/layer.java.ejs b/platform/android/scripts/layer.java.ejs deleted file mode 100644 index a5ca4c0521..0000000000 --- a/platform/android/scripts/layer.java.ejs +++ /dev/null @@ -1,44 +0,0 @@ -<% - const type = locals.type; --%> -// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. -package com.mapbox.mapboxsdk.style.layers; - -/** - * <%- camelize(type) %> Layer - */ -public class <%- camelize(type) %>Layer extends Layer { - - public <%- camelize(type) %>Layer(long nativePtr) { - super(nativePtr); - } - -<% if (type === 'background') { -%> - public <%- camelize(type) %>Layer(String layerId) { - initialize(layerId); - } - - protected native void initialize(String layerId); -<% } else { -%> - public <%- camelize(type) %>Layer(String layerId, String sourceId) { - initialize(layerId, sourceId); - } - - protected native void initialize(String layerId, String sourceId); - - public void setSourceLayer(String sourceLayer) { - nativeSetSourceLayer(sourceLayer); - } -<% } -%> - -<% if (type !== 'background' && type !== 'raster') { -%> - public void setFilter(Filter.Statement filter) { - this.setFilter(filter.toArray()); - } - - public void setFilter(Object[] filter) { - nativeSetFilter(filter); - } - -<% } -%> -} diff --git a/platform/android/scripts/layer_property.java.ejs b/platform/android/scripts/layer_property.java.ejs deleted file mode 100644 index 7119feeef2..0000000000 --- a/platform/android/scripts/layer_property.java.ejs +++ /dev/null @@ -1,42 +0,0 @@ -<% - const properties = locals.properties; --%> -// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. -package com.mapbox.mapboxsdk.style.layers; - -import android.support.annotation.StringDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Paint/Layout properties for Layer - */ -public abstract class Property { - -<% for (const property of properties) { -%> - //<%- property.name %> -<% for (const value of property.values) { -%> - public static final String <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %> = "<%- value %>"; -<% } -%> - - @StringDef({ - <% for (const value of property.values) { -%> - <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %>, - <% } -%> - }) - @Retention(RetentionPolicy.SOURCE) - public @interface <%- snakeCaseUpper(property.name) %> {} - -<% } -%> - - //Class definition - public final String name; - public final T value; - - /* package */ Property(String name, T value) { - this.name = name; - this.value = value; - } - -} diff --git a/platform/android/scripts/layer_property_factory.java.ejs b/platform/android/scripts/layer_property_factory.java.ejs deleted file mode 100644 index 045f206d3f..0000000000 --- a/platform/android/scripts/layer_property_factory.java.ejs +++ /dev/null @@ -1,45 +0,0 @@ -<% - const paintProperties = locals.paintProperties; - const layoutProperties = locals.layoutProperties; --%> -// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. -package com.mapbox.mapboxsdk.style.layers; - -import android.annotation.SuppressLint; -import android.support.annotation.ColorInt; - -/** - * Constructs paint/layout properties for Layers - * @see -<% if (property.type == 'color') { -%> - public static Property <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) { - return new PaintProperty<>("<%- property.name %>", colorToRgbaString(value)); - } - -<% } -%> - public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { - return new PaintProperty<>("<%- property.name %>", value); - } - -<% } -%> -<% for (const property of layoutProperties) { -%> - public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { - return new LayoutProperty<>("<%- property.name %>", value); - } - -<% } -%> - @SuppressLint("DefaultLocale") - static String colorToRgbaString(@ColorInt int value) { - return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); - } - -} diff --git a/platform/android/src/conversion/constant.hpp b/platform/android/src/conversion/constant.hpp new file mode 100644 index 0000000000..9a570d3717 --- /dev/null +++ b/platform/android/src/conversion/constant.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include "conversion.hpp" + +#include +#include + +#include +#include +#include +#include + +namespace mbgl { +namespace android { +namespace conversion { + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const bool& value) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Boolean")).release(); + static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "", "(Z)V"); + return {&jni::NewObject(env, *javaClass, *constructor, (jboolean) value)}; + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const float& value) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Float")).release(); + static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "", "(F)V"); + return {&jni::NewObject(env, *javaClass, *constructor, (jfloat) value)}; + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const std::string& value) const { + return {jni::Make(env, value).Get()}; + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const Color& value) const { + std::stringstream sstream; + sstream << "rgba(" << value.r << ", " << value.g << ", " << value.b << ", " << value.a << ")"; + std::string result = sstream.str(); + return convert(env, result); + } +}; + +template +struct Converter> { + Result operator()(jni::JNIEnv& env, const std::array& value) const { + std::vector v; + for (const float& id : value) { + v.push_back(id); + } + return convert>(env, v); + } +}; + +template <> +struct Converter> { + Result operator()(jni::JNIEnv& env, const std::vector& value) const { + static jni::jclass* stringCass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/String")).release(); + jni::jarray& jarray = jni::NewObjectArray(env, value.size(), *stringCass); + + for(size_t i = 0; i < value.size(); i = i + 1) { + Result converted = convert(env, value.at(i)); + jni::SetObjectArrayElement(env, jarray, i, *converted); + } + + return &jarray; + } +}; + +template <> +struct Converter> { + Result operator()(jni::JNIEnv& env, const std::vector& value) const { + static jni::jclass* floatClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Float")).release(); + jni::jarray& jarray = jni::NewObjectArray(env, value.size(), *floatClass); + + for(size_t i = 0; i < value.size(); i = i + 1) { + Result converted = convert(env, value.at(i)); + jni::SetObjectArrayElement(env, jarray, i, *converted); + } + + return &jarray; + } +}; + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/platform/android/src/conversion/conversion.hpp b/platform/android/src/conversion/conversion.hpp new file mode 100644 index 0000000000..ea8a31bcf2 --- /dev/null +++ b/platform/android/src/conversion/conversion.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include + +#include + +namespace mbgl { +namespace android { +namespace conversion { + +struct Error { std::string message; }; + +template +class Result : private variant { +public: + using variant::variant; + + explicit operator bool() const { + return this->template is(); + } + + T& operator*() { + assert(this->template is()); + return this->template get(); + } + + const T& operator*() const { + assert(this->template is()); + return this->template get(); + } + + const Error& error() const { + assert(this->template is()); + return this->template get(); + } +}; + +template +struct Converter; + +template +Result convert(jni::JNIEnv& env, const V& value, Args&&...args) { + return Converter()(env, value, std::forward(args)...); +} + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 18a22cb8b3..3a7963f11e 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -102,13 +101,6 @@ jni::jfieldID* rectFTopId = nullptr; jni::jfieldID* rectFRightId = nullptr; jni::jfieldID* rectFBottomId = nullptr; -jni::jclass* customLayerClass = nullptr; -jni::jfieldID* customLayerIdId = nullptr; -jni::jfieldID* customLayerContextId = nullptr; -jni::jfieldID* customLayerInitializeFunctionId = nullptr; -jni::jfieldID* customLayerRenderFunctionId = nullptr; -jni::jfieldID* customLayerDeinitializeFunctionId = nullptr; - // Offline declarations start jni::jfieldID* offlineManagerClassPtrId = nullptr; @@ -1069,26 +1061,6 @@ void nativeFlyTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble nativeMapView->getMap().flyTo(cameraOptions, animationOptions); } -void nativeAddCustomLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* customLayer, jni::jstring* before) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddCustomLayer"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().addLayer(std::make_unique( - std_string_from_jstring(env, reinterpret_cast(jni::GetField(*env, customLayer, *customLayerIdId))), - reinterpret_cast(jni::GetField(*env, customLayer, *customLayerInitializeFunctionId)), - reinterpret_cast(jni::GetField(*env, customLayer, *customLayerRenderFunctionId)), - reinterpret_cast(jni::GetField(*env, customLayer, *customLayerDeinitializeFunctionId)), - reinterpret_cast(jni::GetField(*env, customLayer, *customLayerContextId))), - before ? mbgl::optional(std_string_from_jstring(env, before)) : mbgl::optional()); -} - -void nativeRemoveCustomLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveCustomLayer"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().removeLayer(std_string_from_jstring(env, id)); -} - jni::jobject* nativeGetLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* layerId) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetLayer"); @@ -1693,14 +1665,6 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { rectFTopId = &jni::GetFieldID(env, *rectFClass, "top", "F"); rectFBottomId = &jni::GetFieldID(env, *rectFClass, "bottom", "F"); - customLayerClass = &jni::FindClass(env, "com/mapbox/mapboxsdk/layers/CustomLayer"); - customLayerClass = jni::NewGlobalRef(env, customLayerClass).release(); - customLayerIdId = &jni::GetFieldID(env, *customLayerClass, "mID", "Ljava/lang/String;"); - customLayerContextId = &jni::GetFieldID(env, *customLayerClass, "mContext", "J"); - customLayerInitializeFunctionId = &jni::GetFieldID(env, *customLayerClass, "mInitializeFunction", "J"); - customLayerRenderFunctionId = &jni::GetFieldID(env, *customLayerClass, "mRenderFunction", "J"); - customLayerDeinitializeFunctionId = &jni::GetFieldID(env, *customLayerClass, "mDeinitializeFunction", "J"); - jni::jclass& nativeMapViewClass = jni::FindClass(env, "com/mapbox/mapboxsdk/maps/NativeMapView"); onInvalidateId = &jni::GetMethodID(env, nativeMapViewClass, "onInvalidate", "()V"); @@ -1779,8 +1743,6 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { MAKE_NATIVE_METHOD(nativeJumpTo, "(JDDDDD)V"), MAKE_NATIVE_METHOD(nativeEaseTo, "(JDDDJDDZ)V"), MAKE_NATIVE_METHOD(nativeFlyTo, "(JDDDJDD)V"), - MAKE_NATIVE_METHOD(nativeAddCustomLayer, "(JLcom/mapbox/mapboxsdk/layers/CustomLayer;Ljava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeRemoveCustomLayer, "(JLjava/lang/String;)V"), MAKE_NATIVE_METHOD(nativeGetLayer, "(JLjava/lang/String;)Lcom/mapbox/mapboxsdk/style/layers/Layer;"), MAKE_NATIVE_METHOD(nativeAddLayer, "(JJLjava/lang/String;)V"), MAKE_NATIVE_METHOD(nativeRemoveLayer, "(JLjava/lang/String;)V"), diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp index 5128cce51f..0ccb704c0a 100644 --- a/platform/android/src/style/android_conversion.hpp +++ b/platform/android/src/style/android_conversion.hpp @@ -13,10 +13,6 @@ namespace mbgl { namespace style { namespace conversion { - -//XXX -#pragma GCC diagnostic ignored "-Wunused-parameter" - inline bool isUndefined(const mbgl::android::Value& value) { return value.isNull(); } @@ -48,7 +44,7 @@ inline optional objectMember(const mbgl::android::Value& v } template -optional eachMember(const mbgl::android::Value& value, Fn&& fn) { +optional eachMember(const mbgl::android::Value&, Fn&&) { //TODO mbgl::Log::Warning(mbgl::Event::Android, "eachMember not implemented"); return {}; @@ -92,4 +88,4 @@ inline optional toValue(const mbgl::android::Value& value) { } // namespace conversion } // namespace style -} // namespace mbgl \ No newline at end of file +} // namespace mbgl diff --git a/platform/android/src/style/conversion/function.hpp b/platform/android/src/style/conversion/function.hpp new file mode 100644 index 0000000000..ad09ce02d2 --- /dev/null +++ b/platform/android/src/style/conversion/function.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include "../../conversion/conversion.hpp" +#include "../../conversion/constant.hpp" +#include "types.hpp" +#include "function.hpp" + +#include + +#include +#include + +namespace mbgl { +namespace android { +namespace conversion { + +template +inline jni::jobject* toFunctionStopJavaArray(jni::JNIEnv& env, std::vector> value) { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/Function$Stop")).release(); + static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); + + jni::jarray& jarray = jni::NewObjectArray(env, value.size(), *javaClass); + + for(size_t i = 0; i < value.size(); i = i + 1) { + jni::SetObjectArrayElement(env, jarray, i, &jni::NewObject(env, *javaClass, *constructor, value[i].first, *convert(env, value[i].second))); + } + + return &jarray; +} + +template +struct Converter> { + + Result operator()(jni::JNIEnv& env, const mbgl::style::Function& value) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/Function")).release(); + static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "", "([Lcom/mapbox/mapboxsdk/style/layers/Function$Stop;)V"); + static jni::jmethodID* withBase = &jni::GetMethodID(env, *javaClass, "withBase", "(F)Lcom/mapbox/mapboxsdk/style/layers/Function;"); + + //Create object + jni::jobject* jfunction = &jni::NewObject(env, *javaClass, *constructor, *toFunctionStopJavaArray(env, value.getStops())); + + //Set base + jni::CallMethod(env, jfunction, *withBase, value.getBase()); + + return {jfunction}; + } +}; + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/conversion/property_value.hpp b/platform/android/src/style/conversion/property_value.hpp new file mode 100644 index 0000000000..4121192f3f --- /dev/null +++ b/platform/android/src/style/conversion/property_value.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include "../../conversion/conversion.hpp" +#include "../../conversion/constant.hpp" +#include "types.hpp" +#include "function.hpp" + +namespace mbgl { +namespace android { +namespace conversion { + +template +struct Converter> { + + Result operator()(jni::JNIEnv& env, const mbgl::style::PropertyValue& value) const { + + if(value.isUndefined()) { + //Return a nullptr representing a Java null value + return {nullptr}; + } else if (value.isConstant()) { + //Time to convert the constant value + Result result = convert(env, value.asConstant()); + return {*result}; + //return converted; + } else if (value.isFunction()) { + //Must be a function than + return convert>(env, value.asFunction()); + } else { + throw std::runtime_error("Unknown property value type"); + } + + } +}; + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/conversion/types.hpp b/platform/android/src/style/conversion/types.hpp new file mode 100644 index 0000000000..d3c12ff89a --- /dev/null +++ b/platform/android/src/style/conversion/types.hpp @@ -0,0 +1,98 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +#pragma once + +#include "types_string_values.hpp" +#include "../../conversion/conversion.hpp" +#include "../../conversion/constant.hpp" + +#include +#include +#include + +#include + +namespace mbgl { +namespace android { +namespace conversion { + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::VisibilityType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::LineCapType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::LineJoinType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::SymbolPlacementType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::AlignmentType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::IconTextFitType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::TextJustifyType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::TextAnchorType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::TextTransformType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::TranslateAnchorType& value) const { + return convert(env, toString(value)); + } +}; + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::CirclePitchScaleType& value) const { + return convert(env, toString(value)); + } +}; + + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/conversion/types.hpp.ejs b/platform/android/src/style/conversion/types.hpp.ejs new file mode 100644 index 0000000000..de26d061f7 --- /dev/null +++ b/platform/android/src/style/conversion/types.hpp.ejs @@ -0,0 +1,40 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +#pragma once + +#include "types_string_values.hpp" +#include "../../conversion/conversion.hpp" +#include "../../conversion/constant.hpp" + +#include +#include +#include + +#include + +namespace mbgl { +namespace android { +namespace conversion { + +template <> +struct Converter { + Result operator()(jni::JNIEnv& env, const mbgl::style::VisibilityType& value) const { + return convert(env, toString(value)); + } +}; + +<% for (const property of properties) { -%> +template <> +struct Converter> { + Result operator()(jni::JNIEnv& env, const mbgl::style::<%- propertyNativeType(property) %>& value) const { + return convert(env, toString(value)); + } +}; + +<% } -%> + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/conversion/types_string_values.hpp b/platform/android/src/style/conversion/types_string_values.hpp new file mode 100644 index 0000000000..35cdb1cbc9 --- /dev/null +++ b/platform/android/src/style/conversion/types_string_values.hpp @@ -0,0 +1,209 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +#pragma once + +#include + +#include +#include + +namespace mbgl { +namespace android { +namespace conversion { + + //visibility + inline std::string toString(mbgl::style::VisibilityType value) { + switch (value) { + case mbgl::style::VisibilityType::Visible: + return "visible"; + break; + case mbgl::style::VisibilityType::None: + return "none"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //line-cap + inline std::string toString(mbgl::style::LineCapType value) { + switch (value) { + case mbgl::style::LineCapType::Butt: + return "butt"; + break; + case mbgl::style::LineCapType::Round: + return "round"; + break; + case mbgl::style::LineCapType::Square: + return "square"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //line-join + inline std::string toString(mbgl::style::LineJoinType value) { + switch (value) { + case mbgl::style::LineJoinType::Bevel: + return "bevel"; + break; + case mbgl::style::LineJoinType::Round: + return "round"; + break; + case mbgl::style::LineJoinType::Miter: + return "miter"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //symbol-placement + inline std::string toString(mbgl::style::SymbolPlacementType value) { + switch (value) { + case mbgl::style::SymbolPlacementType::Point: + return "point"; + break; + case mbgl::style::SymbolPlacementType::Line: + return "line"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //icon-rotation-alignment + inline std::string toString(mbgl::style::AlignmentType value) { + switch (value) { + case mbgl::style::AlignmentType::Map: + return "map"; + break; + case mbgl::style::AlignmentType::Viewport: + return "viewport"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //icon-text-fit + inline std::string toString(mbgl::style::IconTextFitType value) { + switch (value) { + case mbgl::style::IconTextFitType::None: + return "none"; + break; + case mbgl::style::IconTextFitType::Both: + return "both"; + break; + case mbgl::style::IconTextFitType::Width: + return "width"; + break; + case mbgl::style::IconTextFitType::Height: + return "height"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //text-justify + inline std::string toString(mbgl::style::TextJustifyType value) { + switch (value) { + case mbgl::style::TextJustifyType::Left: + return "left"; + break; + case mbgl::style::TextJustifyType::Center: + return "center"; + break; + case mbgl::style::TextJustifyType::Right: + return "right"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //text-anchor + inline std::string toString(mbgl::style::TextAnchorType value) { + switch (value) { + case mbgl::style::TextAnchorType::Center: + return "center"; + break; + case mbgl::style::TextAnchorType::Left: + return "left"; + break; + case mbgl::style::TextAnchorType::Right: + return "right"; + break; + case mbgl::style::TextAnchorType::Top: + return "top"; + break; + case mbgl::style::TextAnchorType::Bottom: + return "bottom"; + break; + case mbgl::style::TextAnchorType::TopLeft: + return "top-left"; + break; + case mbgl::style::TextAnchorType::TopRight: + return "top-right"; + break; + case mbgl::style::TextAnchorType::BottomLeft: + return "bottom-left"; + break; + case mbgl::style::TextAnchorType::BottomRight: + return "bottom-right"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //text-transform + inline std::string toString(mbgl::style::TextTransformType value) { + switch (value) { + case mbgl::style::TextTransformType::None: + return "none"; + break; + case mbgl::style::TextTransformType::Uppercase: + return "uppercase"; + break; + case mbgl::style::TextTransformType::Lowercase: + return "lowercase"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //fill-translate-anchor + inline std::string toString(mbgl::style::TranslateAnchorType value) { + switch (value) { + case mbgl::style::TranslateAnchorType::Map: + return "map"; + break; + case mbgl::style::TranslateAnchorType::Viewport: + return "viewport"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + //circle-pitch-scale + inline std::string toString(mbgl::style::CirclePitchScaleType value) { + switch (value) { + case mbgl::style::CirclePitchScaleType::Map: + return "map"; + break; + case mbgl::style::CirclePitchScaleType::Viewport: + return "viewport"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/conversion/types_string_values.hpp.ejs b/platform/android/src/style/conversion/types_string_values.hpp.ejs new file mode 100644 index 0000000000..db90a614f5 --- /dev/null +++ b/platform/android/src/style/conversion/types_string_values.hpp.ejs @@ -0,0 +1,48 @@ +<% + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. +#pragma once + +#include + +#include +#include + +namespace mbgl { +namespace android { +namespace conversion { + + //visibility + inline std::string toString(mbgl::style::VisibilityType value) { + switch (value) { + case mbgl::style::VisibilityType::Visible: + return "visible"; + break; + case mbgl::style::VisibilityType::None: + return "none"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + +<% for (const property of properties) { -%> + //<%- property.name %> + inline std::string toString(mbgl::style::<%- propertyNativeType(property) %> value) { + switch (value) { +<% for (const value of property.values) { -%> + case mbgl::style::<%- propertyNativeType(property) %>::<%- camelize(value) %>: + return "<%- value %>"; + break; +<% } -%> + default: + throw std::runtime_error("Not implemented"); + } + } + +<% } -%> + +} // namespace conversion +} // namespace android +} // namespace mbgl \ No newline at end of file diff --git a/platform/android/src/style/layers/background_layer.cpp b/platform/android/src/style/layers/background_layer.cpp index 4847d59420..25526a07fa 100644 --- a/platform/android/src/style/layers/background_layer.cpp +++ b/platform/android/src/style/layers/background_layer.cpp @@ -4,25 +4,41 @@ #include -//XXX -#include +#include "../conversion/property_value.hpp" namespace mbgl { namespace android { BackgroundLayer::BackgroundLayer(jni::JNIEnv& env, jni::String layerId) : Layer(env, std::make_unique(jni::Make(env, layerId))) { - mbgl::Log::Debug(mbgl::Event::JNI, "BackgroundLayer constructed, owning reference"); } BackgroundLayer::BackgroundLayer(mbgl::Map& map, mbgl::style::BackgroundLayer& coreLayer) : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "BackgroundLayer Non-owning reference constructor"); } BackgroundLayer::~BackgroundLayer() = default; + // Property getters + + jni::Object BackgroundLayer::getBackgroundColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->BackgroundLayer::getBackgroundColor()); + return jni::Object(*converted); + } + + jni::Object BackgroundLayer::getBackgroundPattern(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->BackgroundLayer::getBackgroundPattern()); + return jni::Object(*converted); + } + + jni::Object BackgroundLayer::getBackgroundOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->BackgroundLayer::getBackgroundOpacity()); + return jni::Object(*converted); + } + jni::Class BackgroundLayer::javaClass; jni::jobject* BackgroundLayer::createJavaPeer(jni::JNIEnv& env) { @@ -31,8 +47,6 @@ namespace android { } void BackgroundLayer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - //Lookup the class BackgroundLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -43,9 +57,10 @@ namespace android { env, BackgroundLayer::javaClass, "nativePtr", std::make_unique, "initialize", - "finalize" - ); - + "finalize", + METHOD(&BackgroundLayer::getBackgroundColor, "nativeGetBackgroundColor"), + METHOD(&BackgroundLayer::getBackgroundPattern, "nativeGetBackgroundPattern"), + METHOD(&BackgroundLayer::getBackgroundOpacity, "nativeGetBackgroundOpacity")); } } // namespace android diff --git a/platform/android/src/style/layers/background_layer.hpp b/platform/android/src/style/layers/background_layer.hpp index b253b4861c..f201213e46 100644 --- a/platform/android/src/style/layers/background_layer.hpp +++ b/platform/android/src/style/layers/background_layer.hpp @@ -24,8 +24,16 @@ public: ~BackgroundLayer(); + // Property getters + jni::Object getBackgroundColor(jni::JNIEnv&); + + jni::Object getBackgroundPattern(jni::JNIEnv&); + + jni::Object getBackgroundOpacity(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); -}; + +}; // class BackgroundLayer } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/layers/circle_layer.cpp b/platform/android/src/style/layers/circle_layer.cpp index ad0d0b34ce..c2d6ff06d1 100644 --- a/platform/android/src/style/layers/circle_layer.cpp +++ b/platform/android/src/style/layers/circle_layer.cpp @@ -4,25 +4,65 @@ #include -//XXX -#include +#include "../conversion/property_value.hpp" namespace mbgl { namespace android { CircleLayer::CircleLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) : Layer(env, std::make_unique(jni::Make(env, layerId), jni::Make(env, sourceId))) { - mbgl::Log::Debug(mbgl::Event::JNI, "CircleLayer constructed, owning reference"); } CircleLayer::CircleLayer(mbgl::Map& map, mbgl::style::CircleLayer& coreLayer) : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "CircleLayer Non-owning reference constructor"); } CircleLayer::~CircleLayer() = default; + // Property getters + + jni::Object CircleLayer::getCircleRadius(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleRadius()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleColor()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleBlur(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleBlur()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleOpacity()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleTranslate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleTranslate()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCircleTranslateAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCircleTranslateAnchor()); + return jni::Object(*converted); + } + + jni::Object CircleLayer::getCirclePitchScale(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->CircleLayer::getCirclePitchScale()); + return jni::Object(*converted); + } + jni::Class CircleLayer::javaClass; jni::jobject* CircleLayer::createJavaPeer(jni::JNIEnv& env) { @@ -31,8 +71,6 @@ namespace android { } void CircleLayer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - //Lookup the class CircleLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -43,9 +81,14 @@ namespace android { env, CircleLayer::javaClass, "nativePtr", std::make_unique, "initialize", - "finalize" - ); - + "finalize", + METHOD(&CircleLayer::getCircleRadius, "nativeGetCircleRadius"), + METHOD(&CircleLayer::getCircleColor, "nativeGetCircleColor"), + METHOD(&CircleLayer::getCircleBlur, "nativeGetCircleBlur"), + METHOD(&CircleLayer::getCircleOpacity, "nativeGetCircleOpacity"), + METHOD(&CircleLayer::getCircleTranslate, "nativeGetCircleTranslate"), + METHOD(&CircleLayer::getCircleTranslateAnchor, "nativeGetCircleTranslateAnchor"), + METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale")); } } // namespace android diff --git a/platform/android/src/style/layers/circle_layer.hpp b/platform/android/src/style/layers/circle_layer.hpp index e0dc94eb00..91c99c686e 100644 --- a/platform/android/src/style/layers/circle_layer.hpp +++ b/platform/android/src/style/layers/circle_layer.hpp @@ -24,8 +24,24 @@ public: ~CircleLayer(); + // Property getters + jni::Object getCircleRadius(jni::JNIEnv&); + + jni::Object getCircleColor(jni::JNIEnv&); + + jni::Object getCircleBlur(jni::JNIEnv&); + + jni::Object getCircleOpacity(jni::JNIEnv&); + + jni::Object getCircleTranslate(jni::JNIEnv&); + + jni::Object getCircleTranslateAnchor(jni::JNIEnv&); + + jni::Object getCirclePitchScale(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); -}; + +}; // class CircleLayer } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/layers/custom_layer.cpp b/platform/android/src/style/layers/custom_layer.cpp new file mode 100644 index 0000000000..4be6f3800d --- /dev/null +++ b/platform/android/src/style/layers/custom_layer.cpp @@ -0,0 +1,57 @@ +#include "custom_layer.hpp" + +#include + +#include + +namespace mbgl { +namespace android { + + CustomLayer::CustomLayer(jni::JNIEnv& env, jni::String layerId, jni::jlong initializeFunction, jni::jlong renderFunction, jni::jlong deinitializeFunction, jni::jlong context) + : Layer(env, std::make_unique( + jni::Make(env, layerId), + reinterpret_cast(initializeFunction), + reinterpret_cast(renderFunction), + reinterpret_cast(deinitializeFunction), + reinterpret_cast(context)) + ) { + } + + CustomLayer::CustomLayer(mbgl::Map& map, mbgl::style::CustomLayer& coreLayer) + : Layer(map, coreLayer) { + } + + CustomLayer::~CustomLayer() = default; + + void CustomLayer::update(jni::JNIEnv&) { + if (map) { + map->update(mbgl::Update::Repaint); + } else { + Log::Error(mbgl::Event::JNI, "No map reference, cannot update"); + } + } + + jni::Class CustomLayer::javaClass; + + jni::jobject* CustomLayer::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = CustomLayer::javaClass.template GetConstructor(env); + return CustomLayer::javaClass.New(env, constructor, reinterpret_cast(this)); + } + + void CustomLayer::registerNative(jni::JNIEnv& env) { + //Lookup the class + CustomLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); + + #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) + + //Register the peer + jni::RegisterNativePeer( + env, CustomLayer::javaClass, "nativePtr", + std::make_unique, + "initialize", + "finalize", + METHOD(&CustomLayer::update, "nativeUpdate")); + } + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/custom_layer.hpp b/platform/android/src/style/layers/custom_layer.hpp new file mode 100644 index 0000000000..1173d21bfd --- /dev/null +++ b/platform/android/src/style/layers/custom_layer.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "layer.hpp" +#include +#include + +namespace mbgl { +namespace android { + +class CustomLayer : public Layer { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/layers/CustomLayer"; }; + + static jni::Class javaClass; + + static void registerNative(jni::JNIEnv&); + + CustomLayer(jni::JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong); + + CustomLayer(mbgl::Map&, mbgl::style::CustomLayer&); + + ~CustomLayer(); + + void update(jni::JNIEnv&); + + jni::jobject* createJavaPeer(jni::JNIEnv&); + +}; // class CustomLayer + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/fill_layer.cpp b/platform/android/src/style/layers/fill_layer.cpp index 1056c8353b..8cb96c9cd3 100644 --- a/platform/android/src/style/layers/fill_layer.cpp +++ b/platform/android/src/style/layers/fill_layer.cpp @@ -4,25 +4,65 @@ #include -//XXX -#include +#include "../conversion/property_value.hpp" namespace mbgl { namespace android { FillLayer::FillLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) : Layer(env, std::make_unique(jni::Make(env, layerId), jni::Make(env, sourceId))) { - mbgl::Log::Debug(mbgl::Event::JNI, "FillLayer constructed, owning reference"); } FillLayer::FillLayer(mbgl::Map& map, mbgl::style::FillLayer& coreLayer) : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "FillLayer Non-owning reference constructor"); } FillLayer::~FillLayer() = default; + // Property getters + + jni::Object FillLayer::getFillAntialias(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillAntialias()); + return jni::Object(*converted); + } + + jni::Object FillLayer::getFillOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillOpacity()); + return jni::Object(*converted); + } + + jni::Object FillLayer::getFillColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillColor()); + return jni::Object(*converted); + } + + jni::Object FillLayer::getFillOutlineColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillOutlineColor()); + return jni::Object(*converted); + } + + jni::Object FillLayer::getFillTranslate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillTranslate()); + return jni::Object(*converted); + } + + jni::Object FillLayer::getFillTranslateAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillTranslateAnchor()); + return jni::Object(*converted); + } + + jni::Object FillLayer::getFillPattern(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->FillLayer::getFillPattern()); + return jni::Object(*converted); + } + jni::Class FillLayer::javaClass; jni::jobject* FillLayer::createJavaPeer(jni::JNIEnv& env) { @@ -31,8 +71,6 @@ namespace android { } void FillLayer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - //Lookup the class FillLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -43,9 +81,14 @@ namespace android { env, FillLayer::javaClass, "nativePtr", std::make_unique, "initialize", - "finalize" - ); - + "finalize", + METHOD(&FillLayer::getFillAntialias, "nativeGetFillAntialias"), + METHOD(&FillLayer::getFillOpacity, "nativeGetFillOpacity"), + METHOD(&FillLayer::getFillColor, "nativeGetFillColor"), + METHOD(&FillLayer::getFillOutlineColor, "nativeGetFillOutlineColor"), + METHOD(&FillLayer::getFillTranslate, "nativeGetFillTranslate"), + METHOD(&FillLayer::getFillTranslateAnchor, "nativeGetFillTranslateAnchor"), + METHOD(&FillLayer::getFillPattern, "nativeGetFillPattern")); } } // namespace android diff --git a/platform/android/src/style/layers/fill_layer.hpp b/platform/android/src/style/layers/fill_layer.hpp index 5ed80d401f..5dbd7a3412 100644 --- a/platform/android/src/style/layers/fill_layer.hpp +++ b/platform/android/src/style/layers/fill_layer.hpp @@ -24,8 +24,24 @@ public: ~FillLayer(); + // Property getters + jni::Object getFillAntialias(jni::JNIEnv&); + + jni::Object getFillOpacity(jni::JNIEnv&); + + jni::Object getFillColor(jni::JNIEnv&); + + jni::Object getFillOutlineColor(jni::JNIEnv&); + + jni::Object getFillTranslate(jni::JNIEnv&); + + jni::Object getFillTranslateAnchor(jni::JNIEnv&); + + jni::Object getFillPattern(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); -}; + +}; // class FillLayer } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index aec7079698..4d5f90f67e 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -4,10 +4,15 @@ #include #include + +//Java -> C++ conversion #include #include #include +//C++ -> Java conversion +#include "../conversion/property_value.hpp" + #include namespace mbgl { @@ -16,19 +21,15 @@ namespace android { /** * Invoked when the construction is initiated from the jvm through a subclass */ - Layer::Layer(jni::JNIEnv& env, std::unique_ptr coreLayer) + Layer::Layer(jni::JNIEnv&, std::unique_ptr coreLayer) : ownedLayer(std::move(coreLayer)) , layer(*ownedLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "Layer constructed, owning reference"); } Layer::Layer(mbgl::Map& coreMap, mbgl::style::Layer& coreLayer) : layer(coreLayer) , map(&coreMap) { - mbgl::Log::Debug(mbgl::Event::JNI, "Non-owning reference constructor"); } Layer::~Layer() { - mbgl::Log::Debug(mbgl::Event::JNI, "Layer destroyed"); } jni::String Layer::getId(jni::JNIEnv& env) { @@ -41,8 +42,6 @@ namespace android { } void Layer::setLayoutProperty(jni::JNIEnv& env, jni::String jname, jni::Object<> jvalue) { - mbgl::Log::Debug(mbgl::Event::JNI, "Set layout property"); - Value value(env, jvalue); //Convert and set property @@ -51,16 +50,9 @@ namespace android { mbgl::Log::Error(mbgl::Event::JNI, "Error setting property: " + jni::Make(env, jname) + " " + error->message); return; } - - //Update the style if attached - if (ownedLayer == nullptr) { - map->update(mbgl::Update::RecalculateStyle); - } } void Layer::setPaintProperty(jni::JNIEnv& env, jni::String jname, jni::Object<> jvalue) { - mbgl::Log::Debug(mbgl::Event::JNI, "Set paint property"); - Value value(env, jvalue); //Convert and set property @@ -72,8 +64,6 @@ namespace android { } void Layer::updateStyle(jni::JNIEnv&, jni::jboolean updateClasses) { - mbgl::Log::Debug(mbgl::Event::JNI, "Update style property. Update classes: " + std::to_string(updateClasses)); - //Update the style only if attached if (ownedLayer == nullptr) { Update flags = mbgl::Update::RecalculateStyle; @@ -89,7 +79,6 @@ namespace android { void Layer::setFilter(jni::JNIEnv& env, jni::Array> jfilter) { using namespace mbgl::style; using namespace mbgl::style::conversion; - mbgl::Log::Debug(mbgl::Event::JNI, "Set filter"); Value wrapped(env, jfilter); Filter filter; @@ -118,7 +107,6 @@ namespace android { using namespace mbgl::style; std::string layerId = jni::Make(env, sourceLayer); - mbgl::Log::Debug(mbgl::Event::JNI, "Set source layer: " + layerId); if (layer.is()) { layer.as()->setSourceLayer(layerId); @@ -133,11 +121,30 @@ namespace android { } } + jni::jfloat Layer::getMinZoom(jni::JNIEnv&){ + return layer.getMinZoom(); + } + + jni::jfloat Layer::getMaxZoom(jni::JNIEnv&) { + return layer.getMaxZoom(); + } + + void Layer::setMinZoom(jni::JNIEnv&, jni::jfloat zoom) { + layer.setMinZoom(zoom); + } + + void Layer::setMaxZoom(jni::JNIEnv&, jni::jfloat zoom) { + layer.setMaxZoom(zoom); + } + + jni::Object Layer::getVisibility(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + return jni::Object(*convert(env, layer.getVisibility())); + } + jni::Class Layer::javaClass; void Layer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native base layer"); - //Lookup the class Layer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -150,9 +157,15 @@ namespace android { METHOD(&Layer::setPaintProperty, "nativeSetPaintProperty"), METHOD(&Layer::updateStyle, "nativeUpdateStyle"), METHOD(&Layer::setFilter, "nativeSetFilter"), - METHOD(&Layer::setSourceLayer, "nativeSetSourceLayer") + METHOD(&Layer::setSourceLayer, "nativeSetSourceLayer"), + METHOD(&Layer::getMinZoom, "nativeGetMinZoom"), + METHOD(&Layer::getMaxZoom, "nativeGetMaxZoom"), + METHOD(&Layer::setMinZoom, "nativeSetMinZoom"), + METHOD(&Layer::setMaxZoom, "nativeSetMaxZoom"), + METHOD(&Layer::getVisibility, "nativeGetVisibility") ); } -} -} \ No newline at end of file + +} //android +} //mbgl \ No newline at end of file diff --git a/platform/android/src/style/layers/layer.cpp.ejs b/platform/android/src/style/layers/layer.cpp.ejs new file mode 100644 index 0000000000..68dd27b801 --- /dev/null +++ b/platform/android/src/style/layers/layer.cpp.ejs @@ -0,0 +1,69 @@ +<% + const type = locals.type; + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. + +#include "<%- type %>_layer.hpp" + +#include + +#include "../conversion/property_value.hpp" + +namespace mbgl { +namespace android { + +<% if (type === 'background') { -%> + <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(jni::JNIEnv& env, jni::String layerId) + : Layer(env, std::make_uniqueLayer>(jni::Make(env, layerId))) { +<% } else { -%> + <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) + : Layer(env, std::make_uniqueLayer>(jni::Make(env, layerId), jni::Make(env, sourceId))) { +<% } -%> + } + + <%- camelize(type) %>Layer::<%- camelize(type) %>Layer(mbgl::Map& map, mbgl::style::<%- camelize(type) %>Layer& coreLayer) + : Layer(map, coreLayer) { + } + + <%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default; + + // Property getters + +<% for (const property of properties) { -%> + jni::Object <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.asLayer>()-><%- camelize(type) %>Layer::get<%- camelize(property.name) %>()); + return jni::Object(*converted); + } + +<% } -%> + jni::Class<<%- camelize(type) %>Layer> <%- camelize(type) %>Layer::javaClass; + + jni::jobject* <%- camelize(type) %>Layer::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = <%- camelize(type) %>Layer::javaClass.template GetConstructor(env); + return <%- camelize(type) %>Layer::javaClass.New(env, constructor, reinterpret_cast(this)); + } + + void <%- camelize(type) %>Layer::registerNative(jni::JNIEnv& env) { + //Lookup the class + <%- camelize(type) %>Layer::javaClass = *jni::Class<<%- camelize(type) %>Layer>::Find(env).NewGlobalRef(env).release(); + + #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod(name) + + //Register the peer + jni::RegisterNativePeer<<%- camelize(type) %>Layer>( + env, <%- camelize(type) %>Layer::javaClass, "nativePtr", +<% if (type === 'background') { -%> + std::make_unique<<%- camelize(type) %>Layer, JNIEnv&, jni::String>, +<% } else { -%> + std::make_unique<<%- camelize(type) %>Layer, JNIEnv&, jni::String, jni::String>, +<% } -%> + "initialize", + "finalize",<% for(var i = 0; i < properties.length; i++) {%> + METHOD(&<%- camelize(type) %>Layer::get<%- camelize(properties[i].name) %>, "nativeGet<%- camelize(properties[i].name) %>")<% if(i != (properties.length -1)) {-%>,<% } -%> +<% } -%>); + } + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/layer.hpp b/platform/android/src/style/layers/layer.hpp index 8b3487551b..37eb34cdd7 100644 --- a/platform/android/src/style/layers/layer.hpp +++ b/platform/android/src/style/layers/layer.hpp @@ -45,12 +45,26 @@ public: void updateStyle(jni::JNIEnv&, jni::jboolean updateClasses); + //Zoom + + jni::jfloat getMinZoom(jni::JNIEnv&); + + jni::jfloat getMaxZoom(jni::JNIEnv&); + + void setMinZoom(jni::JNIEnv&, jni::jfloat zoom); + + void setMaxZoom(jni::JNIEnv&, jni::jfloat zoom); + /* common properties, but not shared by all */ void setFilter(jni::JNIEnv& env, jni::Array> jfilter); void setSourceLayer(jni::JNIEnv& env, jni::String sourceLayer); + //Property getters + + jni::Object getVisibility(jni::JNIEnv&); + protected: std::unique_ptr ownedLayer; mbgl::style::Layer& layer; diff --git a/platform/android/src/style/layers/layer.hpp.ejs b/platform/android/src/style/layers/layer.hpp.ejs new file mode 100644 index 0000000000..826e133fca --- /dev/null +++ b/platform/android/src/style/layers/layer.hpp.ejs @@ -0,0 +1,45 @@ +<% + const type = locals.type; + const properties = locals.properties; +-%> +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`. + +#pragma once + +#include "layer.hpp" +#include _layer.hpp> +#include + +namespace mbgl { +namespace android { + +class <%- camelize(type) %>Layer : public Layer { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/layers/<%- camelize(type) %>Layer"; }; + + static jni::Class<<%- camelize(type) %>Layer> javaClass; + + static void registerNative(jni::JNIEnv&); + +<% if (type === 'background') { -%> + <%- camelize(type) %>Layer(jni::JNIEnv&, jni::String); +<% } else { -%> + <%- camelize(type) %>Layer(jni::JNIEnv&, jni::String, jni::String); +<% } -%> + + <%- camelize(type) %>Layer(mbgl::Map&, mbgl::style::<%- camelize(type) %>Layer&); + + ~<%- camelize(type) %>Layer(); + + // Property getters +<% for (const property of properties) { -%> + jni::Object get<%- camelize(property.name) %>(jni::JNIEnv&); + +<% } -%> + jni::jobject* createJavaPeer(jni::JNIEnv&); + +}; // class <%- camelize(type) %>Layer + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/layers.cpp b/platform/android/src/style/layers/layers.cpp index 4ccdc829f2..57dbf6f4b1 100644 --- a/platform/android/src/style/layers/layers.cpp +++ b/platform/android/src/style/layers/layers.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "background_layer.hpp" #include "circle_layer.hpp" @@ -13,6 +14,7 @@ #include "line_layer.hpp" #include "raster_layer.hpp" #include "symbol_layer.hpp" +#include "custom_layer.hpp" namespace mbgl { namespace android { @@ -31,6 +33,8 @@ Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) { layer = new RasterLayer(map, *coreLayer.as()); } else if (coreLayer.is()) { layer = new SymbolLayer(map, *coreLayer.as()); + } else if (coreLayer.is()) { + layer = new CustomLayer(map, *coreLayer.as()); } else { throw new std::runtime_error("Layer type not implemented"); } @@ -42,7 +46,6 @@ jni::jobject* createJavaLayerPeer(jni::JNIEnv& env, mbgl::Map& map, mbgl::style: std::unique_ptr peerLayer = std::unique_ptr(initializeLayerPeer(map, coreLayer)); jni::jobject* result = peerLayer->createJavaPeer(env); peerLayer.release(); - return result; } @@ -54,7 +57,8 @@ void registerNativeLayers(jni::JNIEnv& env) { LineLayer::registerNative(env); RasterLayer::registerNative(env); SymbolLayer::registerNative(env); + CustomLayer::registerNative(env); } -} -} \ No newline at end of file +} //android +} //mbgl \ No newline at end of file diff --git a/platform/android/src/style/layers/line_layer.cpp b/platform/android/src/style/layers/line_layer.cpp index fdf2af7973..91d3e4a1cd 100644 --- a/platform/android/src/style/layers/line_layer.cpp +++ b/platform/android/src/style/layers/line_layer.cpp @@ -4,25 +4,107 @@ #include -//XXX -#include +#include "../conversion/property_value.hpp" namespace mbgl { namespace android { LineLayer::LineLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) : Layer(env, std::make_unique(jni::Make(env, layerId), jni::Make(env, sourceId))) { - mbgl::Log::Debug(mbgl::Event::JNI, "LineLayer constructed, owning reference"); } LineLayer::LineLayer(mbgl::Map& map, mbgl::style::LineLayer& coreLayer) : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "LineLayer Non-owning reference constructor"); } LineLayer::~LineLayer() = default; + // Property getters + + jni::Object LineLayer::getLineCap(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineCap()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineJoin(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineJoin()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineMiterLimit(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineMiterLimit()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineRoundLimit(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineRoundLimit()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineOpacity()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineColor()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineTranslate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineTranslate()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineTranslateAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineTranslateAnchor()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineWidth(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineWidth()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineGapWidth(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineGapWidth()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineOffset(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineOffset()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineBlur(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineBlur()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLineDasharray(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLineDasharray()); + return jni::Object(*converted); + } + + jni::Object LineLayer::getLinePattern(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->LineLayer::getLinePattern()); + return jni::Object(*converted); + } + jni::Class LineLayer::javaClass; jni::jobject* LineLayer::createJavaPeer(jni::JNIEnv& env) { @@ -31,8 +113,6 @@ namespace android { } void LineLayer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - //Lookup the class LineLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -43,9 +123,21 @@ namespace android { env, LineLayer::javaClass, "nativePtr", std::make_unique, "initialize", - "finalize" - ); - + "finalize", + METHOD(&LineLayer::getLineCap, "nativeGetLineCap"), + METHOD(&LineLayer::getLineJoin, "nativeGetLineJoin"), + METHOD(&LineLayer::getLineMiterLimit, "nativeGetLineMiterLimit"), + METHOD(&LineLayer::getLineRoundLimit, "nativeGetLineRoundLimit"), + METHOD(&LineLayer::getLineOpacity, "nativeGetLineOpacity"), + METHOD(&LineLayer::getLineColor, "nativeGetLineColor"), + METHOD(&LineLayer::getLineTranslate, "nativeGetLineTranslate"), + METHOD(&LineLayer::getLineTranslateAnchor, "nativeGetLineTranslateAnchor"), + METHOD(&LineLayer::getLineWidth, "nativeGetLineWidth"), + METHOD(&LineLayer::getLineGapWidth, "nativeGetLineGapWidth"), + METHOD(&LineLayer::getLineOffset, "nativeGetLineOffset"), + METHOD(&LineLayer::getLineBlur, "nativeGetLineBlur"), + METHOD(&LineLayer::getLineDasharray, "nativeGetLineDasharray"), + METHOD(&LineLayer::getLinePattern, "nativeGetLinePattern")); } } // namespace android diff --git a/platform/android/src/style/layers/line_layer.hpp b/platform/android/src/style/layers/line_layer.hpp index cb53d82940..da9b564325 100644 --- a/platform/android/src/style/layers/line_layer.hpp +++ b/platform/android/src/style/layers/line_layer.hpp @@ -24,8 +24,38 @@ public: ~LineLayer(); + // Property getters + jni::Object getLineCap(jni::JNIEnv&); + + jni::Object getLineJoin(jni::JNIEnv&); + + jni::Object getLineMiterLimit(jni::JNIEnv&); + + jni::Object getLineRoundLimit(jni::JNIEnv&); + + jni::Object getLineOpacity(jni::JNIEnv&); + + jni::Object getLineColor(jni::JNIEnv&); + + jni::Object getLineTranslate(jni::JNIEnv&); + + jni::Object getLineTranslateAnchor(jni::JNIEnv&); + + jni::Object getLineWidth(jni::JNIEnv&); + + jni::Object getLineGapWidth(jni::JNIEnv&); + + jni::Object getLineOffset(jni::JNIEnv&); + + jni::Object getLineBlur(jni::JNIEnv&); + + jni::Object getLineDasharray(jni::JNIEnv&); + + jni::Object getLinePattern(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); -}; + +}; // class LineLayer } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/layers/raster_layer.cpp b/platform/android/src/style/layers/raster_layer.cpp index 3da246e128..da78ccb8e3 100644 --- a/platform/android/src/style/layers/raster_layer.cpp +++ b/platform/android/src/style/layers/raster_layer.cpp @@ -4,25 +4,65 @@ #include -//XXX -#include +#include "../conversion/property_value.hpp" namespace mbgl { namespace android { RasterLayer::RasterLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) : Layer(env, std::make_unique(jni::Make(env, layerId), jni::Make(env, sourceId))) { - mbgl::Log::Debug(mbgl::Event::JNI, "RasterLayer constructed, owning reference"); } RasterLayer::RasterLayer(mbgl::Map& map, mbgl::style::RasterLayer& coreLayer) : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "RasterLayer Non-owning reference constructor"); } RasterLayer::~RasterLayer() = default; + // Property getters + + jni::Object RasterLayer::getRasterOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterOpacity()); + return jni::Object(*converted); + } + + jni::Object RasterLayer::getRasterHueRotate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterHueRotate()); + return jni::Object(*converted); + } + + jni::Object RasterLayer::getRasterBrightnessMin(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterBrightnessMin()); + return jni::Object(*converted); + } + + jni::Object RasterLayer::getRasterBrightnessMax(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterBrightnessMax()); + return jni::Object(*converted); + } + + jni::Object RasterLayer::getRasterSaturation(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterSaturation()); + return jni::Object(*converted); + } + + jni::Object RasterLayer::getRasterContrast(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterContrast()); + return jni::Object(*converted); + } + + jni::Object RasterLayer::getRasterFadeDuration(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->RasterLayer::getRasterFadeDuration()); + return jni::Object(*converted); + } + jni::Class RasterLayer::javaClass; jni::jobject* RasterLayer::createJavaPeer(jni::JNIEnv& env) { @@ -31,8 +71,6 @@ namespace android { } void RasterLayer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - //Lookup the class RasterLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -43,9 +81,14 @@ namespace android { env, RasterLayer::javaClass, "nativePtr", std::make_unique, "initialize", - "finalize" - ); - + "finalize", + METHOD(&RasterLayer::getRasterOpacity, "nativeGetRasterOpacity"), + METHOD(&RasterLayer::getRasterHueRotate, "nativeGetRasterHueRotate"), + METHOD(&RasterLayer::getRasterBrightnessMin, "nativeGetRasterBrightnessMin"), + METHOD(&RasterLayer::getRasterBrightnessMax, "nativeGetRasterBrightnessMax"), + METHOD(&RasterLayer::getRasterSaturation, "nativeGetRasterSaturation"), + METHOD(&RasterLayer::getRasterContrast, "nativeGetRasterContrast"), + METHOD(&RasterLayer::getRasterFadeDuration, "nativeGetRasterFadeDuration")); } } // namespace android diff --git a/platform/android/src/style/layers/raster_layer.hpp b/platform/android/src/style/layers/raster_layer.hpp index f77771631c..e59cd05f87 100644 --- a/platform/android/src/style/layers/raster_layer.hpp +++ b/platform/android/src/style/layers/raster_layer.hpp @@ -24,8 +24,24 @@ public: ~RasterLayer(); + // Property getters + jni::Object getRasterOpacity(jni::JNIEnv&); + + jni::Object getRasterHueRotate(jni::JNIEnv&); + + jni::Object getRasterBrightnessMin(jni::JNIEnv&); + + jni::Object getRasterBrightnessMax(jni::JNIEnv&); + + jni::Object getRasterSaturation(jni::JNIEnv&); + + jni::Object getRasterContrast(jni::JNIEnv&); + + jni::Object getRasterFadeDuration(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); -}; + +}; // class RasterLayer } // namespace android } // namespace mbgl diff --git a/platform/android/src/style/layers/symbol_layer.cpp b/platform/android/src/style/layers/symbol_layer.cpp index 5de08f6511..fd69b6591f 100644 --- a/platform/android/src/style/layers/symbol_layer.cpp +++ b/platform/android/src/style/layers/symbol_layer.cpp @@ -4,25 +4,311 @@ #include -//XXX -#include +#include "../conversion/property_value.hpp" namespace mbgl { namespace android { SymbolLayer::SymbolLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) : Layer(env, std::make_unique(jni::Make(env, layerId), jni::Make(env, sourceId))) { - mbgl::Log::Debug(mbgl::Event::JNI, "SymbolLayer constructed, owning reference"); } SymbolLayer::SymbolLayer(mbgl::Map& map, mbgl::style::SymbolLayer& coreLayer) : Layer(map, coreLayer) { - - mbgl::Log::Debug(mbgl::Event::JNI, "SymbolLayer Non-owning reference constructor"); } SymbolLayer::~SymbolLayer() = default; + // Property getters + + jni::Object SymbolLayer::getSymbolPlacement(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getSymbolPlacement()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getSymbolSpacing(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getSymbolSpacing()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getSymbolAvoidEdges(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getSymbolAvoidEdges()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconAllowOverlap(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconAllowOverlap()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconIgnorePlacement(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconIgnorePlacement()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconOptional(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconOptional()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconRotationAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconRotationAlignment()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconSize(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconSize()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconTextFit(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconTextFit()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconTextFitPadding(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconTextFitPadding()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconImage(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconImage()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconRotate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconRotate()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconPadding(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconPadding()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconKeepUpright(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconKeepUpright()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconOffset(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconOffset()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextPitchAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextPitchAlignment()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextRotationAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextRotationAlignment()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextField(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextField()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextFont(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextFont()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextSize(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextSize()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextMaxWidth(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextMaxWidth()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextLineHeight(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextLineHeight()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextLetterSpacing(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextLetterSpacing()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextJustify(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextJustify()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextAnchor()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextMaxAngle(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextMaxAngle()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextRotate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextRotate()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextPadding(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextPadding()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextKeepUpright(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextKeepUpright()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextTransform(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextTransform()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextOffset(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextOffset()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextAllowOverlap(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextAllowOverlap()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextIgnorePlacement(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextIgnorePlacement()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextOptional(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextOptional()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconOpacity()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconColor()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconHaloColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconHaloColor()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconHaloWidth(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconHaloWidth()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconHaloBlur(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconHaloBlur()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconTranslate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconTranslate()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getIconTranslateAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getIconTranslateAnchor()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextOpacity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextOpacity()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextColor()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextHaloColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextHaloColor()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextHaloWidth(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextHaloWidth()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextHaloBlur(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextHaloBlur()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextTranslate(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextTranslate()); + return jni::Object(*converted); + } + + jni::Object SymbolLayer::getTextTranslateAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result converted = convert(env, layer.as()->SymbolLayer::getTextTranslateAnchor()); + return jni::Object(*converted); + } + jni::Class SymbolLayer::javaClass; jni::jobject* SymbolLayer::createJavaPeer(jni::JNIEnv& env) { @@ -31,8 +317,6 @@ namespace android { } void SymbolLayer::registerNative(jni::JNIEnv& env) { - mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer"); - //Lookup the class SymbolLayer::javaClass = *jni::Class::Find(env).NewGlobalRef(env).release(); @@ -43,9 +327,55 @@ namespace android { env, SymbolLayer::javaClass, "nativePtr", std::make_unique, "initialize", - "finalize" - ); - + "finalize", + METHOD(&SymbolLayer::getSymbolPlacement, "nativeGetSymbolPlacement"), + METHOD(&SymbolLayer::getSymbolSpacing, "nativeGetSymbolSpacing"), + METHOD(&SymbolLayer::getSymbolAvoidEdges, "nativeGetSymbolAvoidEdges"), + METHOD(&SymbolLayer::getIconAllowOverlap, "nativeGetIconAllowOverlap"), + METHOD(&SymbolLayer::getIconIgnorePlacement, "nativeGetIconIgnorePlacement"), + METHOD(&SymbolLayer::getIconOptional, "nativeGetIconOptional"), + METHOD(&SymbolLayer::getIconRotationAlignment, "nativeGetIconRotationAlignment"), + METHOD(&SymbolLayer::getIconSize, "nativeGetIconSize"), + METHOD(&SymbolLayer::getIconTextFit, "nativeGetIconTextFit"), + METHOD(&SymbolLayer::getIconTextFitPadding, "nativeGetIconTextFitPadding"), + METHOD(&SymbolLayer::getIconImage, "nativeGetIconImage"), + METHOD(&SymbolLayer::getIconRotate, "nativeGetIconRotate"), + METHOD(&SymbolLayer::getIconPadding, "nativeGetIconPadding"), + METHOD(&SymbolLayer::getIconKeepUpright, "nativeGetIconKeepUpright"), + METHOD(&SymbolLayer::getIconOffset, "nativeGetIconOffset"), + METHOD(&SymbolLayer::getTextPitchAlignment, "nativeGetTextPitchAlignment"), + METHOD(&SymbolLayer::getTextRotationAlignment, "nativeGetTextRotationAlignment"), + METHOD(&SymbolLayer::getTextField, "nativeGetTextField"), + METHOD(&SymbolLayer::getTextFont, "nativeGetTextFont"), + METHOD(&SymbolLayer::getTextSize, "nativeGetTextSize"), + METHOD(&SymbolLayer::getTextMaxWidth, "nativeGetTextMaxWidth"), + METHOD(&SymbolLayer::getTextLineHeight, "nativeGetTextLineHeight"), + METHOD(&SymbolLayer::getTextLetterSpacing, "nativeGetTextLetterSpacing"), + METHOD(&SymbolLayer::getTextJustify, "nativeGetTextJustify"), + METHOD(&SymbolLayer::getTextAnchor, "nativeGetTextAnchor"), + METHOD(&SymbolLayer::getTextMaxAngle, "nativeGetTextMaxAngle"), + METHOD(&SymbolLayer::getTextRotate, "nativeGetTextRotate"), + METHOD(&SymbolLayer::getTextPadding, "nativeGetTextPadding"), + METHOD(&SymbolLayer::getTextKeepUpright, "nativeGetTextKeepUpright"), + METHOD(&SymbolLayer::getTextTransform, "nativeGetTextTransform"), + METHOD(&SymbolLayer::getTextOffset, "nativeGetTextOffset"), + METHOD(&SymbolLayer::getTextAllowOverlap, "nativeGetTextAllowOverlap"), + METHOD(&SymbolLayer::getTextIgnorePlacement, "nativeGetTextIgnorePlacement"), + METHOD(&SymbolLayer::getTextOptional, "nativeGetTextOptional"), + METHOD(&SymbolLayer::getIconOpacity, "nativeGetIconOpacity"), + METHOD(&SymbolLayer::getIconColor, "nativeGetIconColor"), + METHOD(&SymbolLayer::getIconHaloColor, "nativeGetIconHaloColor"), + METHOD(&SymbolLayer::getIconHaloWidth, "nativeGetIconHaloWidth"), + METHOD(&SymbolLayer::getIconHaloBlur, "nativeGetIconHaloBlur"), + METHOD(&SymbolLayer::getIconTranslate, "nativeGetIconTranslate"), + METHOD(&SymbolLayer::getIconTranslateAnchor, "nativeGetIconTranslateAnchor"), + METHOD(&SymbolLayer::getTextOpacity, "nativeGetTextOpacity"), + METHOD(&SymbolLayer::getTextColor, "nativeGetTextColor"), + METHOD(&SymbolLayer::getTextHaloColor, "nativeGetTextHaloColor"), + METHOD(&SymbolLayer::getTextHaloWidth, "nativeGetTextHaloWidth"), + METHOD(&SymbolLayer::getTextHaloBlur, "nativeGetTextHaloBlur"), + METHOD(&SymbolLayer::getTextTranslate, "nativeGetTextTranslate"), + METHOD(&SymbolLayer::getTextTranslateAnchor, "nativeGetTextTranslateAnchor")); } } // namespace android diff --git a/platform/android/src/style/layers/symbol_layer.hpp b/platform/android/src/style/layers/symbol_layer.hpp index 3f3b0e1fe6..f5165327bf 100644 --- a/platform/android/src/style/layers/symbol_layer.hpp +++ b/platform/android/src/style/layers/symbol_layer.hpp @@ -24,8 +24,106 @@ public: ~SymbolLayer(); + // Property getters + jni::Object getSymbolPlacement(jni::JNIEnv&); + + jni::Object getSymbolSpacing(jni::JNIEnv&); + + jni::Object getSymbolAvoidEdges(jni::JNIEnv&); + + jni::Object getIconAllowOverlap(jni::JNIEnv&); + + jni::Object getIconIgnorePlacement(jni::JNIEnv&); + + jni::Object getIconOptional(jni::JNIEnv&); + + jni::Object getIconRotationAlignment(jni::JNIEnv&); + + jni::Object getIconSize(jni::JNIEnv&); + + jni::Object getIconTextFit(jni::JNIEnv&); + + jni::Object getIconTextFitPadding(jni::JNIEnv&); + + jni::Object getIconImage(jni::JNIEnv&); + + jni::Object getIconRotate(jni::JNIEnv&); + + jni::Object getIconPadding(jni::JNIEnv&); + + jni::Object getIconKeepUpright(jni::JNIEnv&); + + jni::Object getIconOffset(jni::JNIEnv&); + + jni::Object getTextPitchAlignment(jni::JNIEnv&); + + jni::Object getTextRotationAlignment(jni::JNIEnv&); + + jni::Object getTextField(jni::JNIEnv&); + + jni::Object getTextFont(jni::JNIEnv&); + + jni::Object getTextSize(jni::JNIEnv&); + + jni::Object getTextMaxWidth(jni::JNIEnv&); + + jni::Object getTextLineHeight(jni::JNIEnv&); + + jni::Object getTextLetterSpacing(jni::JNIEnv&); + + jni::Object getTextJustify(jni::JNIEnv&); + + jni::Object getTextAnchor(jni::JNIEnv&); + + jni::Object getTextMaxAngle(jni::JNIEnv&); + + jni::Object getTextRotate(jni::JNIEnv&); + + jni::Object getTextPadding(jni::JNIEnv&); + + jni::Object getTextKeepUpright(jni::JNIEnv&); + + jni::Object getTextTransform(jni::JNIEnv&); + + jni::Object getTextOffset(jni::JNIEnv&); + + jni::Object getTextAllowOverlap(jni::JNIEnv&); + + jni::Object getTextIgnorePlacement(jni::JNIEnv&); + + jni::Object getTextOptional(jni::JNIEnv&); + + jni::Object getIconOpacity(jni::JNIEnv&); + + jni::Object getIconColor(jni::JNIEnv&); + + jni::Object getIconHaloColor(jni::JNIEnv&); + + jni::Object getIconHaloWidth(jni::JNIEnv&); + + jni::Object getIconHaloBlur(jni::JNIEnv&); + + jni::Object getIconTranslate(jni::JNIEnv&); + + jni::Object getIconTranslateAnchor(jni::JNIEnv&); + + jni::Object getTextOpacity(jni::JNIEnv&); + + jni::Object getTextColor(jni::JNIEnv&); + + jni::Object getTextHaloColor(jni::JNIEnv&); + + jni::Object getTextHaloWidth(jni::JNIEnv&); + + jni::Object getTextHaloBlur(jni::JNIEnv&); + + jni::Object getTextTranslate(jni::JNIEnv&); + + jni::Object getTextTranslateAnchor(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); -}; + +}; // class SymbolLayer } // namespace android } // namespace mbgl -- cgit v1.2.1