Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions libandroid-navigation-ui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ android {
testCoverageEnabled = true
}
}

testOptions {
unitTests.returnDefaultValues = true
unitTests.includeAndroidResources = true
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
}
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
Expand All @@ -24,13 +26,14 @@
class MapWayname {

private static final String NAME_PROPERTY = "name";
private final MapWaynameProgressChangeListener progressChangeListener = new MapWaynameProgressChangeListener(this);
private final Set<OnWayNameChangedListener> onWayNameChangedListeners;
private WaynameLayoutProvider layoutProvider;
private MapLayerInteractor layerInteractor;
private WaynameFeatureFinder featureInteractor;
private List<Point> currentStepPoints = new ArrayList<>();
private Location currentLocation = null;
private MapboxNavigation navigation;
private final MapWaynameProgressChangeListener progressChangeListener = new MapWaynameProgressChangeListener(this);
private boolean isAutoQueryEnabled;
private boolean isVisible;
private FeatureFilterTask filterTask;
Expand All @@ -42,19 +45,20 @@ class MapWayname {
this.layerInteractor = layerInteractor;
this.featureInteractor = featureInteractor;
paddingAdjustor.updatePaddingWithDefault();
this.onWayNameChangedListeners = new HashSet<>();
}

void updateWaynameWithPoint(PointF point, SymbolLayer waynameLayer) {
if (!isAutoQueryEnabled || !isVisible) {
if (!isAutoQueryEnabled) {
return;
}
List<Feature> roads = findRoadLabelFeatures(point);
boolean shouldBeVisible = !roads.isEmpty();
adjustWaynameVisibility(shouldBeVisible, waynameLayer);
if (!shouldBeVisible) {
List<Feature> roadLabelFeatures = findRoadLabelFeatures(point);
boolean invalidLabelFeatures = roadLabelFeatures.isEmpty();
if (invalidLabelFeatures) {
updateVisibility(false, waynameLayer);
return;
}
updateLayerWithRoadLabelFeatures(roads, waynameLayer);
executeFeatureFilterTask(roadLabelFeatures, waynameLayer);
}

void updateWaynameLayer(String wayname, SymbolLayer waynameLayer) {
Expand All @@ -63,14 +67,6 @@ void updateWaynameLayer(String wayname, SymbolLayer waynameLayer) {
}
}

void updateWaynameVisibility(boolean isVisible, SymbolLayer waynameLayer) {
this.isVisible = isVisible;
if (checkWaynameVisibility(isVisible, waynameLayer)) {
return;
}
adjustWaynameVisibility(isVisible, waynameLayer);
}

void updateProgress(Location currentLocation, List<Point> currentStepPoints) {
if (!this.currentStepPoints.equals(currentStepPoints)) {
this.currentStepPoints = currentStepPoints;
Expand All @@ -80,6 +76,11 @@ void updateProgress(Location currentLocation, List<Point> currentStepPoints) {
}
}

void updateWaynameVisibility(boolean isVisible, SymbolLayer waynameLayer) {
this.isVisible = isVisible;
updateVisibility(isVisible, waynameLayer);
}

void updateWaynameQueryMap(boolean isEnabled) {
isAutoQueryEnabled = isEnabled;
}
Expand All @@ -97,6 +98,14 @@ void addProgressChangeListener(MapboxNavigation navigation) {
navigation.addProgressChangeListener(progressChangeListener);
}

boolean addOnWayNameChangedListener(OnWayNameChangedListener listener) {
return onWayNameChangedListeners.add(listener);
}

boolean removeOnWayNameChangedListener(OnWayNameChangedListener listener) {
return onWayNameChangedListeners.remove(listener);
}

void onStart() {
if (navigation != null) {
navigation.addProgressChangeListener(progressChangeListener);
Expand All @@ -117,15 +126,6 @@ private List<Feature> findRoadLabelFeatures(PointF point) {
return featureInteractor.queryRenderedFeatures(point, layerIds);
}

private void updateLayerWithRoadLabelFeatures(List<Feature> roadFeatures, final SymbolLayer waynameLayer) {
boolean isValidFeatureList = !roadFeatures.isEmpty();
if (isValidFeatureList) {
executeFeatureFilterTask(roadFeatures, waynameLayer);
} else {
updateWaynameVisibility(false, waynameLayer);
}
}

private void executeFeatureFilterTask(List<Feature> roadFeatures, final SymbolLayer waynameLayer) {
if (isTaskRunning()) {
filterTask.cancel(true);
Expand All @@ -145,22 +145,27 @@ public void onFeatureFiltered(@NonNull Feature feature) {

private boolean isTaskRunning() {
return filterTask != null
&& (filterTask.getStatus() == AsyncTask.Status.PENDING || filterTask.getStatus() == AsyncTask.Status.RUNNING);
&& (filterTask.getStatus() == AsyncTask.Status.PENDING
|| filterTask.getStatus() == AsyncTask.Status.RUNNING);
}

private boolean hasValidProgressData() {
return currentLocation != null && !currentStepPoints.isEmpty();
}

private void createWaynameIcon(String wayname, Layer waynameLayer) {
boolean isVisible = waynameLayer.getVisibility().getValue().contentEquals(Property.VISIBLE);
if (isVisible) {
Bitmap waynameLayoutBitmap = layoutProvider.generateLayoutBitmap(wayname);
if (waynameLayoutBitmap != null) {
layerInteractor.addLayerImage(MAPBOX_WAYNAME_ICON, waynameLayoutBitmap);
waynameLayer.setProperties(iconImage(MAPBOX_WAYNAME_ICON));
}
Bitmap waynameLayoutBitmap = layoutProvider.generateLayoutBitmap(wayname);
if (waynameLayoutBitmap != null) {
layerInteractor.addLayerImage(MAPBOX_WAYNAME_ICON, waynameLayoutBitmap);
waynameLayer.setProperties(iconImage(MAPBOX_WAYNAME_ICON));
}
}

private void updateVisibility(boolean isVisible, SymbolLayer waynameLayer) {
if (checkWaynameVisibility(isVisible, waynameLayer)) {
return;
}
adjustWaynameVisibility(isVisible, waynameLayer);
}

private boolean checkWaynameVisibility(boolean isVisible, Layer waynameLayer) {
Expand All @@ -183,10 +188,21 @@ private void updateWaynameLayerWithNameProperty(SymbolLayer waynameLayer, Featur
String currentWayname = roadFeature.getStringProperty(NAME_PROPERTY);
boolean newWayname = !wayname.contentEquals(currentWayname);
if (newWayname) {
updateListenersWith(currentWayname);
wayname = currentWayname;
updateWaynameVisibility(true, waynameLayer);
if (isVisible) {
updateVisibility(true, waynameLayer);
}
updateWaynameLayer(wayname, waynameLayer);
}
} else {
updateVisibility(false, waynameLayer);
}
}

private void updateListenersWith(String currentWayName) {
for (OnWayNameChangedListener listener : onWayNameChangedListeners) {
listener.onWayNameChanged(currentWayName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public class NavigationMapboxMap {
private NavigationMapRoute mapRoute;
private LocationComponent locationComponent;
private MapPaddingAdjustor mapPaddingAdjustor;
private MapWayname mapWayname;
private MapWayname mapWayName;
private SymbolLayer waynameLayer;
private MapLayerInteractor layerInteractor;
private List<Marker> mapMarkers = new ArrayList<>();
Expand Down Expand Up @@ -117,6 +117,11 @@ public NavigationMapboxMap(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa
this.mapRoute = mapRoute;
}

// Package private (no modifier) for testing purposes
NavigationMapboxMap(MapWayname mapWayName) {
this.mapWayName = mapWayName;
}

/**
* Adds a marker icon on the map at the given position.
* <p>
Expand Down Expand Up @@ -178,7 +183,7 @@ public void updateLocationLayerRenderMode(@RenderMode.Mode int renderMode) {
public void addProgressChangeListener(MapboxNavigation navigation) {
mapRoute.addProgressChangeListener(navigation);
mapCamera.addProgressChangeListener(navigation);
mapWayname.addProgressChangeListener(navigation);
mapWayName.addProgressChangeListener(navigation);
}

/**
Expand All @@ -192,8 +197,8 @@ public void addProgressChangeListener(MapboxNavigation navigation) {
* @param outState to store state variables
*/
public void saveStateWith(String key, Bundle outState) {
boolean isVisible = mapWayname.isVisible();
String waynameText = mapWayname.retrieveWayname();
boolean isVisible = mapWayName.isVisible();
String waynameText = mapWayName.retrieveWayname();
int[] mapPadding = mapPaddingAdjustor.retrieveCurrentPadding();
boolean isUsingDefault = mapPaddingAdjustor.isUsingDefault();
@NavigationCamera.TrackingMode
Expand Down Expand Up @@ -366,7 +371,7 @@ public void showRouteOverview(int[] padding) {
* @param wayname text to be set
*/
public void updateWaynameView(String wayname) {
mapWayname.updateWaynameLayer(wayname, waynameLayer);
mapWayName.updateWaynameLayer(wayname, waynameLayer);
}

/**
Expand All @@ -375,7 +380,7 @@ public void updateWaynameView(String wayname) {
* @param isVisible true to show, false to hide
*/
public void updateWaynameVisibility(boolean isVisible) {
mapWayname.updateWaynameVisibility(isVisible, waynameLayer);
mapWayName.updateWaynameVisibility(isVisible, waynameLayer);
}

/**
Expand All @@ -384,7 +389,7 @@ public void updateWaynameVisibility(boolean isVisible) {
* @return true if visible, false if not
*/
public boolean isWaynameVisible() {
return mapWayname.isVisible();
return mapWayName.isVisible();
}

/**
Expand All @@ -393,7 +398,7 @@ public boolean isWaynameVisible() {
* @param isEnabled true to enable, false to disable
*/
public void updateWaynameQueryMap(boolean isEnabled) {
mapWayname.updateWaynameQueryMap(isEnabled);
mapWayName.updateWaynameQueryMap(isEnabled);
}

/**
Expand All @@ -403,7 +408,7 @@ public void updateWaynameQueryMap(boolean isEnabled) {
public void onStart() {
mapCamera.onStart();
mapRoute.onStart();
mapWayname.onStart();
mapWayName.onStart();
}

/**
Expand All @@ -413,7 +418,7 @@ public void onStart() {
public void onStop() {
mapCamera.onStop();
mapRoute.onStop();
mapWayname.onStop();
mapWayName.onStop();
}

/**
Expand Down Expand Up @@ -496,6 +501,28 @@ public void removeOnCameraTrackingChangedListener(OnCameraTrackingChangedListene
locationComponent.removeOnCameraTrackingChangedListener(listener);
}

/**
* Add a {@link OnWayNameChangedListener} for listening to updates
* to the way name shown on the map below the location icon.
*
* @param listener to be added
* @return true if added, false if listener was not found
*/
public boolean addOnWayNameChangedListener(OnWayNameChangedListener listener) {
return mapWayName.addOnWayNameChangedListener(listener);
}

/**
* Remove a {@link OnWayNameChangedListener} for listening to updates
* to the way name shown on the map below the location icon.
*
* @param listener to be removed
* @return true if removed, false if listener was not found
*/
public boolean removeOnWayNameChangedListener(OnWayNameChangedListener listener) {
return mapWayName.removeOnWayNameChangedListener(listener);
}

/**
* Use this method to position the location icon on the map.
* <p>
Expand Down Expand Up @@ -541,7 +568,7 @@ private void initializeWayname(MapView mapView, MapboxMap mapboxMap, MapLayerInt
WaynameLayoutProvider layoutProvider = new WaynameLayoutProvider(mapView.getContext());
WaynameFeatureFinder featureInteractor = new WaynameFeatureFinder(mapboxMap);
initializeWaynameLayer(layerInteractor);
mapWayname = new MapWayname(layoutProvider, layerInteractor, featureInteractor, paddingAdjustor);
mapWayName = new MapWayname(layoutProvider, layerInteractor, featureInteractor, paddingAdjustor);
}

private void initializeWaynameLayer(MapLayerInteractor layerInteractor) {
Expand Down Expand Up @@ -607,6 +634,6 @@ private void removeAllMarkers() {
private void updateMapWaynameWithLocation(Location location) {
LatLng latLng = new LatLng(location);
PointF mapPoint = mapboxMap.getProjection().toScreenLocation(latLng);
mapWayname.updateWaynameWithPoint(mapPoint, waynameLayer);
mapWayName.updateWaynameWithPoint(mapPoint, waynameLayer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.mapbox.services.android.navigation.ui.v5.map;

/**
* A listener that can be added to the {@link NavigationMapboxMap} with
* {@link NavigationMapboxMap#addOnWayNameChangedListener(OnWayNameChangedListener)}.
* <p>
* This listener is triggered when a new way name is found along the route. It will be triggered
* regardless of the map way name visibility ({@link NavigationMapboxMap#updateWaynameVisibility(boolean)}).
* This is so you can hide our implementation of the way name UI and update your own if you'd like.
*/
public interface OnWayNameChangedListener {

/**
* Triggered every time a new way name is found along the route.
* This will mainly be when transitioning steps, onto new roads.
*
* @param wayName found along the route
*/
void onWayNameChanged(String wayName);
}
Loading