From 4a24e468ed7ec52fde951e101159fa4d3444cea3 Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Wed, 14 Jun 2023 12:34:39 +0200 Subject: [PATCH] Fix Android code generation templates & regenerate generated sources (#1239) --- .../src/cpp/style/layers/layer.hpp.ejs | 4 +- .../android/style/layers/HillshadeLayer.java | 2 +- .../android/style/layers/PropertyFactory.java | 4 +- .../android/style/layers/layer.java.ejs | 349 +++++++++++++----- .../style/layers/property_factory.java.ejs | 185 ++++++---- .../android/style/light/light.java.ejs | 215 ++++++++--- .../android/testapp/style/LightTest.java | 14 +- .../android/testapp/style/layer.junit.ejs | 12 +- .../android/testapp/style/light.junit.ejs | 198 ++++++---- 9 files changed, 680 insertions(+), 303 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/style/layers/layer.hpp.ejs b/platform/android/MapboxGLAndroidSDK/src/cpp/style/layers/layer.hpp.ejs index b74797908..580942270 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/style/layers/layer.hpp.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/style/layers/layer.hpp.ejs @@ -48,7 +48,7 @@ public: }; // class <%- camelize(type) %>Layer -class <%- camelize(type) %>JavaLayerPeerFactory final : public JavaLayerPeerFactory, public mbgl::<%- camelize(type) %>LayerFactory { +class <%- camelize(type) %>JavaLayerPeerFactory final : public JavaLayerPeerFactory, public mbgl::<%- camelize(type) %>LayerFactory { public: ~<%- camelize(type) %>JavaLayerPeerFactory() override; @@ -60,7 +60,7 @@ public: LayerFactory* getLayerFactory() final { return this; } -}; // class <%- camelize(type) %>JavaLayerPeerFactory +}; // class <%- camelize(type) %>JavaLayerPeerFactory } // namespace android } // namespace mbgl diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java index b01e35349..4f396afb4 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java @@ -16,7 +16,7 @@ import org.maplibre.android.style.expressions.Expression; import org.maplibre.android.style.layers.TransitionOptions; /** - * Client-side hillshading visualization based on DEM data. Currently, the implementation only supports MapLibre Terrain RGB and Mapzen Terrarium tiles. + * Client-side hillshading visualization based on DEM data. Currently, the implementation only supports Mapbox Terrain RGB and Mapzen Terrarium tiles. * * @see The online documentation */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java index b60eab575..499b9a1a6 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java @@ -1806,7 +1806,7 @@ public class PropertyFactory { } /** - * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like MapLibre GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. + * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. * * @param value a Boolean value * @return property wrapper around Boolean @@ -1816,7 +1816,7 @@ public class PropertyFactory { } /** - * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like MapLibre GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. + * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. * * @param value a Boolean value * @return property wrapper around Boolean diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/layer.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/layer.java.ejs index 9c421a583..12304dd2d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/layer.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/layer.java.ejs @@ -1,87 +1,262 @@ -<% const type = locals.type; const properties = locals.properties; const doc = -locals.doc; -%> // This file is generated. Edit scripts/generate-style-code.js, -then run `make style-code`. <% if (type === 'location-indicator') { -%> package -org.maplibre.android.location; <% } else { -%> package -org.maplibre.android.style.layers; <% } -%> import androidx.annotation.ColorInt; -import androidx.annotation.Keep; import androidx.annotation.NonNull; import -androidx.annotation.Nullable; import androidx.annotation.UiThread; import static -org.maplibre.android.utils.ColorUtils.rgbaToColor; import -com.google.gson.JsonArray; import com.google.gson.JsonElement; import -org.maplibre.android.style.expressions.Expression; import -org.maplibre.android.style.layers.TransitionOptions; <% if (type === 'symbol') { --%> import org.maplibre.android.style.types.Formatted; import -org.maplibre.android.style.types.FormattedSection; <% } -%> <% if (type === -'location-indicator') { -%> import org.maplibre.android.style.layers.Layer; -import org.maplibre.android.style.layers.PropertyValue; <% } -%> /** * <%- doc -%> * * @see -The online documentation -*/ @UiThread <% if (type === 'location-indicator') { -%> class <%- -camelize(type) %>Layer extends Layer { <% } else { -%> public class <%- -camelize(type) %>Layer extends Layer { <% } -%> /** * Creates a <%- -camelize(type) %>Layer. * * @param nativePtr pointer used by core */ @Keep <%- -camelize(type) %>Layer(long nativePtr) { super(nativePtr); } <% if (type === -'background' || type === 'location-indicator') { -%> /** * Creates a <%- -camelize(type) %>Layer. * * @param layerId the id of the layer */ public <%- -camelize(type) %>Layer(String layerId) { super(); initialize(layerId); } @Keep -protected native void initialize(String layerId); <% } else { -%> /** * Creates -a <%- camelize(type) %>Layer. * * @param layerId the id of the layer * @param -sourceId the id of the source */ public <%- camelize(type) %>Layer(String -layerId, String sourceId) { super(); initialize(layerId, sourceId); } @Keep -protected native void initialize(String layerId, String sourceId); /** * Set the -source layer. * * @param sourceLayer the source layer to set */ public void -setSourceLayer(String sourceLayer) { checkThread(); -nativeSetSourceLayer(sourceLayer); } /** * Set the source Layer. * * @param -sourceLayer the source layer to set * @return This */ @NonNull public <%- -camelize(type) %>Layer withSourceLayer(String sourceLayer) { -setSourceLayer(sourceLayer); return this; } <% } -%> <% if (type !== -'background' && type !== 'location-indicator' && type !== 'custom') { -%> /** * -Get the source id. * * @return id of the source */ @NonNull public String -getSourceId() { checkThread(); return nativeGetSourceId(); } <% } -%> <% if -(type !== 'background' && type !== 'location-indicator' && type !== 'raster' && -type !== 'hillshade') { -%> /** * Get the source layer. * * @return sourceLayer -the source layer to get */ @NonNull public String getSourceLayer() { -checkThread(); return nativeGetSourceLayer(); } /** * Set a single expression -filter. * * @param filter the expression filter to set */ public void -setFilter(@NonNull Expression filter) { checkThread(); -nativeSetFilter(filter.toArray()); } /** * Set a single expression filter. * * -@param filter the expression filter to set * @return This */ @NonNull public <%- -camelize(type) %>Layer withFilter(@NonNull Expression filter) { -setFilter(filter); return this; } /** * Get a single expression filter. * * -@return the expression filter to get */ @Nullable public Expression getFilter() -{ checkThread(); JsonElement jsonElement = nativeGetFilter(); if (jsonElement != -null) { return Expression.Converter.convert(jsonElement); } else { return null; -} } <% } -%> /** * Set a property or properties. * * @param properties the -var-args properties * @return This */ @NonNull public <%- camelize(type) %>Layer -withProperties(@NonNull PropertyValue... properties) { -setProperties(properties); return this; } // Property getters <% for (const -property of properties) { -%> /** * Get the <%- camelize(property.name) %> -property * * @return property wrapper value around <%- propertyType(property) %> -*/ @NonNull @SuppressWarnings("unchecked") public PropertyValue<<%- -propertyType(property) %>> get<%- camelize(property.name) %>() { checkThread(); -return (PropertyValue<<%- propertyType(property) %>>) new PropertyValue("<%- -property.name %>", nativeGet<%- camelize(property.name) %>()); } <% if -(property.type == 'color') { -%> /** * <%- property.doc %> * * @return int -representation of a rgba string color * @throws RuntimeException thrown if -property isn't a value */ @ColorInt public int get<%- camelize(property.name) -%>AsInt() { checkThread(); PropertyValue<<%- propertyType(property) %>> value = -get<%- camelize(property.name) %>(); if (value.isValue()) { return -rgbaToColor(value.getValue()); } else { throw new RuntimeException("<%- -property.name %> was set as a Function"); } } <% } -%> <% if -(property.transition) { -%> /** * Get the <%- camelize(property.name) %> -property transition options * * @return transition options for <%- -propertyType(property) %> */ @NonNull public TransitionOptions get<%- -camelize(property.name) %>Transition() { checkThread(); return nativeGet<%- -camelize(property.name) %>Transition(); } /** * Set the <%- -camelize(property.name) %> property transition options * * @param options -transition options for <%- propertyType(property) %> */ public void set<%- -camelize(property.name) %>Transition(@NonNull TransitionOptions options) { -checkThread(); nativeSet<%- camelize(property.name) -%>Transition(options.getDuration(), options.getDelay()); } <% } -%> <% } -%> <% -for (const property of properties) { -%> @NonNull @Keep private native Object -nativeGet<%- camelize(property.name) %>(); <% if (property.transition) { -%> -@NonNull @Keep private native TransitionOptions nativeGet<%- -camelize(property.name) %>Transition(); @Keep private native void nativeSet<%- -camelize(property.name) %>Transition(long duration, long delay); <% } -%> <% } --%> @Override @Keep protected native void finalize() throws Throwable; } +<% + const type = locals.type; + const properties = locals.properties; + const doc = locals.doc; +-%> +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +<% if (type === 'location-indicator') { -%> +package org.maplibre.android.location; +<% } else { -%> +package org.maplibre.android.style.layers; +<% } -%> + +import androidx.annotation.ColorInt; +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; + +import static org.maplibre.android.utils.ColorUtils.rgbaToColor; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import org.maplibre.android.style.expressions.Expression; +import org.maplibre.android.style.layers.TransitionOptions; +<% if (type === 'symbol') { -%> +import org.maplibre.android.style.types.Formatted; +import org.maplibre.android.style.types.FormattedSection; +<% } -%> +<% if (type === 'location-indicator') { -%> +import org.maplibre.android.style.layers.Layer; +import org.maplibre.android.style.layers.PropertyValue; +<% } -%> + +/** + * <%- doc %> + * + * @see The online documentation + */ +@UiThread +<% if (type === 'location-indicator') { -%> +class <%- camelize(type) %>Layer extends Layer { +<% } else { -%> +public class <%- camelize(type) %>Layer extends Layer { +<% } -%> + + /** + * Creates a <%- camelize(type) %>Layer. + * + * @param nativePtr pointer used by core + */ + @Keep + <%- camelize(type) %>Layer(long nativePtr) { + super(nativePtr); + } + +<% if (type === 'background' || type === 'location-indicator') { -%> + /** + * Creates a <%- camelize(type) %>Layer. + * + * @param layerId the id of the layer + */ + public <%- camelize(type) %>Layer(String layerId) { + super(); + initialize(layerId); + } + + @Keep + protected native void initialize(String layerId); + +<% } else { -%> + /** + * Creates a <%- camelize(type) %>Layer. + * + * @param layerId the id of the layer + * @param sourceId the id of the source + */ + public <%- camelize(type) %>Layer(String layerId, String sourceId) { + super(); + initialize(layerId, sourceId); + } + + @Keep + protected native void initialize(String layerId, String sourceId); + + /** + * Set the source layer. + * + * @param sourceLayer the source layer to set + */ + public void setSourceLayer(String sourceLayer) { + checkThread(); + nativeSetSourceLayer(sourceLayer); + } + + /** + * Set the source Layer. + * + * @param sourceLayer the source layer to set + * @return This + */ + @NonNull + public <%- camelize(type) %>Layer withSourceLayer(String sourceLayer) { + setSourceLayer(sourceLayer); + return this; + } + +<% } -%> +<% if (type !== 'background' && type !== 'location-indicator' && type !== 'custom') { -%> + /** + * Get the source id. + * + * @return id of the source + */ + @NonNull + public String getSourceId() { + checkThread(); + return nativeGetSourceId(); + } + +<% } -%> +<% if (type !== 'background' && type !== 'location-indicator' && type !== 'raster' && type !== 'hillshade') { -%> + /** + * Get the source layer. + * + * @return sourceLayer the source layer to get + */ + @NonNull + public String getSourceLayer() { + checkThread(); + return nativeGetSourceLayer(); + } + + /** + * Set a single expression filter. + * + * @param filter the expression filter to set + */ + public void setFilter(@NonNull Expression filter) { + checkThread(); + nativeSetFilter(filter.toArray()); + } + + /** + * Set a single expression filter. + * + * @param filter the expression filter to set + * @return This + */ + @NonNull + public <%- camelize(type) %>Layer withFilter(@NonNull Expression filter) { + setFilter(filter); + return this; + } + + /** + * Get a single expression filter. + * + * @return the expression filter to get + */ + @Nullable + public Expression getFilter() { + checkThread(); + JsonElement jsonElement = nativeGetFilter(); + if (jsonElement != null) { + return Expression.Converter.convert(jsonElement); + } else { + return null; + } + } + +<% } -%> + /** + * Set a property or properties. + * + * @param properties the var-args properties + * @return This + */ + @NonNull + public <%- camelize(type) %>Layer withProperties(@NonNull PropertyValue... properties) { + setProperties(properties); + return this; + } + + // Property getters +<% for (const property of properties) { -%> + + /** + * Get the <%- camelize(property.name) %> property + * + * @return property wrapper value around <%- propertyType(property) %> + */ + @NonNull + @SuppressWarnings("unchecked") + public PropertyValue<<%- propertyType(property) %>> get<%- camelize(property.name) %>() { + checkThread(); + return (PropertyValue<<%- propertyType(property) %>>) new PropertyValue("<%- property.name %>", nativeGet<%- camelize(property.name) %>()); + } +<% if (property.type == 'color') { -%> + + /** + * <%- property.doc %> + * + * @return int representation of a rgba string color + * @throws RuntimeException thrown if property isn't a value + */ + @ColorInt + public int get<%- camelize(property.name) %>AsInt() { + checkThread(); + PropertyValue<<%- propertyType(property) %>> value = get<%- camelize(property.name) %>(); + if (value.isValue()) { + return rgbaToColor(value.getValue()); + } else { + throw new RuntimeException("<%- property.name %> was set as a Function"); + } + } +<% } -%> +<% if (property.transition) { -%> + + /** + * Get the <%- camelize(property.name) %> property transition options + * + * @return transition options for <%- propertyType(property) %> + */ + @NonNull + public TransitionOptions get<%- camelize(property.name) %>Transition() { + checkThread(); + return nativeGet<%- camelize(property.name) %>Transition(); + } + + /** + * Set the <%- camelize(property.name) %> property transition options + * + * @param options transition options for <%- propertyType(property) %> + */ + public void set<%- camelize(property.name) %>Transition(@NonNull TransitionOptions options) { + checkThread(); + nativeSet<%- camelize(property.name) %>Transition(options.getDuration(), options.getDelay()); + } +<% } -%> +<% } -%> + +<% for (const property of properties) { -%> + @NonNull + @Keep + private native Object nativeGet<%- camelize(property.name) %>(); + +<% if (property.transition) { -%> + @NonNull + @Keep + private native TransitionOptions nativeGet<%- camelize(property.name) %>Transition(); + + @Keep + private native void nativeSet<%- camelize(property.name) %>Transition(long duration, long delay); + +<% } -%> +<% } -%> + @Override + @Keep + protected native void finalize() throws Throwable; + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/property_factory.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/property_factory.java.ejs index b55d39162..769e9f4ce 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/property_factory.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/layers/property_factory.java.ejs @@ -1,70 +1,115 @@ -<% const paintProperties = locals.paintProperties; const layoutProperties = -locals.layoutProperties; const locationIndicator = locals.locationIndicator; -%> -// This file is generated. Edit scripts/generate-style-code.js, then run `make -style-code`. <% if (locationIndicator) { -%> package -org.maplibre.android.location; <% } else { -%> package -org.maplibre.android.style.layers; <% } -%> import androidx.annotation.ColorInt; -import org.maplibre.android.style.expressions.Expression; import -org.maplibre.android.style.types.Formatted; import static -org.maplibre.android.utils.ColorUtils.colorToRgbaString; <% if -(locationIndicator) { -%> import -org.maplibre.android.style.layers.LayoutPropertyValue; import -org.maplibre.android.style.layers.PaintPropertyValue; import -org.maplibre.android.style.layers.Property; import -org.maplibre.android.style.layers.PropertyValue; <% } -%> /** * Constructs -paint/layout properties for Layers * * @see -Layer style documentation -*/ <% if (locationIndicator) { -%> class LocationPropertyFactory { <% } else { --%> public class PropertyFactory { <% } -%> /** * Set the property visibility. * -* @param value the visibility value * @return property wrapper around visibility -*/ public static PropertyValue - visibility(@Property.VISIBILITY String value) { return new - LayoutPropertyValue<>("visibility", value); } <% for (const property of - paintProperties) { -%> <% if (property.type == 'color') { -%> /** * <%- - propertyFactoryMethodDoc(property) %> * * @param value a int color value * - @return property wrapper around String color */ public static - PropertyValue - <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) { - return new PaintPropertyValue<>("<%- property.name %>", - colorToRgbaString(value)); } <% } -%> /** * <%- - propertyFactoryMethodDoc(property) %> * * @param value a <%- - propertyType(property) %> value * @return property wrapper around <%- - propertyType(property) %> */ public static PropertyValue<<%- - propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) - %>(<%- propertyTypeAnnotation(property) %><%- iff(() => - propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> - value) { return new PaintPropertyValue<>("<%- property.name %>", value); } - /** * <%- propertyFactoryMethodDoc(property) %> * * @param expression an - expression statement * @return property wrapper around an expression - statement */ public static PropertyValue - <%- camelizeWithLeadingLowercase(property.name) %>(Expression expression) - { return new PaintPropertyValue<>("<%- property.name %>", expression); } - <% } -%> <% for (const property of layoutProperties) { -%> <% if - (property.type === 'formatted') { -%> /** * <%- - propertyFactoryMethodDoc(property) %> * * @param value a String value * - @return property wrapper around String */ public static - PropertyValue - <%- camelizeWithLeadingLowercase(property.name) %>(String value) { - return new LayoutPropertyValue<>("<%- property.name %>", value); } <% } - -%> /** * <%- propertyFactoryMethodDoc(property) %> * * @param value a - <%- propertyType(property) %> value * @return property wrapper around - <%- propertyType(property) %> */ public static PropertyValue<<%- - propertyType(property) %>> <%- - camelizeWithLeadingLowercase(property.name) %>(<%- - propertyTypeAnnotation(property) %><%- iff(() => - propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> - value) { return new LayoutPropertyValue<>("<%- property.name %>", - value); } /** * <%- propertyFactoryMethodDoc(property) %> * * @param - value a <%- propertyType(property) %> value * @return property wrapper - around <%- propertyType(property) %> */ public static - PropertyValue - <%- camelizeWithLeadingLowercase(property.name) %>(Expression value) { - return new LayoutPropertyValue<>("<%- property.name %>", value); } <% - } -%> } - +<% + const paintProperties = locals.paintProperties; + const layoutProperties = locals.layoutProperties; + const locationIndicator = locals.locationIndicator; +-%> +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +<% if (locationIndicator) { -%> +package org.maplibre.android.location; +<% } else { -%> +package org.maplibre.android.style.layers; +<% } -%> + +import androidx.annotation.ColorInt; + +import org.maplibre.android.style.expressions.Expression; +import org.maplibre.android.style.types.Formatted; +import static org.maplibre.android.utils.ColorUtils.colorToRgbaString; +<% if (locationIndicator) { -%> +import org.maplibre.android.style.layers.LayoutPropertyValue; +import org.maplibre.android.style.layers.PaintPropertyValue; +import org.maplibre.android.style.layers.Property; +import org.maplibre.android.style.layers.PropertyValue; +<% } -%> + +/** + * Constructs paint/layout properties for Layers + * + * @see Layer style documentation + */ +<% if (locationIndicator) { -%> +class LocationPropertyFactory { +<% } else { -%> +public class PropertyFactory { +<% } -%> + + /** + * Set the property visibility. + * + * @param value the visibility value + * @return property wrapper around visibility + */ + public static PropertyValue visibility(@Property.VISIBILITY String value) { + return new LayoutPropertyValue<>("visibility", value); + } + +<% for (const property of paintProperties) { -%> +<% if (property.type == 'color') { -%> + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a int color value + * @return property wrapper around String color + */ + public static PropertyValue <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) { + return new PaintPropertyValue<>("<%- property.name %>", colorToRgbaString(value)); + } + +<% } -%> + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a <%- propertyType(property) %> value + * @return property wrapper around <%- propertyType(property) %> + */ + public static PropertyValue<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { + return new PaintPropertyValue<>("<%- property.name %>", value); + } + + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param expression an expression statement + * @return property wrapper around an expression statement + */ + public static PropertyValue <%- camelizeWithLeadingLowercase(property.name) %>(Expression expression) { + return new PaintPropertyValue<>("<%- property.name %>", expression); + } + +<% } -%> +<% for (const property of layoutProperties) { -%> +<% if (property.type === 'formatted') { -%> + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a String value + * @return property wrapper around String + */ + public static PropertyValue <%- camelizeWithLeadingLowercase(property.name) %>(String value) { + return new LayoutPropertyValue<>("<%- property.name %>", value); + } + +<% } -%> + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a <%- propertyType(property) %> value + * @return property wrapper around <%- propertyType(property) %> + */ + public static PropertyValue<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { + return new LayoutPropertyValue<>("<%- property.name %>", value); + } + + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a <%- propertyType(property) %> value + * @return property wrapper around <%- propertyType(property) %> + */ + public static PropertyValue <%- camelizeWithLeadingLowercase(property.name) %>(Expression value) { + return new LayoutPropertyValue<>("<%- property.name %>", value); + } + +<% } -%> +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/light/light.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/light/light.java.ejs index e82fd6c96..ba6eb2dbf 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/light/light.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/org/maplibre/android/style/light/light.java.ejs @@ -1,61 +1,154 @@ -<% const properties = locals.properties; const doc = locals.doc; -%> // This -file is generated. Edit scripts/generate-style-code.js, then run `make -style-code`. package org.maplibre.android.style.light; import -androidx.annotation.ColorInt; import androidx.annotation.Keep; import -androidx.annotation.NonNull; import androidx.annotation.UiThread; import -org.maplibre.android.style.layers.Property; import -org.maplibre.android.style.layers.TransitionOptions; import -org.maplibre.android.utils.ColorUtils; import -org.maplibre.android.utils.ThreadUtils; /** * The global light source. * * @see -The online documentation -*/ @UiThread public class Light { private static final String TAG = -"Mbgl-Light"; @Keep private long nativePtr; /** * Creates a Light. * * @param -nativePtr pointer used by core */ @Keep Light(long nativePtr) { checkThread(); -this.nativePtr = nativePtr; } <% for (const property of properties) { -%> <% if -(property.name == "position") {-%> /** * Set the <%- camelize(property.name) %> -property. <%- property.doc %> * * @param position of the light */ public void -set<%- camelize(property.name) %>(@NonNull Position position) { checkThread(); -nativeSet<%- camelize(property.name) %>(position); } /** * Get the <%- -camelize(property.name) %> property. <%- property.doc %> * * @return <%- -property.name %> as Position */ @NonNull public Position get<%- -camelize(property.name) %>() { checkThread(); return nativeGet<%- -camelize(property.name) %>(); } <% } else { -%> <% if (property.name == "color") -{-%> /** * Set the <%- camelize(property.name) %> property. <%- property.doc %> -* * @param <%- property.name %> as int */ public void set<%- -camelize(property.name) %>(@ColorInt int <%- property.name %>) { checkThread(); -nativeSet<%- camelize(property.name) %>(ColorUtils.colorToRgbaString(<%- -property.name %>)); } <% } -%> /** * Set the <%- camelize(property.name) %> -property. <%- property.doc %> * * @param <%- property.name %> as <%- -propertyType(property) %> */ public void set<%- camelize(property.name) %>(<%- -propertyTypeAnnotation(property) %><%- iff(() => -propertyTypeAnnotation(property), " ") %><%- propertyJavaType(property) %> <%- -property.name %>) { checkThread(); nativeSet<%- camelize(property.name) %>(<%- -property.name %>); } /** * Get the <%- camelize(property.name) %> property. <%- -property.doc %> * * @return <%- property.name %> as <%- propertyType(property) -%> */ @NonNull <%- propertyTypeAnnotation(property) %> public <%- -propertyJavaType(property) %> get<%- camelize(property.name) %>() { -checkThread(); return nativeGet<%- camelize(property.name) %>(); } <% } -%> <% -if (property.transition) { -%> /** * Get the <%- camelize(property.name) %> -property transition options. * * @return transition options for <%- -property.name %> */ @NonNull public TransitionOptions get<%- -camelize(property.name) %>Transition() { checkThread(); return nativeGet<%- -camelize(property.name) %>Transition(); } /** * Set the <%- -camelize(property.name) %> property transition options. * * @param options -transition options for <%- property.name %> */ public void set<%- -camelize(property.name) %>Transition(@NonNull TransitionOptions options) { -checkThread(); nativeSet<%- camelize(property.name) -%>Transition(options.getDuration(), options.getDelay()); } <% } -%> <% } -%> -private void checkThread(){ ThreadUtils.checkThread(TAG); } <% for (const -property of properties) { -%> <% if (property.name == "position") {-%> @Keep -private native void nativeSet<%- camelize(property.name) %>(Position position); -@NonNull @Keep private native Position nativeGet<%- camelize(property.name) -%>(); <% } else { -%> @Keep private native void nativeSet<%- -camelize(property.name) %>(<%- propertyJavaType(property) -%> <%- property.name -%>); @NonNull @Keep private native <%- propertyJavaType(property) -%> -nativeGet<%- camelize(property.name) %>(); <% } -%> <% if (property.transition) -{ -%> @NonNull @Keep private native TransitionOptions nativeGet<%- -camelize(property.name) %>Transition(); @Keep private native void nativeSet<%- -camelize(property.name) %>Transition(long duration, long delay); <% } -%> <% } --%> } +<% + const properties = locals.properties; + const doc = locals.doc; +-%> +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +package org.maplibre.android.style.light; + +import androidx.annotation.ColorInt; +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.annotation.UiThread; + +import org.maplibre.android.style.layers.Property; +import org.maplibre.android.style.layers.TransitionOptions; +import org.maplibre.android.utils.ColorUtils; +import org.maplibre.android.utils.ThreadUtils; + +/** + * The global light source. + * + * @see The online documentation + */ +@UiThread +public class Light { + + private static final String TAG = "Mbgl-Light"; + + @Keep + private long nativePtr; + + /** + * Creates a Light. + * + * @param nativePtr pointer used by core + */ + @Keep + Light(long nativePtr) { + checkThread(); + this.nativePtr = nativePtr; + } +<% for (const property of properties) { -%> +<% if (property.name == "position") {-%> + + /** + * Set the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @param position of the light + */ + public void set<%- camelize(property.name) %>(@NonNull Position position) { + checkThread(); + nativeSet<%- camelize(property.name) %>(position); + } + + /** + * Get the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @return <%- property.name %> as Position + */ + @NonNull + public Position get<%- camelize(property.name) %>() { + checkThread(); + return nativeGet<%- camelize(property.name) %>(); + } +<% } else { -%> +<% if (property.name == "color") {-%> + + /** + * Set the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @param <%- property.name %> as int + */ + public void set<%- camelize(property.name) %>(@ColorInt int <%- property.name %>) { + checkThread(); + nativeSet<%- camelize(property.name) %>(ColorUtils.colorToRgbaString(<%- property.name %>)); + } +<% } -%> + + /** + * Set the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @param <%- property.name %> as <%- propertyType(property) %> + */ + public void set<%- camelize(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyJavaType(property) %> <%- property.name %>) { + checkThread(); + nativeSet<%- camelize(property.name) %>(<%- property.name %>); + } + + /** + * Get the <%- camelize(property.name) %> property. <%- property.doc %> + * + * @return <%- property.name %> as <%- propertyType(property) %> + */ + @NonNull + <%- propertyTypeAnnotation(property) %> public <%- propertyJavaType(property) %> get<%- camelize(property.name) %>() { + checkThread(); + return nativeGet<%- camelize(property.name) %>(); + } +<% } -%> +<% if (property.transition) { -%> + + /** + * Get the <%- camelize(property.name) %> property transition options. + * + * @return transition options for <%- property.name %> + */ + @NonNull + public TransitionOptions get<%- camelize(property.name) %>Transition() { + checkThread(); + return nativeGet<%- camelize(property.name) %>Transition(); + } + + /** + * Set the <%- camelize(property.name) %> property transition options. + * + * @param options transition options for <%- property.name %> + */ + public void set<%- camelize(property.name) %>Transition(@NonNull TransitionOptions options) { + checkThread(); + nativeSet<%- camelize(property.name) %>Transition(options.getDuration(), options.getDelay()); + } +<% } -%> +<% } -%> + + private void checkThread(){ + ThreadUtils.checkThread(TAG); + } + +<% for (const property of properties) { -%> +<% if (property.name == "position") {-%> + @Keep + private native void nativeSet<%- camelize(property.name) %>(Position position); + + @NonNull + @Keep + private native Position nativeGet<%- camelize(property.name) %>(); +<% } else { -%> + @Keep + private native void nativeSet<%- camelize(property.name) %>(<%- propertyJavaType(property) -%> <%- property.name %>); + + @NonNull + @Keep + private native <%- propertyJavaType(property) -%> nativeGet<%- camelize(property.name) %>(); +<% } -%> +<% if (property.transition) { -%> + @NonNull + @Keep + private native TransitionOptions nativeGet<%- camelize(property.name) %>Transition(); + + @Keep + private native void nativeSet<%- camelize(property.name) %>Transition(long duration, long delay); +<% } -%> +<% } -%> +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/LightTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/LightTest.java index c38bc0594..974287186 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/LightTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/LightTest.java @@ -45,7 +45,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("anchor"); - invoke(maplibreMap, (uiController, mapboxMap) -> { + invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // Set and Get light.setAnchor(ANCHOR_MAP); @@ -58,7 +58,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("positionTransitionOptions"); - invoke(maplibreMap, (uiController, mapboxMap) -> { + invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // Set and Get TransitionOptions options = new TransitionOptions(300, 100); @@ -72,7 +72,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("position"); - invoke(maplibreMap,(uiController, mapboxMap) -> { + invoke(maplibreMap,(uiController, maplibreMap) -> { assertNotNull(light); // Set and Get Position position = new Position(1, 2, 3); @@ -86,7 +86,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("colorTransitionOptions"); - invoke(maplibreMap, (uiController, mapboxMap) -> { + invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // Set and Get TransitionOptions options = new TransitionOptions(300, 100); @@ -100,7 +100,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("color"); - invoke(maplibreMap, (uiController, mapboxMap) -> { + invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // Set and Get light.setColor("rgba(255,128,0,0.7)"); @@ -113,7 +113,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("intensityTransitionOptions"); - invoke(maplibreMap, (uiController, mapboxMap) -> { + invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // Set and Get TransitionOptions options = new TransitionOptions(300, 100); @@ -127,7 +127,7 @@ public class LightTest extends BaseTest { validateTestSetup(); setupLight(); Timber.i("intensity"); - invoke(maplibreMap, (uiController, mapboxMap) -> { + invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // Set and Get light.setIntensity(0.3f); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/layer.junit.ejs index d2eef9275..3edb44933 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/layer.junit.ejs +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/layer.junit.ejs @@ -14,12 +14,12 @@ import android.graphics.Color; import androidx.test.annotation.UiThreadTest; import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; -import com.maplibre.geojson.LineString; -import com.maplibre.geojson.MultiLineString; -import com.maplibre.geojson.MultiPoint; -import com.maplibre.geojson.MultiPolygon; -import com.maplibre.geojson.Point; -import com.maplibre.geojson.Polygon; +import com.mapbox.geojson.LineString; +import com.mapbox.geojson.MultiLineString; +import com.mapbox.geojson.MultiPoint; +import com.mapbox.geojson.MultiPolygon; +import com.mapbox.geojson.Point; +import com.mapbox.geojson.Polygon; import org.maplibre.android.maps.BaseLayerTest; import org.junit.Before; import timber.log.Timber; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/light.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/light.junit.ejs index 1dc76f855..131111361 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/light.junit.ejs +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/org/maplibre/android/testapp/style/light.junit.ejs @@ -1,68 +1,132 @@ -<% const properties = locals.properties; -%> package -org.maplibre.android.testapp.style; import android.graphics.Color; import -androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; -import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; import -android.view.View; import org.maplibre.android.style.light.Light; import -org.maplibre.android.style.expressions.Expression; import -org.maplibre.android.style.layers.FillExtrusionLayer; import -org.maplibre.android.style.layers.TransitionOptions; import -org.maplibre.android.style.light.Position; import -org.maplibre.android.testapp.R; import -org.maplibre.android.testapp.activity.BaseTest; import -org.maplibre.android.testapp.activity.style.FillExtrusionStyleTestActivity; -import timber.log.Timber; import org.hamcrest.Matcher; import org.junit.Test; -import org.junit.runner.RunWith; import static -androidx.test.espresso.Espresso.onView; import static -androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static -androidx.test.espresso.matcher.ViewMatchers.withId; import static -org.maplibre.android.style.expressions.Expression.eq; import static -org.maplibre.android.style.layers.Property.ANCHOR_MAP; import static -org.maplibre.android.style.layers.PropertyFactory.fillExtrusionBase; import -static org.maplibre.android.style.layers.PropertyFactory.fillExtrusionColor; -import static -org.maplibre.android.style.layers.PropertyFactory.fillExtrusionHeight; import -static org.maplibre.android.style.layers.PropertyFactory.fillExtrusionOpacity; +<% + const properties = locals.properties; +-%> +package org.maplibre.android.testapp.style; + +import android.graphics.Color; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; +import android.view.View; + +import org.maplibre.android.style.light.Light; +import org.maplibre.android.style.expressions.Expression; +import org.maplibre.android.style.layers.FillExtrusionLayer; +import org.maplibre.android.style.layers.TransitionOptions; +import org.maplibre.android.style.light.Position; +import org.maplibre.android.testapp.R; +import org.maplibre.android.testapp.activity.BaseTest; +import org.maplibre.android.testapp.activity.style.FillExtrusionStyleTestActivity; + +import timber.log.Timber; + +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static org.maplibre.android.style.expressions.Expression.eq; +import static org.maplibre.android.style.layers.Property.ANCHOR_MAP; +import static org.maplibre.android.style.layers.PropertyFactory.fillExtrusionBase; +import static org.maplibre.android.style.layers.PropertyFactory.fillExtrusionColor; +import static org.maplibre.android.style.layers.PropertyFactory.fillExtrusionHeight; +import static org.maplibre.android.style.layers.PropertyFactory.fillExtrusionOpacity; + import static org.maplibre.android.testapp.action.MapLibreMapAction.invoke; -import static org.junit.Assert.assertEquals; import static -org.junit.Assert.assertNotNull; @RunWith(AndroidJUnit4ClassRunner.class) public -class LightTest extends BaseTest { private Light light; <% for (const property -of properties) { -%> <% if (property.transition) { -%> @Test public void test<%- -camelize(property.name) %>Transition() { validateTestSetup(); setupLight(); -Timber.i("<%- property.name %>TransitionOptions"); invoke(maplibreMap, -(uiController, maplibreMap) -> { assertNotNull(light); // Set and Get -TransitionOptions options = new TransitionOptions(300, 100); light.set<%- -camelize(property.name) %>Transition(options); assertEquals("Transition options -should match", options, light.get<%- camelize(property.name) %>Transition()); -}); } <% } -%> <% if (property.name == "position") { -%> @Test public void -test<%- camelize(property.name) %>() { validateTestSetup(); setupLight(); -Timber.i("<%- property.name %>"); invoke(maplibreMap,(uiController, maplibreMap) --> { assertNotNull(light); // Set and Get Position position = new Position(1, 2, -3); light.set<%- camelize(property.name) %>(position); assertEquals("Position -should match", position, light.get<%- camelize(property.name) %>()); }); } <% } -else { -%> @Test public void test<%- camelize(property.name) %>() { -validateTestSetup(); setupLight(); Timber.i("<%- property.name %>"); -invoke(maplibreMap, (uiController, maplibreMap) -> { assertNotNull(light); // -Set and Get light.set<%- camelize(property.name) %>(<%- -defaultValueJava(property) %>); <% if (property.name == 'color') { -%> -assertEquals("<%- camelize(property.name) %> should match", <%- -defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); <% } -else { -%> assertEquals("<%- camelize(property.name) %> should match", <%- -defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); <% } --%> }); } <% } -%> <% } -%> private void setupLight() { -onView(withId(R.id.mapView)).perform(new ViewAction() { @Override public -Matcher - getConstraints() { return isDisplayed(); } @Override public String - getDescription() { return getClass().getSimpleName(); } @Override public void - perform(UiController uiController, View view) { light = - maplibreMap.getStyle().getLight(); FillExtrusionLayer fillExtrusionLayer = new - FillExtrusionLayer("3d-buildings", "composite"); - fillExtrusionLayer.setSourceLayer("building"); - fillExtrusionLayer.setFilter(eq(Expression.get("extrude"), "true")); - fillExtrusionLayer.setMinZoom(15); fillExtrusionLayer.setProperties( - fillExtrusionColor(Color.LTGRAY), - fillExtrusionHeight(Expression.get("height")), - fillExtrusionBase(Expression.get("min_height")), fillExtrusionOpacity(0.6f) ); - maplibreMap.getStyle().addLayer(fillExtrusionLayer); } }); } @Override - protected Class getActivityClass() { return - FillExtrusionStyleTestActivity.class; } } +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(AndroidJUnit4ClassRunner.class) +public class LightTest extends BaseTest { + + private Light light; +<% for (const property of properties) { -%> +<% if (property.transition) { -%> + + @Test + public void test<%- camelize(property.name) %>Transition() { + validateTestSetup(); + setupLight(); + Timber.i("<%- property.name %>TransitionOptions"); + invoke(maplibreMap, (uiController, maplibreMap) -> { + assertNotNull(light); + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + light.set<%- camelize(property.name) %>Transition(options); + assertEquals("Transition options should match", options, light.get<%- camelize(property.name) %>Transition()); + }); + } +<% } -%> +<% if (property.name == "position") { -%> + + @Test + public void test<%- camelize(property.name) %>() { + validateTestSetup(); + setupLight(); + Timber.i("<%- property.name %>"); + invoke(maplibreMap,(uiController, maplibreMap) -> { + assertNotNull(light); + // Set and Get + Position position = new Position(1, 2, 3); + light.set<%- camelize(property.name) %>(position); + assertEquals("Position should match", position, light.get<%- camelize(property.name) %>()); + }); + } +<% } else { -%> + + @Test + public void test<%- camelize(property.name) %>() { + validateTestSetup(); + setupLight(); + Timber.i("<%- property.name %>"); + invoke(maplibreMap, (uiController, maplibreMap) -> { + assertNotNull(light); + // Set and Get + light.set<%- camelize(property.name) %>(<%- defaultValueJava(property) %>); +<% if (property.name == 'color') { -%> + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()); +<% } else { -%> + assertEquals("<%- camelize(property.name) %> should match", <%- defaultValueJava(property) %>, light.get<%- camelize(property.name) %>()<%- property.type === 'number' ? ', 0f' : '' %>); +<% } -%> + }); + } +<% } -%> +<% } -%> + + private void setupLight() { + onView(withId(R.id.mapView)).perform(new ViewAction() { + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + light = maplibreMap.getStyle().getLight(); + FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite"); + fillExtrusionLayer.setSourceLayer("building"); + fillExtrusionLayer.setFilter(eq(Expression.get("extrude"), "true")); + fillExtrusionLayer.setMinZoom(15); + fillExtrusionLayer.setProperties( + fillExtrusionColor(Color.LTGRAY), + fillExtrusionHeight(Expression.get("height")), + fillExtrusionBase(Expression.get("min_height")), + fillExtrusionOpacity(0.6f) + ); + maplibreMap.getStyle().addLayer(fillExtrusionLayer); + } + }); + } + + @Override + protected Class getActivityClass() { + return FillExtrusionStyleTestActivity.class; + } +} \ No newline at end of file