Update routing helper

This commit is contained in:
Victor Shcherb 2012-08-30 21:19:50 +02:00
parent 20da399a5d
commit a0055e2f08
6 changed files with 145 additions and 125 deletions

View file

@ -210,7 +210,7 @@ public class NavigationService extends Service implements LocationListener {
liveMonitoringHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), liveMonitoringHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(),
location.getSpeed(), location.getAccuracy(), locationTime, settings); location.getSpeed(), location.getAccuracy(), locationTime, settings);
if(routingHelper.isFollowingMode()){ if(routingHelper.isFollowingMode()){
routingHelper.setCurrentLocation(location); routingHelper.setCurrentLocation(location, false);
} }
} }

View file

@ -573,6 +573,13 @@ public class OsmandSettings {
public final OsmandPreference<RouteService> ROUTER_SERVICE = public final OsmandPreference<RouteService> ROUTER_SERVICE =
new EnumIntPreference<RouteService>("router_service", RouteService.OSMAND, RouteService.values()).makeProfile(); new EnumIntPreference<RouteService>("router_service", RouteService.OSMAND, RouteService.values()).makeProfile();
public final CommonPreference<Boolean> SNAP_TO_ROAD = new BooleanPreference("snap_to_road", true).makeProfile().cache();
{
SNAP_TO_ROAD.setModeDefaultValue(ApplicationMode.CAR, true);
SNAP_TO_ROAD.setModeDefaultValue(ApplicationMode.BICYCLE, false);
SNAP_TO_ROAD.setModeDefaultValue(ApplicationMode.PEDESTRIAN, false);
}
public final CommonPreference<Boolean> LEFT_SIDE_NAVIGATION = new BooleanPreference("left_side_navigation", false).makeGlobal(); public final CommonPreference<Boolean> LEFT_SIDE_NAVIGATION = new BooleanPreference("left_side_navigation", false).makeGlobal();

View file

@ -267,7 +267,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
// if destination point was changed try to recalculate route // if destination point was changed try to recalculate route
if (routingHelper.isFollowingMode() && !Algoritms.objectEquals(settings.getPointToNavigate(), routingHelper.getFinalLocation())) { if (routingHelper.isFollowingMode() && !Algoritms.objectEquals(settings.getPointToNavigate(), routingHelper.getFinalLocation())) {
routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute()); routingHelper.setFinalAndCurrentLocation(settings.getPointToNavigate(), getLastKnownLocation(), routingHelper.getCurrentGPXRoute());
} }
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
@ -621,7 +621,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
final LatLon point = settings.getPointToNavigate(); final LatLon point = settings.getPointToNavigate();
if (point != null) { if (point != null) {
if (routingHelper.isRouteCalculated()) { if (routingHelper.isRouteCalculated()) {
routingHelper.getVoiceRouter().announceCurrentDirection(routingHelper.getLastFixedLocation()); routingHelper.getVoiceRouter().announceCurrentDirection(getLastKnownLocation());
} else { } else {
AccessibleToast.makeText(this, getNavigationHint(point), Toast.LENGTH_LONG).show(); AccessibleToast.makeText(this, getNavigationHint(point), Toast.LENGTH_LONG).show();
} }
@ -738,8 +738,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
// For network/gps it's bad way (not accurate). It's widely used for testing purposes // For network/gps it's bad way (not accurate). It's widely used for testing purposes
// possibly keep using only for emulator case // possibly keep using only for emulator case
PointLocationLayer locationLayer = mapLayers.getLocationLayer(); PointLocationLayer locationLayer = mapLayers.getLocationLayer();
if (isRunningOnEmulator() if (locationLayer.getLastKnownLocation() != null) {
&& locationLayer.getLastKnownLocation() != null) {
if (locationLayer.getLastKnownLocation().distanceTo(location) > 3) { if (locationLayer.getLastKnownLocation().distanceTo(location) > 3) {
float d = location.distanceTo(locationLayer.getLastKnownLocation()); float d = location.distanceTo(locationLayer.getLastKnownLocation());
long time = location.getTime() - locationLayer.getLastKnownLocation().getTime(); long time = location.getTime() - locationLayer.getLastKnownLocation().getTime();
@ -758,7 +757,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
} }
if(locationLayer.getLastKnownLocation() != null && !location.hasBearing()){ if(locationLayer.getLastKnownLocation() != null && !location.hasBearing()){
if(locationLayer.getLastKnownLocation().distanceTo(location) > 10 && !isRunningOnEmulator()){ if(locationLayer.getLastKnownLocation().distanceTo(location) > 10 && !isRunningOnEmulator()){
// very innacurate? // very innacurate
// location.setBearing(locationLayer.getLastKnownLocation().bearingTo(location)); // location.setBearing(locationLayer.getLastKnownLocation().bearingTo(location));
} }
} }
@ -772,6 +771,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
if (Log.isLoggable(LogUtil.TAG, Log.DEBUG)) { if (Log.isLoggable(LogUtil.TAG, Log.DEBUG)) {
Log.d(LogUtil.TAG, "Location changed " + location.getProvider()); //$NON-NLS-1$ Log.d(LogUtil.TAG, "Location changed " + location.getProvider()); //$NON-NLS-1$
} }
// 1. Logging services
if (location != null) { if (location != null) {
// use because there is a bug on some devices with location.getTime() // use because there is a bug on some devices with location.getTime()
long locationTime = System.currentTimeMillis(); long locationTime = System.currentTimeMillis();
@ -788,18 +788,25 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
} }
} }
}
if(location != null && isRunningOnEmulator()) {
// only for emulator // only for emulator
updateSpeedBearingEmulator(location); updateSpeedBearingEmulator(location);
} }
// 2. accessibility routing
navigationInfo.setLocation(location);
// 3. routing
boolean enableSensorNavigation = routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get() ? location == null boolean enableSensorNavigation = routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get() ? location == null
|| !location.hasBearing() : false; || !location.hasBearing() : false;
registerUnregisterSensor(location, enableSensorNavigation); registerUnregisterSensor(location, enableSensorNavigation);
Location updatedLocation = location;
if (routingHelper.isFollowingMode()) { if (routingHelper.isFollowingMode()) {
if (location == null || !location.hasAccuracy() || location.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING) { if (location == null || !location.hasAccuracy() || location.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING) {
// Update routing position and get location for sticking mode // Update routing position and get location for sticking mode
Location updatedLocation = routingHelper.setCurrentLocation(location); updatedLocation = routingHelper.setCurrentLocation(location, settings.SNAP_TO_ROAD.get());
if(!routingHelper.isFollowingMode()) { if(!routingHelper.isFollowingMode()) {
// finished // finished
Message msg = Message.obtain(uiHandler, new Runnable() { Message msg = Message.obtain(uiHandler, new Runnable() {
@ -811,7 +818,6 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
}); });
uiHandler.sendMessage(msg); uiHandler.sendMessage(msg);
} }
location = updatedLocation;
// Check with delay that gps location is not lost // Check with delay that gps location is not lost
if (location != null && routingHelper.getLeftDistance() > 0) { if (location != null && routingHelper.getLeftDistance() > 0) {
final long fixTime = location.getTime(); final long fixTime = location.getTime();
@ -834,60 +840,67 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
} }
} }
} }
mapLayers.getLocationLayer().setLastKnownLocation(location);
navigationInfo.setLocation(location);
// Update information
mapLayers.getLocationLayer().setLastKnownLocation(updatedLocation);
if (location != null) { if (location != null) {
long now = System.currentTimeMillis(); updateAutoMapViewConfiguration(updatedLocation);
if (isMapLinkedToLocation()) {
if (settings.AUTO_ZOOM_MAP.get() && location.hasSpeed()) {
float zdelta = defineZoomFromSpeed(location.getSpeed());
if (Math.abs(zdelta) >= OsmandMapTileView.ZOOM_DELTA_1) {
// prevent ui hysteresis (check time interval for autozoom)
if (zdelta >= 2) {
// decrease a bit
zdelta -= 3 * OsmandMapTileView.ZOOM_DELTA_1;
} else if (zdelta <= -2) {
// decrease a bit
zdelta += 3 * OsmandMapTileView.ZOOM_DELTA_1;
}
if (now - lastTimeAutoZooming > 4500) {
lastTimeAutoZooming = now;
mapView.setZoom(mapView.getFloatZoom() + zdelta);
// mapView.getAnimatedDraggingThread().startZooming(mapView.getFloatZoom() + zdelta, false);
}
}
}
int currentMapRotation = settings.ROTATE_MAP.get();
if (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) {
if (location.hasBearing()) {
mapView.setRotate(-location.getBearing());
} else if (routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get()) {
if (Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -previousSensorValue)) > 15
&& now - lastTimeSensorRotation > 1500) {
lastTimeSensorRotation = now;
mapView.setRotate(-previousSensorValue);
}
}
}
mapView.setLatLon(location.getLatitude(), location.getLongitude());
} else {
if (!mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) {
mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(true);
}
if (settings.AUTO_FOLLOW_ROUTE.get() > 0 && routingHelper.isFollowingMode() && !uiHandler.hasMessages(AUTO_FOLLOW_MSG_ID)) {
backToLocationWithDelay(1);
}
}
} else { } else {
if (mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) { if (mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) {
mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(false); mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(false);
} }
} }
// When location is changed we need to refresh map in order to show movement! // When location is changed we need to refresh map in order to show movement!
mapView.refreshMap(); mapView.refreshMap();
} }
private void updateAutoMapViewConfiguration(Location location) {
long now = System.currentTimeMillis();
if (isMapLinkedToLocation()) {
if (settings.AUTO_ZOOM_MAP.get() && location.hasSpeed()) {
float zdelta = defineZoomFromSpeed(location.getSpeed());
if (Math.abs(zdelta) >= OsmandMapTileView.ZOOM_DELTA_1) {
// prevent ui hysteresis (check time interval for autozoom)
if (zdelta >= 2) {
// decrease a bit
zdelta -= 3 * OsmandMapTileView.ZOOM_DELTA_1;
} else if (zdelta <= -2) {
// decrease a bit
zdelta += 3 * OsmandMapTileView.ZOOM_DELTA_1;
}
if (now - lastTimeAutoZooming > 4500) {
lastTimeAutoZooming = now;
mapView.setZoom(mapView.getFloatZoom() + zdelta);
// mapView.getAnimatedDraggingThread().startZooming(mapView.getFloatZoom() + zdelta, false);
}
}
}
int currentMapRotation = settings.ROTATE_MAP.get();
if (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) {
if (location.hasBearing()) {
mapView.setRotate(-location.getBearing());
} else if (routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get()) {
if (previousSensorValue != 0 && Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -previousSensorValue)) > 15) {
if(now - lastTimeSensorRotation > 1500 && now - lastTimeSensorRotation < 15000) {
lastTimeSensorRotation = now;
mapView.setRotate(-previousSensorValue);
}
}
}
}
mapView.setLatLon(location.getLatitude(), location.getLongitude());
} else {
if (!mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) {
mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(true);
}
if (settings.AUTO_FOLLOW_ROUTE.get() > 0 && routingHelper.isFollowingMode() && !uiHandler.hasMessages(AUTO_FOLLOW_MSG_ID)) {
backToLocationWithDelay(1);
}
}
}
public float defineZoomFromSpeed(float speed) { public float defineZoomFromSpeed(float speed) {
if (speed < 7f / 3.6) { if (speed < 7f / 3.6) {
return 0; return 0;
@ -915,7 +928,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
} else { } else {
settings.clearPointToNavigate(); settings.clearPointToNavigate();
} }
routingHelper.setFinalAndCurrentLocation(point, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute()); routingHelper.setFinalAndCurrentLocation(point, getLastKnownLocation(), routingHelper.getCurrentGPXRoute());
mapLayers.getNavigationLayer().setPointToNavigate(point); mapLayers.getNavigationLayer().setPointToNavigate(point);
} }

View file

@ -910,7 +910,7 @@ public class MapActivityActions implements DialogProvider {
public boolean onClick(MenuItem item) { public boolean onClick(MenuItem item) {
if (mapActivity.getMapLayers().getNavigationLayer().getPointToNavigate() != null) { if (mapActivity.getMapLayers().getNavigationLayer().getPointToNavigate() != null) {
if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) { if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) {
routingHelper.setFinalAndCurrentLocation(null, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute()); routingHelper.setFinalAndCurrentLocation(null, mapActivity.getLastKnownLocation(), routingHelper.getCurrentGPXRoute());
// restore default mode // restore default mode
boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get());
mapActivity.updateApplicationModeSettings(); mapActivity.updateApplicationModeSettings();

View file

@ -49,7 +49,9 @@ public class RoutingHelper {
private RouteCalculationResult route = new RouteCalculationResult(""); private RouteCalculationResult route = new RouteCalculationResult("");
private LatLon finalLocation; private LatLon finalLocation;
private Location lastProjection;
private Location lastFixedLocation; private Location lastFixedLocation;
private RouteRecalculationThread currentRunningJob; private RouteRecalculationThread currentRunningJob;
private long lastTimeEvaluatedRoute = 0; private long lastTimeEvaluatedRoute = 0;
private int evalWaitInterval = 3000; private int evalWaitInterval = 3000;
@ -64,6 +66,7 @@ public class RoutingHelper {
private boolean makeUturnWhenPossible = false; private boolean makeUturnWhenPossible = false;
private long makeUTwpDetected = 0; private long makeUTwpDetected = 0;
public boolean makeUturnWhenPossible() { public boolean makeUturnWhenPossible() {
return makeUturnWhenPossible; return makeUturnWhenPossible;
} }
@ -93,7 +96,7 @@ public class RoutingHelper {
clearCurrentRoute(finalLocation); clearCurrentRoute(finalLocation);
currentGPXRoute = gpxRoute; currentGPXRoute = gpxRoute;
// to update route // to update route
setCurrentLocation(currentLocation); setCurrentLocation(currentLocation, false);
} }
@ -117,7 +120,7 @@ public class RoutingHelper {
settings.FOLLOW_THE_ROUTE.set(false); settings.FOLLOW_THE_ROUTE.set(false);
settings.FOLLOW_THE_GPX_ROUTE.set(null); settings.FOLLOW_THE_GPX_ROUTE.set(null);
// clear last fixed location // clear last fixed location
this.lastFixedLocation = null; this.lastProjection = null;
this.isFollowingMode = false; this.isFollowingMode = false;
} }
} }
@ -144,10 +147,6 @@ public class RoutingHelper {
return finalLocation; return finalLocation;
} }
public Location getLastFixedLocation() {
return lastFixedLocation;
}
public boolean isRouteCalculated(){ public boolean isRouteCalculated(){
return route.isCalculated(); return route.isCalculated();
} }
@ -156,8 +155,8 @@ public class RoutingHelper {
return voiceRouter; return voiceRouter;
} }
public Location getCurrentLocation() { public Location getLastProjection(){
return lastFixedLocation; return lastProjection;
} }
public void addListener(IRouteInformationListener l){ public void addListener(IRouteInformationListener l){
@ -169,22 +168,22 @@ public class RoutingHelper {
} }
public Location setCurrentLocation(Location currentLocation) { public Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation ) {
Location locationProjection = currentLocation; Location locationProjection = currentLocation;
if (finalLocation == null || currentLocation == null) { if (finalLocation == null || currentLocation == null) {
makeUturnWhenPossible = false; makeUturnWhenPossible = false;
return locationProjection; return locationProjection;
} }
float posTolerance = POSITION_TOLERANCE;
if(currentLocation.hasAccuracy()) {
posTolerance = POSITION_TOLERANCE / 2 + currentLocation.getAccuracy();
}
boolean calculateRoute = false; boolean calculateRoute = false;
synchronized (this) { synchronized (this) {
// 0. Route empty or needs to be extended? Then re-calculate route. // 0. Route empty or needs to be extended? Then re-calculate route.
if(route.isEmpty()) { if(route.isEmpty()) {
calculateRoute = true; calculateRoute = true;
} else { } else {
float posTolerance = POSITION_TOLERANCE;
if(currentLocation.hasAccuracy()) {
posTolerance = POSITION_TOLERANCE / 2 + currentLocation.getAccuracy();
}
// 1. Update current route position status according to latest received location // 1. Update current route position status according to latest received location
boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance); boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance);
if (finished) { if (finished) {
@ -221,46 +220,48 @@ public class RoutingHelper {
// calculate projection of current location // calculate projection of current location
if (currentRoute > 0) { if (currentRoute > 0) {
double dist = getOrthogonalDistance(currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute)); locationProjection = new Location(currentLocation);
double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2; Location nextLocation = routeNodes.get(currentRoute);
locationProjection = new Location(locationProjection); LatLon project = getProject(currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute));
if (dist < projectDist) {
Location nextLocation = routeNodes.get(currentRoute); locationProjection.setLatitude(project.getLatitude());
LatLon project = getProject(currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute)); locationProjection.setLongitude(project.getLongitude());
// we need to update bearing too
locationProjection.setLatitude(project.getLatitude()); if (locationProjection.hasBearing()) {
locationProjection.setLongitude(project.getLongitude()); float bearingTo = locationProjection.bearingTo(nextLocation);
// we need to update bearing too locationProjection.setBearing(bearingTo);
if (locationProjection.hasBearing()) {
float bearingTo = locationProjection.bearingTo(nextLocation);
locationProjection.setBearing(bearingTo);
}
} }
} }
} }
lastFixedLocation = locationProjection; lastFixedLocation = currentLocation;
lastProjection = locationProjection;
} }
if (calculateRoute) { if (calculateRoute) {
recalculateRouteInBackground(lastFixedLocation, finalLocation, currentGPXRoute, recalculateRouteInBackground(currentLocation, finalLocation, currentGPXRoute,
route.isCalculated()? route : null); route.isCalculated()? route : null);
} }
return locationProjection; double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2;
if(returnUpdatedLocation && currentLocation.distanceTo(locationProjection) < projectDist) {
return locationProjection;
} else {
return currentLocation;
}
} }
private double getOrthogonalDistance(Location loc, Location from, Location to) { private static double getOrthogonalDistance(Location loc, Location from, Location to) {
return MapUtils.getOrthogonalDistance(loc.getLatitude(), return MapUtils.getOrthogonalDistance(loc.getLatitude(),
loc.getLongitude(), from.getLatitude(), from.getLongitude(), loc.getLongitude(), from.getLatitude(), from.getLongitude(),
to.getLatitude(), to.getLongitude()); to.getLatitude(), to.getLongitude());
} }
private LatLon getProject(Location loc, Location from, Location to) { private static LatLon getProject(Location loc, Location from, Location to) {
return MapUtils.getProjection(loc.getLatitude(), return MapUtils.getProjection(loc.getLatitude(),
loc.getLongitude(), from.getLatitude(), from.getLongitude(), loc.getLongitude(), from.getLatitude(), from.getLongitude(),
to.getLatitude(), to.getLongitude()); to.getLatitude(), to.getLongitude());
} }
private int lookAheadFindMinOrthogonalDistance(Location currentLocation, List<Location> routeNodes, int currentRoute, int iterations) { private static int lookAheadFindMinOrthogonalDistance(Location currentLocation, List<Location> routeNodes, int currentRoute, int iterations) {
double newDist; double newDist;
double dist = Double.POSITIVE_INFINITY; double dist = Double.POSITIVE_INFINITY;
int index = currentRoute; int index = currentRoute;
@ -353,9 +354,8 @@ public class RoutingHelper {
return makeUturnWhenPossible; return makeUturnWhenPossible;
} }
boolean makeUturnWhenPossible = false; boolean makeUturnWhenPossible = false;
if (currentLocation.hasBearing() || lastFixedLocation != null) { if (currentLocation.hasBearing()) {
float bearingMotion = currentLocation.hasBearing() ? currentLocation.getBearing() : lastFixedLocation float bearingMotion = currentLocation.getBearing() ;
.bearingTo(currentLocation);
Location nextRoutePosition = route.getNextRouteLocation(); Location nextRoutePosition = route.getNextRouteLocation();
float bearingToRoute = currentLocation.bearingTo(nextRoutePosition); float bearingToRoute = currentLocation.bearingTo(nextRoutePosition);
double diff = MapUtils.degreesDiff(bearingMotion, bearingToRoute); double diff = MapUtils.degreesDiff(bearingMotion, bearingToRoute);
@ -387,12 +387,12 @@ public class RoutingHelper {
* the difference is more than 90 degrees * the difference is more than 90 degrees
*/ */
public boolean checkWrongMovementDirection(Location currentLocation, Location nextRouteLocation) { public boolean checkWrongMovementDirection(Location currentLocation, Location nextRouteLocation) {
if ((currentLocation.hasBearing() || lastFixedLocation != null) && nextRouteLocation!= null) { // measuring without bearing could be really error prone (with last fixed location)
float bearingMotion = currentLocation.hasBearing() ? currentLocation.getBearing() : lastFixedLocation // this code has an effect on route recalculation which should be detected without mistakes
.bearingTo(currentLocation); if (currentLocation.hasBearing() && nextRouteLocation != null) {
float bearingMotion = currentLocation.getBearing();
float bearingToRoute = currentLocation.bearingTo(nextRouteLocation); float bearingToRoute = currentLocation.bearingTo(nextRouteLocation);
double diff = MapUtils.degreesDiff(bearingMotion, bearingToRoute); double diff = MapUtils.degreesDiff(bearingMotion, bearingToRoute);
// 6. Suppress turn prompt if prescribed direction of motion is between 45 and 135 degrees off
if (Math.abs(diff) > 60f) { if (Math.abs(diff) > 60f) {
return true; return true;
} }
@ -404,24 +404,24 @@ public class RoutingHelper {
final boolean newRoute = !this.route.isCalculated(); final boolean newRoute = !this.route.isCalculated();
route = res; route = res;
if (isFollowingMode) { if (isFollowingMode) {
if(lastFixedLocation != null) {
start = lastFixedLocation;
}
// try remove false route-recalculated prompts by checking direction to second route node // try remove false route-recalculated prompts by checking direction to second route node
boolean wrongMovementDirection = false; boolean wrongMovementDirection = false;
Location prev = res.getNextRouteLocation(); List<Location> routeNodes = res.getImmutableLocations();
if (prev != null) { if (routeNodes != null && !routeNodes.isEmpty()) {
int i = 1; int newCurrentRoute = lookAheadFindMinOrthogonalDistance(start, routeNodes, res.currentRoute, 15);
while (res.getNextRouteLocation(i) != null && prev.distanceTo(start) < POSITION_TOLERANCE) { if (newCurrentRoute + 1 < routeNodes.size()) {
prev = res.getNextRouteLocation(i); // This check is valid for Online/GPX services (offline routing is aware of route direction)
i++; wrongMovementDirection = checkWrongMovementDirection(start, routeNodes.get(newCurrentRoute + 1));
} // set/reset evalWaitInterval only if new route is in forward direction
// This check could be valid only for Online/GPX services if (!wrongMovementDirection) {
// because offline routing is aware of route directions evalWaitInterval = 3000;
wrongMovementDirection = checkWrongMovementDirection(start, prev); } else {
// set/reset evalWaitInterval only if new route is in forward direction evalWaitInterval = evalWaitInterval * 3 / 2;
if (!wrongMovementDirection) { evalWaitInterval = Math.min(evalWaitInterval, 120000);
evalWaitInterval = 3000; }
} else {
evalWaitInterval = evalWaitInterval * 3 / 2;
evalWaitInterval = Math.min(evalWaitInterval, 120000);
} }
} }
@ -466,9 +466,9 @@ public class RoutingHelper {
} }
public synchronized NextDirectionInfo getNextRouteDirectionInfo(NextDirectionInfo info, boolean toSpeak){ public synchronized NextDirectionInfo getNextRouteDirectionInfo(NextDirectionInfo info, boolean toSpeak){
NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastFixedLocation, toSpeak); NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastProjection, toSpeak);
if(i != null) { if(i != null) {
i.imminent = voiceRouter.calculateImminent(i.distanceTo, lastFixedLocation); i.imminent = voiceRouter.calculateImminent(i.distanceTo, lastProjection);
} }
return i; return i;
} }
@ -476,9 +476,9 @@ public class RoutingHelper {
public synchronized AlarmInfo getMostImportantAlarm(MetricsConstants mc, boolean showCameras){ public synchronized AlarmInfo getMostImportantAlarm(MetricsConstants mc, boolean showCameras){
float mxspeed = route.getCurrentMaxSpeed(); float mxspeed = route.getCurrentMaxSpeed();
AlarmInfo speedAlarm = null; AlarmInfo speedAlarm = null;
if(mxspeed != 0 && lastFixedLocation != null && lastFixedLocation.hasSpeed()) { if(mxspeed != 0 && lastProjection != null && lastProjection.hasSpeed()) {
float delta = 5f/3.6f; float delta = 5f/3.6f;
if(lastFixedLocation.getSpeed() > mxspeed + delta) { if(lastProjection.getSpeed() > mxspeed + delta) {
int speed; int speed;
if(mc == MetricsConstants.KILOMETERS_AND_METERS) { if(mc == MetricsConstants.KILOMETERS_AND_METERS) {
speed = Math.round(mxspeed * 3.6f); speed = Math.round(mxspeed * 3.6f);
@ -488,7 +488,7 @@ public class RoutingHelper {
speedAlarm = AlarmInfo.createSpeedLimit(speed); speedAlarm = AlarmInfo.createSpeedLimit(speed);
} }
} }
return route.getMostImportantAlarm(lastFixedLocation, speedAlarm, showCameras); return route.getMostImportantAlarm(lastProjection, speedAlarm, showCameras);
} }
public String formatStreetName(String name, String ref) { public String formatStreetName(String name, String ref) {

View file

@ -3,7 +3,6 @@ package net.osmand.plus.views;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.osmand.osm.MapUtils;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import android.graphics.Canvas; import android.graphics.Canvas;
@ -66,8 +65,9 @@ public class RouteLayer extends OsmandMapLayer {
} }
int w = view.getWidth(); int w = view.getWidth();
int h = view.getHeight(); int h = view.getHeight();
if(helper.getCurrentLocation() != null && Location lastProjection = helper.getLastProjection();
view.isPointOnTheRotatedMap(helper.getCurrentLocation().getLatitude(), helper.getCurrentLocation().getLongitude())){ if(lastProjection != null &&
view.isPointOnTheRotatedMap(lastProjection.getLatitude(), lastProjection.getLongitude())){
boundsRect = new Rect(-w / 2, -h, 3 * w / 2, h); boundsRect = new Rect(-w / 2, -h, 3 * w / 2, h);
} else { } else {
boundsRect = new Rect(0, 0, w, h); boundsRect = new Rect(0, 0, w, h);
@ -102,11 +102,11 @@ public class RouteLayer extends OsmandMapLayer {
public synchronized void fillLocationsToShow(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) { public synchronized void fillLocationsToShow(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) {
points.clear(); points.clear();
boolean previousVisible = false; boolean previousVisible = false;
Location lastFixedLocation = helper.getLastFixedLocation(); Location lastProjection = helper.getLastProjection();
if (lastFixedLocation != null) { if (lastProjection != null) {
if (leftLongitude <= lastFixedLocation.getLongitude() && lastFixedLocation.getLongitude() <= rightLongitude if (leftLongitude <= lastProjection.getLongitude() && lastProjection.getLongitude() <= rightLongitude
&& bottomLatitude <= lastFixedLocation.getLatitude() && lastFixedLocation.getLatitude() <= topLatitude) { && bottomLatitude <= lastProjection.getLatitude() && lastProjection.getLatitude() <= topLatitude) {
points.add(lastFixedLocation); points.add(lastProjection);
previousVisible = true; previousVisible = true;
} }
} }
@ -119,8 +119,8 @@ public class RouteLayer extends OsmandMapLayer {
if (!previousVisible) { if (!previousVisible) {
if (i > 0) { if (i > 0) {
points.add(0, routeNodes.get(i - 1)); points.add(0, routeNodes.get(i - 1));
} else if (lastFixedLocation != null) { } else if (lastProjection != null) {
points.add(0, lastFixedLocation); points.add(0, lastProjection);
} }
} }
previousVisible = true; previousVisible = true;