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 0db0c52635..d4731dcd8d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/MapUtils.java @@ -697,39 +697,10 @@ public class MapUtils { return new LatLon(Math.toDegrees(phi2), Math.toDegrees(lambda2)); } - public static double getVectorMagnitude(int startX, int startY, int endX, int endY) { - return Math.sqrt(Math.pow((double) (endX - startX), 2.0) + Math.pow((double) (endY - startY), 2.0)); + public static double getSqrtDistance(int startX, int startY, int endX, int endY) { + return Math.sqrt((endX - startX) * (endX - startX) + (endY - startY) * (endY - startY)); } - //angle of vector - public static double getAngleForRadiusVector(int startX, int startY, int endX, int endY) { - return 2 * Math.atan((endY - startY) / (endX - startX - + Math.sqrt(Math.pow((double) (endX - startX), 2.0) + Math.pow((double) (endY - startY), 2.0)))); - } - - //returns coordinates of point on circle - public static double[] getCoordinatesFromRadiusAndAngle(double centerX, double centerY, double radius, double angle) { - double x = centerX + radius * Math.cos(angle); - double y = centerY + radius * Math.sin(angle); - return new double[]{x,y}; - } - - //returns signed angle between vectors in radians - public static double getAngleBetweenVectors(int vectorAStartX, int vectorAStartY, int vectorAEndX, int vectorAEndY, - int vectorBStartX, int vectorBStartY, int vectorBEndX, int vectorBEndY) { - int[] vectorA = new int[] {getVectorAxisValue(vectorAStartX, vectorAEndX), getVectorAxisValue(vectorAStartY, vectorAEndY)}; - int[] vectorB = new int[] {getVectorAxisValue(vectorBStartX, vectorBEndX), getVectorAxisValue(vectorBStartY, vectorBEndY)}; - return Math.atan2(vectorA[0] * vectorB[1] - vectorA[1] * vectorB [0], vectorA[0] * vectorB[0] + vectorA[1] * vectorB[1]); - } - - //calculates vector value for axis - public static int getVectorAxisValue(int axisStart, int axisEnd) { - if (axisEnd < axisStart) { - return Math.abs(axisEnd) - Math.abs(axisStart); - } else { - return Math.abs(axisStart) - Math.abs(axisEnd); - } - } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index b133d185aa..7b2569b2ae 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -1153,6 +1153,13 @@ public class RouteCalculationResult { } return 0; } + + public int getDistanceFromPoint(int locationIndex) { + if(listDistance != null && locationIndex < listDistance.length) { + return listDistance[locationIndex]; + } + return 0; + } public boolean isPointPassed(int locationIndex) { return locationIndex <= currentRoute; diff --git a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java index f45625b466..3996cbde5c 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java @@ -1148,44 +1148,39 @@ public class RouteLayer extends OsmandMapLayer implements ContextMenuLayer.ICont } private double[] calculateProjectionOnRoutePoint(List routeNodes, RoutingHelper helper, RotatedTileBox box) { - double[] projectionXY; - boolean visible; - Location nextInRoute = null; - // TODO simplifiy all culation! + double[] projectionXY = null; Location ll = helper.getLastFixedLocation(); - Location previousInRoute = routeNodes.get(helper.getRoute().getCurrentRoute() > 0 ? helper.getRoute().getCurrentRoute() - 1 : 0); - if (helper.getRoute().getIntermediatePointsToPass() > 0) { - for (int i = 1; i < routeNodes.size(); i++) { - LatLon routePoint = new LatLon(routeNodes.get(i).getLatitude(), routeNodes.get(i).getLongitude()); - if (routePoint.equals(helper.getIntermediatePoints().get(0))) { - nextInRoute = routeNodes.get(i); - } - } - } else { - nextInRoute = routeNodes.get(routeNodes.size()-1); + RouteCalculationResult route = helper.getRoute(); + List locs = route.getImmutableAllLocations(); + int cr = route.getCurrentRoute(); + int locIndex = locs.size() - 1; + if(route.getIntermediatePointsToPass() > 0) { + locIndex = route.getIndexOfIntermediate(route.getIntermediatePointsToPass() - 1); } + if(ll != null && cr > 0 && cr < locs.size() && locIndex >= 0 && locIndex < locs.size()) { + Location loc1 = locs.get(cr - 1); + Location loc2 = locs.get(cr); + double distLeft = route.getDistanceFromPoint(cr) - route.getDistanceFromPoint(locIndex); + double baDist = route.getDistanceFromPoint(cr - 1) - route.getDistanceFromPoint(cr); + Location target = locs.get(locIndex); + double dTarget = ll.distanceTo(target); + final int aX = box.getPixXFromLonNoRot(loc1.getLongitude()); + final int aY = box.getPixYFromLatNoRot(loc1.getLatitude()); + final int bX = box.getPixXFromLonNoRot(loc2.getLongitude()); + final int bY = box.getPixYFromLatNoRot(loc2.getLatitude()); + if(baDist != 0) { + double CF = (dTarget - distLeft) / baDist; + double rX = bX - CF * (bX - aX); + double rY = bY - CF * (bY - aY); + projectionXY = new double[] {rX, rY}; + } + } + if(projectionXY != null) { - if (nextInRoute != null && previousInRoute != null) { - -// double Ri = MapUtils.getDistance(nextInRoute, ll); -// - - final int aX = box.getPixXFromLonNoRot(ll.getLongitude()); - final int aY = box.getPixYFromLatNoRot(ll.getLatitude()); - final int centerX = box.getPixXFromLonNoRot(nextInRoute.getLongitude()); - final int centerY = box.getPixYFromLatNoRot(nextInRoute.getLatitude()); - final int bX = box.getPixXFromLonNoRot(previousInRoute.getLongitude()); - final int bY = box.getPixYFromLatNoRot(previousInRoute.getLatitude()); - double radius = MapUtils.getVectorMagnitude(centerX, centerY, aX, aY); - double angle2 = MapUtils.getAngleForRadiusVector(centerX, centerY, bX, bY); - projectionXY = MapUtils.getCoordinatesFromRadiusAndAngle(centerX, centerY, radius, angle2); - double distanceLoc2Proj = MapUtils.getVectorMagnitude(aX, aY, (int)projectionXY[0], (int)projectionXY[1]); - boolean isProjectionOnSegment = MapUtils.getVectorMagnitude(centerX ,centerY, (int) projectionXY[0], (int) projectionXY[1]) - < MapUtils.getVectorMagnitude(centerX, centerY, bX, bY); - visible = box.containsPoint((float)projectionXY[0], (float)projectionXY[1], 20.0f) - && Math.abs(Math.toDegrees(MapUtils.getAngleBetweenVectors(centerX, centerY, aX, aY, centerX, centerY, bX, bY))) < 90 - && distanceLoc2Proj > AndroidUtils.dpToPx(view.getContext(), 52) / 2.0 - && isProjectionOnSegment; + double distanceLoc2Proj = MapUtils.getSqrtDistance((int)projectionXY[0], (int) projectionXY[1], + box.getPixXFromLonNoRot(ll.getLongitude()), box.getPixYFromLatNoRot(ll.getLatitude())); + boolean visible = box.containsPoint((float) projectionXY[0], (float) projectionXY[1], 20.0f) + && distanceLoc2Proj > AndroidUtils.dpToPx(view.getContext(), 52) / 2.0; if (visible) { return projectionXY; }