Update routing helper
This commit is contained in:
parent
20da399a5d
commit
a0055e2f08
6 changed files with 145 additions and 125 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue