Skip to content

Commit

Permalink
Create groundwork for FasterRouteDetector
Browse files Browse the repository at this point in the history
  • Loading branch information
danesfeder committed Jan 8, 2018
1 parent bda98c8 commit 0f74331
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
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.offroute.OffRouteListener;
import com.mapbox.services.android.navigation.v5.route.FasterRoute;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.snap.Snap;
import com.mapbox.services.android.navigation.v5.snap.SnapToRoute;
Expand Down Expand Up @@ -51,6 +52,7 @@ public class MapboxNavigation implements ServiceConnection {
private List<Milestone> milestones;
private final String accessToken;
private OffRoute offRouteEngine;
private FasterRoute fasterRouteEngine;
private Snap snapEngine;
private Context context;
private boolean isBound;
Expand Down Expand Up @@ -140,7 +142,6 @@ private void initialize() {
if (options.defaultMilestonesEnabled()) {
addMilestone(new VoiceInstructionMilestone.Builder().setIdentifier(VOICE_INSTRUCTION_MILESTONE_ID).build());
}

if (options.snapToRoute()) {
snapEngine = new SnapToRoute();
}
Expand Down Expand Up @@ -612,6 +613,38 @@ public OffRoute getOffRouteEngine() {
return offRouteEngine;
}

/**
* This API is used to pass in a custom implementation of the faster-route detection logic, A default
* faster-route detection engine is attached when this class is first initialized; setting a custom
* one will replace it with your own implementation.
* <p>
* The engine can be changed at anytime, even during a navigation session.
* </p>
*
* @param fasterRouteEngine a custom implementation of the {@link FasterRoute} class
* @see FasterRoute
* @since 0.9.0
*/
@SuppressWarnings("WeakerAccess") // Public exposed for usage outside SDK
public void setFasterRouteEngine(@NonNull FasterRoute fasterRouteEngine) {
this.fasterRouteEngine = fasterRouteEngine;
}

/**
* This will return the currently set faster-route engine which will or is being used during the
* navigation session. If no faster-route engine has been set yet, the default engine will be
* returned.
*
* @return the faster-route engine currently set and will/is being used for the navigation session
* @see FasterRoute
* @since 0.9.0
*/
@SuppressWarnings("WeakerAccess") // Public exposed for usage outside SDK
@NonNull
public FasterRoute getFasterRouteEngine() {
return fasterRouteEngine;
}

/**
* Creates a new {@link FeedbackEvent} with a given type, description, and source.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public abstract class MapboxNavigationOptions {

public abstract boolean enableOffRouteDetection();

public abstract boolean enableFasterRouteDetection();

public abstract boolean manuallyEndNavigationUponCompletion();

public abstract boolean enableNotification();
Expand Down Expand Up @@ -73,6 +75,8 @@ public abstract static class Builder {

public abstract Builder enableOffRouteDetection(boolean enableOffRouteDetection);

public abstract Builder enableFasterRouteDetection(boolean enableFasterRouteDetection);

public abstract Builder manuallyEndNavigationUponCompletion(boolean manuallyEndNavigation);

public abstract Builder enableNotification(boolean enableNotification);
Expand Down Expand Up @@ -102,6 +106,7 @@ public static Builder builder() {
.userLocationSnapDistance(NavigationConstants.USER_LOCATION_SNAPPING_DISTANCE)
.secondsBeforeReroute(NavigationConstants.SECONDS_BEFORE_REROUTE)
.enableOffRouteDetection(true)
.enableFasterRouteDetection(false)
.snapToRoute(true)
.manuallyEndNavigationUponCompletion(false)
.defaultMilestonesEnabled(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.isUserOffRoute;
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.legDistanceRemaining;
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.routeDistanceRemaining;
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.shouldCheckFasterRoute;
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.stepDistanceRemaining;
import static com.mapbox.services.android.navigation.v5.navigation.NavigationHelper.userSnappedToRoutePosition;
import static com.mapbox.core.constants.Constants.PRECISION_6;
Expand Down Expand Up @@ -67,14 +68,23 @@ private void handleRequest(final NewLocationModel newLocationModel) {
final RouteProgress routeProgress = generateNewRouteProgress(
newLocationModel.mapboxNavigation(), newLocationModel.location(),
newLocationModel.recentDistancesFromManeuverInMeters());

// Check milestone list to see if any should be triggered
final List<Milestone> milestones = checkMilestones(
previousRouteProgress, routeProgress, newLocationModel.mapboxNavigation());

// Check if user has gone off-route
final boolean userOffRoute = isUserOffRoute(newLocationModel, routeProgress);

// Create snapped location
final Location location = !userOffRoute && newLocationModel.mapboxNavigation().options().snapToRoute()
? getSnappedLocation(newLocationModel.mapboxNavigation(), newLocationModel.location(),
routeProgress, stepPositions)
: newLocationModel.location();

// Check for faster route only if not off-route
final boolean checkFasterRoute = !userOffRoute && shouldCheckFasterRoute(newLocationModel);

previousRouteProgress = routeProgress;

responseHandler.post(new Runnable() {
Expand All @@ -83,6 +93,7 @@ public void run() {
callback.onNewRouteProgress(location, routeProgress);
callback.onMilestoneTrigger(milestones, routeProgress);
callback.onUserOffRoute(location, userOffRoute);
callback.onCheckFasterRoute(location, checkFasterRoute);
}
});
}
Expand Down Expand Up @@ -161,5 +172,7 @@ interface Callback {
void onMilestoneTrigger(List<Milestone> triggeredMilestones, RouteProgress routeProgress);

void onUserOffRoute(Location location, boolean userOffRoute);

void onCheckFasterRoute(Location location, boolean checkFasterRoute);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.mapbox.geojson.Point;
import com.mapbox.services.android.navigation.v5.milestone.Milestone;
import com.mapbox.services.android.navigation.v5.offroute.OffRoute;
import com.mapbox.services.android.navigation.v5.route.FasterRoute;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.snap.Snap;
import com.mapbox.services.android.telemetry.utils.MathUtils;
Expand Down Expand Up @@ -182,6 +183,11 @@ static boolean isUserOffRoute(NewLocationModel newLocationModel, RouteProgress r
newLocationModel.recentDistancesFromManeuverInMeters());
}

static boolean shouldCheckFasterRoute(NewLocationModel newLocationModel) {
FasterRoute fasterRoute = newLocationModel.mapboxNavigation().getFasterRouteEngine();
return fasterRoute.shouldCheckFasterRoute(newLocationModel.location());
}

static Location getSnappedLocation(MapboxNavigation mapboxNavigation, Location location,
RouteProgress routeProgress, List<Point> stepCoordinates) {
Snap snap = mapboxNavigation.getSnapEngine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.mapbox.api.directions.v5.DirectionsCriteria;
import com.mapbox.api.directions.v5.DirectionsCriteria.AnnotationCriteria;
Expand All @@ -12,6 +13,7 @@
import com.mapbox.api.directions.v5.MapboxDirections;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.api.directions.v5.models.RouteOptions;
import com.mapbox.core.exceptions.ServicesException;
import com.mapbox.geojson.Point;

Expand Down Expand Up @@ -420,6 +422,43 @@ public Builder baseUrl(String baseUrl) {
return this;
}

/**
* Optionally create a {@link Builder} based on all variables
* from given {@link RouteOptions}.
*
* @param options containing all variables for request
* @return this builder for chaining options together
* @since 0.9.0
*/
public Builder routeOptions(RouteOptions options) {
directionsBuilder.language(new Locale(options.language()));
directionsBuilder.alternatives(options.alternatives());

if (!TextUtils.isEmpty(options.profile())) {
directionsBuilder.profile(options.profile());
}

if (options.bannerInstructions() != null) {
directionsBuilder.bannerInstructions(options.bannerInstructions());
}

if (options.continueStraight() != null) {
directionsBuilder.continueStraight(options.continueStraight());
}

if (options.alternatives() != null) {
directionsBuilder.alternatives(options.alternatives());
}

if (!TextUtils.isEmpty(options.voiceUnits())) {
directionsBuilder.voiceUnits(options.voiceUnits());
}

// TODO add missing options here

return this;
}

/**
* This uses the provided parameters set using the {@link Builder} and adds the required
* settings for navigation to work correctly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import android.support.annotation.Nullable;

import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Point;
import com.mapbox.services.android.navigation.v5.milestone.Milestone;
import com.mapbox.services.android.navigation.v5.navigation.notification.NavigationNotification;
import com.mapbox.services.android.navigation.v5.route.RouteEngine;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.utils.RingBuffer;
import com.mapbox.services.android.telemetry.location.LocationEngine;
Expand All @@ -37,7 +39,7 @@
* </p>
*/
public class NavigationService extends Service implements LocationEngineListener,
NavigationEngine.Callback {
NavigationEngine.Callback, RouteEngine.Callback {

// Message id used when a new location update occurs and we send to the thread.
private static final int MSG_LOCATION_UPDATED = 1001;
Expand All @@ -47,6 +49,7 @@ public class NavigationService extends Service implements LocationEngineListener

private NavigationNotification navigationNotification;
private MapboxNavigation mapboxNavigation;
private RouteEngine routeEngine;
private LocationEngine locationEngine;
private NavigationEngine thread;

Expand Down Expand Up @@ -143,13 +146,29 @@ public void onUserOffRoute(Location location, boolean userOffRoute) {
}
}

// TODO add javadoc
@Override
public void onCheckFasterRoute(Location location, boolean checkFasterRoute) {
if (checkFasterRoute) {
Point origin = Point.fromLngLat(location.getLongitude(), location.getLatitude());
routeEngine.fetchFasterRoute(origin, mapboxNavigation.getRoute().routeOptions());
}
}

// TODO add javadoc
@Override
public void onFasterRouteFound(DirectionsRoute route) {
mapboxNavigation.startNavigation(route);
}

/**
* This gets called when {@link MapboxNavigation#startNavigation(DirectionsRoute)} is called and
* setups variables among other things on the Navigation Service side.
*/
void startNavigation(MapboxNavigation mapboxNavigation) {
this.mapboxNavigation = mapboxNavigation;
initNotification(mapboxNavigation);
initRouteEngine(mapboxNavigation);
acquireLocationEngine();
forceLocationUpdate();
}
Expand Down Expand Up @@ -210,6 +229,20 @@ private void initializeNotification(MapboxNavigationOptions options) {
}
}

/**
* Builds a new route engine which can be used to find faster routes
* during a navigation session based on traffic.
* <p>
* Check to see if this functionality is enabled / disabled first.
*
* @param mapboxNavigation for options to check if enabled / disabled
*/
private void initRouteEngine(MapboxNavigation mapboxNavigation) {
if (mapboxNavigation.options().enableFasterRouteDetection()) {
routeEngine = new RouteEngine(this);
}
}

/**
* Starts the given notification flagged as a foreground service.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.mapbox.services.android.navigation.v5.route;

import android.location.Location;

public abstract class FasterRoute {

public abstract boolean shouldCheckFasterRoute(Location location);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.mapbox.services.android.navigation.v5.route;

import android.location.Location;

public class FasterRouteDetector extends FasterRoute {

private Location lastLocation;

@Override
public boolean shouldCheckFasterRoute(Location location) {
if (lastLocation == null) {
return false;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.mapbox.services.android.navigation.v5.route;

import android.support.annotation.NonNull;

import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.api.directions.v5.models.RouteOptions;
import com.mapbox.geojson.Point;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class RouteEngine implements Callback<DirectionsResponse> {

private Callback engineCallback;

public RouteEngine(Callback engineCallback) {
this.engineCallback = engineCallback;
}

public void fetchFasterRoute(Point origin, RouteOptions options) {
if (options == null) {
return;
}

NavigationRoute.builder()
.origin(origin)
.routeOptions(options)
.build()
.getRoute(this);
}

@Override
public void onResponse(@NonNull Call<DirectionsResponse> call, @NonNull Response<DirectionsResponse> response) {
// Check for successful response
if (!response.isSuccessful()) {
return;
}

if (isFasterRoute(response.body())) {
engineCallback.onFasterRouteFound(response.body().routes().get(0));
}
}

@Override
public void onFailure(@NonNull Call<DirectionsResponse> call, @NonNull Throwable throwable) {

}

public interface Callback {
void onFasterRouteFound(DirectionsRoute route);
}

private boolean isFasterRoute(DirectionsResponse response) {

// TODO determine is faster route

return false;
}
}

0 comments on commit 0f74331

Please sign in to comment.