public synchronized void clearCurrentRoute( LatLon newFinalLocation, List<LatLon> newIntermediatePoints) { route = new RouteCalculationResult(""); makeUturnWhenPossible = false; evalWaitInterval = 3000; app.runInUIThread( new Runnable() { @Override public void run() { for (IRouteInformationListener l : listeners) { l.routeWasCancelled(); } } }); this.finalLocation = newFinalLocation; this.intermediatePoints = newIntermediatePoints; if (currentRunningJob instanceof RouteRecalculationThread) { ((RouteRecalculationThread) currentRunningJob).stopCalculation(); } if (newFinalLocation == null) { settings.FOLLOW_THE_ROUTE.set(false); settings.FOLLOW_THE_GPX_ROUTE.set(null); // clear last fixed location this.lastProjection = null; setFollowingMode(false); } }
private Location setCurrentLocation( Location currentLocation, boolean returnUpdatedLocation, RouteCalculationResult previousRoute) { Location locationProjection = currentLocation; if (finalLocation == null || currentLocation == null) { makeUturnWhenPossible = false; return locationProjection; } float posTolerance = POSITION_TOLERANCE; if (currentLocation.hasAccuracy()) { posTolerance = POSITION_TOLERANCE / 2 + currentLocation.getAccuracy(); } boolean calculateRoute = false; synchronized (this) { // 0. Route empty or needs to be extended? Then re-calculate route. if (route.isEmpty()) { calculateRoute = true; } else { // 1. Update current route position status according to latest received location boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance); if (finished) { return null; } List<Location> routeNodes = route.getImmutableAllLocations(); int currentRoute = route.currentRoute; // 2. Analyze if we need to recalculate route // >100m off current route (sideways) if (currentRoute > 0) { double dist = getOrthogonalDistance( currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute)); if (dist > 1.7 * posTolerance) { log.info("Recalculate route, because correlation : " + dist); // $NON-NLS-1$ calculateRoute = true; } if (dist > 350) { voiceRouter.announceOffRoute(dist); } } // 3. Identify wrong movement direction Location next = route.getNextRouteLocation(); boolean wrongMovementDirection = checkWrongMovementDirection(currentLocation, next); if (wrongMovementDirection && currentLocation.distanceTo(routeNodes.get(currentRoute)) > 2 * posTolerance) { log.info( "Recalculate route, because wrong movement direction: " + currentLocation.distanceTo(routeNodes.get(currentRoute))); // $NON-NLS-1$ calculateRoute = true; } // 4. Identify if UTurn is needed boolean uTurnIsNeeded = identifyUTurnIsNeeded(currentLocation, posTolerance); // 5. Update Voice router if (isFollowingMode) { // don't update in route planing mode announceGpxWaypoints(currentLocation); boolean inRecalc = calculateRoute || isRouteBeingCalculated(); if (!inRecalc && !uTurnIsNeeded && !wrongMovementDirection) { voiceRouter.updateStatus(currentLocation, false); } else if (uTurnIsNeeded) { voiceRouter.makeUTStatus(); } } // calculate projection of current location if (currentRoute > 0) { locationProjection = new Location(currentLocation); Location nextLocation = routeNodes.get(currentRoute); LatLon project = getProject( currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute)); locationProjection.setLatitude(project.getLatitude()); locationProjection.setLongitude(project.getLongitude()); // we need to update bearing too float bearingTo = locationProjection.bearingTo(nextLocation); locationProjection.setBearing(bearingTo); } } lastFixedLocation = currentLocation; lastProjection = locationProjection; } if (calculateRoute) { recalculateRouteInBackground( false, currentLocation, finalLocation, intermediatePoints, currentGPXRoute, previousRoute.isCalculated() ? previousRoute : null); } else if (currentRunningJob != null && currentRunningJob instanceof RouteRecalculationThread) { RouteRecalculationThread thread = (RouteRecalculationThread) currentRunningJob; thread.stopCalculation(); } double projectDist = mode != null && mode.hasFastSpeed() ? posTolerance : posTolerance / 2; if (returnUpdatedLocation && locationProjection != null && currentLocation.distanceTo(locationProjection) < projectDist) { return locationProjection; } else { return currentLocation; } }