diff options
Diffstat (limited to 'platform')
21 files changed, 2279 insertions, 31 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HillshadeLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HillshadeLayer.java new file mode 100644 index 0000000000..be0df6c145 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HillshadeLayer.java @@ -0,0 +1,308 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.annotation.UiThread; + +import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; + +/** + * Client-side hillshading visualization based on DEM data. Currently, the implementation only supports Mapbox Terrain RGB tiles + * + * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-hillshade">The online documentation</a> + */ +@UiThread +public class HillshadeLayer extends Layer { + + /** + * Creates a HillshadeLayer. + * + * @param nativePtr pointer used by core + */ + public HillshadeLayer(long nativePtr) { + super(nativePtr); + } + + /** + * Creates a HillshadeLayer. + * + * @param layerId the id of the layer + * @param sourceId the id of the source + */ + public HillshadeLayer(String layerId, String sourceId) { + initialize(layerId, sourceId); + } + + protected native void initialize(String layerId, String sourceId); + + /** + * Set the source layer. + * + * @param sourceLayer the source layer to set + */ + public void setSourceLayer(String sourceLayer) { + nativeSetSourceLayer(sourceLayer); + } + + /** + * Set the source Layer. + * + * @param sourceLayer the source layer to set + * @return This + */ + public HillshadeLayer withSourceLayer(String sourceLayer) { + setSourceLayer(sourceLayer); + return this; + } + + /** + * Set a property or properties. + * + * @param properties the var-args properties + * @return This + */ + public HillshadeLayer withProperties(@NonNull PropertyValue<?>... properties) { + setProperties(properties); + return this; + } + + // Property getters + + /** + * Get the HillshadeIlluminationDirection property + * + * @return property wrapper value around Float + */ + @SuppressWarnings("unchecked") + public PropertyValue<Float> getHillshadeIlluminationDirection() { + return (PropertyValue<Float>) new PropertyValue("hillshade-illumination-direction", nativeGetHillshadeIlluminationDirection()); + } + + /** + * Get the HillshadeIlluminationDirection property transition options + * + * @return transition options for Float + */ + public TransitionOptions getHillshadeIlluminationDirectionTransition() { + return nativeGetHillshadeIlluminationDirectionTransition(); + } + + /** + * Set the HillshadeIlluminationDirection property transition options + * + * @param options transition options for Float + */ + public void setHillshadeIlluminationDirectionTransition(TransitionOptions options) { + nativeSetHillshadeIlluminationDirectionTransition(options.getDuration(), options.getDelay()); + } + + /** + * Get the HillshadeIlluminationAnchor property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue<String> getHillshadeIlluminationAnchor() { + return (PropertyValue<String>) new PropertyValue("hillshade-illumination-anchor", nativeGetHillshadeIlluminationAnchor()); + } + + /** + * Get the HillshadeExaggeration property + * + * @return property wrapper value around Float + */ + @SuppressWarnings("unchecked") + public PropertyValue<Float> getHillshadeExaggeration() { + return (PropertyValue<Float>) new PropertyValue("hillshade-exaggeration", nativeGetHillshadeExaggeration()); + } + + /** + * Get the HillshadeExaggeration property transition options + * + * @return transition options for Float + */ + public TransitionOptions getHillshadeExaggerationTransition() { + return nativeGetHillshadeExaggerationTransition(); + } + + /** + * Set the HillshadeExaggeration property transition options + * + * @param options transition options for Float + */ + public void setHillshadeExaggerationTransition(TransitionOptions options) { + nativeSetHillshadeExaggerationTransition(options.getDuration(), options.getDelay()); + } + + /** + * Get the HillshadeShadowColor property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue<String> getHillshadeShadowColor() { + return (PropertyValue<String>) new PropertyValue("hillshade-shadow-color", nativeGetHillshadeShadowColor()); + } + + /** + * The shading color of areas that face away from the light source. + * + * @return int representation of a rgba string color + * @throws RuntimeException thrown if property isn't a value + */ + @ColorInt + public int getHillshadeShadowColorAsInt() { + PropertyValue<String> value = getHillshadeShadowColor(); + if (value.isValue()) { + return rgbaToColor(value.getValue()); + } else { + throw new RuntimeException("hillshade-shadow-color was set as a Function"); + } + } + + /** + * Get the HillshadeShadowColor property transition options + * + * @return transition options for String + */ + public TransitionOptions getHillshadeShadowColorTransition() { + return nativeGetHillshadeShadowColorTransition(); + } + + /** + * Set the HillshadeShadowColor property transition options + * + * @param options transition options for String + */ + public void setHillshadeShadowColorTransition(TransitionOptions options) { + nativeSetHillshadeShadowColorTransition(options.getDuration(), options.getDelay()); + } + + /** + * Get the HillshadeHighlightColor property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue<String> getHillshadeHighlightColor() { + return (PropertyValue<String>) new PropertyValue("hillshade-highlight-color", nativeGetHillshadeHighlightColor()); + } + + /** + * The shading color of areas that faces towards the light source. + * + * @return int representation of a rgba string color + * @throws RuntimeException thrown if property isn't a value + */ + @ColorInt + public int getHillshadeHighlightColorAsInt() { + PropertyValue<String> value = getHillshadeHighlightColor(); + if (value.isValue()) { + return rgbaToColor(value.getValue()); + } else { + throw new RuntimeException("hillshade-highlight-color was set as a Function"); + } + } + + /** + * Get the HillshadeHighlightColor property transition options + * + * @return transition options for String + */ + public TransitionOptions getHillshadeHighlightColorTransition() { + return nativeGetHillshadeHighlightColorTransition(); + } + + /** + * Set the HillshadeHighlightColor property transition options + * + * @param options transition options for String + */ + public void setHillshadeHighlightColorTransition(TransitionOptions options) { + nativeSetHillshadeHighlightColorTransition(options.getDuration(), options.getDelay()); + } + + /** + * Get the HillshadeAccentColor property + * + * @return property wrapper value around String + */ + @SuppressWarnings("unchecked") + public PropertyValue<String> getHillshadeAccentColor() { + return (PropertyValue<String>) new PropertyValue("hillshade-accent-color", nativeGetHillshadeAccentColor()); + } + + /** + * The shading color used to accentuate rugged terrain like sharp cliffs and gorges. + * + * @return int representation of a rgba string color + * @throws RuntimeException thrown if property isn't a value + */ + @ColorInt + public int getHillshadeAccentColorAsInt() { + PropertyValue<String> value = getHillshadeAccentColor(); + if (value.isValue()) { + return rgbaToColor(value.getValue()); + } else { + throw new RuntimeException("hillshade-accent-color was set as a Function"); + } + } + + /** + * Get the HillshadeAccentColor property transition options + * + * @return transition options for String + */ + public TransitionOptions getHillshadeAccentColorTransition() { + return nativeGetHillshadeAccentColorTransition(); + } + + /** + * Set the HillshadeAccentColor property transition options + * + * @param options transition options for String + */ + public void setHillshadeAccentColorTransition(TransitionOptions options) { + nativeSetHillshadeAccentColorTransition(options.getDuration(), options.getDelay()); + } + + private native Object nativeGetHillshadeIlluminationDirection(); + + private native TransitionOptions nativeGetHillshadeIlluminationDirectionTransition(); + + private native void nativeSetHillshadeIlluminationDirectionTransition(long duration, long delay); + + private native Object nativeGetHillshadeIlluminationAnchor(); + + private native Object nativeGetHillshadeExaggeration(); + + private native TransitionOptions nativeGetHillshadeExaggerationTransition(); + + private native void nativeSetHillshadeExaggerationTransition(long duration, long delay); + + private native Object nativeGetHillshadeShadowColor(); + + private native TransitionOptions nativeGetHillshadeShadowColorTransition(); + + private native void nativeSetHillshadeShadowColorTransition(long duration, long delay); + + private native Object nativeGetHillshadeHighlightColor(); + + private native TransitionOptions nativeGetHillshadeHighlightColorTransition(); + + private native void nativeSetHillshadeHighlightColorTransition(long duration, long delay); + + private native Object nativeGetHillshadeAccentColor(); + + private native TransitionOptions nativeGetHillshadeAccentColorTransition(); + + private native void nativeSetHillshadeAccentColorTransition(long duration, long delay); + + @Override + protected native void finalize() throws Throwable; + +} 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 8d6c7dd055..e52474c35b 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 @@ -570,6 +570,27 @@ public final class Property { @Retention(RetentionPolicy.SOURCE) public @interface FILL_EXTRUSION_TRANSLATE_ANCHOR {} + // HILLSHADE_ILLUMINATION_ANCHOR: Direction of light source when map is rotated. + + /** + * The hillshade illumination is relative to the north direction. + */ + public static final String HILLSHADE_ILLUMINATION_ANCHOR_MAP = "map"; + /** + * The hillshade illumination is relative to the top of the viewport. + */ + public static final String HILLSHADE_ILLUMINATION_ANCHOR_VIEWPORT = "viewport"; + + /** + * Direction of light source when map is rotated. + */ + @StringDef({ + HILLSHADE_ILLUMINATION_ANCHOR_MAP, + HILLSHADE_ILLUMINATION_ANCHOR_VIEWPORT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface HILLSHADE_ILLUMINATION_ANCHOR {} + // ANCHOR: Whether extruded geometries are lit relative to the map or viewport. /** 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 93d4cfa1b7..1b9106afaf 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 @@ -1988,6 +1988,234 @@ public class PropertyFactory { } /** + * The direction of the light source used to generate the hillshading with 0 as the top of the viewport if {@link Property.HILLSHADE_ILLUMINATION_ANCHOR} is set to `viewport` and due north if {@link Property.HILLSHADE_ILLUMINATION_ANCHOR} is set to `map`. + * + * @param value a Float value + * @return property wrapper around Float + */ + public static PropertyValue<Float> hillshadeIlluminationDirection(Float value) { + return new PaintPropertyValue<>("hillshade-illumination-direction", value); + } + + /** + * The direction of the light source used to generate the hillshading with 0 as the top of the viewport if {@link Property.HILLSHADE_ILLUMINATION_ANCHOR} is set to `viewport` and due north if {@link Property.HILLSHADE_ILLUMINATION_ANCHOR} is set to `map`. + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue<Expression> hillshadeIlluminationDirection(Expression expression) { + return new PaintPropertyValue<>("hillshade-illumination-direction", expression); + } + + + /** + * The direction of the light source used to generate the hillshading with 0 as the top of the viewport if {@link Property.HILLSHADE_ILLUMINATION_ANCHOR} is set to `viewport` and due north if {@link Property.HILLSHADE_ILLUMINATION_ANCHOR} is set to `map`. + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float + * @return property wrapper around a Float function + */ + @Deprecated + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> hillshadeIlluminationDirection(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("hillshade-illumination-direction", function); + } + + /** + * Direction of light source when map is rotated. + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue<String> hillshadeIlluminationAnchor(@Property.HILLSHADE_ILLUMINATION_ANCHOR String value) { + return new PaintPropertyValue<>("hillshade-illumination-anchor", value); + } + + /** + * Direction of light source when map is rotated. + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue<Expression> hillshadeIlluminationAnchor(Expression expression) { + return new PaintPropertyValue<>("hillshade-illumination-anchor", expression); + } + + + /** + * Direction of light source when map is rotated. + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String + * @return property wrapper around a String function + */ + @Deprecated + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> hillshadeIlluminationAnchor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("hillshade-illumination-anchor", function); + } + + /** + * Intensity of the hillshade + * + * @param value a Float value + * @return property wrapper around Float + */ + public static PropertyValue<Float> hillshadeExaggeration(Float value) { + return new PaintPropertyValue<>("hillshade-exaggeration", value); + } + + /** + * Intensity of the hillshade + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue<Expression> hillshadeExaggeration(Expression expression) { + return new PaintPropertyValue<>("hillshade-exaggeration", expression); + } + + + /** + * Intensity of the hillshade + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float + * @return property wrapper around a Float function + */ + @Deprecated + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> hillshadeExaggeration(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("hillshade-exaggeration", function); + } + + /** + * The shading color of areas that face away from the light source. + * + * @param value a int color value + * @return property wrapper around String color + */ + public static PropertyValue<String> hillshadeShadowColor(@ColorInt int value) { + return new PaintPropertyValue<>("hillshade-shadow-color", colorToRgbaString(value)); + } + + /** + * The shading color of areas that face away from the light source. + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue<String> hillshadeShadowColor(String value) { + return new PaintPropertyValue<>("hillshade-shadow-color", value); + } + + /** + * The shading color of areas that face away from the light source. + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue<Expression> hillshadeShadowColor(Expression expression) { + return new PaintPropertyValue<>("hillshade-shadow-color", expression); + } + + + /** + * The shading color of areas that face away from the light source. + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String + * @return property wrapper around a String function + */ + @Deprecated + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> hillshadeShadowColor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("hillshade-shadow-color", function); + } + + /** + * The shading color of areas that faces towards the light source. + * + * @param value a int color value + * @return property wrapper around String color + */ + public static PropertyValue<String> hillshadeHighlightColor(@ColorInt int value) { + return new PaintPropertyValue<>("hillshade-highlight-color", colorToRgbaString(value)); + } + + /** + * The shading color of areas that faces towards the light source. + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue<String> hillshadeHighlightColor(String value) { + return new PaintPropertyValue<>("hillshade-highlight-color", value); + } + + /** + * The shading color of areas that faces towards the light source. + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue<Expression> hillshadeHighlightColor(Expression expression) { + return new PaintPropertyValue<>("hillshade-highlight-color", expression); + } + + + /** + * The shading color of areas that faces towards the light source. + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String + * @return property wrapper around a String function + */ + @Deprecated + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> hillshadeHighlightColor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("hillshade-highlight-color", function); + } + + /** + * The shading color used to accentuate rugged terrain like sharp cliffs and gorges. + * + * @param value a int color value + * @return property wrapper around String color + */ + public static PropertyValue<String> hillshadeAccentColor(@ColorInt int value) { + return new PaintPropertyValue<>("hillshade-accent-color", colorToRgbaString(value)); + } + + /** + * The shading color used to accentuate rugged terrain like sharp cliffs and gorges. + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue<String> hillshadeAccentColor(String value) { + return new PaintPropertyValue<>("hillshade-accent-color", value); + } + + /** + * The shading color used to accentuate rugged terrain like sharp cliffs and gorges. + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue<Expression> hillshadeAccentColor(Expression expression) { + return new PaintPropertyValue<>("hillshade-accent-color", expression); + } + + + /** + * The shading color used to accentuate rugged terrain like sharp cliffs and gorges. + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String + * @return property wrapper around a String function + */ + @Deprecated + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> hillshadeAccentColor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("hillshade-accent-color", function); + } + + /** * The color with which the background will be drawn. * * @param value a int color value 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 index 56e0af8b45..77fa11808e 100644 --- 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 @@ -78,7 +78,7 @@ public class <%- camelize(type) %>Layer extends Layer { } <% } -%> -<% if (type !== 'background' && type !== 'raster') { -%> +<% if (type !== 'background' && type !== 'raster' && type !== 'hillshade') { -%> /** * Get the source layer. * diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java new file mode 100644 index 0000000000..c76dccdedb --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/HillshadeLayerTest.java @@ -0,0 +1,523 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +package com.mapbox.mapboxsdk.testapp.style; + +import android.graphics.Color; +import android.support.test.espresso.UiController; +import android.support.test.runner.AndroidJUnit4; + +import timber.log.Timber; + +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.functions.CompositeFunction; +import com.mapbox.mapboxsdk.style.functions.CameraFunction; +import com.mapbox.mapboxsdk.style.functions.SourceFunction; +import com.mapbox.mapboxsdk.style.functions.stops.CategoricalStops; +import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops; +import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops; +import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; +import com.mapbox.mapboxsdk.style.functions.stops.Stop; +import com.mapbox.mapboxsdk.style.functions.stops.Stops; +import com.mapbox.mapboxsdk.style.layers.HillshadeLayer; +import com.mapbox.mapboxsdk.testapp.action.MapboxMapAction; +import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.mapbox.mapboxsdk.style.functions.Function.*; +import static com.mapbox.mapboxsdk.style.functions.stops.Stop.stop; +import static com.mapbox.mapboxsdk.style.functions.stops.Stops.*; +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.*; +import static com.mapbox.mapboxsdk.style.layers.Property.*; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*; + +import com.mapbox.mapboxsdk.style.layers.TransitionOptions; +import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; + +/** + * Basic smoke tests for HillshadeLayer + */ +@RunWith(AndroidJUnit4.class) +public class HillshadeLayerTest extends BaseActivityTest { + + private HillshadeLayer layer; + + @Override + protected Class getActivityClass() { + return EspressoTestActivity.class; + } + + private void setupLayer() { + Timber.i("Retrieving layer"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + if ((layer = mapboxMap.getLayerAs("my-layer")) == null) { + Timber.i("Adding layer"); + layer = new HillshadeLayer("my-layer", "composite"); + layer.setSourceLayer("composite"); + mapboxMap.addLayer(layer); + // Layer reference is now stale, get new reference + layer = mapboxMap.getLayerAs("my-layer"); + } + } + }); + } + + @Test + public void testSetVisibility() { + validateTestSetup(); + setupLayer(); + Timber.i("Visibility"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Get initial + assertEquals(layer.getVisibility().getValue(), VISIBLE); + + // Set + layer.setProperties(visibility(NONE)); + assertEquals(layer.getVisibility().getValue(), NONE); + } + }); + } + + @Test + public void testHillshadeIlluminationDirectionTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-illumination-directionTransitionOptions"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeIlluminationDirectionTransition(options); + assertEquals(layer.getHillshadeIlluminationDirectionTransition(), options); + } + }); + } + + @Test + public void testHillshadeIlluminationDirectionAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-illumination-direction"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeIlluminationDirection(0.3f)); + assertEquals((Float) layer.getHillshadeIlluminationDirection().getValue(), (Float) 0.3f); + } + }); + } + + @Test + public void testHillshadeIlluminationDirectionAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-illumination-direction"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + hillshadeIlluminationDirection( + zoom( + exponential( + stop(2, hillshadeIlluminationDirection(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getHillshadeIlluminationDirection()); + assertNotNull(layer.getHillshadeIlluminationDirection().getFunction()); + assertEquals(CameraFunction.class, layer.getHillshadeIlluminationDirection().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getHillshadeIlluminationDirection().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getHillshadeIlluminationDirection().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getHillshadeIlluminationDirection().getFunction().getStops()).size()); + } + }); + } + + @Test + public void testHillshadeIlluminationAnchorAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-illumination-anchor"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeIlluminationAnchor(HILLSHADE_ILLUMINATION_ANCHOR_MAP)); + assertEquals((String) layer.getHillshadeIlluminationAnchor().getValue(), (String) HILLSHADE_ILLUMINATION_ANCHOR_MAP); + } + }); + } + + @Test + public void testHillshadeIlluminationAnchorAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-illumination-anchor"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + hillshadeIlluminationAnchor( + zoom( + interval( + stop(2, hillshadeIlluminationAnchor(HILLSHADE_ILLUMINATION_ANCHOR_MAP)) + ) + ) + ) + ); + + // Verify + assertNotNull(layer.getHillshadeIlluminationAnchor()); + assertNotNull(layer.getHillshadeIlluminationAnchor().getFunction()); + assertEquals(CameraFunction.class, layer.getHillshadeIlluminationAnchor().getFunction().getClass()); + assertEquals(IntervalStops.class, layer.getHillshadeIlluminationAnchor().getFunction().getStops().getClass()); + assertEquals(1, ((IntervalStops) layer.getHillshadeIlluminationAnchor().getFunction().getStops()).size()); + } + }); + } + + @Test + public void testHillshadeExaggerationTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-exaggerationTransitionOptions"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeExaggerationTransition(options); + assertEquals(layer.getHillshadeExaggerationTransition(), options); + } + }); + } + + @Test + public void testHillshadeExaggerationAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-exaggeration"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeExaggeration(0.3f)); + assertEquals((Float) layer.getHillshadeExaggeration().getValue(), (Float) 0.3f); + } + }); + } + + @Test + public void testHillshadeExaggerationAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-exaggeration"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + hillshadeExaggeration( + zoom( + exponential( + stop(2, hillshadeExaggeration(0.3f)) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getHillshadeExaggeration()); + assertNotNull(layer.getHillshadeExaggeration().getFunction()); + assertEquals(CameraFunction.class, layer.getHillshadeExaggeration().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getHillshadeExaggeration().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getHillshadeExaggeration().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getHillshadeExaggeration().getFunction().getStops()).size()); + } + }); + } + + @Test + public void testHillshadeShadowColorTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-shadow-colorTransitionOptions"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeShadowColorTransition(options); + assertEquals(layer.getHillshadeShadowColorTransition(), options); + } + }); + } + + @Test + public void testHillshadeShadowColorAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-shadow-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeShadowColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getHillshadeShadowColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); + } + + @Test + public void testHillshadeShadowColorAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-shadow-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + hillshadeShadowColor( + zoom( + exponential( + stop(2, hillshadeShadowColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getHillshadeShadowColor()); + assertNotNull(layer.getHillshadeShadowColor().getFunction()); + assertEquals(CameraFunction.class, layer.getHillshadeShadowColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getHillshadeShadowColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getHillshadeShadowColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getHillshadeShadowColor().getFunction().getStops()).size()); + } + }); + } + + @Test + public void testHillshadeShadowColorAsIntConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-shadow-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeShadowColor(Color.RED)); + assertEquals(layer.getHillshadeShadowColorAsInt(), Color.RED); + } + }); + } + + @Test + public void testHillshadeHighlightColorTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-highlight-colorTransitionOptions"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeHighlightColorTransition(options); + assertEquals(layer.getHillshadeHighlightColorTransition(), options); + } + }); + } + + @Test + public void testHillshadeHighlightColorAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-highlight-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeHighlightColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getHillshadeHighlightColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); + } + + @Test + public void testHillshadeHighlightColorAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-highlight-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + hillshadeHighlightColor( + zoom( + exponential( + stop(2, hillshadeHighlightColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getHillshadeHighlightColor()); + assertNotNull(layer.getHillshadeHighlightColor().getFunction()); + assertEquals(CameraFunction.class, layer.getHillshadeHighlightColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getHillshadeHighlightColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getHillshadeHighlightColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getHillshadeHighlightColor().getFunction().getStops()).size()); + } + }); + } + + @Test + public void testHillshadeHighlightColorAsIntConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-highlight-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeHighlightColor(Color.RED)); + assertEquals(layer.getHillshadeHighlightColorAsInt(), Color.RED); + } + }); + } + + @Test + public void testHillshadeAccentColorTransition() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-accent-colorTransitionOptions"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setHillshadeAccentColorTransition(options); + assertEquals(layer.getHillshadeAccentColorTransition(), options); + } + }); + } + + @Test + public void testHillshadeAccentColorAsConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-accent-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeAccentColor("rgba(0, 0, 0, 1)")); + assertEquals((String) layer.getHillshadeAccentColor().getValue(), (String) "rgba(0, 0, 0, 1)"); + } + }); + } + + @Test + public void testHillshadeAccentColorAsCameraFunction() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-accent-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set + layer.setProperties( + hillshadeAccentColor( + zoom( + exponential( + stop(2, hillshadeAccentColor("rgba(0, 0, 0, 1)")) + ).withBase(0.5f) + ) + ) + ); + + // Verify + assertNotNull(layer.getHillshadeAccentColor()); + assertNotNull(layer.getHillshadeAccentColor().getFunction()); + assertEquals(CameraFunction.class, layer.getHillshadeAccentColor().getFunction().getClass()); + assertEquals(ExponentialStops.class, layer.getHillshadeAccentColor().getFunction().getStops().getClass()); + assertEquals(0.5f, ((ExponentialStops) layer.getHillshadeAccentColor().getFunction().getStops()).getBase(), 0.001); + assertEquals(1, ((ExponentialStops) layer.getHillshadeAccentColor().getFunction().getStops()).size()); + } + }); + } + + @Test + public void testHillshadeAccentColorAsIntConstant() { + validateTestSetup(); + setupLayer(); + Timber.i("hillshade-accent-color"); + invoke(mapboxMap, new MapboxMapAction.OnInvokeActionListener() { + @Override + public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) { + assertNotNull(layer); + + // Set and Get + layer.setProperties(hillshadeAccentColor(Color.RED)); + assertEquals(layer.getHillshadeAccentColorAsInt(), Color.RED); + } + }); + } + +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs index 192740f708..206497b860 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs @@ -99,7 +99,7 @@ public class <%- camelize(type) %>LayerTest extends BaseActivityTest { } }); } -<% if (!(type === 'background' || type === 'raster')) { -%> +<% if (!(type === 'background' || type === 'raster' || type === 'hillshade')) { -%> @Test public void testSourceLayer() { diff --git a/platform/android/config.cmake b/platform/android/config.cmake index f5de7a6052..54c6bbee40 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -158,6 +158,8 @@ add_library(mbgl-android STATIC platform/android/src/style/layers/fill_extrusion_layer.hpp platform/android/src/style/layers/fill_layer.cpp platform/android/src/style/layers/fill_layer.hpp + platform/android/src/style/layers/hillshade_layer.cpp + platform/android/src/style/layers/hillshade_layer.hpp platform/android/src/style/layers/layer.cpp platform/android/src/style/layers/layer.hpp platform/android/src/style/layers/layers.cpp diff --git a/platform/android/src/style/conversion/types.hpp b/platform/android/src/style/conversion/types.hpp index 375d1a33aa..8a75b870b3 100644 --- a/platform/android/src/style/conversion/types.hpp +++ b/platform/android/src/style/conversion/types.hpp @@ -93,6 +93,13 @@ struct Converter<jni::jobject*, mbgl::style::CirclePitchScaleType> { }; template <> +struct Converter<jni::jobject*, mbgl::style::HillshadeIlluminationAnchorType> { + Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::HillshadeIlluminationAnchorType& value) const { + return convert<jni::jobject*, std::string>(env, toString(value)); + } +}; + +template <> struct Converter<jni::jobject*, mbgl::style::LightAnchorType> { Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::LightAnchorType& value) const { return convert<jni::jobject*, std::string>(env, toString(value)); diff --git a/platform/android/src/style/conversion/types_string_values.hpp b/platform/android/src/style/conversion/types_string_values.hpp index a19ca33a2f..7e4fd4a7f7 100644 --- a/platform/android/src/style/conversion/types_string_values.hpp +++ b/platform/android/src/style/conversion/types_string_values.hpp @@ -206,6 +206,20 @@ namespace conversion { } } + // hillshade-illumination-anchor + inline std::string toString(mbgl::style::HillshadeIlluminationAnchorType value) { + switch (value) { + case mbgl::style::HillshadeIlluminationAnchorType::Map: + return "map"; + break; + case mbgl::style::HillshadeIlluminationAnchorType::Viewport: + return "viewport"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + // anchor inline std::string toString(mbgl::style::LightAnchorType value) { switch (value) { diff --git a/platform/android/src/style/layers/hillshade_layer.cpp b/platform/android/src/style/layers/hillshade_layer.cpp new file mode 100644 index 0000000000..b58bc3b947 --- /dev/null +++ b/platform/android/src/style/layers/hillshade_layer.cpp @@ -0,0 +1,178 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#include "hillshade_layer.hpp" + +#include <string> + +#include "../conversion/property_value.hpp" +#include "../conversion/transition_options.hpp" + +namespace mbgl { +namespace android { + + /** + * Creates an owning peer object (for layers not attached to the map) from the JVM side + */ + HillshadeLayer::HillshadeLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) + : Layer(env, std::make_unique<mbgl::style::HillshadeLayer>(jni::Make<std::string>(env, layerId), jni::Make<std::string>(env, sourceId))) { + } + + /** + * Creates a non-owning peer object (for layers currently attached to the map) + */ + HillshadeLayer::HillshadeLayer(mbgl::Map& map, mbgl::style::HillshadeLayer& coreLayer) + : Layer(map, coreLayer) { + } + + /** + * Creates an owning peer object (for layers not attached to the map) + */ + HillshadeLayer::HillshadeLayer(mbgl::Map& map, std::unique_ptr<mbgl::style::HillshadeLayer> coreLayer) + : Layer(map, std::move(coreLayer)) { + } + + HillshadeLayer::~HillshadeLayer() = default; + + // Property getters + + jni::Object<jni::ObjectTag> HillshadeLayer::getHillshadeIlluminationDirection(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeIlluminationDirection()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HillshadeLayer::getHillshadeIlluminationDirectionTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeIlluminationDirectionTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HillshadeLayer::setHillshadeIlluminationDirectionTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::setHillshadeIlluminationDirectionTransition(options); + } + + jni::Object<jni::ObjectTag> HillshadeLayer::getHillshadeIlluminationAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeIlluminationAnchor()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<jni::ObjectTag> HillshadeLayer::getHillshadeExaggeration(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeExaggeration()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HillshadeLayer::getHillshadeExaggerationTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeExaggerationTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HillshadeLayer::setHillshadeExaggerationTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::setHillshadeExaggerationTransition(options); + } + + jni::Object<jni::ObjectTag> HillshadeLayer::getHillshadeShadowColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeShadowColor()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HillshadeLayer::getHillshadeShadowColorTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeShadowColorTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HillshadeLayer::setHillshadeShadowColorTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::setHillshadeShadowColorTransition(options); + } + + jni::Object<jni::ObjectTag> HillshadeLayer::getHillshadeHighlightColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeHighlightColor()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HillshadeLayer::getHillshadeHighlightColorTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeHighlightColorTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HillshadeLayer::setHillshadeHighlightColorTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::setHillshadeHighlightColorTransition(options); + } + + jni::Object<jni::ObjectTag> HillshadeLayer::getHillshadeAccentColor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeAccentColor()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HillshadeLayer::getHillshadeAccentColorTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::getHillshadeAccentColorTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HillshadeLayer::setHillshadeAccentColorTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HillshadeLayer>()->HillshadeLayer::setHillshadeAccentColorTransition(options); + } + + + jni::Class<HillshadeLayer> HillshadeLayer::javaClass; + + jni::jobject* HillshadeLayer::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = HillshadeLayer::javaClass.template GetConstructor<jni::jlong>(env); + return HillshadeLayer::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)); + } + + void HillshadeLayer::registerNative(jni::JNIEnv& env) { + // Lookup the class + HillshadeLayer::javaClass = *jni::Class<HillshadeLayer>::Find(env).NewGlobalRef(env).release(); + + #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) + + // Register the peer + jni::RegisterNativePeer<HillshadeLayer>( + env, HillshadeLayer::javaClass, "nativePtr", + std::make_unique<HillshadeLayer, JNIEnv&, jni::String, jni::String>, + "initialize", + "finalize", + METHOD(&HillshadeLayer::getHillshadeIlluminationDirectionTransition, "nativeGetHillshadeIlluminationDirectionTransition"), + METHOD(&HillshadeLayer::setHillshadeIlluminationDirectionTransition, "nativeSetHillshadeIlluminationDirectionTransition"), + METHOD(&HillshadeLayer::getHillshadeIlluminationDirection, "nativeGetHillshadeIlluminationDirection"), + METHOD(&HillshadeLayer::getHillshadeIlluminationAnchor, "nativeGetHillshadeIlluminationAnchor"), + METHOD(&HillshadeLayer::getHillshadeExaggerationTransition, "nativeGetHillshadeExaggerationTransition"), + METHOD(&HillshadeLayer::setHillshadeExaggerationTransition, "nativeSetHillshadeExaggerationTransition"), + METHOD(&HillshadeLayer::getHillshadeExaggeration, "nativeGetHillshadeExaggeration"), + METHOD(&HillshadeLayer::getHillshadeShadowColorTransition, "nativeGetHillshadeShadowColorTransition"), + METHOD(&HillshadeLayer::setHillshadeShadowColorTransition, "nativeSetHillshadeShadowColorTransition"), + METHOD(&HillshadeLayer::getHillshadeShadowColor, "nativeGetHillshadeShadowColor"), + METHOD(&HillshadeLayer::getHillshadeHighlightColorTransition, "nativeGetHillshadeHighlightColorTransition"), + METHOD(&HillshadeLayer::setHillshadeHighlightColorTransition, "nativeSetHillshadeHighlightColorTransition"), + METHOD(&HillshadeLayer::getHillshadeHighlightColor, "nativeGetHillshadeHighlightColor"), + METHOD(&HillshadeLayer::getHillshadeAccentColorTransition, "nativeGetHillshadeAccentColorTransition"), + METHOD(&HillshadeLayer::setHillshadeAccentColorTransition, "nativeSetHillshadeAccentColorTransition"), + METHOD(&HillshadeLayer::getHillshadeAccentColor, "nativeGetHillshadeAccentColor")); + } + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/hillshade_layer.hpp b/platform/android/src/style/layers/hillshade_layer.hpp new file mode 100644 index 0000000000..101febb228 --- /dev/null +++ b/platform/android/src/style/layers/hillshade_layer.hpp @@ -0,0 +1,58 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#pragma once + +#include "layer.hpp" +#include "../transition_options.hpp" +#include <mbgl/style/layers/hillshade_layer.hpp> +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { + +class HillshadeLayer : public Layer { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/layers/HillshadeLayer"; }; + + static jni::Class<HillshadeLayer> javaClass; + + static void registerNative(jni::JNIEnv&); + + HillshadeLayer(jni::JNIEnv&, jni::String, jni::String); + + HillshadeLayer(mbgl::Map&, mbgl::style::HillshadeLayer&); + + HillshadeLayer(mbgl::Map&, std::unique_ptr<mbgl::style::HillshadeLayer>); + + ~HillshadeLayer(); + + // Properties + + jni::Object<jni::ObjectTag> getHillshadeIlluminationDirection(jni::JNIEnv&); + void setHillshadeIlluminationDirectionTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHillshadeIlluminationDirectionTransition(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHillshadeIlluminationAnchor(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHillshadeExaggeration(jni::JNIEnv&); + void setHillshadeExaggerationTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHillshadeExaggerationTransition(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHillshadeShadowColor(jni::JNIEnv&); + void setHillshadeShadowColorTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHillshadeShadowColorTransition(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHillshadeHighlightColor(jni::JNIEnv&); + void setHillshadeHighlightColorTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHillshadeHighlightColorTransition(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHillshadeAccentColor(jni::JNIEnv&); + void setHillshadeAccentColorTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHillshadeAccentColorTransition(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); + +}; // class HillshadeLayer + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index 31032b117f..da1550bdb1 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -10,6 +10,7 @@ #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer.hpp> +#include <mbgl/style/layers/hillshade_layer.hpp> #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/symbol_layer.hpp> @@ -110,6 +111,7 @@ namespace android { void operator()(style::BackgroundLayer&) { Log::Warning(mbgl::Event::JNI, "BackgroundLayer doesn't support filters"); } void operator()(style::CustomLayer&) { Log::Warning(mbgl::Event::JNI, "CustomLayer doesn't support filters"); } void operator()(style::RasterLayer&) { Log::Warning(mbgl::Event::JNI, "RasterLayer doesn't support filters"); } + void operator()(style::HillshadeLayer&) { Log::Warning(mbgl::Event::JNI, "HillshadeLayer doesn't support filters"); } template <class LayerType> void operator()(LayerType& layer) { @@ -137,6 +139,7 @@ namespace android { void operator()(style::BackgroundLayer&) { Log::Warning(mbgl::Event::JNI, "BackgroundLayer doesn't support source layer"); } void operator()(style::CustomLayer&) { Log::Warning(mbgl::Event::JNI, "CustomLayer doesn't support source layer"); } void operator()(style::RasterLayer&) { Log::Warning(mbgl::Event::JNI, "RasterLayer doesn't support source layer"); } + void operator()(style::HillshadeLayer&) { Log::Warning(mbgl::Event::JNI, "HillshadeLayer doesn't support source layer"); } template <class LayerType> void operator()(LayerType& layer) { @@ -157,6 +160,7 @@ namespace android { std::string operator()(style::BackgroundLayer&) { return noop("BackgroundLayer"); } std::string operator()(style::CustomLayer&) { return noop("CustomLayer"); } std::string operator()(style::RasterLayer&) { return noop("RasterLayer"); } + std::string operator()(style::HillshadeLayer&) { return noop("HillshadeLayer"); } template <class LayerType> std::string operator()(LayerType& layer) { diff --git a/platform/android/src/style/layers/layers.cpp b/platform/android/src/style/layers/layers.cpp index 9803b6f841..5d1d1bbcbf 100644 --- a/platform/android/src/style/layers/layers.cpp +++ b/platform/android/src/style/layers/layers.cpp @@ -5,6 +5,7 @@ #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/layers/hillshade_layer.hpp> #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/symbol_layer.hpp> @@ -15,6 +16,7 @@ #include "custom_layer.hpp" #include "fill_extrusion_layer.hpp" #include "fill_layer.hpp" +#include "hillshade_layer.hpp" #include "line_layer.hpp" #include "raster_layer.hpp" #include "symbol_layer.hpp" @@ -30,6 +32,7 @@ template <> struct PeerType<style::BackgroundLayer> { using Type = android::Back template <> struct PeerType<style::CircleLayer> { using Type = android::CircleLayer; }; template <> struct PeerType<style::FillExtrusionLayer> { using Type = android::FillExtrusionLayer; }; template <> struct PeerType<style::FillLayer> { using Type = android::FillLayer; }; +template <> struct PeerType<style::HillshadeLayer> { using Type = android::HillshadeLayer; }; template <> struct PeerType<style::LineLayer> { using Type = android::LineLayer; }; template <> struct PeerType<style::RasterLayer> { using Type = android::RasterLayer; }; template <> struct PeerType<style::SymbolLayer> { using Type = android::SymbolLayer; }; @@ -92,6 +95,7 @@ void registerNativeLayers(jni::JNIEnv& env) { CustomLayer::registerNative(env); FillExtrusionLayer::registerNative(env); FillLayer::registerNative(env); + HillshadeLayer::registerNative(env); LineLayer::registerNative(env); RasterLayer::registerNative(env); SymbolLayer::registerNative(env); diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.h b/platform/darwin/src/MGLHillshadeStyleLayer.h new file mode 100644 index 0000000000..0fe49d510d --- /dev/null +++ b/platform/darwin/src/MGLHillshadeStyleLayer.h @@ -0,0 +1,276 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLFoundation.h" +#import "MGLStyleValue.h" +#import "MGLVectorStyleLayer.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Direction of light source when map is rotated. + + Values of this type are used in the `MGLHillshadeStyleLayer.hillshadeIlluminationAnchor` + property. + */ +typedef NS_ENUM(NSUInteger, MGLHillshadeIlluminationAnchor) { + /** + The hillshade illumination is relative to the north direction. + */ + MGLHillshadeIlluminationAnchorMap, + /** + The hillshade illumination is relative to the top of the viewport. + */ + MGLHillshadeIlluminationAnchorViewport, +}; + +/** + Client-side hillshading visualization based on DEM data. Currently, the + implementation only supports Mapbox Terrain RGB tiles + + You can access an existing hillshade style layer using the + `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; + otherwise, find it using the `MGLStyle.layers` property. You can also create a + new hillshade style layer and add it to the style using a method such as + `-[MGLStyle addLayer:]`. + + ### Example + + ```swift + ``` + */ +MGL_EXPORT +@interface MGLHillshadeStyleLayer : MGLVectorStyleLayer + +/** + Returns a hillshade style layer initialized with an identifier and source. + + After initializing and configuring the style layer, add it to a map view’s + style using the `-[MGLStyle addLayer:]` or + `-[MGLStyle insertLayer:belowLayer:]` method. + + @param identifier A string that uniquely identifies the source in the style to + which it is added. + @param source The source from which to obtain the data to style. If the source + has not yet been added to the current style, the behavior is undefined. + @return An initialized foreground style layer. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; + +#pragma mark - Accessing the Paint Attributes + +#if TARGET_OS_IPHONE +/** + The shading color used to accentuate rugged terrain like sharp cliffs and + gorges. + + The default value of this property is an `MGLStyleValue` object containing + `UIColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *hillshadeAccentColor; +#else +/** + The shading color used to accentuate rugged terrain like sharp cliffs and + gorges. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *hillshadeAccentColor; +#endif + +/** + The transition affecting any changes to this layer’s `hillshadeAccentColor` property. + + This property corresponds to the `hillshade-accent-color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeAccentColorTransition; + +/** + Intensity of the hillshade + + The default value of this property is an `MGLStyleValue` object containing an + `NSNumber` object containing the float `0.5`. Set this property to `nil` to + reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *hillshadeExaggeration; + +/** + The transition affecting any changes to this layer’s `hillshadeExaggeration` property. + + This property corresponds to the `hillshade-exaggeration-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeExaggerationTransition; + +#if TARGET_OS_IPHONE +/** + The shading color of areas that faces towards the light source. + + The default value of this property is an `MGLStyleValue` object containing + `UIColor.whiteColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *hillshadeHighlightColor; +#else +/** + The shading color of areas that faces towards the light source. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.whiteColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *hillshadeHighlightColor; +#endif + +/** + The transition affecting any changes to this layer’s `hillshadeHighlightColor` property. + + This property corresponds to the `hillshade-highlight-color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeHighlightColorTransition; + +/** + Direction of light source when map is rotated. + + The default value of this property is an `MGLStyleValue` object containing an + `NSValue` object containing `MGLHillshadeIlluminationAnchorViewport`. Set this + property to `nil` to reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of + `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *hillshadeIlluminationAnchor; + +/** + The direction of the light source used to generate the hillshading with 0 as + the top of the viewport if `hillshadeIlluminationAnchor` is set to + `MGLHillshadeIlluminationAnchorViewport` and due north if + `hillshadeIlluminationAnchor` is set to `MGLHillshadeIlluminationAnchorMap`. + + The default value of this property is an `MGLStyleValue` object containing an + `NSNumber` object containing the float `335`. Set this property to `nil` to + reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *hillshadeIlluminationDirection; + +/** + The transition affecting any changes to this layer’s `hillshadeIlluminationDirection` property. + + This property corresponds to the `hillshade-illumination-direction-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeIlluminationDirectionTransition; + +#if TARGET_OS_IPHONE +/** + The shading color of areas that face away from the light source. + + The default value of this property is an `MGLStyleValue` object containing + `UIColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *hillshadeShadowColor; +#else +/** + The shading color of areas that face away from the light source. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *hillshadeShadowColor; +#endif + +/** + The transition affecting any changes to this layer’s `hillshadeShadowColor` property. + + This property corresponds to the `hillshade-shadow-color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeShadowColorTransition; + +@end + +/** + Methods for wrapping an enumeration value for a style layer attribute in an + `MGLHillshadeStyleLayer` object and unwrapping its raw value. + */ +@interface NSValue (MGLHillshadeStyleLayerAdditions) + +#pragma mark Working with Hillshade Style Layer Attribute Values + +/** + Creates a new value object containing the given `MGLHillshadeIlluminationAnchor` enumeration. + + @param hillshadeIlluminationAnchor The value for the new object. + @return A new value object that contains the enumeration value. + */ ++ (instancetype)valueWithMGLHillshadeIlluminationAnchor:(MGLHillshadeIlluminationAnchor)hillshadeIlluminationAnchor; + +/** + The `MGLHillshadeIlluminationAnchor` enumeration representation of the value. + */ +@property (readonly) MGLHillshadeIlluminationAnchor MGLHillshadeIlluminationAnchorValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.mm b/platform/darwin/src/MGLHillshadeStyleLayer.mm new file mode 100644 index 0000000000..3225feb587 --- /dev/null +++ b/platform/darwin/src/MGLHillshadeStyleLayer.mm @@ -0,0 +1,286 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLSource.h" +#import "NSPredicate+MGLAdditions.h" +#import "NSDate+MGLAdditions.h" +#import "MGLStyleLayer_Private.h" +#import "MGLStyleValue_Private.h" +#import "MGLHillshadeStyleLayer.h" + +#include <mbgl/style/transition_options.hpp> +#include <mbgl/style/layers/hillshade_layer.hpp> + +namespace mbgl { + + MBGL_DEFINE_ENUM(MGLHillshadeIlluminationAnchor, { + { MGLHillshadeIlluminationAnchorMap, "map" }, + { MGLHillshadeIlluminationAnchorViewport, "viewport" }, + }); + +} + +@interface MGLHillshadeStyleLayer () + +@property (nonatomic, readonly) mbgl::style::HillshadeLayer *rawLayer; + +@end + +@implementation MGLHillshadeStyleLayer + +- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source +{ + auto layer = std::make_unique<mbgl::style::HillshadeLayer>(identifier.UTF8String, source.identifier.UTF8String); + return self = [super initWithPendingLayer:std::move(layer)]; +} + +- (mbgl::style::HillshadeLayer *)rawLayer +{ + return (mbgl::style::HillshadeLayer *)super.rawLayer; +} + +- (NSString *)sourceIdentifier +{ + MGLAssertStyleLayerIsValid(); + + return @(self.rawLayer->getSourceID().c_str()); +} + +- (NSString *)sourceLayerIdentifier +{ + MGLAssertStyleLayerIsValid(); + + auto layerID = self.rawLayer->getSourceLayer(); + return layerID.empty() ? nil : @(layerID.c_str()); +} + +- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier +{ + MGLAssertStyleLayerIsValid(); + + self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); +} + +- (void)setPredicate:(NSPredicate *)predicate +{ + MGLAssertStyleLayerIsValid(); + + self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::NullFilter()); +} + +- (NSPredicate *)predicate +{ + MGLAssertStyleLayerIsValid(); + + return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; +} + +#pragma mark - Accessing the Paint Attributes + +- (void)setHillshadeAccentColor:(MGLStyleValue<MGLColor *> *)hillshadeAccentColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toInterpolatablePropertyValue(hillshadeAccentColor); + self.rawLayer->setHillshadeAccentColor(mbglValue); +} + +- (MGLStyleValue<MGLColor *> *)hillshadeAccentColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeAccentColor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(self.rawLayer->getDefaultHillshadeAccentColor()); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeAccentColorTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeAccentColorTransition(options); +} + +- (MGLTransition)hillshadeAccentColorTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeAccentColorTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeExaggeration:(MGLStyleValue<NSNumber *> *)hillshadeExaggeration { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(hillshadeExaggeration); + self.rawLayer->setHillshadeExaggeration(mbglValue); +} + +- (MGLStyleValue<NSNumber *> *)hillshadeExaggeration { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeExaggeration(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultHillshadeExaggeration()); + } + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeExaggerationTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeExaggerationTransition(options); +} + +- (MGLTransition)hillshadeExaggerationTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeExaggerationTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeHighlightColor:(MGLStyleValue<MGLColor *> *)hillshadeHighlightColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toInterpolatablePropertyValue(hillshadeHighlightColor); + self.rawLayer->setHillshadeHighlightColor(mbglValue); +} + +- (MGLStyleValue<MGLColor *> *)hillshadeHighlightColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeHighlightColor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(self.rawLayer->getDefaultHillshadeHighlightColor()); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeHighlightColorTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeHighlightColorTransition(options); +} + +- (MGLTransition)hillshadeHighlightColorTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeHighlightColorTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeIlluminationAnchor:(MGLStyleValue<NSValue *> *)hillshadeIlluminationAnchor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toEnumPropertyValue(hillshadeIlluminationAnchor); + self.rawLayer->setHillshadeIlluminationAnchor(mbglValue); +} + +- (MGLStyleValue<NSValue *> *)hillshadeIlluminationAnchor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeIlluminationAnchor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toEnumStyleValue(self.rawLayer->getDefaultHillshadeIlluminationAnchor()); + } + return MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toEnumStyleValue(propertyValue); +} + +- (void)setHillshadeIlluminationDirection:(MGLStyleValue<NSNumber *> *)hillshadeIlluminationDirection { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(hillshadeIlluminationDirection); + self.rawLayer->setHillshadeIlluminationDirection(mbglValue); +} + +- (MGLStyleValue<NSNumber *> *)hillshadeIlluminationDirection { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeIlluminationDirection(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultHillshadeIlluminationDirection()); + } + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeIlluminationDirectionTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeIlluminationDirectionTransition(options); +} + +- (MGLTransition)hillshadeIlluminationDirectionTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeIlluminationDirectionTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeShadowColor:(MGLStyleValue<MGLColor *> *)hillshadeShadowColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toInterpolatablePropertyValue(hillshadeShadowColor); + self.rawLayer->setHillshadeShadowColor(mbglValue); +} + +- (MGLStyleValue<MGLColor *> *)hillshadeShadowColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeShadowColor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(self.rawLayer->getDefaultHillshadeShadowColor()); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeShadowColorTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeShadowColorTransition(options); +} + +- (MGLTransition)hillshadeShadowColorTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeShadowColorTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +@end + +@implementation NSValue (MGLHillshadeStyleLayerAdditions) + ++ (NSValue *)valueWithMGLHillshadeIlluminationAnchor:(MGLHillshadeIlluminationAnchor)hillshadeIlluminationAnchor { + return [NSValue value:&hillshadeIlluminationAnchor withObjCType:@encode(MGLHillshadeIlluminationAnchor)]; +} + +- (MGLHillshadeIlluminationAnchor)MGLHillshadeIlluminationAnchorValue { + MGLHillshadeIlluminationAnchor hillshadeIlluminationAnchor; + [self getValue:&hillshadeIlluminationAnchor]; + return hillshadeIlluminationAnchor; +} + +@end diff --git a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm new file mode 100644 index 0000000000..283830ccb5 --- /dev/null +++ b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm @@ -0,0 +1,345 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLStyleLayerTests.h" +#import "../../darwin/src/NSDate+MGLAdditions.h" + +#import "MGLStyleLayer_Private.h" + +#include <mbgl/style/layers/hillshade_layer.hpp> +#include <mbgl/style/transition_options.hpp> + +@interface MGLHillshadeLayerTests : MGLStyleLayerTests +@end + +@implementation MGLHillshadeLayerTests + ++ (NSString *)layerType { + return @"hillshade"; +} + +- (void)testPredicates { + MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil]; + MGLHillshadeStyleLayer *layer = [[MGLHillshadeStyleLayer alloc] initWithIdentifier:@"layerID" source:source]; + + XCTAssertNil(layer.sourceLayerIdentifier); + layer.sourceLayerIdentifier = @"layerID"; + XCTAssertEqualObjects(layer.sourceLayerIdentifier, @"layerID"); + layer.sourceLayerIdentifier = nil; + XCTAssertNil(layer.sourceLayerIdentifier); + + XCTAssertNil(layer.predicate); + layer.predicate = [NSPredicate predicateWithValue:NO]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = nil; + XCTAssertNil(layer.predicate); +} + +- (void)testProperties { + MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil]; + + MGLHillshadeStyleLayer *layer = [[MGLHillshadeStyleLayer alloc] initWithIdentifier:@"layerID" source:source]; + XCTAssertNotEqual(layer.rawLayer, nullptr); + XCTAssertTrue(layer.rawLayer->is<mbgl::style::HillshadeLayer>()); + auto rawLayer = layer.rawLayer->as<mbgl::style::HillshadeLayer>(); + + MGLTransition transitionTest = MGLTransitionMake(5, 4); + + + // hillshade-accent-color + { + XCTAssertTrue(rawLayer->getHillshadeAccentColor().isUndefined(), + @"hillshade-accent-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.hillshadeAccentColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.hillshadeAccentColor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getHillshadeAccentColor(), propertyValue, + @"Setting hillshadeAccentColor to a constant value should update hillshade-accent-color."); + XCTAssertEqualObjects(layer.hillshadeAccentColor, constantStyleValue, + @"hillshadeAccentColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeAccentColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeAccentColor(), propertyValue, + @"Setting hillshadeAccentColor to a camera function should update hillshade-accent-color."); + XCTAssertEqualObjects(layer.hillshadeAccentColor, functionStyleValue, + @"hillshadeAccentColor should round-trip camera functions."); + + + + layer.hillshadeAccentColor = nil; + XCTAssertTrue(rawLayer->getHillshadeAccentColor().isUndefined(), + @"Unsetting hillshadeAccentColor should return hillshade-accent-color to the default value."); + XCTAssertEqualObjects(layer.hillshadeAccentColor, defaultStyleValue, + @"hillshadeAccentColor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeAccentColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeAccentColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeAccentColorTransition = transitionTest; + auto toptions = rawLayer->getHillshadeAccentColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeAccentColorTransition = layer.hillshadeAccentColorTransition; + XCTAssertEqual(hillshadeAccentColorTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeAccentColorTransition.duration, transitionTest.duration); + } + + // hillshade-exaggeration + { + XCTAssertTrue(rawLayer->getHillshadeExaggeration().isUndefined(), + @"hillshade-exaggeration should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.hillshadeExaggeration; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.hillshadeExaggeration = constantStyleValue; + mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getHillshadeExaggeration(), propertyValue, + @"Setting hillshadeExaggeration to a constant value should update hillshade-exaggeration."); + XCTAssertEqualObjects(layer.hillshadeExaggeration, constantStyleValue, + @"hillshadeExaggeration should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeExaggeration = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeExaggeration(), propertyValue, + @"Setting hillshadeExaggeration to a camera function should update hillshade-exaggeration."); + XCTAssertEqualObjects(layer.hillshadeExaggeration, functionStyleValue, + @"hillshadeExaggeration should round-trip camera functions."); + + + + layer.hillshadeExaggeration = nil; + XCTAssertTrue(rawLayer->getHillshadeExaggeration().isUndefined(), + @"Unsetting hillshadeExaggeration should return hillshade-exaggeration to the default value."); + XCTAssertEqualObjects(layer.hillshadeExaggeration, defaultStyleValue, + @"hillshadeExaggeration should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeExaggeration = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeExaggeration = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeExaggerationTransition = transitionTest; + auto toptions = rawLayer->getHillshadeExaggerationTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeExaggerationTransition = layer.hillshadeExaggerationTransition; + XCTAssertEqual(hillshadeExaggerationTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeExaggerationTransition.duration, transitionTest.duration); + } + + // hillshade-highlight-color + { + XCTAssertTrue(rawLayer->getHillshadeHighlightColor().isUndefined(), + @"hillshade-highlight-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.hillshadeHighlightColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.hillshadeHighlightColor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getHillshadeHighlightColor(), propertyValue, + @"Setting hillshadeHighlightColor to a constant value should update hillshade-highlight-color."); + XCTAssertEqualObjects(layer.hillshadeHighlightColor, constantStyleValue, + @"hillshadeHighlightColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeHighlightColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeHighlightColor(), propertyValue, + @"Setting hillshadeHighlightColor to a camera function should update hillshade-highlight-color."); + XCTAssertEqualObjects(layer.hillshadeHighlightColor, functionStyleValue, + @"hillshadeHighlightColor should round-trip camera functions."); + + + + layer.hillshadeHighlightColor = nil; + XCTAssertTrue(rawLayer->getHillshadeHighlightColor().isUndefined(), + @"Unsetting hillshadeHighlightColor should return hillshade-highlight-color to the default value."); + XCTAssertEqualObjects(layer.hillshadeHighlightColor, defaultStyleValue, + @"hillshadeHighlightColor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeHighlightColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeHighlightColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeHighlightColorTransition = transitionTest; + auto toptions = rawLayer->getHillshadeHighlightColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeHighlightColorTransition = layer.hillshadeHighlightColorTransition; + XCTAssertEqual(hillshadeHighlightColorTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeHighlightColorTransition.duration, transitionTest.duration); + } + + // hillshade-illumination-anchor + { + XCTAssertTrue(rawLayer->getHillshadeIlluminationAnchor().isUndefined(), + @"hillshade-illumination-anchor should be unset initially."); + MGLStyleValue<NSValue *> *defaultStyleValue = layer.hillshadeIlluminationAnchor; + + MGLStyleValue<NSValue *> *constantStyleValue = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLHillshadeIlluminationAnchor:MGLHillshadeIlluminationAnchorViewport]]; + layer.hillshadeIlluminationAnchor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::style::HillshadeIlluminationAnchorType> propertyValue = { mbgl::style::HillshadeIlluminationAnchorType::Viewport }; + XCTAssertEqual(rawLayer->getHillshadeIlluminationAnchor(), propertyValue, + @"Setting hillshadeIlluminationAnchor to a constant value should update hillshade-illumination-anchor."); + XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, constantStyleValue, + @"hillshadeIlluminationAnchor should round-trip constant values."); + + MGLStyleValue<NSValue *> * functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeIlluminationAnchor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::style::HillshadeIlluminationAnchorType> intervalStops = { {{18, mbgl::style::HillshadeIlluminationAnchorType::Viewport}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::style::HillshadeIlluminationAnchorType> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeIlluminationAnchor(), propertyValue, + @"Setting hillshadeIlluminationAnchor to a camera function should update hillshade-illumination-anchor."); + XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, functionStyleValue, + @"hillshadeIlluminationAnchor should round-trip camera functions."); + + + + layer.hillshadeIlluminationAnchor = nil; + XCTAssertTrue(rawLayer->getHillshadeIlluminationAnchor().isUndefined(), + @"Unsetting hillshadeIlluminationAnchor should return hillshade-illumination-anchor to the default value."); + XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, defaultStyleValue, + @"hillshadeIlluminationAnchor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + } + + // hillshade-illumination-direction + { + XCTAssertTrue(rawLayer->getHillshadeIlluminationDirection().isUndefined(), + @"hillshade-illumination-direction should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.hillshadeIlluminationDirection; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.hillshadeIlluminationDirection = constantStyleValue; + mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getHillshadeIlluminationDirection(), propertyValue, + @"Setting hillshadeIlluminationDirection to a constant value should update hillshade-illumination-direction."); + XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, constantStyleValue, + @"hillshadeIlluminationDirection should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeIlluminationDirection = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeIlluminationDirection(), propertyValue, + @"Setting hillshadeIlluminationDirection to a camera function should update hillshade-illumination-direction."); + XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, functionStyleValue, + @"hillshadeIlluminationDirection should round-trip camera functions."); + + + + layer.hillshadeIlluminationDirection = nil; + XCTAssertTrue(rawLayer->getHillshadeIlluminationDirection().isUndefined(), + @"Unsetting hillshadeIlluminationDirection should return hillshade-illumination-direction to the default value."); + XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, defaultStyleValue, + @"hillshadeIlluminationDirection should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationDirection = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationDirection = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeIlluminationDirectionTransition = transitionTest; + auto toptions = rawLayer->getHillshadeIlluminationDirectionTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeIlluminationDirectionTransition = layer.hillshadeIlluminationDirectionTransition; + XCTAssertEqual(hillshadeIlluminationDirectionTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeIlluminationDirectionTransition.duration, transitionTest.duration); + } + + // hillshade-shadow-color + { + XCTAssertTrue(rawLayer->getHillshadeShadowColor().isUndefined(), + @"hillshade-shadow-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.hillshadeShadowColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.hillshadeShadowColor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getHillshadeShadowColor(), propertyValue, + @"Setting hillshadeShadowColor to a constant value should update hillshade-shadow-color."); + XCTAssertEqualObjects(layer.hillshadeShadowColor, constantStyleValue, + @"hillshadeShadowColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeShadowColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeShadowColor(), propertyValue, + @"Setting hillshadeShadowColor to a camera function should update hillshade-shadow-color."); + XCTAssertEqualObjects(layer.hillshadeShadowColor, functionStyleValue, + @"hillshadeShadowColor should round-trip camera functions."); + + + + layer.hillshadeShadowColor = nil; + XCTAssertTrue(rawLayer->getHillshadeShadowColor().isUndefined(), + @"Unsetting hillshadeShadowColor should return hillshade-shadow-color to the default value."); + XCTAssertEqualObjects(layer.hillshadeShadowColor, defaultStyleValue, + @"hillshadeShadowColor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeShadowColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeShadowColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeShadowColorTransition = transitionTest; + auto toptions = rawLayer->getHillshadeShadowColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeShadowColorTransition = layer.hillshadeShadowColorTransition; + XCTAssertEqual(hillshadeShadowColorTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeShadowColorTransition.duration, transitionTest.duration); + } +} + +- (void)testPropertyNames { + [self testPropertyName:@"hillshade-accent-color" isBoolean:NO]; + [self testPropertyName:@"hillshade-exaggeration" isBoolean:NO]; + [self testPropertyName:@"hillshade-highlight-color" isBoolean:NO]; + [self testPropertyName:@"hillshade-illumination-anchor" isBoolean:NO]; + [self testPropertyName:@"hillshade-illumination-direction" isBoolean:NO]; + [self testPropertyName:@"hillshade-shadow-color" isBoolean:NO]; +} + +- (void)testValueAdditions { + XCTAssertEqual([NSValue valueWithMGLHillshadeIlluminationAnchor:MGLHillshadeIlluminationAnchorMap].MGLHillshadeIlluminationAnchorValue, MGLHillshadeIlluminationAnchorMap); + XCTAssertEqual([NSValue valueWithMGLHillshadeIlluminationAnchor:MGLHillshadeIlluminationAnchorViewport].MGLHillshadeIlluminationAnchorValue, MGLHillshadeIlluminationAnchorViewport); +} + +@end diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp index 8bb16993a5..ba504c1f9b 100644 --- a/platform/default/mbgl/storage/offline_download.cpp +++ b/platform/default/mbgl/storage/offline_download.cpp @@ -7,6 +7,7 @@ #include <mbgl/style/parser.hpp> #include <mbgl/style/sources/vector_source.hpp> #include <mbgl/style/sources/raster_source.hpp> +#include <mbgl/style/sources/raster_dem_source.hpp> #include <mbgl/style/sources/geojson_source.hpp> #include <mbgl/style/sources/image_source.hpp> #include <mbgl/style/conversion/json.hpp> @@ -110,6 +111,12 @@ OfflineRegionStatus OfflineDownload::getStatus() const { handleTiledSource(rasterSource.getURLOrTileset(), rasterSource.getTileSize()); break; } + + case SourceType::RasterDEM: { + const auto& rasterDEMSource = *source->as<RasterDEMSource>(); + handleTiledSource(rasterDEMSource.getURLOrTileset(), rasterDEMSource.getTileSize()); + break; + } case SourceType::GeoJSON: { const auto& geojsonSource = *source->as<GeoJSONSource>(); @@ -195,6 +202,12 @@ void OfflineDownload::activateDownload() { handleTiledSource(rasterSource.getURLOrTileset(), rasterSource.getTileSize()); break; } + + case SourceType::RasterDEM: { + const auto& rasterDEMSource = *source->as<RasterDEMSource>(); + handleTiledSource(rasterDEMSource.getURLOrTileset(), rasterDEMSource.getTileSize()); + break; + } case SourceType::GeoJSON: { const auto& geojsonSource = *source->as<GeoJSONSource>(); diff --git a/platform/ios/docs/guides/For Style Authors.md b/platform/ios/docs/guides/For Style Authors.md index 7eabfed777..00dba95419 100644 --- a/platform/ios/docs/guides/For Style Authors.md +++ b/platform/ios/docs/guides/For Style Authors.md @@ -190,6 +190,7 @@ In style JSON | In the SDK `circle` | `MGLCircleStyleLayer` `fill` | `MGLFillStyleLayer` `fill-extrusion` | `MGLFillExtrusionStyleLayer` +`hillshade` | `MGLHillshadeStyleLayer` `line` | `MGLLineStyleLayer` `raster` | `MGLRasterStyleLayer` `symbol` | `MGLSymbolStyleLayer` diff --git a/platform/macos/docs/guides/For Style Authors.md b/platform/macos/docs/guides/For Style Authors.md index 3cacc81376..9eeb159b75 100644 --- a/platform/macos/docs/guides/For Style Authors.md +++ b/platform/macos/docs/guides/For Style Authors.md @@ -177,6 +177,7 @@ In style JSON | In the SDK `circle` | `MGLCircleStyleLayer` `fill` | `MGLFillStyleLayer` `fill-extrusion` | `MGLFillExtrusionStyleLayer` +`hillshade` | `MGLHillshadeStyleLayer` `line` | `MGLLineStyleLayer` `raster` | `MGLRasterStyleLayer` `symbol` | `MGLSymbolStyleLayer` diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index b8c5e9cc88..5dd5e6b490 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -14,6 +14,7 @@ #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer.hpp> +#include <mbgl/style/layers/hillshade_layer.hpp> #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/symbol_layer.hpp> @@ -800,6 +801,10 @@ struct SetFilterVisitor { Nan::ThrowTypeError("layer doesn't support filters"); } + void operator()(mbgl::style::HillshadeLayer&) { + Nan::ThrowTypeError("layer doesn't support filters"); + } + void operator()(mbgl::style::BackgroundLayer&) { Nan::ThrowTypeError("layer doesn't support filters"); } diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index 6428bcf49f..1341fc86a1 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -62,21 +62,13 @@ "render-tests/text-pitch-scaling/line-half": "https://github.com/mapbox/mapbox-gl-native/issues/9732", "render-tests/video/default": "skip - https://github.com/mapbox/mapbox-gl-native/issues/601", "render-tests/background-color/colorSpace-hcl": "needs issue", - "render-tests/hillshade-accent-color/default": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-accent-color/literal": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-accent-color/zoom-function": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-highlight-color/default": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-highlight-color/literal": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-highlight-color/zoom-function": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-shadow-color/default": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-shadow-color/literal": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/hillshade-shadow-color/zoom-function": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642", "render-tests/combinations/background-opaque--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/background-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/circle-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/fill-extrusion-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/fill-opaque--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/fill-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", + "render-tests/combinations/hillshade-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/heatmap-translucent--background-opaque": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/heatmap-translucent--background-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/heatmap-translucent--circle-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", @@ -91,35 +83,17 @@ "render-tests/combinations/line-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/raster-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", "render-tests/combinations/symbol-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/issues/10146", - "render-tests/combinations/background-opaque--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/background-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/circle-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/fill-extrusion-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/fill-opaque--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/fill-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--background-opaque": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--background-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--circle-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--fill-extrusion-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--fill-opaque": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--fill-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--heatmap-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--line-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--raster-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/hillshade-translucent--symbol-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/line-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/raster-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", - "render-tests/combinations/symbol-translucent--hillshade-translucent": "https://github.com/mapbox/mapbox-gl-native/pull/10642", "render-tests/combinations/background-opaque--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/background-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/circle-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/fill-extrusion-translucent--background-translucent": "needs investigation", "render-tests/combinations/fill-extrusion-translucent--circle-translucent": "needs investigation", + "render-tests/combinations/fill-extrusion-translucent--hillshade-translucent": "needs investigation", "render-tests/combinations/fill-extrusion-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/fill-extrusion-translucent--fill-translucent": "needs investigation", "render-tests/combinations/fill-extrusion-translucent--line-translucent": "needs investigation", "render-tests/combinations/fill-extrusion-translucent--symbol-translucent": "needs investigation", + "render-tests/combinations/hillshade-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/fill-opaque--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/fill-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/combinations/line-translucent--fill-extrusion-translucent": "needs investigation", |