diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index 503977c7b7..9ae8f5cb02 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -9,8 +9,7 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.Version; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; -import net.osmand.plus.onlinerouting.parser.ResponseParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; @@ -95,8 +94,7 @@ public class OnlineRoutingHelper { boolean leftSideNavigation) throws IOException, JSONException { String url = engine.getFullUrl(path); String content = makeRequest(url); - ResponseParser parser = engine.getResponseParser(); - return parser.parseResponse(content, app, leftSideNavigation); + return engine.parseResponse(content, app, leftSideNavigation); } @NonNull diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java index 1f6146273d..676ea6ba48 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GpxEngine.java @@ -3,12 +3,16 @@ package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.GpxParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; import java.util.Set; @@ -56,9 +60,29 @@ public class GpxEngine extends OnlineRoutingEngine { params.add(EngineParameter.CUSTOM_URL); } - @NonNull @Override - protected ResponseParser createParser() { - return new GpxParser(); + @Nullable + public OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) { + GPXFile gpxFile = parseGpx(content); + return gpxFile != null ? new OnlineRoutingResponse(parseGpx(content)) : null; + } + + @Override + public boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) { + return parseGpx(content) != null; + } + + private GPXFile parseGpx(@NonNull String content) { + InputStream gpxStream = null; + try { + gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8")); + return GPXUtilities.loadGPXFile(gpxStream); + } catch (UnsupportedEncodingException e) { + LOG.debug("Error when parsing GPX from server response: " + e.getMessage()); + } + return null; } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index 14852e2633..68122b3bdd 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -9,8 +9,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.JSONParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.router.TurnType; import net.osmand.util.GeoPolylineParserUtil; @@ -26,7 +24,7 @@ import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; -public class GraphhopperEngine extends OnlineRoutingEngine { +public class GraphhopperEngine extends JsonOnlineRoutingEngine { public GraphhopperEngine(@Nullable Map params) { super(params); @@ -67,12 +65,6 @@ public class GraphhopperEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("small_truck", R.string.routing_engine_vehicle_type_small_truck)); } - @NonNull - @Override - protected ResponseParser createParser() { - return new GraphhopperParser(); - } - @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -95,148 +87,146 @@ public class GraphhopperEngine extends OnlineRoutingEngine { sb.append('&').append("details=").append("lanes"); } - private static class GraphhopperParser extends JSONParser { + @Nullable + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encoded = root.getString("points"); + List points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); - @Nullable - protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encoded = root.getString("points"); - 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<>(); + for (int i = 0; i < instructions.length(); i++) { + JSONObject instruction = instructions.getJSONObject(i); + int distance = (int) Math.round(instruction.getDouble("distance")); + String description = instruction.getString("text"); + String streetName = instruction.getString("street_name"); + int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); + JSONArray interval = instruction.getJSONArray("interval"); + int startPointOffset = interval.getInt(0); + int endPointOffset = interval.getInt(1); - JSONArray instructions = root.getJSONArray("instructions"); - List directions = new ArrayList<>(); - for (int i = 0; i < instructions.length(); i++) { - JSONObject instruction = instructions.getJSONObject(i); - int distance = (int) Math.round(instruction.getDouble("distance")); - String description = instruction.getString("text"); - String streetName = instruction.getString("street_name"); - int timeInSeconds = Math.round(instruction.getInt("time") / 1000f); - JSONArray interval = instruction.getJSONArray("interval"); - int startPointOffset = interval.getInt(0); - int endPointOffset = interval.getInt(1); + float averageSpeed = (float) distance / timeInSeconds; + TurnType turnType = parseTurnType(instruction, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - float averageSpeed = (float) distance / timeInSeconds; - TurnType turnType = parseTurnType(instruction, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - - direction.routePointOffset = startPointOffset; - direction.setDescriptionRoute(description); - direction.setStreetName(streetName); - direction.setDistance(distance); - directions.add(direction); - } - return new OnlineRoutingResponse(route, directions); - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject instruction, - boolean leftSide) throws JSONException { - int sign = instruction.getInt("sign"); - TurnType turnType = identifyTurnType(sign, leftSide); - - if (turnType == null) { - turnType = TurnType.straight(); - } else if (turnType.isRoundAbout()) { - if (instruction.has("exit_number")) { - int exit = instruction.getInt("exit_number"); - turnType.setExitOut(exit); - } - if (instruction.has("turn_angle")) { - float angle = (float) instruction.getDouble("turn_angle"); - turnType.setTurnAngle(angle); - } - } else { - // TODO turnType.setTurnAngle() - } - - return turnType; - } - - @Nullable - public static TurnType identifyTurnType(int sign, boolean leftSide) { - Integer id = null; - - 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 - id = TurnType.C; - - } 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 != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "paths"; + direction.routePointOffset = startPointOffset; + direction.setDescriptionRoute(description); + direction.setStreetName(streetName); + direction.setDistance(distance); + directions.add(direction); } + return new OnlineRoutingResponse(route, directions); } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject instruction, + boolean leftSide) throws JSONException { + int sign = instruction.getInt("sign"); + TurnType turnType = identifyTurnType(sign, leftSide); + + if (turnType == null) { + turnType = TurnType.straight(); + } else if (turnType.isRoundAbout()) { + if (instruction.has("exit_number")) { + int exit = instruction.getInt("exit_number"); + turnType.setExitOut(exit); + } + if (instruction.has("turn_angle")) { + float angle = (float) instruction.getDouble("turn_angle"); + turnType.setTurnAngle(angle); + } + } else { + // TODO turnType.setTurnAngle() + } + + return turnType; + } + + @Nullable + public static TurnType identifyTurnType(int sign, boolean leftSide) { + Integer id = null; + + 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 + id = TurnType.C; + + } 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 != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "paths"; + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/JsonOnlineRoutingEngine.java similarity index 90% rename from OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/engine/JsonOnlineRoutingEngine.java index e0676f68c2..dcd191da19 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/JSONParser.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/JsonOnlineRoutingEngine.java @@ -1,4 +1,4 @@ -package net.osmand.plus.onlinerouting.parser; +package net.osmand.plus.onlinerouting.engine; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -15,10 +15,15 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static net.osmand.util.Algorithms.isEmpty; -public abstract class JSONParser extends ResponseParser { +public abstract class JsonOnlineRoutingEngine extends OnlineRoutingEngine { + + public JsonOnlineRoutingEngine(@Nullable Map params) { + super(params); + } @Nullable public OnlineRoutingResponse parseResponse(@NonNull String content, diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index b2bba21ca6..85514dec85 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -5,16 +5,20 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.data.LatLon; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.ResponseParser; +import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; +import org.json.JSONException; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +40,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { private final Map params = new HashMap<>(); private final List allowedVehicles = new ArrayList<>(); private final Set allowedParameters = new HashSet<>(); - private ResponseParser responseParser; public OnlineRoutingEngine(@Nullable Map params) { if (!isEmpty(params)) { @@ -97,16 +100,13 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull public abstract String getStandardUrl(); - @NonNull - public ResponseParser getResponseParser() { - if (responseParser == null) { - responseParser = createParser(); - } - return responseParser; - } + @Nullable + public abstract OnlineRoutingResponse parseResponse(@NonNull String content, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException; - @NonNull - protected abstract ResponseParser createParser(); + public abstract boolean isResultOk(@NonNull StringBuilder errorMessage, + @NonNull String content) throws JSONException; @NonNull public Map getParams() { @@ -194,4 +194,34 @@ public abstract class OnlineRoutingEngine implements Cloneable { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); } + public static class OnlineRoutingResponse { + + private List route; + private List directions; + private GPXFile gpxFile; + + // constructor for JSON responses + public OnlineRoutingResponse(List route, List directions) { + this.route = route; + this.directions = directions; + } + + // constructor for GPX responses + public OnlineRoutingResponse(GPXFile gpxFile) { + this.gpxFile = gpxFile; + } + + public List getRoute() { + return route; + } + + public List getDirections() { + return directions; + } + + public GPXFile getGpxFile() { + return gpxFile; + } + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index d80d3df3c1..9a16be62ee 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -9,8 +9,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.JSONParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import org.json.JSONArray; import org.json.JSONException; @@ -23,7 +21,7 @@ import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; -public class OrsEngine extends OnlineRoutingEngine { +public class OrsEngine extends JsonOnlineRoutingEngine { public OrsEngine(@Nullable Map params) { super(params); @@ -64,12 +62,6 @@ public class OrsEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("wheelchair", R.string.routing_engine_vehicle_type_wheelchair)); } - @NonNull - @Override - protected ResponseParser createParser() { - return new OrsParser(); - } - @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -92,38 +84,36 @@ public class OrsEngine extends OnlineRoutingEngine { } } - private static class OrsParser extends JSONParser { - - @Nullable - @Override - public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); - 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)); - points.add(new LatLon(lat, lon)); - } - if (!isEmpty(points)) { - List route = convertRouteToLocationsList(points); - new OnlineRoutingResponse(route, null); - } - return null; + @Nullable + @Override + public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates"); + 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)); + points.add(new LatLon(lat, lon)); } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "error"; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "features"; + if (!isEmpty(points)) { + List route = convertRouteToLocationsList(points); + new OnlineRoutingResponse(route, null); } + return null; } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "error"; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "features"; + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index 19860ee15c..4219204cca 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -9,8 +9,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.VehicleType; -import net.osmand.plus.onlinerouting.parser.JSONParser; -import net.osmand.plus.onlinerouting.parser.ResponseParser; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.router.TurnType; @@ -29,7 +27,7 @@ import java.util.Set; import static net.osmand.util.Algorithms.isEmpty; import static net.osmand.util.Algorithms.objectEquals; -public class OsrmEngine extends OnlineRoutingEngine { +public class OsrmEngine extends JsonOnlineRoutingEngine { public OsrmEngine(@Nullable Map params) { super(params); @@ -63,12 +61,6 @@ public class OsrmEngine extends OnlineRoutingEngine { vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot)); } - @NonNull - @Override - protected ResponseParser createParser() { - return new OsrmParser(); - } - @Override protected void makeFullUrl(@NonNull StringBuilder sb, @NonNull List path) { @@ -88,167 +80,165 @@ public class OsrmEngine extends OnlineRoutingEngine { sb.append('&').append("steps=true"); } - private static class OsrmParser extends JSONParser { + @Nullable + @Override + protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, + @NonNull OsmandApplication app, + boolean leftSideNavigation) throws JSONException { + String encodedPoints = root.getString("geometry"); + List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); + if (isEmpty(points)) return null; - @Nullable - @Override - protected OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException { - String encodedPoints = root.getString("geometry"); - List points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); - if (isEmpty(points)) return null; + List route = convertRouteToLocationsList(points); + List directions = new ArrayList<>(); + int startSearchingId = 0; + JSONArray legs = root.getJSONArray("legs"); + for (int i = 0; i < legs.length(); i++) { + JSONObject leg = legs.getJSONObject(i); + if (!leg.has("steps")) continue; - List route = convertRouteToLocationsList(points); - List directions = new ArrayList<>(); - int startSearchingId = 0; - JSONArray legs = root.getJSONArray("legs"); - for (int i = 0; i < legs.length(); i++) { - JSONObject leg = legs.getJSONObject(i); - if (!leg.has("steps")) continue; + JSONArray steps = leg.getJSONArray("steps"); + for (int j = 0; j < steps.length(); j++) { + JSONObject instruction = steps.getJSONObject(j); + JSONObject maneuver = instruction.getJSONObject("maneuver"); + String maneuverType = maneuver.getString("type"); - JSONArray steps = leg.getJSONArray("steps"); - for (int j = 0; j < steps.length(); j++) { - JSONObject instruction = steps.getJSONObject(j); - JSONObject maneuver = instruction.getJSONObject("maneuver"); - String maneuverType = maneuver.getString("type"); + JSONArray location = maneuver.getJSONArray("location"); + double lon = location.getDouble(0); + double lat = location.getDouble(1); + Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); + if (routePointOffset == null) continue; + startSearchingId = routePointOffset; - JSONArray location = maneuver.getJSONArray("location"); - double lon = location.getDouble(0); - double lat = location.getDouble(1); - Integer routePointOffset = getLocationIndexInList(route, startSearchingId, lat, lon); - if (routePointOffset == null) continue; - startSearchingId = routePointOffset; + // in meters + int distance = (int) Math.round(instruction.getDouble("distance")); + // in seconds + int duration = (int) Math.round(instruction.getDouble("duration")); - // in meters - int distance = (int) Math.round(instruction.getDouble("distance")); - // in seconds - int duration = (int) Math.round(instruction.getDouble("duration")); + float averageSpeed = (float) distance / duration; + TurnType turnType = parseTurnType(maneuver, leftSideNavigation); + RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); + direction.setDistance(distance); - float averageSpeed = (float) distance / duration; - TurnType turnType = parseTurnType(maneuver, leftSideNavigation); - RouteDirectionInfo direction = new RouteDirectionInfo(averageSpeed, turnType); - direction.setDistance(distance); - - String streetName = instruction.getString("name"); - String description = ""; - if (!objectEquals(maneuverType, "arrive")) { - description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; - } - description = description.trim(); - - direction.setStreetName(streetName); - direction.setDescriptionRoute(description); - direction.routePointOffset = routePointOffset; - directions.add(direction); + String streetName = instruction.getString("name"); + String description = ""; + if (!objectEquals(maneuverType, "arrive")) { + description = RouteCalculationResult.toString(turnType, app, false) + " " + streetName; } - } + description = description.trim(); - return new OnlineRoutingResponse(route, directions); + direction.setStreetName(streetName); + direction.setDescriptionRoute(description); + direction.routePointOffset = routePointOffset; + directions.add(direction); + } } - @Nullable - private Integer getLocationIndexInList(@NonNull List locations, - int startIndex, double lat, double lon) { - for (int i = startIndex; i < locations.size(); i++) { - Location l = locations.get(i); - if (MapUtils.areLatLonEqual(l, lat, lon)) { - return i; - } - } - return null; - } - - @NonNull - private TurnType parseTurnType(@NonNull JSONObject maneuver, - boolean leftSide) throws JSONException { - TurnType turnType = null; - - String type = maneuver.getString("type"); - String modifier = null; - if (maneuver.has("modifier")) { - modifier = maneuver.getString("modifier"); - } - - if (objectEquals(type, "roundabout") - || objectEquals(type, "rotary") - || objectEquals(type, "roundabout turn")) { - if (maneuver.has("exit")) { - int exit = maneuver.getInt("exit"); - turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); - } else if (modifier != null) { - // for simple roundabout turn without "exit" parameter - turnType = identifyTurnType(modifier, leftSide); - } - } else { - // for other maneuver types find TurnType - // like a basic turn into direction of the modifier - if (modifier != null) { - turnType = identifyTurnType(modifier, leftSide); - } - } - if (turnType == null) { - turnType = TurnType.straight(); - } - - int bearingBefore = maneuver.getInt("bearing_before"); - int bearingAfter = maneuver.getInt("bearing_after"); - float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); - turnType.setTurnAngle(angle); - - return turnType; - } - - @Nullable - private TurnType identifyTurnType(@NonNull String modifier, - boolean leftSide) { - Integer id = null; - switch (modifier) { - case "uturn": - id = TurnType.TU; - break; - - case "sharp right": - id = TurnType.TSHR; - break; - - case "right": - id = TurnType.TR; - break; - - case "slight right": - id = TurnType.TSLR; - break; - - case "straight": - id = TurnType.C; - break; - - case "slight left": - id = TurnType.TSLL; - break; - - case "left": - id = TurnType.TL; - break; - - case "sharp left": - id = TurnType.TSHL; - break; - } - return id != null ? TurnType.valueOf(id, leftSide) : null; - } - - @NonNull - @Override - protected String getRootArrayKey() { - return "routes"; - } - - @NonNull - @Override - protected String getErrorMessageKey() { - return "message"; - } + return new OnlineRoutingResponse(route, directions); } + + @Nullable + private Integer getLocationIndexInList(@NonNull List locations, + int startIndex, double lat, double lon) { + for (int i = startIndex; i < locations.size(); i++) { + Location l = locations.get(i); + if (MapUtils.areLatLonEqual(l, lat, lon)) { + return i; + } + } + return null; + } + + @NonNull + private TurnType parseTurnType(@NonNull JSONObject maneuver, + boolean leftSide) throws JSONException { + TurnType turnType = null; + + String type = maneuver.getString("type"); + String modifier = null; + if (maneuver.has("modifier")) { + modifier = maneuver.getString("modifier"); + } + + if (objectEquals(type, "roundabout") + || objectEquals(type, "rotary") + || objectEquals(type, "roundabout turn")) { + if (maneuver.has("exit")) { + int exit = maneuver.getInt("exit"); + turnType = TurnType.getExitTurn(exit, 0.0f, leftSide); + } else if (modifier != null) { + // for simple roundabout turn without "exit" parameter + turnType = identifyTurnType(modifier, leftSide); + } + } else { + // for other maneuver types find TurnType + // like a basic turn into direction of the modifier + if (modifier != null) { + turnType = identifyTurnType(modifier, leftSide); + } + } + if (turnType == null) { + turnType = TurnType.straight(); + } + + int bearingBefore = maneuver.getInt("bearing_before"); + int bearingAfter = maneuver.getInt("bearing_after"); + float angle = (float) MapUtils.degreesDiff(bearingAfter, bearingBefore); + turnType.setTurnAngle(angle); + + return turnType; + } + + @Nullable + private TurnType identifyTurnType(@NonNull String modifier, + boolean leftSide) { + Integer id = null; + switch (modifier) { + case "uturn": + id = TurnType.TU; + break; + + case "sharp right": + id = TurnType.TSHR; + break; + + case "right": + id = TurnType.TR; + break; + + case "slight right": + id = TurnType.TSLR; + break; + + case "straight": + id = TurnType.C; + break; + + case "slight left": + id = TurnType.TSLL; + break; + + case "left": + id = TurnType.TL; + break; + + case "sharp left": + id = TurnType.TSHL; + break; + } + return id != null ? TurnType.valueOf(id, leftSide) : null; + } + + @NonNull + @Override + protected String getRootArrayKey() { + return "routes"; + } + + @NonNull + @Override + protected String getErrorMessageKey() { + return "message"; + } + } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java deleted file mode 100644 index 92621b2b3f..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/GpxParser.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.GPXUtilities; -import net.osmand.GPXUtilities.GPXFile; -import net.osmand.plus.OsmandApplication; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -public class GpxParser extends ResponseParser { - - @Override - @Nullable - public OnlineRoutingResponse parseResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) { - GPXFile gpxFile = parseGpx(content); - return gpxFile != null ? new OnlineRoutingResponse(parseGpx(content)) : null; - } - - @Override - public boolean isResultOk(@NonNull StringBuilder errorMessage, - @NonNull String content) { - return parseGpx(content) != null; - } - - private GPXFile parseGpx(@NonNull String content) { - InputStream gpxStream = null; - try { - gpxStream = new ByteArrayInputStream(content.getBytes("UTF-8")); - return GPXUtilities.loadGPXFile(gpxStream); - } catch (UnsupportedEncodingException e) { - LOG.debug("Error when parsing GPX from server response: " + e.getMessage()); - } - return null; - } - -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java b/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java deleted file mode 100644 index 62cf7e0f44..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/parser/ResponseParser.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.osmand.plus.onlinerouting.parser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.GPXUtilities.GPXFile; -import net.osmand.Location; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.routing.RouteDirectionInfo; - -import org.apache.commons.logging.Log; -import org.json.JSONException; - -import java.util.List; - -public abstract class ResponseParser { - - protected static final Log LOG = PlatformUtil.getLog(ResponseParser.class); - - @Nullable - public abstract OnlineRoutingResponse parseResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) throws JSONException; - - public abstract boolean isResultOk(@NonNull StringBuilder errorMessage, - @NonNull String content) throws JSONException; - - public static ResponseParser emptyParser() { - return new ResponseParser() { - @Nullable - @Override - public OnlineRoutingResponse parseResponse(@NonNull String content, - @NonNull OsmandApplication app, - boolean leftSideNavigation) { - return null; - } - - @Override - public boolean isResultOk(@NonNull StringBuilder errorMessage, - @NonNull String content) { - return false; - } - }; - } - - public static class OnlineRoutingResponse { - - private List route; - private List directions; - private GPXFile gpxFile; - - // constructor for JSON responses - public OnlineRoutingResponse(List route, List directions) { - this.route = route; - this.directions = directions; - } - - // constructor for GPX responses - public OnlineRoutingResponse(GPXFile gpxFile) { - this.gpxFile = gpxFile; - } - - public List getRoute() { - return route; - } - - public List getDirections() { - return directions; - } - - public GPXFile getGpxFile() { - return gpxFile; - } - } - -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index 4f626569d7..fee3d02524 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -462,7 +462,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { boolean resultOk = false; try { String response = helper.makeRequest(exampleCard.getEditedText()); - resultOk = requestedEngine.getResponseParser().isResultOk(errorMessage, response); + resultOk = requestedEngine.isResultOk(errorMessage, response); } catch (IOException | JSONException e) { errorMessage.append(e.toString()); } diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 0eb5a74e52..19d0fcd3f7 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -23,7 +23,7 @@ import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; -import net.osmand.plus.onlinerouting.parser.ResponseParser.OnlineRoutingResponse; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.CommonPreference;