diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.kt new file mode 100644 index 000000000..fda0b42df --- /dev/null +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.kt @@ -0,0 +1,388 @@ +package com.mapbox.mapboxsdk.plugins.localization + +import android.content.Context +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.IdlingRegistry +import android.support.test.espresso.UiController +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.matcher.ViewMatchers.withId +import android.support.test.filters.LargeTest +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.mapbox.mapboxsdk.constants.Style +import com.mapbox.mapboxsdk.maps.MapboxMap +import com.mapbox.mapboxsdk.plugins.testapp.activity.LocalizationActivity +import com.mapbox.mapboxsdk.style.layers.SymbolLayer +import com.mapbox.mapboxsdk.utils.GenericPluginAction +import com.mapbox.mapboxsdk.utils.OnMapReadyIdlingResource +import org.hamcrest.CoreMatchers.equalTo +import org.junit.After +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import timber.log.Timber + +@RunWith(AndroidJUnit4::class) +@LargeTest +class LocalizationPluginTest { + + @Rule + @JvmField + val rule = ActivityTestRule(LocalizationActivity::class.java) + + private var idlingResource: OnMapReadyIdlingResource? = null + private var localizationPlugin: LocalizationPlugin? = null + private var mapboxMap: MapboxMap? = null + + @Before + fun beforeTest() { + Timber.e("@Before: register idle resource") + // If idlingResource is null, throw Kotlin exception + idlingResource = OnMapReadyIdlingResource(rule.activity) + IdlingRegistry.getInstance().register(idlingResource!!) + onView(withId(android.R.id.content)).check(matches(isDisplayed())) + mapboxMap = idlingResource!!.mapboxMap + localizationPlugin = rule.activity.localizationPlugin + } + + // + // Style Changes + // + + @Test + fun styleChanged_theCurrentLanguageRemainsTheSame() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("country-label-lg")!! + + // Change the language + plugin?.setMapLanguage(MapLocale.RUSSIAN) + var language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + mapboxMap.setStyleUrl(Style.DARK) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + // + // Country Labels + // + + @Test + fun languageChanged_changesCountryLabelLgLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("country-label-lg")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesCountryLabelMdLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("country-label-md")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesCountryLabelSmLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("country-label-sm")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + // + // State Labels + // + + @Test + fun languageChanged_changesStateLabelLgLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("state-label-lg")!! + var language = layer.textField.expression!!.toArray()[5].toString() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.expression!!.toArray()[5].toString() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesStateLabelMdLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("state-label-md")!! + var language = layer.textField.expression!!.toArray()[5].toString() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.expression!!.toArray()[5].toString() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesStateLabelSmLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("state-label-sm")!! + var language = layer.textField.expression!!.toArray()[5].toString() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.expression!!.toArray()[5].toString() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + // + // Marine Labels + // + + @Test + fun languageChanged_changesMarineLabelLgPtLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("marine-label-lg-pt")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesMarineLabelLgLnLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("marine-label-lg-ln")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesMarineLabelMdPtLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("marine-label-md-pt")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesMarineLabelMdLnLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("marine-label-md-ln")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesMarineLabelSmPtLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("marine-label-sm-pt")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesMarineLabelSmLnLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("marine-label-sm-ln")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + // + // City Labels + // + + @Test + fun languageChanged_changesPlaceCityLgnLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("place-city-lg-n")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesPlaceCityLgsLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("place-city-lg-s")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesPlaceCityMdnLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("place-city-md-n")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesPlaceCityMdsLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("place-city-md-s")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @Test + fun languageChanged_changesPlaceCitySmLanguage() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocalizationPlugin?, mapboxMap: MapboxMap?, + uiController: UiController, context: Context) { + val layer: SymbolLayer = mapboxMap?.getLayerAs("place-city-sm")!! + var language = layer.textField.getValue() + + assertThat(language, equalTo("{name_en}")) + plugin?.setMapLanguage(MapLocale.RUSSIAN) + language = layer.textField.getValue() + assertThat(language, equalTo("{name_ru}")) + } + } + executePluginTest(pluginAction) + } + + @After + fun afterTest() { + Timber.e("@After: unregister idle resource") + IdlingRegistry.getInstance().unregister(idlingResource!!) + } + + private fun executePluginTest(listener: GenericPluginAction.OnPerformGenericPluginAction) { + onView(withId(android.R.id.content)).perform(GenericPluginAction(mapboxMap, localizationPlugin, listener)) + } +} diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/LocalizationActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/LocalizationActivity.java index 724f0fa06..597552c33 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/LocalizationActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/LocalizationActivity.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.plugins.testapp.activity; import android.os.Bundle; +import android.support.annotation.VisibleForTesting; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; @@ -14,14 +15,11 @@ import com.mapbox.mapboxsdk.plugins.testapp.R; import com.mapbox.mapboxsdk.plugins.testapp.Utils; -import butterknife.BindView; -import butterknife.ButterKnife; import butterknife.OnClick; public class LocalizationActivity extends AppCompatActivity implements OnMapReadyCallback { - @BindView(R.id.mapView) - MapView mapView; + private MapView mapView; private LocalizationPlugin localizationPlugin; private MapboxMap mapboxMap; @@ -45,9 +43,10 @@ public class LocalizationActivity extends AppCompatActivity implements OnMapRead protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_localization); - ButterKnife.bind(this); + mapIsLocalized = true; Toast.makeText(this, R.string.change_language_instruction, Toast.LENGTH_LONG).show(); + mapView = findViewById(R.id.map_view); mapView.onCreate(savedInstanceState); mapView.getMapAsync(this); } @@ -184,5 +183,10 @@ public static MapLocale getNextMapLocale() { } return LOCALES[index]; } + + @VisibleForTesting + public LocalizationPlugin getLocalizationPlugin() { + return localizationPlugin; + } } diff --git a/app/src/main/res/layout/activity_localization.xml b/app/src/main/res/layout/activity_localization.xml index c66ccfced..1fdebc803 100644 --- a/app/src/main/res/layout/activity_localization.xml +++ b/app/src/main/res/layout/activity_localization.xml @@ -15,9 +15,7 @@ app:mapbox_cameraTilt="20" app:mapbox_cameraZoom="2.5" app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets" - app:mapbox_uiAttribution="false"> - - + app:mapbox_uiAttribution="false"/> + app:layout_constraintEnd_toEndOf="parent" + app:srcCompat="@drawable/ic_translate_white_24dp"/> + app:layout_constraintRight_toRightOf="parent" + app:srcCompat="@drawable/ic_layers"/> + app:layout_constraintRight_toRightOf="parent" + app:srcCompat="@drawable/ic_camera"/> \ No newline at end of file diff --git a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java index f1dd32fa0..04b15d452 100644 --- a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java +++ b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java @@ -1,12 +1,17 @@ package com.mapbox.mapboxsdk.plugins.localization; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.plugins.localization.MapLocale.Languages; +import com.mapbox.mapboxsdk.style.expressions.Expression; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.Source; @@ -105,22 +110,64 @@ public void setMapLanguage(@NonNull MapLocale mapLocale) { if (sourceIsFromMapbox(source)) { for (Layer layer : layers) { if (layerHasAdjustableTextField(layer)) { - String textField = ((SymbolLayer) layer).getTextField().getValue(); - if (textField != null - && (textField.contains("{name") || textField.contains("{abbr}"))) { - textField = textField.replaceAll("[{]((name).*?)[}]", - String.format("{%s}", mapLocale.getMapLanguage())); - layer.setProperties(textField(textField)); - } + transformTextFieldValues(layer); + } else if (layerHasAdjustableExpressionTextField(layer)) { + transformExpressionTextFieldValue(layer); } } } } } - /* - * Camera bounding box - */ + private void transformTextFieldValues(Layer layer) { + String textField = ((SymbolLayer) layer).getTextField().getValue(); + if (textField != null + && (textField.contains("{name") || textField.contains("{abbr}"))) { + textField = textField.replaceAll("[{]((name).*?)[}]", + String.format("{%s}", mapLocale.getMapLanguage())); + layer.setProperties(textField(textField)); + } + } + + // TODO Finish transforming expression + private void transformExpressionTextFieldValue(Layer layer) { + SymbolLayer textLayer = (SymbolLayer) layer; + int position; + for (position = 0; position < textLayer.getTextField().getExpression().toArray().length; position++) { + if (textLayer.getTextField().getExpression().toArray()[position] instanceof String + && textLayer.getTextField().getExpression().toArray()[position].toString().contains("{name")) { + break; + } + } + System.out.println(textLayer.getId()); +// Object[] expressionArray = textLayer.getTextField().getExpression().toArray(); + + String s = textLayer.getTextField().getExpression().toString(); + System.out.println(s); + s = s.replaceAll("[{]((name).*?)[}]", String.format("[\"get\", \"{%s}\"]", mapLocale.getMapLanguage())); +// s = s.replace(", ,", ",[\"literal\", \"\"],"); + + + s = s.replace("{ref}", "[\"get\", \"{ref}\"]"); + s = s.replace("{abbr}", "[\"get\", \"{abbr}\"]"); + s = s.replace("{code}", "[\"get\", \"{code}\"]"); + System.out.println(s); + + Gson gson = new Gson(); + JsonArray jsonArray = gson.fromJson(s, JsonArray.class); + + +// expressionArray[position] = mapLocale.getMapLanguage(); + System.out.println(jsonArray.toString()); + + + textLayer.setProperties(textField(Expression.Converter.convert(jsonArray))); + } + + + // + // Camera bounding box + // /** * Adjust the map's camera position so that the entire countries boarders are within the viewport. @@ -164,9 +211,9 @@ public void setCameraToLocaleCountry(MapLocale mapLocale) { mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } - /* - * Supporting methods - */ + // + // Supporting methods + // private MapLocale checkMapLocalNonNull(Locale locale) { MapLocale mapLocale = MapLocale.getMapLocale(locale); @@ -185,22 +232,56 @@ private MapLocale checkMapLocalNonNull(Locale locale) { * @return true if the source is from the Mapbox Streets vector source, false if it's not. */ private boolean sourceIsFromMapbox(Source singleSource) { - return singleSource instanceof VectorSource - && ((VectorSource) singleSource).getUrl().substring(0, 9).equals("mapbox://") - && (((VectorSource) singleSource).getUrl().contains("mapbox.mapbox-streets-v7") - || ((VectorSource) singleSource).getUrl().contains("mapbox.mapbox-streets-v6")); + String url = ((VectorSource) singleSource).getUrl(); + + return url != null + && (url.substring(0, 9).equals("mapbox://") + && url.contains("mapbox.mapbox-streets-v8") + || url.contains("mapbox.mapbox-streets-v7") + || url.contains("mapbox.mapbox-streets-v6")); } /** * Checks whether a single map layer has a textField that could potentially be localized to the * device's language. * - * @param singleLayer an individual layer from the map + * @param layer an individual layer from the map style * @return true if the layer has a textField eligible for translation, false if not. */ - private boolean layerHasAdjustableTextField(Layer singleLayer) { - return singleLayer instanceof SymbolLayer && (((SymbolLayer) singleLayer).getTextField() != null - && (((SymbolLayer) singleLayer).getTextField().getValue() != null - && !(((SymbolLayer) singleLayer).getTextField().getValue().isEmpty()))); + private boolean layerHasAdjustableTextField(Layer layer) { + // Check that the layers a symbol layer + SymbolLayer textLayer = isSymbolLayer(layer); + if (textLayer == null) { + return false; + } + + return textLayer.getTextField() != null && textLayer.getTextField().getValue() != null + && !TextUtils.isEmpty(textLayer.getTextField().getValue()); + } + + private boolean layerHasAdjustableExpressionTextField(Layer layer) { + // Check that the layers a symbol layer + SymbolLayer textLayer = isSymbolLayer(layer); + if (textLayer == null) { + return false; + } + + return textLayer.getTextField() != null && textLayer.getTextField().isExpression(); + } + + /** + * Checks that the layer is an instance of a symbol layer and if so, returns the layer as an + * instance of {@link SymbolLayer}. + * + * @param layer an individual layer from the map style + * @return true if the layer is an instance of a symbol layer + */ + @Nullable + private SymbolLayer isSymbolLayer(Layer layer) { + if (layer instanceof SymbolLayer) { + return (SymbolLayer) layer; + } else { + return null; + } } } \ No newline at end of file