Fix routing helper to support points

This commit is contained in:
Victor Shcherb 2020-02-17 17:06:04 +01:00
parent 3629ee40a2
commit 1c7c254718
5 changed files with 92 additions and 17 deletions

View file

@ -57,7 +57,23 @@ public class MapUtils {
// Scalar multiplication between (AB, AC)
return (xB - xA) * (xC - xA) + (yB - yA) * (yC - yA);
}
public static Location calculateMidPoint(Location s1, Location s2) {
double lat1 = s1.getLatitude() / 180 * Math.PI;
double lon1 = s1.getLongitude() / 180 * Math.PI;
double lat2 = s2.getLatitude() / 180 * Math.PI;
double lon2 = s2.getLongitude() / 180 * Math.PI;
double Bx = Math.cos(lat2) * Math.cos(lon2 - lon1);
double By = Math.cos(lat2) * Math.sin(lon2 - lon1);
double latMid = Math.atan2(Math.sin(lat1) + Math.sin(lat2),
Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
double lonMid = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
Location r = new Location("");
r.setLatitude(MapUtils.checkLatitude(latMid * 180 / Math.PI));
r.setLongitude(MapUtils.checkLongitude(lonMid * 180 / Math.PI));
return r;
}
public static LatLon calculateMidPoint(LatLon s1, LatLon s2) {
double lat1 = s1.getLatitude() / 180 * Math.PI;
double lon1 = s1.getLongitude() / 180 * Math.PI;

View file

@ -20,7 +20,6 @@ public class RouteCalculationParams {
public Location currentLocation;
public OsmandApplication ctx;
public RoutingContext cachedRoutingContext;
public ApplicationMode mode;
public GPXRouteParams gpxRoute;
public RouteCalculationResult previousToRecalculate;
@ -35,7 +34,6 @@ public class RouteCalculationParams {
public RouteCalculationProgressCallback calculationProgressCallback;
public RouteCalculationResultListener resultListener;
public boolean showOriginalRoute;
public float routeRecalculationDistance;
public interface RouteCalculationResultListener {

View file

@ -2,6 +2,7 @@ package net.osmand.plus.routing;
import android.content.Context;
import android.support.annotation.Nullable;
import android.system.Os;
import net.osmand.Location;
import net.osmand.PlatformUtil;
@ -55,6 +56,12 @@ public class RouteCalculationResult {
protected List<RouteDirectionInfo> cacheAgreggatedDirections;
protected List<LocationPoint> locationPoints = new ArrayList<LocationPoint>();
// parmas
protected final ApplicationMode appMode;
protected final RouteProvider.RouteService routeService;
protected final double routeRecalcDistance;
protected final double routeVisibleAngle = 30;
// Note always currentRoute > get(currentDirectionInfo).routeOffset,
// but currentRoute <= get(currentDirectionInfo+1).routeOffset
protected int currentDirectionInfo = 0;
@ -62,10 +69,11 @@ public class RouteCalculationResult {
protected int nextIntermediate = 0;
protected int currentWaypointGPX = 0;
protected int lastWaypointGPX = 0;
protected ApplicationMode appMode;
protected int currentStraightAngleRoute = -1;
protected Location currentStraightAnglePoint = null;
protected boolean showOriginalRoute = false;
protected double routeRecalcDistance = 0.d;
public RouteCalculationResult(String errorMessage) {
this.errorMessage = errorMessage;
@ -79,6 +87,9 @@ public class RouteCalculationResult {
this.listDistance = new int[0];
this.directions = new ArrayList<RouteDirectionInfo>();
this.alarmInfo = new ArrayList<AlarmInfo>();
this.routeService = null;
this.appMode = null;
this.routeRecalcDistance = 0;
}
public RouteCalculationResult(List<Location> list, List<RouteDirectionInfo> directions, RouteCalculationParams params, List<LocationPoint> waypoints, boolean addMissingTurns) {
@ -112,11 +123,11 @@ public class RouteCalculationResult {
calculateIntermediateIndexes(params.ctx, this.locations, params.intermediates, localDirections, this.intermediatePoints);
this.directions = Collections.unmodifiableList(localDirections);
updateDirectionsTime(this.directions, this.listDistance);
this.showOriginalRoute = params.showOriginalRoute;
if (params.routeRecalculationDistance != 0.f) {
this.routeRecalcDistance = params.routeRecalculationDistance;
this.routeService = params.mode.getRouteService();
if(params.ctx != null) {
this.routeRecalcDistance = params.ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(params.mode);
} else {
this.routeRecalcDistance = 0;
}
}
@ -143,10 +154,12 @@ public class RouteCalculationResult {
calculateIntermediateIndexes(ctx, this.locations, intermediates, computeDirections, this.intermediatePoints);
updateListDistanceTime(this.listDistance, this.locations);
this.appMode = mode;
this.routeService = mode.getRouteService();
this.directions = Collections.unmodifiableList(computeDirections);
updateDirectionsTime(this.directions, this.listDistance);
this.alarmInfo = Collections.unmodifiableList(alarms);
this.routeRecalcDistance = ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(mode);
}
public ApplicationMode getAppMode() {
@ -242,6 +255,14 @@ public class RouteCalculationResult {
return routeRecalcDistance;
}
public RouteProvider.RouteService getRouteService() {
return routeService;
}
public double getRouteVisibleAngle() {
return routeVisibleAngle;
}
public List<RouteSegmentResult> getOriginalRoute() {
if (segments.size() == 0) {
return null;
@ -1210,7 +1231,20 @@ public class RouteCalculationResult {
private int getListDistance(int index) {
return listDistance.length > index ? listDistance[index] : 0;
}
public int getCurrentStraightAngleRoute() {
return currentStraightAngleRoute > currentRoute ? currentStraightAngleRoute : currentRoute;
}
public Location getCurrentStraightAnglePoint() {
return currentStraightAnglePoint;
}
public void updateNextVisiblePoint(int nextPoint, Location mp) {
currentStraightAngleRoute = nextPoint;
currentStraightAnglePoint = mp;
}
public static class NextDirectionInfo {
public RouteDirectionInfo directionInfo;
public int distanceTo;
@ -1220,7 +1254,4 @@ public class RouteCalculationResult {
private int directionInfoInd;
}
public boolean isShowOriginalRoute() {
return showOriginalRoute;
}
}

View file

@ -1270,7 +1270,6 @@ public class RouteProvider {
}
private RouteCalculationResult findDirectTo(RouteCalculationParams params) {
params.showOriginalRoute = true;
double[] lats = new double[] { params.start.getLatitude(), params.end.getLatitude() };
double[] lons = new double[] { params.start.getLongitude(), params.end.getLongitude() };
List<LatLon> intermediates = params.intermediates;

View file

@ -43,7 +43,6 @@ public class RoutingHelper {
private static final float POSITION_TOLERANCE = 60;
private static final int CACHE_RADIUS = 100000;
public static final float ALLOWED_DEVIATION = 2;
public static final double ANGLE_TO_DECLINE = 15;
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
private List<WeakReference<IRoutingDataUpdateListener>> updateListeners = new LinkedList<>();
@ -462,6 +461,7 @@ public class RoutingHelper {
if (allowableDeviation == 0) {
allowableDeviation = getDefaultAllowedDeviation(settings, route.getAppMode(), posTolerance);
}
// 2. Analyze if we need to recalculate route
// >100m off current route (sideways) or parameter (for Straight line)
if (currentRoute > 0 && allowableDeviation > 0) {
@ -698,6 +698,37 @@ public class RoutingHelper {
// targets.clearPointToNavigate(false);
return true;
}
}
// 4. update angle point
if (route.getRouteVisibleAngle() > 0) {
// proceed to the next point with min acceptable bearing
double ANGLE_TO_DECLINE = route.getRouteVisibleAngle();
int nextPoint = route.currentRoute;
for (; nextPoint < routeNodes.size() - 1; nextPoint++) {
float bearingTo = currentLocation.bearingTo(routeNodes.get(nextPoint));
float bearingTo2 = currentLocation.bearingTo(routeNodes.get(nextPoint + 1));
if (Math.abs(MapUtils.degreesDiff(bearingTo2, bearingTo)) <= ANGLE_TO_DECLINE) {
break;
}
}
if(nextPoint > 0) {
float bearingTo = currentLocation.bearingTo(routeNodes.get(nextPoint));
Location mp = MapUtils.calculateMidPoint(routeNodes.get(nextPoint - 1), routeNodes.get(nextPoint));
boolean found = false;
while (mp.distanceTo(routeNodes.get(nextPoint)) > 100) {
float bearingMid = currentLocation.bearingTo(mp);
if (Math.abs(MapUtils.degreesDiff(bearingMid, bearingTo)) <= ANGLE_TO_DECLINE) {
route.updateNextVisiblePoint(nextPoint, mp);
found = true;
break;
}
}
if(!found) {
route.updateNextVisiblePoint(nextPoint, null);
}
}
}
return false;