From 87896f852b9a2e79cd7f9f3c7093d0b9cc09a7e5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 31 Mar 2015 22:33:09 -0400 Subject: [PATCH] fix Google Maps URL parsing for all known URLS This fixes the FIXME URLs, and adds a new URL with the query name in the fragment. --- .../net/osmand/util/GeoPointParserUtil.java | 90 +++++++++++++++---- 1 file changed, 73 insertions(+), 17 deletions(-) diff --git a/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java b/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java index 3f03497517..31d673258b 100644 --- a/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java +++ b/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java @@ -341,19 +341,39 @@ public class GeoPointParserUtil { actual = GeoPointParserUtil.parse(url); assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); + // http://www.google.com/maps/?q=loc:34,-106&z=11 + url = "http://www.google.com/maps/?q=loc:" + ilat + "," + ilon + "&z=" + z; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse(url); + assertGeoPoint(actual, new GeoParsedPoint(ilat, ilon, z)); + + // http://www.google.com/maps/?q=loc:34.99393,-106.61568&z=11 + url = "http://www.google.com/maps/?q=loc:" + dlat + "," + dlon + "&z=" + z; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse(url); + assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); + + // https://www.google.com/maps/preview#!q=paris&data=!4m15!2m14!1m13!1s0x47e66e1f06e2b70f%3A0x40b82c3688c9460!3m8!1m3!1d24383582!2d-95.677068!3d37.0625!3m2!1i1222!2i718!4f13.1!4m2!3d48.856614!4d2.3522219 + url = "https://www.google.com/maps/preview#!q=paris&data=!4m15!2m14!1m13!1s0x47e66e1f06e2b70f%3A0x40b82c3688c9460!3m8!1m3!1d24383582!2d-95.677068!3d37.0625!3m2!1i1222!2i718!4f13.1!4m2!3d48.856614!4d2.3522219"; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse(url); + assertGeoPoint(actual, new GeoParsedPoint("paris")); + + // TODO this URL does not work, where is it used? // http://maps.google.com/maps/q=loc:34,-106&z=11 url = "http://maps.google.com/maps/q=loc:" + ilat + "," + ilon + "&z=" + z; System.out.println("url: " + url); actual = GeoPointParserUtil.parse(url); assertGeoPoint(actual, new GeoParsedPoint(ilat, ilon, z)); + // TODO this URL does not work, where is it used? // http://maps.google.com/maps/q=loc:34.99393,-106.61568&z=11 url = "http://maps.google.com/maps/q=loc:" + dlat + "," + dlon + "&z=" + z; System.out.println("url: " + url); actual = GeoPointParserUtil.parse(url); assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); - + // TODO this URL does not work, where is it used? // whatsapp // http://maps.google.com/maps/q=loc:34,-106 (You) z = GeoParsedPoint.NO_ZOOM; @@ -362,6 +382,7 @@ public class GeoPointParserUtil { actual = GeoPointParserUtil.parse(url); assertGeoPoint(actual, new GeoParsedPoint(ilat, ilon, z)); + // TODO this URL does not work, where is it used? // whatsapp // http://maps.google.com/maps/q=loc:34.99393,-106.61568 (You) z = GeoParsedPoint.NO_ZOOM; @@ -424,6 +445,27 @@ public class GeoPointParserUtil { actual = GeoPointParserUtil.parse(url); assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); + // http://maps.google.co.uk/?q=34.99393,-106.61568 + z = GeoParsedPoint.NO_ZOOM; + url = "http://maps.google.co.uk/?q=" + dlat + "," + dlon; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse(url); + assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); + + // http://www.google.com.tr/maps?q=34.99393,-106.61568 + z = GeoParsedPoint.NO_ZOOM; + url = "http://www.google.com.tr/maps?q=" + dlat + "," + dlon; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse(url); + assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); + + // https://www.google.com/maps/place/34%C2%B059'38.1%22N+106%C2%B036'56.5%22W/@34.99393,-106.61568,17z/data=!3m1!4b1!4m2!3m1!1s0x0:0x0 + z = 17; + url = "https://www.google.com/maps/place/34%C2%B059'38.1%22N+106%C2%B036'56.5%22W/@" + dlat + "," + dlon + "," + z + "z/data=!3m1!4b1!4m2!3m1!1s0x0:0x0"; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse(url); + assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); + // http://www.google.com/maps/place/760+West+Genesee+Street+Syracuse+NY+13204 qstr = "760 West Genesee Street Syracuse NY 13204"; url = "http://www.google.com/maps/place/" + URLEncoder.encode(qstr); @@ -578,21 +620,6 @@ public class GeoPointParserUtil { throw new RuntimeException(u + " not parsable!"); System.out.println("Properly parsed as: " + actual.getGeoUriString()); } - - // http://www.google.com/maps/?q=loc:34,-106&z=11 - url = "http://www.google.com/maps/?q=loc:" + ilat + "," + ilon + "&z=" + z; - System.out.println("url: " + url); - actual = GeoPointParserUtil.parse(url); - // FIXME FAIL - assertGeoPoint(actual, new GeoParsedPoint(ilat, ilon, z)); - - // http://www.google.com/maps/?q=loc:34.99393,-106.61568&z=11 - url = "http://www.google.com/maps/?q=loc:" + dlat + "," + dlon + "&z=" + z; - System.out.println("url: " + url); - actual = GeoPointParserUtil.parse(url); - // FIXME FAIL - assertGeoPoint(actual, new GeoParsedPoint(dlat, dlon, z)); - // these URLs are not parsable, but should not crash or cause problems String[] unparsableUrls = { @@ -784,7 +811,7 @@ public class GeoPointParserUtil { simpleDomains.add("www.openstreetmap.de"); - final Pattern commaSeparatedPairPattern = Pattern.compile("([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)"); + final Pattern commaSeparatedPairPattern = Pattern.compile("(?:loc:)?([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)"); try { if (host.equals("osm.org") || host.endsWith("openstreetmap.org")) { @@ -862,7 +889,29 @@ public class GeoPointParserUtil { } } } else if (host.matches("(?:www\\.)?(?:maps\\.)?google\\.[a-z.]+")) { + String latString = null; + String lonString = null; + String z = String.valueOf(GeoParsedPoint.NO_ZOOM); Map params = getQueryParameters(uri); + if(params.containsKey("q")){ + Matcher matcher = commaSeparatedPairPattern.matcher(params.get("q")); + if (matcher.matches()) { + latString = matcher.group(1); + lonString = matcher.group(2); + } + } else if(params.containsKey("ll")){ + Matcher matcher = commaSeparatedPairPattern.matcher(params.get("ll")); + if (matcher.matches()) { + latString = matcher.group(1); + lonString = matcher.group(2); + } + } + if (latString != null && lonString != null) { + if (params.containsKey("z")) { + z = params.get("z"); + } + return new GeoParsedPoint(latString, lonString, z); + } if(params.containsKey("daddr")){ return parseGoogleMapsPath(params.get("daddr"), params); } else if(params.containsKey("saddr")){ @@ -870,6 +919,13 @@ public class GeoPointParserUtil { } else if(params.containsKey("q")){ return parseGoogleMapsPath(params.get("q"), params); } + if (fragment != null) { + Pattern p = Pattern.compile(".*[!&]q=([^&!]+).*"); + Matcher m = p.matcher(fragment); + if (m.matches()) { + return new GeoParsedPoint(m.group(1)); + } + } String[] pathPrefixes = new String[] { "/@", "/ll=", "loc:", "/" };