use of com.mapbox.geojson.Point in project mapbox-navigation-android by mapbox.
the class OffRouteDetector method movingAwayFromManeuver.
/**
* Checks to see if the current point is moving away from the maneuver.
* <p>
* If the current point is farther away from the maneuver than the last point in the
* stack, add it to the stack.
* <p>
* If the stack if >= 3 distances, return true to fire an off-route event as it
* can be considered that the user is no longer going in the right direction.
*
* @param routeProgress for the upcoming step maneuver
* @param distancesAwayFromManeuver current stack of distances away
* @param stepPoints current step points being traveled along
* @param currentPoint to determine if moving away or not
* @return true if moving away from maneuver, false if not
*/
private static boolean movingAwayFromManeuver(RouteProgress routeProgress, RingBuffer<Integer> distancesAwayFromManeuver, List<Point> stepPoints, Point currentPoint) {
if (routeProgress.currentLegProgress().upComingStep() == null || stepPoints.isEmpty()) {
return false;
}
LineString stepLineString = LineString.fromLngLats(stepPoints);
Point maneuverPoint = stepPoints.get(stepPoints.size() - 1);
Point userPointOnStep = (Point) TurfMisc.nearestPointOnLine(currentPoint, stepPoints).geometry();
if (userPointOnStep == null || maneuverPoint.equals(userPointOnStep)) {
return false;
}
LineString remainingStepLineString = TurfMisc.lineSlice(userPointOnStep, maneuverPoint, stepLineString);
double userDistanceToManeuver = TurfMeasurement.length(remainingStepLineString, TurfConstants.UNIT_METERS);
boolean hasDistances = !distancesAwayFromManeuver.isEmpty();
boolean validOffRouteDistanceTraveled = hasDistances && distancesAwayFromManeuver.peekLast() - distancesAwayFromManeuver.peekFirst() < MINIMUM_BACKUP_DISTANCE_FOR_OFF_ROUTE;
boolean exceedsManeuverDistancesThreshold = validOffRouteDistanceTraveled && distancesAwayFromManeuver.size() >= 3;
if (exceedsManeuverDistancesThreshold) {
// User's moving away from maneuver position, thus offRoute.
return true;
}
if (distancesAwayFromManeuver.isEmpty()) {
distancesAwayFromManeuver.push((int) userDistanceToManeuver);
} else if (userDistanceToManeuver > distancesAwayFromManeuver.peek()) {
distancesAwayFromManeuver.push((int) userDistanceToManeuver);
} else {
// If we get a descending distance, reset the counter
distancesAwayFromManeuver.clear();
}
return false;
}
use of com.mapbox.geojson.Point in project mapbox-navigation-android by mapbox.
the class OffRouteDetector method isUserOffRoute.
/**
* Method in charge of running a series of test based on the device current location
* and the user progress along the route.
* <p>
* Test #1:
* Valid or invalid off-route. An off-route check can only continue if the device has received
* at least 1 location update (for comparison) and the user has traveled passed
* the {@link MapboxNavigationOptions#minimumDistanceBeforeRerouting()} checked against the last re-route location.
* <p>
* Test #2:
* Distance from the step. This test is checked against the max of the dynamic rerouting tolerance or the
* accuracy based tolerance. If this test passes, this method then also checks if there have been >= 3
* location updates moving away from the maneuver point. If false, this method will return false early.
* <p>
* Test #3:
* Checks if the user is close the upcoming step. At this point, the user is considered off-route.
* But, if the location update is within the {@link MapboxNavigationOptions#maneuverZoneRadius()} of the
* upcoming step, this method will return false as well as send fire {@link OffRouteCallback#onShouldIncreaseIndex()}
* to let the <tt>NavigationEngine</tt> know that the
* step index should be increased on the next location update.
*
* @return true if the users off-route, else false.
* @since 0.2.0
*/
@Override
public boolean isUserOffRoute(Location location, RouteProgress routeProgress, MapboxNavigationOptions options) {
if (!validOffRoute(location, options)) {
return false;
}
Point currentPoint = Point.fromLngLat(location.getLongitude(), location.getLatitude());
// Get distance from the current step to future point
LegStep currentStep = routeProgress.currentLegProgress().currentStep();
double distanceFromCurrentStep = userTrueDistanceFromStep(currentPoint, currentStep);
// Create off-route radius from the max of our dynamic or accuracy based tolerances
double offRouteRadius = createOffRouteRadius(location, routeProgress, options, currentPoint);
// Off route if this distance is greater than our offRouteRadius
boolean isOffRoute = distanceFromCurrentStep > offRouteRadius;
// If not offRoute at this point, do not continue with remaining logic
if (!isOffRoute) {
// moving away from the maneuver.
return isMovingAwayFromManeuver(location, routeProgress, distancesAwayFromManeuver, currentPoint);
}
// If the user is considered off-route at this point, but they are close to the upcoming step,
// do not send an off-route event and increment the step index to the upcoming step
LegStep upComingStep = routeProgress.currentLegProgress().upComingStep();
if (closeToUpcomingStep(options, callback, currentPoint, upComingStep)) {
return false;
}
// All checks have run, return true
updateLastReroutePoint(location);
return true;
}
use of com.mapbox.geojson.Point in project mapbox-navigation-android by mapbox.
the class MeasurementUtilsTest method userTrueDistanceFromStep_returnsZeroWhenCurrentStepAndPointEqualSame.
@Test
public void userTrueDistanceFromStep_returnsZeroWhenCurrentStepAndPointEqualSame() {
Point futurePoint = Point.fromLngLat(-95.367697, 29.758938);
List<Point> geometryPoints = new ArrayList<>();
geometryPoints.add(futurePoint);
double[] rawLocation = { 0, 0 };
LegStep step = getLegStep(rawLocation, geometryPoints);
double distance = MeasurementUtils.userTrueDistanceFromStep(futurePoint, step);
assertEquals(0d, distance, DELTA);
}
use of com.mapbox.geojson.Point in project mapbox-navigation-android by mapbox.
the class MeasurementUtilsTest method userTrueDistanceFromStep_onlyOnePointInLineStringStillMeasuresDistanceCorrectly.
@Test
public void userTrueDistanceFromStep_onlyOnePointInLineStringStillMeasuresDistanceCorrectly() {
Point futurePoint = Point.fromLngLat(-95.3676974, 29.7589382);
List<Point> geometryPoints = new ArrayList<>();
geometryPoints.add(Point.fromLngLat(-95.8427, 29.7757));
double[] rawLocation = { 0, 0 };
LegStep step = getLegStep(rawLocation, geometryPoints);
double distance = MeasurementUtils.userTrueDistanceFromStep(futurePoint, step);
assertEquals(45900.73617999494, distance, DELTA);
}
use of com.mapbox.geojson.Point in project mapbox-navigation-android by mapbox.
the class RerouteActivity method userOffRoute.
@Override
public void userOffRoute(Location location) {
Point newOrigin = Point.fromLngLat(location.getLongitude(), location.getLatitude());
getRoute(newOrigin, destination, location.getBearing());
Snackbar.make(contentLayout, "User Off Route", Snackbar.LENGTH_SHORT).show();
mapboxMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())));
}
Aggregations