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
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ class LocationUpdatedThread extends HandlerThread {
private boolean userOffRoute;
private boolean snapToRoute;
private DirectionsRoute directionsRoute;
private MapboxNavigationOptions options;
private Location location;

LocationUpdatedThread(Handler responseHandler) {
LocationUpdatedThread(Handler responseHandler, MapboxNavigationOptions options) {
super(TAG);
this.responseHandler = responseHandler;
this.options = options;
// By default we snap to route when possible.
snapToRoute = true;
}
Expand Down Expand Up @@ -153,8 +155,8 @@ private RouteProgress monitorStepProgress(@NonNull RouteProgress routeProgress,
boolean courseMatchesManeuverFinalHeading = false;

// TODO set to eventually adjust for different direction profiles.
int minimumDistanceForHighAlert = NavigationConstants.MINIMUM_DISTANCE_FOR_HIGH_ALERT;
int minimumDistanceForMediumAlert = NavigationConstants.MINIMUM_DISTANCE_FOR_MEDIUM_ALERT;
double minimumDistanceForHighAlert = options.getMinimumHighAlertDistance();
double minimumDistanceForMediumAlert = options.getMinimumMediumAlertDistance();

// Bearings need to be normalized so when the bearingAfter is 359 and the user heading is 1, we count this as
// within the MAXIMUM_ALLOWED_DEGREE_OFFSET_FOR_TURN_COMPLETION.
Expand All @@ -164,19 +166,19 @@ private RouteProgress monitorStepProgress(@NonNull RouteProgress routeProgress,
double userHeadingNormalized = MathUtils.wrap(location.getBearing(), 0, 360);
courseMatchesManeuverFinalHeading = MathUtils.differenceBetweenAngles(
finalHeadingNormalized, userHeadingNormalized
) <= NavigationConstants.MAXIMUM_ALLOWED_DEGREE_OFFSET_FOR_TURN_COMPLETION;
) <= options.getMaxTurnCompletionOffset();
}

// When departing, userSnapToStepDistanceFromManeuver is most often less than RouteControllerManeuverZoneRadius
// since the user will most often be at the beginning of the route, in the maneuver zone
if (alertLevel == NavigationConstants.DEPART_ALERT_LEVEL && userSnapToStepDistanceFromManeuver
<= NavigationConstants.MANEUVER_ZONE_RADIUS) {
<= options.getManeuverZoneRadius()) {
// If the user is close to the maneuver location, don't give a departure instruction, instead, give a high alert.
if (secondsToEndOfStep <= NavigationConstants.HIGH_ALERT_INTERVAL) {
if (secondsToEndOfStep <= options.getHighAlertInterval()) {
alertLevel = NavigationConstants.HIGH_ALERT_LEVEL;
}

} else if (userSnapToStepDistanceFromManeuver <= NavigationConstants.MANEUVER_ZONE_RADIUS) {
} else if (userSnapToStepDistanceFromManeuver <= options.getManeuverZoneRadius()) {

// Use the currentStep if there is not a next step, this occurs when arriving.
if (routeProgress.getCurrentLegProgress().getUpComingStep() != null) {
Expand All @@ -189,7 +191,7 @@ private RouteProgress monitorStepProgress(@NonNull RouteProgress routeProgress,
// userAbsoluteDistanceToManeuverLocation is set to nil by default
// If it's set to nil, we know the user has never entered the maneuver radius
if (userDistanceToManeuverLocation == 0.0) {
userDistanceToManeuverLocation = NavigationConstants.MANEUVER_ZONE_RADIUS;
userDistanceToManeuverLocation = options.getManeuverZoneRadius();
}

double lastKnownUserAbsoluteDistance = userDistanceToManeuverLocation;
Expand Down Expand Up @@ -218,15 +220,15 @@ private RouteProgress monitorStepProgress(@NonNull RouteProgress routeProgress,
routeProgress.getCurrentLegProgress().getStepIndex()
);
secondsToEndOfStep = userSnapToStepDistanceFromManeuver / location.getSpeed();
alertLevel = secondsToEndOfStep <= NavigationConstants.MEDIUM_ALERT_INTERVAL
alertLevel = secondsToEndOfStep <= options.getMediumAlertInterval()
? NavigationConstants.MEDIUM_ALERT_LEVEL : NavigationConstants.LOW_ALERT_LEVEL;
}
} else if (secondsToEndOfStep <= NavigationConstants.HIGH_ALERT_INTERVAL
} else if (secondsToEndOfStep <= options.getHighAlertInterval()
&& routeProgress.getCurrentLegProgress().getCurrentStep().getDistance() > minimumDistanceForHighAlert) {
alertLevel = NavigationConstants.HIGH_ALERT_LEVEL;
// Don't alert if the route segment is shorter than X however, if it's the beginning of the route There needs to
// be an alert
} else if (secondsToEndOfStep <= NavigationConstants.MEDIUM_ALERT_INTERVAL
} else if (secondsToEndOfStep <= options.getMediumAlertInterval()
&& routeProgress.getCurrentLegProgress().getCurrentStep().getDistance() > minimumDistanceForMediumAlert) {
alertLevel = NavigationConstants.MEDIUM_ALERT_LEVEL;
}
Expand Down Expand Up @@ -257,14 +259,14 @@ private RouteProgress monitorStepProgress(@NonNull RouteProgress routeProgress,
private boolean userIsOnRoute(Location location, RouteLeg routeLeg) {
Position locationToPosition = Position.fromCoordinates(location.getLongitude(), location.getLatitude());
// Find future location of user
double metersInFrontOfUser = location.getSpeed() * NavigationConstants.DEAD_RECKONING_TIME_INTERVAL;
double metersInFrontOfUser = location.getSpeed() * options.getDeadReckoningTimeInterval();

Position locationInFrontOfUser = TurfMeasurement.destination(
locationToPosition, metersInFrontOfUser, location.getBearing(), TurfConstants.UNIT_METERS
);

return RouteUtils.isOffRoute(locationInFrontOfUser, routeLeg,
NavigationConstants.MAXIMUM_DISTANCE_BEFORE_OFF_ROUTE);
options.getMaximumDistanceOffRoute());
}

private float snapUserBearing(RouteProgress routeProgress) {
Expand All @@ -279,7 +281,7 @@ private float snapUserBearing(RouteProgress routeProgress) {
newCoordinate = Position.fromCoordinates(location.getLongitude(), location.getLatitude());
}

double userDistanceBuffer = location.getSpeed() * NavigationConstants.DEAD_RECKONING_TIME_INTERVAL;
double userDistanceBuffer = location.getSpeed() * options.getDeadReckoningTimeInterval();

if (routeProgress.getDistanceTraveled() + userDistanceBuffer
> RouteUtils.getDistanceToEndOfRoute(
Expand Down Expand Up @@ -311,11 +313,11 @@ private float snapUserBearing(RouteProgress routeProgress) {
double absoluteBearing = MathUtils.wrap(wrappedCurrentBearing + averageRelativeAngle, 0, 360);

if (MathUtils.differenceBetweenAngles(absoluteBearing, location.getBearing())
> NavigationConstants.MAX_MANIPULATED_COURSE_ANGLE) {
> options.getMaxManipulatedCourseAngle()) {
return location.getBearing();
}

return averageRelativeAngle <= NavigationConstants.MAXIMUM_ALLOWED_DEGREE_OFFSET_FOR_TURN_COMPLETION ? (float)
return averageRelativeAngle <= options.getMaxTurnCompletionOffset() ? (float)
absoluteBearing : location.getBearing();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;

import com.mapbox.services.Experimental;
import com.mapbox.services.android.location.LostLocationEngine;
Expand Down Expand Up @@ -41,6 +42,7 @@ public class MapboxNavigation {
// Navigation service variables
private NavigationServiceConnection connection;
private NavigationService navigationService;
private MapboxNavigationOptions options;
private Context context;
private boolean isBound;

Expand All @@ -53,7 +55,7 @@ public class MapboxNavigation {
private boolean snapToRoute;

// Requesting route variables
private String profile = DirectionsCriteria.PROFILE_DRIVING_TRAFFIC;
private String profile;
private DirectionsRoute route;
private Position destination;
private Integer userBearing;
Expand All @@ -64,14 +66,36 @@ public class MapboxNavigation {
* Constructor
*/

public MapboxNavigation(Context context, String accessToken) {
/**
* Creates a new MapboxNavigation object.
*
* @param context {@link Context} used for various things internally, cannot be null.
* @param accessToken A valid Mapbox access token.
* @since 0.1.0
*/
public MapboxNavigation(@NonNull Context context, @NonNull String accessToken) {
this(context, accessToken, new MapboxNavigationOptions());
}

/**
* Creates a new MapboxNavigation object.
*
* @param context {@link Context} used for various things internally, cannot be null.
* @param accessToken A valid Mapbox access token.
* @param options a {@link MapboxNavigationOptions} with your customized options.
* @since 0.2.0
*/
public MapboxNavigation(@NonNull Context context, @NonNull String accessToken,
@NonNull MapboxNavigationOptions options) {
Timber.d("MapboxNavigation initiated.");
this.context = context;
this.accessToken = accessToken;
this.options = options;
connection = new NavigationServiceConnection();
isBound = false;
navigationService = null;
snapToRoute = true;
profile = DirectionsCriteria.PROFILE_DRIVING_TRAFFIC;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't the current profile an option too? Because options can't change once you instantiated MapboxNavigation but profile can?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, eventually we will support the usage of different profiles which means until the user actual starts the navigation session, they should have the option to change the profile (they'll also need to get a new DirectionsResponse if the profiles changed).

alertLevelChangeListeners = new CopyOnWriteArrayList<>();
navigationEventListeners = new CopyOnWriteArrayList<>();
progressChangeListeners = new CopyOnWriteArrayList<>();
Expand Down Expand Up @@ -415,6 +439,7 @@ public void onServiceConnected(ComponentName componentName, IBinder service) {
NavigationService.LocalBinder binder = (NavigationService.LocalBinder) service;
navigationService = binder.getService();
navigationService.setLocationEngine(getLocationEngine());
navigationService.setOptions(options);
navigationService.setNavigationEventListeners(navigationEventListeners);

if (alertLevelChangeListeners != null) {
Expand Down
Loading