New GEO URI parser
This commit is contained in:
parent
deba789918
commit
3d7ca7e09c
1 changed files with 80 additions and 47 deletions
|
@ -1,6 +1,8 @@
|
||||||
package net.osmand.util;
|
package net.osmand.util;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -82,15 +84,15 @@ public class GeoPointParserUtil {
|
||||||
|
|
||||||
// google calendar
|
// google calendar
|
||||||
// geo:0,0?q=760 West Genesee Street Syracuse NY 13204
|
// geo:0,0?q=760 West Genesee Street Syracuse NY 13204
|
||||||
String qstr = "q=760 West Genesee Street Syracuse NY 13204";
|
String qstr = "760 West Genesee Street Syracuse NY 13204";
|
||||||
url = "geo:0,0?" + qstr;
|
url = "geo:0,0?q=" + qstr;
|
||||||
System.out.println("url: " + url);
|
System.out.println("url: " + url);
|
||||||
actual = GeoPointParserUtil.parse("geo", url);
|
actual = GeoPointParserUtil.parse("geo", url);
|
||||||
assertGeoPoint(actual, new GeoParsedPoint(qstr.replaceAll("\\s+", "+")));
|
assertGeoPoint(actual, new GeoParsedPoint(qstr));
|
||||||
|
|
||||||
// geo:0,0?z=11&q=1600+Amphitheatre+Parkway,+CA
|
// geo:0,0?z=11&q=1600+Amphitheatre+Parkway,+CA
|
||||||
qstr = "q=1600+Amphitheatre+Parkway,+CA";
|
qstr = "1600 Amphitheatre Parkway, CA";
|
||||||
url = "geo:0,0?z=11&" + qstr;
|
url = "geo:0,0?z=11&q=" + URLEncoder.encode(qstr);
|
||||||
System.out.println("url: " + url);
|
System.out.println("url: " + url);
|
||||||
actual = GeoPointParserUtil.parse("geo", url);
|
actual = GeoPointParserUtil.parse("geo", url);
|
||||||
assertGeoPoint(actual, new GeoParsedPoint(qstr));
|
assertGeoPoint(actual, new GeoParsedPoint(qstr));
|
||||||
|
@ -450,48 +452,79 @@ public class GeoPointParserUtil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ("geo".equals(scheme) || "osmand.geo".equals(scheme)) {
|
if ("geo".equals(scheme) || "osmand.geo".equals(scheme)) {
|
||||||
final String schemeSpecific = data.getSchemeSpecificPart();
|
String schemeSpecific = data.getSchemeSpecificPart();
|
||||||
if (schemeSpecific == null) {
|
if (schemeSpecific == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (schemeSpecific.startsWith("0,0?")) {
|
|
||||||
// geo:0,0?q=34.99,-106.61(Treasure Island)
|
String name = null;
|
||||||
// geo:0,0?z=11&q=34.99,-106.61(Treasure Island)
|
final Pattern namePattern = Pattern.compile("[\\+\\s]*\\((.*)\\)[\\+\\s]*$");
|
||||||
String query = schemeSpecific.substring("0,0?".length());
|
final Matcher nameMatcher = namePattern.matcher(schemeSpecific);
|
||||||
final String pattern = "(?:z=(\\d{1,2}))?&?q=([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)[\\+]?(?:\\((.+?)\\))?";
|
if (nameMatcher.find()) {
|
||||||
final Matcher matcher = Pattern.compile(pattern).matcher(query);
|
name = URLDecoder.decode(nameMatcher.group(1));
|
||||||
if (matcher.matches()) {
|
if (name != null) {
|
||||||
final String z = matcher.group(1);
|
schemeSpecific = schemeSpecific.substring(0, nameMatcher.start());
|
||||||
final String name = matcher.group(4);
|
}
|
||||||
final int zoom = z != null ? Integer.parseInt(z) : GeoParsedPoint.NO_ZOOM;
|
}
|
||||||
final double lat = Double.parseDouble(matcher.group(2));
|
|
||||||
final double lon = Double.parseDouble(matcher.group(3));
|
String positionPart;
|
||||||
return new GeoParsedPoint(lat, lon, zoom, name);
|
String queryPart = "";
|
||||||
} else {
|
int queryStartIndex = schemeSpecific.indexOf('?');
|
||||||
// geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA
|
if (queryStartIndex == -1) {
|
||||||
if (query.contains("z="))
|
positionPart = schemeSpecific;
|
||||||
query = query.substring(query.indexOf("&") + 1);
|
} else {
|
||||||
return new GeoParsedPoint(query);
|
positionPart = schemeSpecific.substring(0, queryStartIndex);
|
||||||
}
|
if (queryStartIndex < schemeSpecific.length())
|
||||||
} else {
|
queryPart = schemeSpecific.substring(queryStartIndex + 1);
|
||||||
// geo:47.6,-122.3
|
}
|
||||||
// geo:47.6,-122.3?z=11 (Treasure Island)
|
|
||||||
final String pattern = "([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)(?:(?:\\?z=(\\d{1,2}))?|(?:\\?q=.*?)?)[\\+]?(?:\\((.*?)\\))?";
|
final Pattern positionPattern = Pattern.compile(
|
||||||
final Matcher matcher = Pattern.compile(pattern).matcher(schemeSpecific);
|
"([+-]?\\d+(?:\\.\\d+)?),([+-]?\\d+(?:\\.\\d+)?)");
|
||||||
if (matcher.matches()) {
|
final Matcher positionMatcher = positionPattern.matcher(positionPart);
|
||||||
final double lat = Double.valueOf(matcher.group(1));
|
if (!positionMatcher.find()) {
|
||||||
final double lon = Double.valueOf(matcher.group(2));
|
return null;
|
||||||
final String name = matcher.group(4);
|
}
|
||||||
int zoom = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : GeoParsedPoint.NO_ZOOM;
|
double lat = Double.valueOf(positionMatcher.group(1));
|
||||||
if (zoom != GeoParsedPoint.NO_ZOOM) {
|
double lon = Double.valueOf(positionMatcher.group(2));
|
||||||
return new GeoParsedPoint(lat, lon, zoom, name);
|
|
||||||
} else {
|
int zoom = GeoParsedPoint.NO_ZOOM;
|
||||||
return new GeoParsedPoint(lat, lon, name);
|
String searchRequest = null;
|
||||||
}
|
for (String param : queryPart.split("&")) {
|
||||||
} else {
|
String paramName;
|
||||||
return null;
|
String paramValue = null;
|
||||||
}
|
int nameValueDelimititerIndex = param.indexOf('=');
|
||||||
}
|
if (nameValueDelimititerIndex == -1) {
|
||||||
|
paramName = param;
|
||||||
|
} else {
|
||||||
|
paramName = param.substring(0, nameValueDelimititerIndex);
|
||||||
|
if (nameValueDelimititerIndex < param.length())
|
||||||
|
paramValue = param.substring(nameValueDelimititerIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("z".equals(paramName) && paramValue != null) {
|
||||||
|
zoom = Integer.parseInt(paramValue);
|
||||||
|
} else if ("q".equals(paramName) && paramValue != null) {
|
||||||
|
searchRequest = URLDecoder.decode(paramValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchRequest != null) {
|
||||||
|
final Matcher positionInSearchRequestMatcher =
|
||||||
|
positionPattern.matcher(searchRequest);
|
||||||
|
if (lat == 0.0 && lon == 0.0 && positionInSearchRequestMatcher.find()) {
|
||||||
|
lat = Double.valueOf(positionInSearchRequestMatcher.group(1));
|
||||||
|
lon = Double.valueOf(positionInSearchRequestMatcher.group(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lat == 0.0 && lon == 0.0 && searchRequest != null) {
|
||||||
|
return new GeoParsedPoint(searchRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoom != GeoParsedPoint.NO_ZOOM) {
|
||||||
|
return new GeoParsedPoint(lat, lon, zoom, name);
|
||||||
|
}
|
||||||
|
return new GeoParsedPoint(lat, lon, name);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue