Skip to content

Commit

Permalink
Add voice instruction from NavigationStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
danesfeder committed Sep 17, 2018
1 parent 26995b6 commit 6d6e4da
Show file tree
Hide file tree
Showing 25 changed files with 260 additions and 384 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ buildscript {
google()
jcenter()
maven { url 'https://plugins.gradle.org/m2' }
maven { url 'https://mapbox.bintray.com/mapbox' }
}
dependencies {
classpath pluginDependencies.gradle
Expand Down
2 changes: 2 additions & 0 deletions gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ext {
mapboxMapSdk : '6.5.0',
mapboxSdkServices : '3.4.1',
mapboxEvents : '3.2.0',
mapboxNavigator : '2.0.0',
locationLayerPlugin: '0.8.1',
autoValue : '1.5.4',
autoValueParcel : '0.2.5',
Expand Down Expand Up @@ -51,6 +52,7 @@ ext {
mapboxSdkServices : "com.mapbox.mapboxsdk:mapbox-sdk-services:${version.mapboxSdkServices}",
mapboxSdkTurf : "com.mapbox.mapboxsdk:mapbox-sdk-turf:${version.mapboxSdkServices}",
mapboxEvents : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${version.mapboxEvents}",
mapboxNavigator : "com.mapbox.navigator:mapbox-navigation-native:${version.mapboxNavigator}",
locationLayerPlugin : "com.mapbox.mapboxsdk:mapbox-android-plugin-locationlayer:${version.locationLayerPlugin}",

// AutoValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ RouteProgress buildTestRouteProgress(DirectionsRoute route,
.intersectionDistancesAlongStep(intersectionDistances)
.stepIndex(stepIndex)
.legIndex(legIndex)
.inTunnel(false)
.build();
}

Expand Down
4 changes: 2 additions & 2 deletions libandroid-navigation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ dependencies {
api dependenciesList.mapboxSdkServices
api dependenciesList.mapboxSdkTurf

// Native
implementation 'com.mapbox.navigator:mapbox-navigation-native:master-SNAPSHOT'
// Navigator
implementation dependenciesList.mapboxNavigator

// Support
implementation dependenciesList.supportAppcompatV7
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.mapbox.services.android.navigation.v5.milestone;

import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.api.directions.v5.models.LegStep;
import com.mapbox.api.directions.v5.models.VoiceInstructions;
import com.mapbox.services.android.navigation.v5.instruction.Instruction;
import com.mapbox.services.android.navigation.v5.navigation.VoiceInstructionLoader;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.utils.RouteUtils;

/**
* A default milestone that is added to {@link com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation}
Expand All @@ -18,39 +15,25 @@
public class VoiceInstructionMilestone extends Milestone {

private static final String EMPTY_STRING = "";

private VoiceInstructions instructions;
private DirectionsRoute currentRoute;
private RouteUtils routeUtils;
private String announcement = EMPTY_STRING;
private String ssmlAnnouncement = EMPTY_STRING;

VoiceInstructionMilestone(Builder builder) {
super(builder);
routeUtils = new RouteUtils();
}

@Override
public boolean isOccurring(RouteProgress previousRouteProgress, RouteProgress routeProgress) {
if (isNewRoute(routeProgress)) {
cacheInstructions(routeProgress, true);
}
LegStep currentStep = routeProgress.currentLegProgress().currentStep();
double stepDistanceRemaining = routeProgress.currentLegProgress().currentStepProgress().distanceRemaining();
VoiceInstructions instructions = routeUtils.findCurrentVoiceInstructions(currentStep, stepDistanceRemaining);
if (shouldBeVoiced(instructions, stepDistanceRemaining)) {
return updateInstructions(routeProgress, instructions);
}
return false;
checkForNewRoute(previousRouteProgress, routeProgress);
return updateCurrentAnnouncement(routeProgress);
}

@Override
public Instruction getInstruction() {
return new Instruction() {
@Override
public String buildInstruction(RouteProgress routeProgress) {
if (instructions == null) {
return routeProgress.currentLegProgress().currentStep().name();
}
return instructions.announcement();
return announcement;
}
};
}
Expand All @@ -65,10 +48,7 @@ public String buildInstruction(RouteProgress routeProgress) {
* @since 0.8.0
*/
public String getSsmlAnnouncement() {
if (instructions == null) {
return EMPTY_STRING;
}
return instructions.ssmlAnnouncement();
return ssmlAnnouncement;
}

/**
Expand All @@ -80,55 +60,7 @@ public String getSsmlAnnouncement() {
* @since 0.12.0
*/
public String getAnnouncement() {
if (instructions == null) {
return EMPTY_STRING;
}
return instructions.announcement();
}

/**
* Looks to see if we have a new route.
*
* @param routeProgress provides updated route information
* @return true if new route, false if not
*/
private boolean isNewRoute(RouteProgress routeProgress) {
boolean newRoute = currentRoute == null || !currentRoute.equals(routeProgress.directionsRoute());
currentRoute = routeProgress.directionsRoute();
return newRoute;
}

/**
* Checks if the current instructions are different from the instructions
* determined by the step distance remaining.
*
* @param instructions the current voice instructions from the list of step instructions
* @param stepDistanceRemaining the current step distance remaining
* @return true if time to voice the announcement, false if not
*/
private boolean shouldBeVoiced(VoiceInstructions instructions, double stepDistanceRemaining) {
boolean isNewInstruction = this.instructions == null || !this.instructions.equals(instructions);
boolean isValidNewInstruction = instructions != null && isNewInstruction;
return isValidNewInstruction && instructions.distanceAlongGeometry() >= stepDistanceRemaining;
}

private boolean updateInstructions(RouteProgress routeProgress, VoiceInstructions instructions) {
cacheInstructions(routeProgress, false);
this.instructions = instructions;
return true;
}

/**
* Caches the instructions in the VoiceInstructionLoader if it has been initialized
*
* @param routeProgress containing the instructions
* @param isFirst whether it's the first routeProgress of the route
*/
private void cacheInstructions(RouteProgress routeProgress, boolean isFirst) {
VoiceInstructionLoader voiceInstructionLoader = VoiceInstructionLoader.getInstance();
if (voiceInstructionLoader != null) {
voiceInstructionLoader.cacheInstructions(routeProgress, isFirst);
}
return announcement;
}

public static final class Builder extends Milestone.Builder {
Expand All @@ -155,4 +87,29 @@ public VoiceInstructionMilestone build() {
return new VoiceInstructionMilestone(this);
}
}

private void checkForNewRoute(RouteProgress previousRouteProgress, RouteProgress routeProgress) {
DirectionsRoute previousRoute = previousRouteProgress.directionsRoute();
DirectionsRoute currentRoute = routeProgress.directionsRoute();
if (!previousRoute.equals(currentRoute)) {
cacheInstructions(routeProgress, true);
}
}

private void cacheInstructions(RouteProgress routeProgress, boolean isFirst) {
VoiceInstructionLoader voiceInstructionLoader = VoiceInstructionLoader.getInstance();
if (voiceInstructionLoader != null) {
voiceInstructionLoader.cacheInstructions(routeProgress, isFirst);
}
}

private boolean updateCurrentAnnouncement(RouteProgress routeProgress) {
if (!announcement.equals(routeProgress.currentAnnouncement())) {
announcement = routeProgress.currentAnnouncement();
ssmlAnnouncement = routeProgress.currentSsmlAnnouncement();
cacheInstructions(routeProgress, false);
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class MapboxNavigation implements ServiceConnection {
private NavigationEngineFactory navigationEngineFactory;
private NavigationTelemetry navigationTelemetry = null;
private NavigationService navigationService;
private Navigator navigator;
private MapboxNavigator mapboxNavigator;
private DirectionsRoute directionsRoute;
private MapboxNavigationOptions options;
private LocationEngine locationEngine = null;
Expand All @@ -64,7 +64,9 @@ public class MapboxNavigation implements ServiceConnection {
private Context applicationContext;
private boolean isBound;

static { NavigationLibraryLoader.load(); }
static {
NavigationLibraryLoader.load();
}

/**
* Constructs a new instance of this class using the default options. This should be used over
Expand Down Expand Up @@ -155,9 +157,9 @@ private void initializeForTest() {
*/
private void initialize() {
// Initialize event dispatcher and add internal listeners
navigator = new Navigator();
mapboxNavigator = new MapboxNavigator(new Navigator());
navigationEventDispatcher = new NavigationEventDispatcher();
navigationEngineFactory = new NavigationEngineFactory(navigator);
navigationEngineFactory = new NavigationEngineFactory();
initializeDefaultLocationEngine();
initializeTelemetry();

Expand Down Expand Up @@ -794,14 +796,14 @@ NavigationEngineFactory retrieveEngineFactory() {
return navigationEngineFactory;
}

Navigator retrieveNavigator() {
return navigator;
MapboxNavigator retrieveMapboxNavigator() {
return mapboxNavigator;
}

private void startNavigationWith(@NonNull DirectionsRoute directionsRoute) {
ValidationUtils.validDirectionsRoute(directionsRoute, options.defaultMilestonesEnabled());
this.directionsRoute = directionsRoute;
navigator.setDirections(directionsRoute.toJson());
mapboxNavigator.updateRoute(directionsRoute.toJson());
if (!isBound) {
navigationTelemetry.startSession(directionsRoute);
startNavigationService();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.mapbox.services.android.navigation.v5.navigation;

import android.location.Location;

import com.mapbox.geojson.Point;
import com.mapbox.navigator.FixLocation;
import com.mapbox.navigator.NavigationStatus;
import com.mapbox.navigator.Navigator;

import java.util.Date;

class MapboxNavigator {

private final Navigator navigator;

MapboxNavigator(Navigator navigator) {
this.navigator = navigator;
}

synchronized void updateRoute(String routeJson) {
navigator.setDirections(routeJson);
}

synchronized NavigationStatus retrieveStatus(Date date) {
return navigator.getStatus(date);
}

void updateLocation(Location location) {
navigator.updateLocation(buildFixLocationFrom(location));
}

private FixLocation buildFixLocationFrom(Location rawLocation) {
Point rawPoint = Point.fromLngLat(rawLocation.getLongitude(), rawLocation.getLatitude());
Date time = new Date(rawLocation.getTime());
Float speed = rawLocation.getSpeed();
Float bearing = rawLocation.getBearing();
Float altitude = (float) rawLocation.getAltitude();
Float horizontalAccuracy = rawLocation.getAccuracy();
String provider = rawLocation.getProvider();

return new FixLocation(
rawPoint,
time,
speed,
bearing,
altitude,
horizontalAccuracy,
provider
);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package com.mapbox.services.android.navigation.v5.navigation;

import android.location.Location;

import com.mapbox.navigator.Navigator;
import com.mapbox.services.android.navigation.v5.navigation.camera.Camera;
import com.mapbox.services.android.navigation.v5.navigation.camera.SimpleCamera;
import com.mapbox.services.android.navigation.v5.offroute.OffRoute;
import com.mapbox.services.android.navigation.v5.offroute.OffRouteDetector;
import com.mapbox.services.android.navigation.v5.route.FasterRoute;
import com.mapbox.services.android.navigation.v5.route.FasterRouteDetector;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.snap.Snap;
import com.mapbox.services.android.navigation.v5.snap.SnapToRoute;

Expand All @@ -20,26 +16,8 @@ class NavigationEngineFactory {
private Snap snapEngine;
private Camera cameraEngine;

NavigationEngineFactory(Navigator navigator) {
initializeDefaultEngines(navigator);
}

// For testing purposes only
NavigationEngineFactory() {
cameraEngine = new SimpleCamera();
fasterRouteEngine = new FasterRouteDetector();
snapEngine = new Snap() {
@Override
public Location getSnappedLocation(Location location, RouteProgress routeProgress) {
return location;
}
};
offRouteEngine = new OffRoute() {
@Override
public boolean isUserOffRoute(Location location, RouteProgress routeProgress, MapboxNavigationOptions options) {
return false;
}
};
initializeDefaultEngines();
}

OffRoute retrieveOffRouteEngine() {
Expand Down Expand Up @@ -86,10 +64,10 @@ void updateCameraEngine(Camera cameraEngine) {
this.cameraEngine = cameraEngine;
}

private void initializeDefaultEngines(Navigator navigator) {
private void initializeDefaultEngines() {
cameraEngine = new SimpleCamera();
snapEngine = new SnapToRoute(navigator);
offRouteEngine = new OffRouteDetector(navigator);
snapEngine = new SnapToRoute();
offRouteEngine = new OffRouteDetector();
fasterRouteEngine = new FasterRouteDetector();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,7 @@ public void load(String name) {
private static volatile NavigationLibraryLoader loader = DEFAULT;

/**
* Set the library loader that loads the shared library.
*
* @param libraryLoader the library loader
*/
public static void setLibraryLoader(NavigationLibraryLoader libraryLoader) {
loader = libraryLoader;
}

/**
* Loads navigation native shared library.
* Loads navigation shared library.
* <p>
* Catches UnsatisfiedLinkErrors and prints a warning to logcat.
* </p>
Expand Down
Loading

0 comments on commit 6d6e4da

Please sign in to comment.