diff --git a/OsmAnd/src/net/osmand/plus/NavigationService.java b/OsmAnd/src/net/osmand/plus/NavigationService.java index bd817cd450..789162eb99 100644 --- a/OsmAnd/src/net/osmand/plus/NavigationService.java +++ b/OsmAnd/src/net/osmand/plus/NavigationService.java @@ -210,7 +210,7 @@ public class NavigationService extends Service implements LocationListener { liveMonitoringHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getSpeed(), location.getAccuracy(), locationTime, settings); if(routingHelper.isFollowingMode()){ - routingHelper.setCurrentLocation(location); + routingHelper.setCurrentLocation(location, false); } } diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 09f7eba4b9..5ead7a4e10 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -573,6 +573,13 @@ public class OsmandSettings { public final OsmandPreference ROUTER_SERVICE = new EnumIntPreference("router_service", RouteService.OSMAND, RouteService.values()).makeProfile(); + public final CommonPreference 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 LEFT_SIDE_NAVIGATION = new BooleanPreference("left_side_navigation", false).makeGlobal(); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 51822acbc0..198427a4e6 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -267,7 +267,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe // if destination point was changed try to recalculate route 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); @@ -621,7 +621,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe final LatLon point = settings.getPointToNavigate(); if (point != null) { if (routingHelper.isRouteCalculated()) { - routingHelper.getVoiceRouter().announceCurrentDirection(routingHelper.getLastFixedLocation()); + routingHelper.getVoiceRouter().announceCurrentDirection(getLastKnownLocation()); } else { 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 // possibly keep using only for emulator case PointLocationLayer locationLayer = mapLayers.getLocationLayer(); - if (isRunningOnEmulator() - && locationLayer.getLastKnownLocation() != null) { + if (locationLayer.getLastKnownLocation() != null) { if (locationLayer.getLastKnownLocation().distanceTo(location) > 3) { float d = location.distanceTo(locationLayer.getLastKnownLocation()); 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().distanceTo(location) > 10 && !isRunningOnEmulator()){ - // very innacurate? + // very innacurate // location.setBearing(locationLayer.getLastKnownLocation().bearingTo(location)); } } @@ -772,6 +771,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe if (Log.isLoggable(LogUtil.TAG, Log.DEBUG)) { Log.d(LogUtil.TAG, "Location changed " + location.getProvider()); //$NON-NLS-1$ } + // 1. Logging services if (location != null) { // use because there is a bug on some devices with location.getTime() long locationTime = System.currentTimeMillis(); @@ -788,18 +788,25 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } } + + } + + if(location != null && isRunningOnEmulator()) { // only for emulator updateSpeedBearingEmulator(location); } + // 2. accessibility routing + navigationInfo.setLocation(location); + // 3. routing boolean enableSensorNavigation = routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get() ? location == null || !location.hasBearing() : false; registerUnregisterSensor(location, enableSensorNavigation); - + Location updatedLocation = location; if (routingHelper.isFollowingMode()) { if (location == null || !location.hasAccuracy() || location.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING) { // 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()) { // finished Message msg = Message.obtain(uiHandler, new Runnable() { @@ -811,7 +818,6 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe }); uiHandler.sendMessage(msg); } - location = updatedLocation; // Check with delay that gps location is not lost if (location != null && routingHelper.getLeftDistance() > 0) { 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) { - 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 (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); - } - } + updateAutoMapViewConfiguration(updatedLocation); } else { if (mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) { mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(false); } } + // When location is changed we need to refresh map in order to show movement! 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) { if (speed < 7f / 3.6) { return 0; @@ -915,7 +928,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } else { settings.clearPointToNavigate(); } - routingHelper.setFinalAndCurrentLocation(point, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute()); + routingHelper.setFinalAndCurrentLocation(point, getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); mapLayers.getNavigationLayer().setPointToNavigate(point); } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 9f2bc7e301..c2fb2d7ce5 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -910,7 +910,7 @@ public class MapActivityActions implements DialogProvider { public boolean onClick(MenuItem item) { if (mapActivity.getMapLayers().getNavigationLayer().getPointToNavigate() != null) { if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) { - routingHelper.setFinalAndCurrentLocation(null, routingHelper.getCurrentLocation(), routingHelper.getCurrentGPXRoute()); + routingHelper.setFinalAndCurrentLocation(null, mapActivity.getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); // restore default mode boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); mapActivity.updateApplicationModeSettings(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 7cb73164e4..8b83ca2c49 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -49,7 +49,9 @@ public class RoutingHelper { private RouteCalculationResult route = new RouteCalculationResult(""); private LatLon finalLocation; + private Location lastProjection; private Location lastFixedLocation; + private RouteRecalculationThread currentRunningJob; private long lastTimeEvaluatedRoute = 0; private int evalWaitInterval = 3000; @@ -64,6 +66,7 @@ public class RoutingHelper { private boolean makeUturnWhenPossible = false; private long makeUTwpDetected = 0; + public boolean makeUturnWhenPossible() { return makeUturnWhenPossible; } @@ -93,7 +96,7 @@ public class RoutingHelper { clearCurrentRoute(finalLocation); currentGPXRoute = gpxRoute; // to update route - setCurrentLocation(currentLocation); + setCurrentLocation(currentLocation, false); } @@ -117,7 +120,7 @@ public class RoutingHelper { settings.FOLLOW_THE_ROUTE.set(false); settings.FOLLOW_THE_GPX_ROUTE.set(null); // clear last fixed location - this.lastFixedLocation = null; + this.lastProjection = null; this.isFollowingMode = false; } } @@ -144,10 +147,6 @@ public class RoutingHelper { return finalLocation; } - public Location getLastFixedLocation() { - return lastFixedLocation; - } - public boolean isRouteCalculated(){ return route.isCalculated(); } @@ -156,8 +155,8 @@ public class RoutingHelper { return voiceRouter; } - public Location getCurrentLocation() { - return lastFixedLocation; + public Location getLastProjection(){ + return lastProjection; } 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; 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 { - float posTolerance = POSITION_TOLERANCE; - if(currentLocation.hasAccuracy()) { - posTolerance = POSITION_TOLERANCE / 2 + currentLocation.getAccuracy(); - } // 1. Update current route position status according to latest received location boolean finished = updateCurrentRouteStatus(currentLocation, posTolerance); if (finished) { @@ -221,46 +220,48 @@ public class RoutingHelper { // calculate projection of current location if (currentRoute > 0) { - double dist = getOrthogonalDistance(currentLocation, routeNodes.get(currentRoute - 1), routeNodes.get(currentRoute)); - double projectDist = mode == ApplicationMode.CAR ? posTolerance : posTolerance / 2; - locationProjection = new Location(locationProjection); - if (dist < projectDist) { - 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 - if (locationProjection.hasBearing()) { - float bearingTo = locationProjection.bearingTo(nextLocation); - locationProjection.setBearing(bearingTo); - } + 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 + if (locationProjection.hasBearing()) { + float bearingTo = locationProjection.bearingTo(nextLocation); + locationProjection.setBearing(bearingTo); } } } - lastFixedLocation = locationProjection; + lastFixedLocation = currentLocation; + lastProjection = locationProjection; } if (calculateRoute) { - recalculateRouteInBackground(lastFixedLocation, finalLocation, currentGPXRoute, + recalculateRouteInBackground(currentLocation, finalLocation, currentGPXRoute, 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(), loc.getLongitude(), from.getLatitude(), from.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(), loc.getLongitude(), from.getLatitude(), from.getLongitude(), to.getLatitude(), to.getLongitude()); } - private int lookAheadFindMinOrthogonalDistance(Location currentLocation, List routeNodes, int currentRoute, int iterations) { + private static int lookAheadFindMinOrthogonalDistance(Location currentLocation, List routeNodes, int currentRoute, int iterations) { double newDist; double dist = Double.POSITIVE_INFINITY; int index = currentRoute; @@ -353,9 +354,8 @@ public class RoutingHelper { return makeUturnWhenPossible; } boolean makeUturnWhenPossible = false; - if (currentLocation.hasBearing() || lastFixedLocation != null) { - float bearingMotion = currentLocation.hasBearing() ? currentLocation.getBearing() : lastFixedLocation - .bearingTo(currentLocation); + if (currentLocation.hasBearing()) { + float bearingMotion = currentLocation.getBearing() ; Location nextRoutePosition = route.getNextRouteLocation(); float bearingToRoute = currentLocation.bearingTo(nextRoutePosition); double diff = MapUtils.degreesDiff(bearingMotion, bearingToRoute); @@ -387,12 +387,12 @@ public class RoutingHelper { * the difference is more than 90 degrees */ public boolean checkWrongMovementDirection(Location currentLocation, Location nextRouteLocation) { - if ((currentLocation.hasBearing() || lastFixedLocation != null) && nextRouteLocation!= null) { - float bearingMotion = currentLocation.hasBearing() ? currentLocation.getBearing() : lastFixedLocation - .bearingTo(currentLocation); + // measuring without bearing could be really error prone (with last fixed location) + // this code has an effect on route recalculation which should be detected without mistakes + if (currentLocation.hasBearing() && nextRouteLocation != null) { + float bearingMotion = currentLocation.getBearing(); float bearingToRoute = currentLocation.bearingTo(nextRouteLocation); 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) { return true; } @@ -404,24 +404,24 @@ public class RoutingHelper { final boolean newRoute = !this.route.isCalculated(); route = res; if (isFollowingMode) { + if(lastFixedLocation != null) { + start = lastFixedLocation; + } // try remove false route-recalculated prompts by checking direction to second route node boolean wrongMovementDirection = false; - Location prev = res.getNextRouteLocation(); - if (prev != null) { - int i = 1; - while (res.getNextRouteLocation(i) != null && prev.distanceTo(start) < POSITION_TOLERANCE) { - prev = res.getNextRouteLocation(i); - i++; - } - // This check could be valid only for Online/GPX services - // because offline routing is aware of route directions - wrongMovementDirection = checkWrongMovementDirection(start, prev); - // set/reset evalWaitInterval only if new route is in forward direction - if (!wrongMovementDirection) { - evalWaitInterval = 3000; - } else { - evalWaitInterval = evalWaitInterval * 3 / 2; - evalWaitInterval = Math.min(evalWaitInterval, 120000); + List routeNodes = res.getImmutableLocations(); + if (routeNodes != null && !routeNodes.isEmpty()) { + int newCurrentRoute = lookAheadFindMinOrthogonalDistance(start, routeNodes, res.currentRoute, 15); + if (newCurrentRoute + 1 < routeNodes.size()) { + // This check is valid for Online/GPX services (offline routing is aware of route direction) + wrongMovementDirection = checkWrongMovementDirection(start, routeNodes.get(newCurrentRoute + 1)); + // set/reset evalWaitInterval only if new route is in forward direction + if (!wrongMovementDirection) { + 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){ - NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastFixedLocation, toSpeak); + NextDirectionInfo i = route.getNextRouteDirectionInfo(info, lastProjection, toSpeak); if(i != null) { - i.imminent = voiceRouter.calculateImminent(i.distanceTo, lastFixedLocation); + i.imminent = voiceRouter.calculateImminent(i.distanceTo, lastProjection); } return i; } @@ -476,9 +476,9 @@ public class RoutingHelper { public synchronized AlarmInfo getMostImportantAlarm(MetricsConstants mc, boolean showCameras){ float mxspeed = route.getCurrentMaxSpeed(); AlarmInfo speedAlarm = null; - if(mxspeed != 0 && lastFixedLocation != null && lastFixedLocation.hasSpeed()) { + if(mxspeed != 0 && lastProjection != null && lastProjection.hasSpeed()) { float delta = 5f/3.6f; - if(lastFixedLocation.getSpeed() > mxspeed + delta) { + if(lastProjection.getSpeed() > mxspeed + delta) { int speed; if(mc == MetricsConstants.KILOMETERS_AND_METERS) { speed = Math.round(mxspeed * 3.6f); @@ -488,7 +488,7 @@ public class RoutingHelper { speedAlarm = AlarmInfo.createSpeedLimit(speed); } } - return route.getMostImportantAlarm(lastFixedLocation, speedAlarm, showCameras); + return route.getMostImportantAlarm(lastProjection, speedAlarm, showCameras); } public String formatStreetName(String name, String ref) { diff --git a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java index 3eab15f7e9..9d0da52a39 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java @@ -3,7 +3,6 @@ package net.osmand.plus.views; import java.util.ArrayList; import java.util.List; -import net.osmand.osm.MapUtils; import net.osmand.plus.R; import net.osmand.plus.routing.RoutingHelper; import android.graphics.Canvas; @@ -66,8 +65,9 @@ public class RouteLayer extends OsmandMapLayer { } int w = view.getWidth(); int h = view.getHeight(); - if(helper.getCurrentLocation() != null && - view.isPointOnTheRotatedMap(helper.getCurrentLocation().getLatitude(), helper.getCurrentLocation().getLongitude())){ + Location lastProjection = helper.getLastProjection(); + if(lastProjection != null && + view.isPointOnTheRotatedMap(lastProjection.getLatitude(), lastProjection.getLongitude())){ boundsRect = new Rect(-w / 2, -h, 3 * w / 2, h); } else { 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) { points.clear(); boolean previousVisible = false; - Location lastFixedLocation = helper.getLastFixedLocation(); - if (lastFixedLocation != null) { - if (leftLongitude <= lastFixedLocation.getLongitude() && lastFixedLocation.getLongitude() <= rightLongitude - && bottomLatitude <= lastFixedLocation.getLatitude() && lastFixedLocation.getLatitude() <= topLatitude) { - points.add(lastFixedLocation); + Location lastProjection = helper.getLastProjection(); + if (lastProjection != null) { + if (leftLongitude <= lastProjection.getLongitude() && lastProjection.getLongitude() <= rightLongitude + && bottomLatitude <= lastProjection.getLatitude() && lastProjection.getLatitude() <= topLatitude) { + points.add(lastProjection); previousVisible = true; } } @@ -119,8 +119,8 @@ public class RouteLayer extends OsmandMapLayer { if (!previousVisible) { if (i > 0) { points.add(0, routeNodes.get(i - 1)); - } else if (lastFixedLocation != null) { - points.add(0, lastFixedLocation); + } else if (lastProjection != null) { + points.add(0, lastProjection); } } previousVisible = true;