diff --git a/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java b/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java index bb561c4cc6..b1c4c54566 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java @@ -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; diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java index e53158f1a2..bed0858ab5 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationParams.java @@ -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 { diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index 11741dd54a..f7f2fc2570 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -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 cacheAgreggatedDirections; protected List locationPoints = new ArrayList(); + // 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(); this.alarmInfo = new ArrayList(); + this.routeService = null; + this.appMode = null; + this.routeRecalcDistance = 0; } public RouteCalculationResult(List list, List directions, RouteCalculationParams params, List 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 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; - } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index fc84e4a1ee..861d0d36af 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -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 intermediates = params.intermediates; diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index e8d98e626a..532c5161f1 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -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> listeners = new LinkedList<>(); private List> 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;