From 5b78dd0143f89917826752504a1278a1d2a698f7 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 24 Jan 2021 16:55:05 +0200 Subject: [PATCH 1/5] Implement Graphhopper turn types --- .../onlinerouting/OnlineRoutingHelper.java | 7 +- .../onlinerouting/OnlineRoutingResponse.java | 24 ++++ .../engine/GraphhopperEngine.java | 134 +++++++++++++++++- .../engine/OnlineRoutingEngine.java | 4 +- .../plus/onlinerouting/engine/OrsEngine.java | 6 +- .../plus/onlinerouting/engine/OsrmEngine.java | 11 +- .../plus/routing/RouteCalculationResult.java | 2 +- .../osmand/plus/routing/RouteProvider.java | 11 +- 8 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 9b3d042699..fc8d52dbb4 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -72,11 +72,12 @@ public class OnlineRoutingHelper { } @NonNull - public List calculateRouteOnline(@NonNull OnlineRoutingEngine engine, - @NonNull List path) throws IOException, JSONException { + public OnlineRoutingResponse calculateRouteOnline(@NonNull OnlineRoutingEngine engine, + @NonNull List path, + boolean leftSideNavigation) throws IOException, JSONException { String url = engine.getFullUrl(path); String content = makeRequest(url); - return engine.parseServerResponse(content); + return engine.parseServerResponse(content, leftSideNavigation); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java new file mode 100644 index 0000000000..8a29c7a210 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java @@ -0,0 +1,24 @@ +package net.osmand.plus.onlinerouting; + +import net.osmand.data.LatLon; +import net.osmand.plus.routing.RouteDirectionInfo; + +import java.util.List; + +public class OnlineRoutingResponse { + private List route; + private List directions; + + public OnlineRoutingResponse(List route, List directions) { + this.route = route; + this.directions = directions; + } + + public List getRoute() { + return route; + } + + public List getDirections() { + return directions; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index df9381352b..aace78266a 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -6,12 +6,17 @@ import androidx.annotation.Nullable; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.routing.RouteDirectionInfo; +import net.osmand.router.TurnType; import net.osmand.util.GeoPolylineParserUtil; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -71,15 +76,58 @@ public class GraphhopperEngine extends OnlineRoutingEngine { if (!isEmpty(apiKey)) { sb.append('&').append("key=").append(apiKey); } + // available Graphhopper details data + sb.append('&').append("details=").append("street_name"); + sb.append('&').append("details=").append("time"); + sb.append('&').append("details=").append("distance"); + sb.append('&').append("details=").append("max_speed"); + sb.append('&').append("details=").append("toll"); + sb.append('&').append("details=").append("road_class"); + sb.append('&').append("details=").append("road_class_link"); + sb.append('&').append("details=").append("road_access"); + sb.append('&').append("details=").append("road_environment"); + sb.append('&').append("details=").append("lanes"); + sb.append('&').append("details=").append("surface"); } @NonNull @Override - public List parseServerResponse(@NonNull String content) throws JSONException { + public OnlineRoutingResponse parseServerResponse(@NonNull String content, + boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); - return GeoPolylineParserUtil.parse( - obj.getJSONArray("paths").getJSONObject(0).getString("points"), - GeoPolylineParserUtil.PRECISION_5); + JSONObject root = obj.getJSONArray("paths").getJSONObject(0); + + String encoded = root.getString("points"); + List route = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + + JSONArray instructions = root.getJSONArray("instructions"); + List directions = new ArrayList<>(); + for (int i = 0; i < instructions.length(); i++) { + JSONObject item = instructions.getJSONObject(i); + int sign = Integer.parseInt(item.getString("sign")); + double distance = Double.parseDouble(item.getString("distance")); + String text = item.getString("text"); + String streetName = item.getString("street_name"); + int time = Integer.parseInt(item.getString("time")) / 1000; + JSONArray interval = item.getJSONArray("interval"); + int startPointOffset = interval.getInt(0); + int endPointOffset = interval.getInt(1); + + float averageSpeed = (float) distance / time; + TurnType turnType = identifyTurnType(sign, leftSideNavigation); + // TODO turnType.setTurnAngle() + + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.routePointOffset = startPointOffset; + if (turnType != null && turnType.isRoundAbout()) { + direction.routeEndPointOffset = endPointOffset; + } + direction.setDescriptionRoute(text); + direction.setStreetName(streetName); + direction.setDistance((int) distance); // TODO convert to int correctly + directions.add(direction); + } + return new OnlineRoutingResponse(route, directions); } @Override @@ -92,4 +140,82 @@ public class GraphhopperEngine extends OnlineRoutingEngine { } return obj.has("paths"); } + + /** + * @param sign a number which specifies the turn type to show (Graphhopper API) + * @return TurnType object defined in OsmAnd which is similar to Graphhopper sign parameter + * + * For future compatibility it is important that all clients + * are able to handle also unknown instruction sign numbers + */ + @Nullable + public static TurnType identifyTurnType(int sign, boolean leftSide) { + int id = -1; + + if (sign == -98) { + // an U-turn without the knowledge + // if it is a right or left U-turn + id = TurnType.TU; + + } else if (sign == -8) { + // a left U-turn + leftSide = false; + id = TurnType.TU; + + } else if (sign == -7) { + // keep left + id = TurnType.KL; + + } else if (sign == -6) { + // not yet used: leave roundabout + + } else if (sign == -3) { + // turn sharp left + id = TurnType.TSHL; + + } else if (sign == -2) { + // turn left + id = TurnType.TL; + + } else if (sign == -1) { + // turn slight left + id = TurnType.TSLL; + + } else if (sign == 0) { + // continue on street + id = TurnType.C; + + } else if (sign == 1) { + // turn slight right + id = TurnType.TSLR; + + } else if (sign == 2) { + // turn right + id = TurnType.TR; + + } else if (sign == 3) { + // turn sharp right + id = TurnType.TSHR; + + } else if (sign == 4) { + // the finish instruction before the last point + + } else if (sign == 5) { + // the instruction before a via point + + } else if (sign == 6) { + // the instruction before entering a roundabout + id = TurnType.RNDB; + + } else if (sign == 7) { + // keep right + id = TurnType.KR; + + } else if (sign == 8) { + // a right U-turn + id = TurnType.TRU; + } + + return id != -1 ? TurnType.valueOf(id, leftSide) : null; + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 511f31cc67..54b70a7676 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -9,6 +9,7 @@ import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; +import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.util.Algorithms; @@ -91,7 +92,8 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull List path); @NonNull - public abstract List parseServerResponse(@NonNull String content) throws JSONException; + public abstract OnlineRoutingResponse parseServerResponse(@NonNull String content, + boolean leftSideNavigation) throws JSONException; @NonNull public abstract String getStandardUrl(); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 7c57737d46..d1fa59e11d 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -6,6 +6,7 @@ import androidx.annotation.Nullable; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; import org.json.JSONArray; @@ -77,7 +78,8 @@ public class OrsEngine extends OnlineRoutingEngine { @NonNull @Override - public List parseServerResponse(@NonNull String content) throws JSONException { + public OnlineRoutingResponse parseServerResponse(@NonNull String content, + boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); JSONArray array = obj.getJSONArray("features").getJSONObject(0) .getJSONObject("geometry").getJSONArray("coordinates"); @@ -88,7 +90,7 @@ public class OrsEngine extends OnlineRoutingEngine { double lat = Double.parseDouble(point.getString(1)); track.add(new LatLon(lat, lon)); } - return track; + return new OnlineRoutingResponse(track, null); } @Override diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 1ef9c1a622..5042dc5fab 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -6,6 +6,7 @@ import androidx.annotation.Nullable; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.util.GeoPolylineParserUtil; @@ -60,15 +61,17 @@ public class OsrmEngine extends OnlineRoutingEngine { } sb.append('?'); sb.append("overview=full"); + sb.append('&').append("steps=true"); } @NonNull @Override - public List parseServerResponse(@NonNull String content) throws JSONException { + public OnlineRoutingResponse parseServerResponse(@NonNull String content, + boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); - return GeoPolylineParserUtil.parse( - obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), - GeoPolylineParserUtil.PRECISION_5); + String encoded = obj.getJSONArray("routes").getJSONObject(0).getString("geometry"); + List route = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + return new OnlineRoutingResponse(route, null); } @Override diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java index e6efcc321f..4ef286826d 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteCalculationResult.java @@ -711,7 +711,7 @@ public class RouteCalculationResult { if (directions != null && directions.size() > 1) { for (int i = 1; i < directions.size();) { RouteDirectionInfo r = directions.get(i); - if (r.getTurnType().getValue() == TurnType.C) { + if (r.getTurnType() != null && r.getTurnType().getValue() == TurnType.C) { RouteDirectionInfo prev = directions.get(i - 1); prev.setAverageSpeed((prev.distance + r.distance) / (prev.distance / prev.getAverageSpeed() + r.distance / r.getAverageSpeed())); diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 96017bc96c..49d8165adc 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -21,6 +21,7 @@ import net.osmand.data.LocationPoint; import net.osmand.data.WptLocationPoint; import net.osmand.plus.OsmandApplication; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; +import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; @@ -1203,20 +1204,20 @@ public class RouteProvider { OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); String stringKey = params.mode.getRoutingProfile(); OnlineRoutingEngine engine = helper.getEngineByKey(stringKey); - List route = null; + OnlineRoutingResponse response = null; if (engine != null) { - route = helper.calculateRouteOnline(engine, getFullPathFromParams(params)); + response = helper.calculateRouteOnline(engine, getFullPathFromParams(params), params.leftSide); } - if (!Algorithms.isEmpty(route)) { + if (response != null && !Algorithms.isEmpty(response.getRoute())) { List res = new ArrayList<>(); - for (LatLon pt : route) { + for (LatLon pt : response.getRoute()) { WptPt wpt = new WptPt(); wpt.lat = pt.getLatitude(); wpt.lon = pt.getLongitude(); res.add(createLocation(wpt)); } params.intermediates = null; - return new RouteCalculationResult(res, null, params, null, true); + return new RouteCalculationResult(res, response.getDirections(), params, null, true); } else { return new RouteCalculationResult("Route is empty"); } From 5097b11dfea5397742b77e6b45f812f06fae578e Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 25 Jan 2021 09:51:54 +0200 Subject: [PATCH 2/5] small Graphhopper turn types code improvement --- .../engine/GraphhopperEngine.java | 31 ++++++------------- .../engine/OnlineRoutingEngine.java | 3 +- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index aace78266a..6a7ca0fc49 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -76,18 +76,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine { if (!isEmpty(apiKey)) { sb.append('&').append("key=").append(apiKey); } - // available Graphhopper details data - sb.append('&').append("details=").append("street_name"); - sb.append('&').append("details=").append("time"); - sb.append('&').append("details=").append("distance"); - sb.append('&').append("details=").append("max_speed"); - sb.append('&').append("details=").append("toll"); - sb.append('&').append("details=").append("road_class"); - sb.append('&').append("details=").append("road_class_link"); - sb.append('&').append("details=").append("road_access"); - sb.append('&').append("details=").append("road_environment"); sb.append('&').append("details=").append("lanes"); - sb.append('&').append("details=").append("surface"); } @NonNull @@ -105,15 +94,15 @@ public class GraphhopperEngine extends OnlineRoutingEngine { for (int i = 0; i < instructions.length(); i++) { JSONObject item = instructions.getJSONObject(i); int sign = Integer.parseInt(item.getString("sign")); - double distance = Double.parseDouble(item.getString("distance")); - String text = item.getString("text"); + int distance = (int) Math.round(Double.parseDouble(item.getString("distance"))); + String description = item.getString("text"); String streetName = item.getString("street_name"); - int time = Integer.parseInt(item.getString("time")) / 1000; + int timeInSeconds = (int) Math.round(Integer.parseInt(item.getString("time")) / 1000f); JSONArray interval = item.getJSONArray("interval"); int startPointOffset = interval.getInt(0); int endPointOffset = interval.getInt(1); - float averageSpeed = (float) distance / time; + float averageSpeed = (float) distance / timeInSeconds; TurnType turnType = identifyTurnType(sign, leftSideNavigation); // TODO turnType.setTurnAngle() @@ -122,9 +111,9 @@ public class GraphhopperEngine extends OnlineRoutingEngine { if (turnType != null && turnType.isRoundAbout()) { direction.routeEndPointOffset = endPointOffset; } - direction.setDescriptionRoute(text); + direction.setDescriptionRoute(description); direction.setStreetName(streetName); - direction.setDistance((int) distance); // TODO convert to int correctly + direction.setDistance(distance); directions.add(direction); } return new OnlineRoutingResponse(route, directions); @@ -142,15 +131,15 @@ public class GraphhopperEngine extends OnlineRoutingEngine { } /** - * @param sign a number which specifies the turn type to show (Graphhopper API) - * @return TurnType object defined in OsmAnd which is similar to Graphhopper sign parameter + * @param sign - a number which specifies the turn type to show (Graphhopper API value) + * @return a TurnType object defined in OsmAnd which is equivalent to a value from the Graphhopper API * * For future compatibility it is important that all clients * are able to handle also unknown instruction sign numbers */ @Nullable public static TurnType identifyTurnType(int sign, boolean leftSide) { - int id = -1; + int id = INVALID_ID; if (sign == -98) { // an U-turn without the knowledge @@ -216,6 +205,6 @@ public class GraphhopperEngine extends OnlineRoutingEngine { id = TurnType.TRU; } - return id != -1 ? TurnType.valueOf(id, leftSide) : null; + return id != INVALID_ID ? TurnType.valueOf(id, leftSide) : null; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 54b70a7676..a566b1e9a7 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -29,7 +29,8 @@ import static net.osmand.util.Algorithms.isEmpty; public abstract class OnlineRoutingEngine implements Cloneable { public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; - public static final VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom); + public final static VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom); + public final static int INVALID_ID = -1; private final Map params = new HashMap<>(); private final List allowedVehicles = new ArrayList<>(); From f4391b7008a418bf5c0d12402d5cf027c81ebbf1 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 25 Jan 2021 10:48:47 +0200 Subject: [PATCH 3/5] small refactoring --- .../onlinerouting/OnlineRoutingHelper.java | 18 +++++++-- .../onlinerouting/OnlineRoutingResponse.java | 8 ++-- .../engine/GraphhopperEngine.java | 12 ++++-- .../engine/OnlineRoutingEngine.java | 37 ++++++++++++++----- .../plus/onlinerouting/engine/OrsEngine.java | 16 +++++--- .../plus/onlinerouting/engine/OsrmEngine.java | 17 ++++++--- .../osmand/plus/routing/RouteProvider.java | 23 +++--------- 7 files changed, 82 insertions(+), 49 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index fc8d52dbb4..c62d952eb3 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -25,6 +25,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static net.osmand.util.Algorithms.isEmpty; + public class OnlineRoutingHelper { private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class); @@ -71,7 +73,15 @@ public class OnlineRoutingHelper { return null; } - @NonNull + @Nullable + public OnlineRoutingResponse calculateRouteOnline(@Nullable String stringKey, + @NonNull List path, + boolean leftSideNavigation) throws IOException, JSONException { + OnlineRoutingEngine engine = getEngineByKey(stringKey); + return engine != null ? calculateRouteOnline(engine, path, leftSideNavigation) : null; + } + + @Nullable public OnlineRoutingResponse calculateRouteOnline(@NonNull OnlineRoutingEngine engine, @NonNull List path, boolean leftSideNavigation) throws IOException, JSONException { @@ -132,7 +142,7 @@ public class OnlineRoutingHelper { @NonNull private String createEngineKeyIfNeeded(@NonNull OnlineRoutingEngine engine) { String key = engine.get(EngineParameter.KEY); - if (Algorithms.isEmpty(key)) { + if (isEmpty(key)) { key = OnlineRoutingEngine.generateKey(); engine.put(EngineParameter.KEY, key); } @@ -152,7 +162,7 @@ public class OnlineRoutingHelper { private List readFromSettings() { List engines = new ArrayList<>(); String jsonString = settings.ONLINE_ROUTING_ENGINES.get(); - if (!Algorithms.isEmpty(jsonString)) { + if (!isEmpty(jsonString)) { try { JSONObject json = new JSONObject(jsonString); OnlineRoutingUtils.readFromJson(json, engines); @@ -164,7 +174,7 @@ public class OnlineRoutingHelper { } private void saveCacheToSettings() { - if (!Algorithms.isEmpty(cachedEngines)) { + if (!isEmpty(cachedEngines)) { try { JSONObject json = new JSONObject(); OnlineRoutingUtils.writeToJson(json, getEngines()); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java index 8a29c7a210..02a6a8f53c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingResponse.java @@ -1,20 +1,20 @@ package net.osmand.plus.onlinerouting; -import net.osmand.data.LatLon; +import net.osmand.Location; import net.osmand.plus.routing.RouteDirectionInfo; import java.util.List; public class OnlineRoutingResponse { - private List route; + private List route; private List directions; - public OnlineRoutingResponse(List route, List directions) { + public OnlineRoutingResponse(List route, List directions) { this.route = route; this.directions = directions; } - public List getRoute() { + public List getRoute() { return route; } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 6a7ca0fc49..f2c7e19829 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -3,6 +3,7 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Location; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; @@ -28,8 +29,9 @@ public class GraphhopperEngine extends OnlineRoutingEngine { super(params); } + @NonNull @Override - public @NonNull EngineType getType() { + public EngineType getType() { return EngineType.GRAPHHOPPER; } @@ -79,7 +81,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine { sb.append('&').append("details=").append("lanes"); } - @NonNull + @Nullable @Override public OnlineRoutingResponse parseServerResponse(@NonNull String content, boolean leftSideNavigation) throws JSONException { @@ -87,7 +89,9 @@ public class GraphhopperEngine extends OnlineRoutingEngine { JSONObject root = obj.getJSONArray("paths").getJSONObject(0); String encoded = root.getString("points"); - List route = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); JSONArray instructions = root.getJSONArray("instructions"); List directions = new ArrayList<>(); @@ -158,7 +162,7 @@ public class GraphhopperEngine extends OnlineRoutingEngine { } else if (sign == -6) { // not yet used: leave roundabout - } else if (sign == -3) { + } else if (sign == -3) { // turn sharp left id = TurnType.TSHL; diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index a566b1e9a7..af94be4282 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -5,12 +5,15 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.GPXUtilities.WptPt; +import net.osmand.Location; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.routing.RouteProvider; import net.osmand.util.Algorithms; import org.json.JSONException; @@ -73,15 +76,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { } } - @NonNull - public String getBaseUrl() { - String customUrl = get(EngineParameter.CUSTOM_URL); - if (isEmpty(customUrl)) { - return getStandardUrl(); - } - return customUrl; - } - @NonNull public String getFullUrl(@NonNull List path) { StringBuilder sb = new StringBuilder(getBaseUrl()); @@ -93,11 +87,34 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull List path); @NonNull + public String getBaseUrl() { + String customUrl = get(EngineParameter.CUSTOM_URL); + if (isEmpty(customUrl)) { + return getStandardUrl(); + } + return customUrl; + } + + @NonNull + public abstract String getStandardUrl(); + + @Nullable public abstract OnlineRoutingResponse parseServerResponse(@NonNull String content, boolean leftSideNavigation) throws JSONException; @NonNull - public abstract String getStandardUrl(); + protected List convertRouteToLocationsList(@NonNull List route) { + List result = new ArrayList<>(); + if (!isEmpty(route)) { + for (LatLon pt : route) { + WptPt wpt = new WptPt(); + wpt.lat = pt.getLatitude(); + wpt.lon = pt.getLongitude(); + result.add(RouteProvider.createLocation(wpt)); + } + } + return result; + } @NonNull public Map getParams() { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index d1fa59e11d..4502f5e957 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -3,6 +3,7 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Location; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; @@ -25,8 +26,9 @@ public class OrsEngine extends OnlineRoutingEngine { super(params); } + @NonNull @Override - public @NonNull EngineType getType() { + public EngineType getType() { return EngineType.ORS; } @@ -76,21 +78,25 @@ public class OrsEngine extends OnlineRoutingEngine { } } - @NonNull + @Nullable @Override public OnlineRoutingResponse parseServerResponse(@NonNull String content, boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); JSONArray array = obj.getJSONArray("features").getJSONObject(0) .getJSONObject("geometry").getJSONArray("coordinates"); - List track = new ArrayList<>(); + List points = new ArrayList<>(); for (int i = 0; i < array.length(); i++) { JSONArray point = array.getJSONArray(i); double lon = Double.parseDouble(point.getString(0)); double lat = Double.parseDouble(point.getString(1)); - track.add(new LatLon(lat, lon)); + points.add(new LatLon(lat, lon)); } - return new OnlineRoutingResponse(track, null); + if (!isEmpty(points)) { + List route = convertRouteToLocationsList(points); + new OnlineRoutingResponse(route, null); + } + return null; } @Override diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 5042dc5fab..478c24886e 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -3,6 +3,7 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.Location; import net.osmand.data.LatLon; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; @@ -25,7 +26,8 @@ public class OsrmEngine extends OnlineRoutingEngine { } @Override - public @NonNull EngineType getType() { + public @NonNull + EngineType getType() { return EngineType.OSRM; } @@ -36,7 +38,8 @@ public class OsrmEngine extends OnlineRoutingEngine { } @Override - protected void collectAllowedParameters() { } + protected void collectAllowedParameters() { + } @Override protected void collectAllowedVehicles(@NonNull List vehicles) { @@ -64,14 +67,18 @@ public class OsrmEngine extends OnlineRoutingEngine { sb.append('&').append("steps=true"); } - @NonNull + @Nullable @Override public OnlineRoutingResponse parseServerResponse(@NonNull String content, boolean leftSideNavigation) throws JSONException { JSONObject obj = new JSONObject(content); String encoded = obj.getJSONArray("routes").getJSONObject(0).getString("geometry"); - List route = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); - return new OnlineRoutingResponse(route, null); + List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + if (!isEmpty(points)) { + List route = convertRouteToLocationsList(points); + return new OnlineRoutingResponse(route, null); + } + return null; } @Override diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 49d8165adc..96bb1b19dc 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -22,7 +22,6 @@ import net.osmand.data.WptLocationPoint; import net.osmand.plus.OsmandApplication; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingResponse; -import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; @@ -327,7 +326,7 @@ public class RouteProvider { } } - private static Location createLocation(WptPt pt){ + public static Location createLocation(WptPt pt){ Location loc = new Location("OsmandRouteProvider"); loc.setLatitude(pt.lat); loc.setLongitude(pt.lon); @@ -1203,27 +1202,17 @@ public class RouteProvider { private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException { OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); String stringKey = params.mode.getRoutingProfile(); - OnlineRoutingEngine engine = helper.getEngineByKey(stringKey); - OnlineRoutingResponse response = null; - if (engine != null) { - response = helper.calculateRouteOnline(engine, getFullPathFromParams(params), params.leftSide); - } - if (response != null && !Algorithms.isEmpty(response.getRoute())) { - List res = new ArrayList<>(); - for (LatLon pt : response.getRoute()) { - WptPt wpt = new WptPt(); - wpt.lat = pt.getLatitude(); - wpt.lon = pt.getLongitude(); - res.add(createLocation(wpt)); - } + OnlineRoutingResponse response = + helper.calculateRouteOnline(stringKey, getPathFromParams(params), params.leftSide); + if (response != null) { params.intermediates = null; - return new RouteCalculationResult(res, response.getDirections(), params, null, true); + return new RouteCalculationResult(response.getRoute(), response.getDirections(), params, null, true); } else { return new RouteCalculationResult("Route is empty"); } } - private static List getFullPathFromParams(RouteCalculationParams params) { + private static List getPathFromParams(RouteCalculationParams params) { List points = new ArrayList<>(); points.add(new LatLon(params.start.getLatitude(), params.start.getLongitude())); if (Algorithms.isEmpty(params.intermediates)) { From aeb099cb8a7e1ad2b2f52a4df84084cab6452594 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 25 Jan 2021 10:15:47 +0100 Subject: [PATCH 4/5] Change - to +: according to comment --- .../src/main/java/net/osmand/router/RouteResultPreparation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java index 6bb4da1ce5..26d984b2da 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java @@ -1222,7 +1222,7 @@ public class RouteResultPreparation { // 3. calculate angle difference // This method doesn't work if you go from S to N touching only 1 point of roundabout, // but it is very important to identify very sharp or very large angle to understand did you pass whole roundabout or small entrance - float turnAngleBasedOnCircle = (float) MapUtils.degreesDiff(firstRoundabout.getBearingBegin(), lastRoundabout.getBearingEnd() + 180); + float turnAngleBasedOnCircle = (float) -MapUtils.degreesDiff(firstRoundabout.getBearingBegin(), lastRoundabout.getBearingEnd() + 180); if (Math.abs(turnAngleBasedOnOutRoads) > 120) { // correctly identify if angle is +- 180, so we approach from left or right side t.setTurnAngle(turnAngleBasedOnCircle) ; From 0f0a41283d46c3aa94535f009f0dbe156d7ca21e Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 25 Jan 2021 14:55:52 +0200 Subject: [PATCH 5/5] Added icon: user account 16dp --- .../res/drawable/ic_action_user_account_16.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 OsmAnd/res/drawable/ic_action_user_account_16.xml diff --git a/OsmAnd/res/drawable/ic_action_user_account_16.xml b/OsmAnd/res/drawable/ic_action_user_account_16.xml new file mode 100644 index 0000000000..f05533e018 --- /dev/null +++ b/OsmAnd/res/drawable/ic_action_user_account_16.xml @@ -0,0 +1,17 @@ + + + + +