diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/MapLayerInteractor.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/MapLayerInteractor.java index 71ace3ff25a..6279c87000f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/MapLayerInteractor.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/MapLayerInteractor.java @@ -1,5 +1,7 @@ package com.mapbox.services.android.navigation.ui.v5.map; +import android.graphics.Color; + import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.LineLayer; @@ -9,20 +11,22 @@ import static com.mapbox.mapboxsdk.style.layers.Property.NONE; import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility; +import static com.mapbox.services.android.navigation.ui.v5.map.NavigationMapboxMap.STREETS_LAYER_ID; class MapLayerInteractor { - private MapboxMap mapboxMap; + private static final float DEFAULT_WIDTH = 20f; + private static final int LAST_INDEX = 0; + + private final MapboxMap mapboxMap; MapLayerInteractor(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; } - Layer retrieveLayerFromId(String layerId) { - return mapboxMap.getStyle().getLayerAs(layerId); - } - void updateLayerVisibility(boolean isVisible, String layerIdentifier) { // TODO add sourceIdentifier logic when https://github.com/mapbox/mapbox-gl-native/issues/12691 lands List layers = mapboxMap.getStyle().getLayers(); @@ -35,6 +39,16 @@ boolean isLayerVisible(String layerIdentifier) { return findLayerVisibility(layerIdentifier, layers); } + void addStreetsLayer(String sourceId, String sourceLayer) { + LineLayer streetsLayer = new LineLayer(STREETS_LAYER_ID, sourceId) + .withProperties( + lineWidth(DEFAULT_WIDTH), + lineColor(Color.WHITE) + ) + .withSourceLayer(sourceLayer); + mapboxMap.getStyle().addLayerAt(streetsLayer, LAST_INDEX); + } + private void updateLayerWithVisibility(String layerIdentifier, List layers, boolean isVisible) { for (Layer layer : layers) { if (isValid(layer)) { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMap.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMap.java index 5913040929c..9922e490e79 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMap.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMap.java @@ -2,12 +2,12 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.graphics.Color; import android.graphics.PointF; import android.location.Location; import android.os.Bundle; import android.os.PersistableBundle; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.FragmentActivity; import com.mapbox.api.directions.v5.models.DirectionsRoute; @@ -23,7 +23,7 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; -import com.mapbox.mapboxsdk.style.layers.LineLayer; +import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.style.sources.VectorSource; import com.mapbox.services.android.navigation.ui.v5.NavigationSnapshotReadyCallback; import com.mapbox.services.android.navigation.ui.v5.R; @@ -36,8 +36,6 @@ import java.util.ArrayList; import java.util.List; -import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor; -import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth; import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants.NAVIGATION_MINIMUM_MAP_ZOOM; /** @@ -51,11 +49,11 @@ public class NavigationMapboxMap { static final String STREETS_LAYER_ID = "streetsLayer"; - private static final String MAPBOX_STREETS_V7 = "mapbox://mapbox.mapbox-streets-v7"; - private static final String STREETS_SOURCE_ID = "streetsSource"; - private static final String ROAD_LABEL = "road_label"; - private static final float DEFAULT_WIDTH = 20f; - private static final int LAST_INDEX = 0; + private static final String MAPBOX_STREETS_V7_URL = "mapbox.mapbox-streets-v7"; + private static final String MAPBOX_STREETS_V8_URL = "mapbox.mapbox-streets-v8"; + private static final String STREETS_SOURCE_ID = "com.mapbox.services.android.navigation.streets"; + private static final String STREETS_V7_ROAD_LABEL = "road_label"; + private static final String STREETS_V8_ROAD_LABEL = "road"; private static final String INCIDENTS_LAYER_ID = "closures"; private static final String TRAFFIC_LAYER_ID = "traffic"; private static final int[] ZERO_MAP_PADDING = {0, 0, 0, 0}; @@ -113,6 +111,12 @@ public NavigationMapboxMap(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa this.mapFpsDelegate = mapFpsDelegate; } + // Package private (no modifier) for testing purposes + NavigationMapboxMap(MapboxMap mapboxMap, MapLayerInteractor layerInteractor, MapPaddingAdjustor adjustor) { + this.layerInteractor = layerInteractor; + initializeWayname(mapboxMap, adjustor); + } + /** * Adds a marker icon on the map at the given position. *

@@ -562,15 +566,33 @@ private void initializeWayname(MapboxMap mapboxMap, MapPaddingAdjustor paddingAd } private void initializeStreetsSource(MapboxMap mapboxMap) { - VectorSource streetSource = new VectorSource(STREETS_SOURCE_ID, MAPBOX_STREETS_V7); - mapboxMap.getStyle().addSource(streetSource); - LineLayer streetsLayer = new LineLayer(STREETS_LAYER_ID, STREETS_SOURCE_ID) - .withProperties( - lineWidth(DEFAULT_WIDTH), - lineColor(Color.WHITE) - ) - .withSourceLayer(ROAD_LABEL); - mapboxMap.getStyle().addLayerAt(streetsLayer, LAST_INDEX); + List sources = mapboxMap.getStyle().getSources(); + Source sourceV7 = findSourceByUrl(sources, MAPBOX_STREETS_V7_URL); + Source sourceV8 = findSourceByUrl(sources, MAPBOX_STREETS_V8_URL); + + if (sourceV7 != null) { + layerInteractor.addStreetsLayer(sourceV7.getId(), STREETS_V7_ROAD_LABEL); + } else if (sourceV8 != null) { + layerInteractor.addStreetsLayer(sourceV8.getId(), STREETS_V8_ROAD_LABEL); + } else { + VectorSource streetSource = new VectorSource(STREETS_SOURCE_ID, MAPBOX_STREETS_V8_URL); + mapboxMap.getStyle().addSource(streetSource); + layerInteractor.addStreetsLayer(STREETS_SOURCE_ID, STREETS_V8_ROAD_LABEL); + } + } + + @Nullable + private Source findSourceByUrl(List sources, String streetsUrl) { + for (Source source : sources) { + if (source instanceof VectorSource) { + VectorSource vectorSource = (VectorSource) source; + String url = vectorSource.getUrl(); + if (url != null && url.contains(streetsUrl)) { + return vectorSource; + } + } + } + return null; } private void initializeRoute(MapView mapView, MapboxMap map) { diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMapTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMapTest.java index bbfac4c59d5..427e6962ee9 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMapTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/map/NavigationMapboxMapTest.java @@ -3,6 +3,11 @@ import com.mapbox.api.directions.v5.models.DirectionsRoute; import com.mapbox.mapboxsdk.location.LocationComponent; import com.mapbox.mapboxsdk.location.modes.RenderMode; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.mapboxsdk.style.sources.VectorSource; import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute; import com.mapbox.services.android.navigation.ui.v5.route.OnRouteSelectionChangeListener; @@ -14,6 +19,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class NavigationMapboxMapTest { @@ -146,4 +152,49 @@ public void updateMapFpsThrottleEnabled_mapFpsDelegateIsEnabled() { verify(delegate).updateEnabled(isEnabled); } + + @Test + public void onInitializeWayName_existingV7StreetSourceIsUsed() { + Style style = mock(Style.class); + String urlV7 = "mapbox://mapbox.mapbox-streets-v7"; + List sources = buildMockSourcesWith(urlV7); + when(style.getSources()).thenReturn(sources); + MapboxMap mapboxMap = mock(MapboxMap.class); + when(mapboxMap.getStyle()).thenReturn(style); + MapLayerInteractor layerInteractor = mock(MapLayerInteractor.class); + MapPaddingAdjustor adjustor = mock(MapPaddingAdjustor.class); + + new NavigationMapboxMap(mapboxMap, layerInteractor, adjustor); + + verify(layerInteractor).addStreetsLayer("composite", "road_label"); + } + + @Test + public void onInitializeWayName_exisitingV8StreetSourceIsUsed() { + Style style = mock(Style.class); + String urlV7 = "mapbox://mapbox.mapbox-streets-v8"; + List sources = buildMockSourcesWith(urlV7); + when(style.getSources()).thenReturn(sources); + MapboxMap mapboxMap = mock(MapboxMap.class); + when(mapboxMap.getStyle()).thenReturn(style); + MapLayerInteractor layerInteractor = mock(MapLayerInteractor.class); + MapPaddingAdjustor adjustor = mock(MapPaddingAdjustor.class); + + new NavigationMapboxMap(mapboxMap, layerInteractor, adjustor); + + verify(layerInteractor).addStreetsLayer("composite", "road"); + } + + private List buildMockSourcesWith(String url) { + List sources = new ArrayList<>(); + VectorSource vectorSource1 = mock(VectorSource.class); + VectorSource vectorSource2 = mock(VectorSource.class); + when(vectorSource2.getId()).thenReturn("composite"); + when(vectorSource2.getUrl()).thenReturn(url); + GeoJsonSource geoJsonSource = mock(GeoJsonSource.class); + sources.add(vectorSource1); + sources.add(vectorSource2); + sources.add(geoJsonSource); + return sources; + } } \ No newline at end of file