From f30318bf49b58f679e2e6bc4de0563063600e08e Mon Sep 17 00:00:00 2001 From: Roman Inflianskas Date: Sat, 16 Apr 2016 18:39:01 +0300 Subject: [PATCH] Fix #2436 --- .../osmand/util/GeoPolylineParserUtil.java | 45 ++++++++++ .../util/GeoPolylineParserUtilTest.java | 88 +++++++++++++++++++ .../osmand/plus/routing/RouteProvider.java | 34 +++---- 3 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 OsmAnd-java/src/net/osmand/util/GeoPolylineParserUtil.java create mode 100644 OsmAnd-java/test/java/net/osmand/util/GeoPolylineParserUtilTest.java diff --git a/OsmAnd-java/src/net/osmand/util/GeoPolylineParserUtil.java b/OsmAnd-java/src/net/osmand/util/GeoPolylineParserUtil.java new file mode 100644 index 0000000000..7209dfc60a --- /dev/null +++ b/OsmAnd-java/src/net/osmand/util/GeoPolylineParserUtil.java @@ -0,0 +1,45 @@ +package net.osmand.util; + +import net.osmand.data.LatLon; +import java.util.ArrayList; +import java.util.List; + +public class GeoPolylineParserUtil { + /** + * Parses Google esque polyline + * + * @param encoded The polyline as a String + * @return {@link List} + */ + public static List parse(final String encoded) { + List track = new ArrayList(); + int index = 0; + int lat = 0, lng = 0; + double precision = 1E6; + + while (index < encoded.length()) { + int b, shift = 0, result = 0; + do { + b = encoded.charAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + lat += dlat; + + shift = 0; + result = 0; + do { + b = encoded.charAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + lng += dlng; + + LatLon p = new LatLon((double) lat / precision, (double) lng / precision); + track.add(p); + } + return track; + } +} diff --git a/OsmAnd-java/test/java/net/osmand/util/GeoPolylineParserUtilTest.java b/OsmAnd-java/test/java/net/osmand/util/GeoPolylineParserUtilTest.java new file mode 100644 index 0000000000..5b5895a280 --- /dev/null +++ b/OsmAnd-java/test/java/net/osmand/util/GeoPolylineParserUtilTest.java @@ -0,0 +1,88 @@ +package net.osmand.util; + +import net.osmand.data.LatLon; + +import java.util.Arrays; +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by rominf on 4/16/16. + */ + +public class GeoPolylineParserUtilTest { + @Test + public void testDecode() { + Assert.assertEquals(Arrays.asList( + new LatLon(52.503032, 13.420526), + new LatLon(52.503240, 13.420671), + new LatLon(52.503669, 13.420973), + new LatLon(52.504054, 13.421244), + new LatLon(52.504302, 13.421418), + new LatLon(52.504454, 13.421525), + new LatLon(52.504616, 13.421639), + new LatLon(52.504843, 13.421798), + new LatLon(52.505043, 13.421939), + new LatLon(52.505102, 13.421981), + new LatLon(52.505092, 13.422116), + new LatLon(52.505075, 13.422305), + new LatLon(52.505063, 13.422509), + new LatLon(52.505050, 13.422942), + new LatLon(52.505055, 13.423287), + new LatLon(52.505071, 13.423649), + new LatLon(52.505092, 13.423895), + new LatLon(52.505160, 13.424429), + new LatLon(52.505204, 13.424704), + new LatLon(52.505278, 13.425052), + new LatLon(52.505370, 13.425399), + new LatLon(52.505508, 13.425830), + new LatLon(52.505680, 13.426272), + new LatLon(52.505796, 13.426507), + new LatLon(52.505851, 13.426619), + new LatLon(52.505995, 13.426914), + new LatLon(52.506250, 13.427290), + new LatLon(52.506366, 13.427431), + new LatLon(52.506438, 13.427521), + new LatLon(52.506637, 13.427728), + new LatLon(52.506849, 13.427905), + new LatLon(52.507004, 13.428004), + new LatLon(52.507104, 13.428081), + new LatLon(52.507253, 13.428195), + new LatLon(52.507353, 13.428258), + new LatLon(52.507484, 13.428282), + new LatLon(52.507651, 13.428288), + new LatLon(52.507947, 13.428300), + new LatLon(52.508137, 13.428360), + new LatLon(52.508293, 13.428475), + new LatLon(52.508412, 13.428562), + new LatLon(52.508687, 13.428804), + new LatLon(52.508874, 13.428973), + new LatLon(52.509587, 13.429607), + new LatLon(52.509697, 13.429708), + new LatLon(52.510056, 13.430027), + new LatLon(52.510192, 13.430113), + new LatLon(52.510476, 13.430249), + new LatLon(52.510559, 13.430042), + new LatLon(52.510925, 13.429097), + new LatLon(52.511293, 13.428160), + new LatLon(52.511772, 13.427079), + new LatLon(52.511958, 13.427142), + new LatLon(52.512213, 13.427215), + new LatLon(52.512322, 13.427244), + new LatLon(52.512495, 13.427291), + new LatLon(52.512879, 13.427406), + new LatLon(52.513202, 13.427515), + new LatLon(52.513547, 13.427699), + new LatLon(52.514054, 13.427939), + new LatLon(52.514941, 13.428551), + new LatLon(52.515179, 13.428724), + new LatLon(52.515530, 13.428902), + new LatLon(52.515872, 13.429033), + new LatLon(52.516514, 13.429265), + new LatLon(52.516582, 13.429288)), + GeoPolylineParserUtil.parse("" + + "o~occB{}brX_LaHyY{QaW}OoN{IoHuEcIcFeM}HoKyGuBsARmG`@yJVwKXaZIqT_@sUi@kNgCk`@wAePsCwTwDuTsG}Y" + + "wIsZgFuMmB_F_HmQ}NoVgFyGoCsDmK}KgLaJuHeEgEyCiHcFgE}BeGo@mIKoQW{JwBwHeFmFmDePcNuJqIqk@sf@{EiE" + + "mU}RoGkDwPoGeD|K{U`z@_Vpy@}\\pbAsJ}B}NqCyEy@yI}A_WeFeSyEqToJu^_Nmv@ge@{MyI}TcJkTeGcg@oMgCm@")); + } +} diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 0b2ad2f354..e6054187ca 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -1,6 +1,7 @@ package net.osmand.plus.routing; +import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -56,7 +57,9 @@ import net.osmand.router.RoutingContext; import net.osmand.router.TurnType; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; +import net.osmand.util.GeoPolylineParserUtil; +import org.json.JSONObject; import org.json.JSONException; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -1142,30 +1145,31 @@ public class RouteProvider { } } appendOSRMLoc(uri, params.end); - uri.append("&output=gpx"); //$NON-NLS-1$ - + log.info("URL route " + uri); URLConnection connection = NetworkUtils.getHttpURLConnection(uri.toString()); connection.setRequestProperty("User-Agent", Version.getFullVersion(params.ctx)); -// StringBuilder content = new StringBuilder(); -// BufferedReader rs = new BufferedReader(new InputStreamReader(connection.getInputStream())); -// String s; -// while((s = rs.readLine()) != null) { -// content.append(s); -// } -// JSONObject obj = new JSONObject(content.toString()); - final InputStream inputStream = connection.getInputStream(); - GPXFile gpxFile = GPXUtilities.loadGPXFile(params.ctx, inputStream); + StringBuilder content = new StringBuilder(); + BufferedReader rs = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String s; + while((s = rs.readLine()) != null) { + content.append(s); + } + JSONObject obj = new JSONObject(content.toString()); try { - inputStream.close(); + rs.close(); } catch(IOException e){ } - if(gpxFile.routes.isEmpty()) { + List route = GeoPolylineParserUtil.parse(obj.get("route_geometry").toString()); + if (route.isEmpty()) { return new RouteCalculationResult("Route is empty"); } - for (WptPt pt : gpxFile.routes.get(0).points) { - res.add(createLocation(pt)); + for (LatLon pt : route) { + 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);