diff --git a/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java b/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java new file mode 100644 index 0000000000..0e8db4bb03 --- /dev/null +++ b/OsmAnd-java/src/net/osmand/util/GeoPointParserUtil.java @@ -0,0 +1,356 @@ +package net.osmand.util; + +import java.net.URI; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class GeoPointParserUtil { + + public static void main(String[] args) { + final double lat = 34.99, lon = -106.61; + final String name = "Treasure"; + int z = GeoParsedPoint.NO_ZOOM; + String url; + + // 0,0?q=34.99,-106.61(Treasure) + url = "geo:0,0?q=" + lat + "," + lon + "(" + name + ")"; + System.out.println("url: " + url); + GeoParsedPoint actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(lat, lon, z, name)); + + // geo:0,0?z=11&q=34.99,-106.61(Treasure) + z = 11; + url = "geo:0,0?z=" + z + "&q=" + lat + "," + lon + "(" + name + ")"; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(lat, lon, z, name)); + + // geo:0,0?z=11&q=34.99,-106.61 + z = 11; + url = "geo:0,0?z=" + z + "&q=" + lat + "," + lon; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(lat, lon, z)); + + // geo:34.99,-106.61 + z = -1; + url = "geo:" + lat + "," + lon; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(lat, lon, z)); + + // geo:34.99,-106.61?z=11 + z = 11; + url = "geo:" + lat + "," + lon + "?" + "z=" + z; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(lat, lon, z)); + + // geo:0,0?q=1600+Amphitheatre+Parkway,+CA + String qstr = "q=1600+Amphitheatre+Parkway,+CA"; + url = "geo:0,0?" + qstr; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(qstr)); + + // geo:0,0?z=11&q=1600+Amphitheatre+Parkway,+CA + qstr = "q=1600+Amphitheatre+Parkway,+CA"; + url = "geo:0,0?z=11&" + qstr; + System.out.println("url: " + url); + actual = GeoPointParserUtil.parse("geo", url); + assertGeoPoint(actual, new GeoParsedPoint(qstr)); + } + + private static void assertGeoPoint(GeoParsedPoint actual, GeoParsedPoint expected) { + if (expected.getQuery() != null) { + if (!expected.getQuery().equals(actual.getQuery())) + throw new RuntimeException("Query param not equal"); + } else { + double aLat = actual.getLat(), eLat = expected.getLat(), aLon = actual.getLon(), eLon = expected.getLon(); + int aZoom = actual.getZoom(), eZoom = expected.getZoom(); + String aName = actual.getName(), eName = expected.getName(); + if (eName != null) { + if (!aName.equals(eName)) { + throw new RuntimeException("Point name\\capture is not equal; actual=" + aName + ", expected=" + + eName); + } + } + if (eLat != aLat) { + throw new RuntimeException("Latitude is not equal; actual=" + aLat + ", expected=" + eLat); + } + if (eLon != aLon) { + throw new RuntimeException("Longitude is not equal; actual=" + aLon + ", expected=" + eLon); + } + if (eZoom != aZoom) { + throw new RuntimeException("Zoom is not equal; actual=" + aZoom + ", expected=" + aZoom); + } + } + System.out.println("Passed!"); + } + + private static String getQueryParameter(final String param, URI data) { + final String query = data.getQuery(); + String value = null; + if (query.contains(param)) { + String[] params = query.split("&"); + for (String p : params) { + if (p.contains(param)) { + value = p.substring(p.indexOf("=") + 1, p.length()); + break; + } + } + } + return value; + } + + /** + * Parses geo and map intents: + * + * @param scheme + * The intent scheme + * @param data + * The URI object + * @return {@link GeoParsedPoint} + */ + public static GeoParsedPoint parse(final String scheme, final String uri) { + final URI data = URI.create(uri.replaceAll("\\s+", "")); + if ("http".equals(scheme) || "https".equals(scheme)) { + + final String schemeSpecific = data.getSchemeSpecificPart(); + + if (schemeSpecific == null) { + return null; + } + + final String[] osmandNetSite = { "//download.osmand.net/go?" }; + + final String[] osmandNetPattern = { "lat=(-?\\d{1,3}.\\d+)&lon=(-?\\d{1,3}.\\d+)&z=(\\d{1,2})" }; + + final String[] openstreetmapOrgSite = { "//openstreetmap.org/", "//www.openstreetmap.org/" }; + + final String[] openstreetmapOrgPattern = { "(?:.*)(?:map=)(\\d{1,2})/(-?\\d{1,3}.\\d+)/(-?\\d{1,3}.\\d+)(?:.*)" }; + + final String[] openstreetmapDeSite = { "//openstreetmap.de/", "//www.openstreetmap.de/" }; + + final String[] openstreetmapDePattern = { + "(?:.*)zoom=(\\d{1,2})&lat=(-?\\d{1,3}.\\d+)&lon=(-?\\d{1,3}.\\d+)(?:.*)", + "(?:.*)lat=(-?\\d{1,3}.\\d+)&lon=(-?\\d{1,3}.\\d+)&z(?:oom)?=(\\d{1,2})(?:.*)" }; + + final String[] googleComSite = { "//www.google.com/maps/", "//maps.google.com/maps" }; + + final String[] googleComPattern = { "(?:.*)@(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+),(\\d{1,2})z(?:.*)", + "(?:.*)ll=(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+)(?:.+)z=(\\d{1,2})(?:.*)", + "(?:.*)q=([\\-+]?\\d{1,3}.\\d+),([\\-+]?\\d{1,3}.\\d+)(?:.*)&z=(\\d{1,2})", + "(?:.*)q=loc:(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+)&z=(\\d{1,2})(?:.*)" }; + + final String[] yandexRuSite = { "//maps.yandex.ru/" }; + + final String[] yandexRuPattern = { "(?:.*)ll=(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+)(?:.+)z=(\\d{1,2})(?:.*)" }; + + final String sites[][] = { osmandNetSite, openstreetmapOrgSite, openstreetmapDeSite, googleComSite, + yandexRuSite }; + + final String patterns[][] = { osmandNetPattern, openstreetmapOrgPattern, openstreetmapDePattern, + googleComPattern, yandexRuPattern }; + + for (int s = 0; s < sites.length; s++) { + for (int si = 0; si < sites[s].length; si++) { + if (schemeSpecific.startsWith(sites[s][si])) { + for (int p = 0; p < patterns[s].length; p++) { + String subString = schemeSpecific.substring(sites[s][si].length()); + + if (subString.equals("")) { + subString = data.getFragment(); + } + + final Matcher matcher = Pattern.compile(patterns[s][p]).matcher(subString); + + if (matcher.matches()) { + try { + + final double lat; + final double lon; + final int zoom; + + // check sequence of values + if (!matcher.group(3).contains(".")) { + lat = Double.valueOf(matcher.group(1)); + lon = Double.valueOf(matcher.group(2)); + zoom = Integer.valueOf(matcher.group(3)); + } else { + zoom = Integer.valueOf(matcher.group(1)); + lat = Double.valueOf(matcher.group(2)); + lon = Double.valueOf(matcher.group(3)); + } + + return new GeoParsedPoint(lat, lon, zoom); + } catch (NumberFormatException e) { + return null; + } + } + } + break; + } + } + } + + String q = null; + String parameter = getQueryParameter("q", data); + if (parameter == null) { + parameter = getQueryParameter("daddr", data); + } + if (parameter != null) { + q = parameter.split(" ")[0]; + } + if (q.indexOf(',') != -1) { + int i = q.indexOf(','); + String lat = q.substring(0, i); + String lon = q.substring(i + 1); + if (lat.indexOf(':') != -1) { + i = lat.indexOf(':'); + lat = lat.substring(i + 1); + } + try { + double llat = Double.parseDouble(lat.trim()); + double llon = Double.parseDouble(lon.trim()); + return new GeoParsedPoint(llat, llon); + } catch (NumberFormatException e) { + return null; + } + } else { + return null; + } + } + if ("geo".equals(scheme) || "osmand.geo".equals(scheme)) { + final String schemeSpecific = data.getSchemeSpecificPart(); + if (schemeSpecific == null) { + return null; + } + if (schemeSpecific.startsWith("0,0?")) { + // geo:0,0?q=34.99,-106.61(Treasure) + // geo:0,0?z=11&q=34.99,-106.61(Treasure) + String query = schemeSpecific.substring("0,0?".length()); + final String pattern = "(?:z=([0-9]{1,2})?)?&?q=([\\-0-9\\.]+)?,([\\-0-9\\.]+)?\\s*(?:\\((.+?)\\))?"; + final Matcher matcher = Pattern.compile(pattern).matcher(query); + if (matcher.matches()) { + final String z = matcher.group(1); + 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)); + return new GeoParsedPoint(lat, lon, zoom, name); + } else { + // geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA + // geo:0,0?z=11&q=1600+Amphitheatre+Parkway%2C+CA + // zoom parameter is not used in GeoAddressSearch + if (query.contains("z=")) + query = query.substring(query.indexOf("&") + 1); + return new GeoParsedPoint(query); + } + } else { + // geo:47.6,-122.3 + // geo:47.6,-122.3?z=11 + // allow for http://tools.ietf.org/html/rfc5870 (geo uri) , + // just + // ignore everything after ';' + final String pattern = "([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?z=([0-9]+))?(?:;.*)?"; + int indexQ = schemeSpecific.indexOf("&q"); + final Matcher matcher; + if (indexQ != -1) { + final String schemeQ = schemeSpecific.substring(0, indexQ); + matcher = Pattern.compile(pattern).matcher(schemeQ); + } else { + matcher = Pattern.compile(pattern).matcher(schemeSpecific); + } + + final String pattern2 = "([\\-0-9.]+),([\\-0-9.]+)(?:.*)"; // c:geo + final Matcher matcher2 = Pattern.compile(pattern2).matcher(schemeSpecific); + + if (matcher.matches()) { + final double lat = Double.valueOf(matcher.group(1)); + final double lon = Double.valueOf(matcher.group(2)); + if (matcher.group(4) == null) { + return new GeoParsedPoint(lat, lon); + } else { + return new GeoParsedPoint(lat, lon, Integer.valueOf(matcher.group(4))); + } + } else if (matcher2.matches()) { + final double lat = Double.valueOf(matcher2.group(1)); + final double lon = Double.valueOf(matcher2.group(2)); + return new GeoParsedPoint(lat, lon); + } else { + return null; + } + } + } + return null; + } + + public static class GeoParsedPoint { + private static final int NO_ZOOM = -1; + + private double lat; + private double lon; + private int zoom = NO_ZOOM; + private String name; + private String query; + private boolean geoPoint; + private boolean geoAddress; + + public GeoParsedPoint(double lat, double lon) { + super(); + this.lat = lat; + this.lon = lon; + this.geoPoint = true; + } + + public GeoParsedPoint(double lat, double lon, String name) { + this(lat, lon); + this.name = name; + } + + public GeoParsedPoint(double lat, double lon, int zoom) { + this(lat, lon); + this.zoom = zoom; + } + + public GeoParsedPoint(double lat, double lon, int zoom, String name) { + this(lat, lon, zoom); + this.name = name; + } + + public GeoParsedPoint(String query) { + super(); + this.query = query; + this.geoAddress = true; + } + + public double getLat() { + return lat; + } + + public double getLon() { + return lon; + } + + public int getZoom() { + return zoom; + } + + public String getName() { + return name; + } + + public String getQuery() { + return query; + } + + public boolean isGeoPoint() { + return geoPoint; + } + + public boolean isGeoAddress() { + return geoAddress; + } + } +} diff --git a/OsmAnd/.classpath b/OsmAnd/.classpath index 107ea5f643..dcd2d81373 100644 --- a/OsmAnd/.classpath +++ b/OsmAnd/.classpath @@ -1,10 +1,10 @@ - - + + diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index c61e7151d5..ed455258a9 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -1,4 +1,4 @@ - + Без аўтаматычнага масштабіраваньня Зачыніць Для сярэдняга масштаба diff --git a/OsmAnd/res/values-ca/strings.xml b/OsmAnd/res/values-ca/strings.xml index 54c04f0179..300d9dc3c7 100644 --- a/OsmAnd/res/values-ca/strings.xml +++ b/OsmAnd/res/values-ca/strings.xml @@ -1,4 +1,4 @@ - + Mostra els missatges d\'avís… Rutes amb fluorescència Mostra el regle diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 3043266f40..0f245653b7 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -1,4 +1,4 @@ - + Vektorové mapy toto místo neobsahují. Mapová data můžete stáhnout v Nastaveních (Spravovat mapové soubory), nebo se přepněte na online mapy. "Změny ve verzi 0.7.2 : \n\t- Native rendering pro všechna zařízení diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index a559ff5fab..efe2652899 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -1,4 +1,4 @@ - + Configura pantalla diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index c8c40745fc..8fcefd91c5 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -1,4 +1,4 @@ - + Modifications hors-ligne Toujours utiliser l\'édition hors-ligne "Changements en 0.7.1 : diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 0c22c5a211..0d99071add 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -1,4 +1,4 @@ - + 新しいデータを展開中… オンライン経路案内を使用しようとしていますが インターネット接続されていません。 diff --git a/OsmAnd/res/values-ko/strings.xml b/OsmAnd/res/values-ko/strings.xml index 5c6e9716dd..edcc91ff3e 100644 --- a/OsmAnd/res/values-ko/strings.xml +++ b/OsmAnd/res/values-ko/strings.xml @@ -1,4 +1,4 @@ - + 벡터 맵이 더욱 빠르게 표시됩니다. 하지만, 어떤 기기에서는 잘 작동하지 않을 수 있습니다. 현재 선택된 음성 명령을 재생합니다 diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index 91d5861bab..8668725029 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -1,4 +1,4 @@ - + "Zmiany w 0.6.9: \n\t- poprawiono renderowanie map offline \n\t- szybkie renderowanie natywne (wersja eksperymentalna - może nie działać na niektórych urządzeniach) \n\t- poprawki w interfejsie \n\t- dodano wyświetlanie informacji o wysokości (altitude) \n\t- nowe tłumaczenia (polskie, wietnamskie) \n\t- inne, mniejsze poprawki " Przezroczysty styl diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index 07bd6f87de..6b3f0a95a4 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -1,4 +1,4 @@ - + Ammustra sa positzione semper a su tzentru Boghe Mistura diff --git a/OsmAnd/res/values-sv/strings.xml b/OsmAnd/res/values-sv/strings.xml index b351a7de03..669934b26c 100644 --- a/OsmAnd/res/values-sv/strings.xml +++ b/OsmAnd/res/values-sv/strings.xml @@ -1,4 +1,4 @@ - + För att låsa upp skärmen tryck på låsikonen Välj land Välj stad diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index fafd961174..2d4cf00508 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -1,4 +1,4 @@ - + Зміни в 0.8.1: \n\t* Більш точні маршрути (трохи повільніше) \n\t* Розумний і швидкий перерахунок маршруту diff --git a/OsmAnd/res/values-zh-rCN/strings.xml b/OsmAnd/res/values-zh-rCN/strings.xml index 3739569db9..4520da6e7e 100644 --- a/OsmAnd/res/values-zh-rCN/strings.xml +++ b/OsmAnd/res/values-zh-rCN/strings.xml @@ -1,4 +1,4 @@ - + 電子郵件 名稱 打開 diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 08b417cc74..0a9ca89b6e 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -1,4 +1,4 @@ - + 選擇道路的色彩調配: 道路的色彩調配 顯示目的地方向 diff --git a/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java index c1209f865b..0987f9a917 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/GeoIntentActivity.java @@ -1,6 +1,5 @@ package net.osmand.plus.activities.search; -import android.os.AsyncTask; import gnu.trove.map.hash.TLongObjectHashMap; import java.util.ArrayList; @@ -8,8 +7,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import net.osmand.ResultMatcher; import net.osmand.access.AccessibleToast; @@ -27,6 +24,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandListActivity; import net.osmand.plus.resources.RegionAddressRepository; import net.osmand.plus.resources.ResourceManager; +import net.osmand.util.GeoPointParserUtil; import net.osmand.util.MapUtils; import android.app.Dialog; import android.app.ProgressDialog; @@ -34,6 +32,7 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -45,125 +44,102 @@ import android.widget.Toast; public class GeoIntentActivity extends OsmandListActivity { - private ProgressDialog progressDlg; + private ProgressDialog progressDlg; private LatLon location; private ProgressDialog startProgressDialog; - @Override - protected void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - setContentView(R.layout.search_address_offline); - getSupportActionBar().setTitle(R.string.search_osm_offline); - startProgressDialog = new ProgressDialog(this); - getMyApplication().checkApplicationIsBeingInitialized(this, startProgressDialog); - location = getMyApplication().getSettings().getLastKnownMapLocation(); + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.search_address_offline); + getSupportActionBar().setTitle(R.string.search_osm_offline); + startProgressDialog = new ProgressDialog(this); + getMyApplication().checkApplicationIsBeingInitialized(this, startProgressDialog); + location = getMyApplication().getSettings().getLastKnownMapLocation(); - final Intent intent = getIntent(); - if (intent != null) - { - final ProgressDialog progress = ProgressDialog.show(GeoIntentActivity.this, getString(R.string.searching), getString(R.string.searching_address)); - final GeoIntentTask task = new GeoIntentTask(progress, intent); + final Intent intent = getIntent(); + if (intent != null) { + final ProgressDialog progress = ProgressDialog.show(GeoIntentActivity.this, getString(R.string.searching), + getString(R.string.searching_address)); + final GeoIntentTask task = new GeoIntentTask(progress, intent); - progress.setOnCancelListener(new OnCancelListener() - { - @Override - public void onCancel(DialogInterface dialog) - { - task.cancel(true); - } - }); - progress.setCancelable(true); + progress.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + task.cancel(true); + } + }); + progress.setCancelable(true); - task.execute(); + task.execute(); setIntent(null); - } - } + } + } - private class GeoIntentTask extends AsyncTask - { - private final ProgressDialog progress; - private final Intent intent; + private class GeoIntentTask extends AsyncTask { + private final ProgressDialog progress; + private final Intent intent; - private GeoIntentTask(final ProgressDialog progress, final Intent intent) - { - this.progress = progress; - this.intent = intent; - } + private GeoIntentTask(final ProgressDialog progress, final Intent intent) { + this.progress = progress; + this.intent = intent; + } - @Override - protected void onPreExecute() - { - } + @Override + protected void onPreExecute() { + } - @Override - protected ExecutionResult doInBackground(Void... nothing) - { - try - { - while (getMyApplication().isApplicationInitializing()) - { - Thread.sleep(200); - } - return extract(intent.getScheme(), intent.getData()).execute(); - } - catch (Exception e) - { - return null; - } - } + @Override + protected ExecutionResult doInBackground(Void... nothing) { + try { + while (getMyApplication().isApplicationInitializing()) { + Thread.sleep(200); + } + return extract(intent.getScheme(), intent.getData()).execute(); + } catch (Exception e) { + return null; + } + } - @Override - protected void onPostExecute(ExecutionResult result) - { - progress.dismiss(); - if (result != null) - { - if (result.isEmpty()) - { - AccessibleToast.makeText(GeoIntentActivity.this, getString(R.string.search_nothing_found), Toast.LENGTH_LONG).show(); - } - else - { - if (result.hasZoom()) - { - getMyApplication().getSettings().setLastKnownMapZoom(result.getZoom()); - } + @Override + protected void onPostExecute(ExecutionResult result) { + progress.dismiss(); + if (result != null) { + if (result.isEmpty()) { + AccessibleToast.makeText(GeoIntentActivity.this, getString(R.string.search_nothing_found), + Toast.LENGTH_LONG).show(); + } else { + if (result.hasZoom()) { + getMyApplication().getSettings().setLastKnownMapZoom(result.getZoom()); + } - final List places = new ArrayList(result.getMapObjects()); + final List places = new ArrayList(result.getMapObjects()); setListAdapter(new MapObjectAdapter(places)); - if (places.size() == 1) - { - onListItemClick( - getListView(), - getListAdapter().getView(0, null, null), - 0, - getListAdapter().getItemId(0) - ); - } - } - } - else - { - AccessibleToast.makeText(GeoIntentActivity.this, getString(R.string.search_offline_geo_error, intent.getData()), Toast.LENGTH_LONG).show(); - } - } + if (places.size() == 1) { + onListItemClick(getListView(), getListAdapter().getView(0, null, null), 0, getListAdapter() + .getItemId(0)); + } + } + } else { + AccessibleToast.makeText(GeoIntentActivity.this, + getString(R.string.search_offline_geo_error, intent.getData()), Toast.LENGTH_LONG).show(); + } + } - } + } @Override protected Dialog onCreateDialog(int id) { - if(id == OsmandApplication.PROGRESS_DIALOG){ + if (id == OsmandApplication.PROGRESS_DIALOG) { return startProgressDialog; } return super.onCreateDialog(id); } - + private class MapObjectAdapter extends ArrayAdapter { public MapObjectAdapter(List places) { - super(GeoIntentActivity.this, - R.layout.search_address_offline_list_item, places); + super(GeoIntentActivity.this, R.layout.search_address_offline_list_item, places); } @Override @@ -171,19 +147,15 @@ public class GeoIntentActivity extends OsmandListActivity { View row = convertView; if (row == null) { LayoutInflater inflater = getLayoutInflater(); - row = inflater.inflate( - R.layout.search_address_offline_list_item, parent, - false); + row = inflater.inflate(R.layout.search_address_offline_list_item, parent, false); } MapObject model = getItem(position); TextView label = (TextView) row.findViewById(R.id.label); - TextView distanceLabel = (TextView) row - .findViewById(R.id.distance_label); + TextView distanceLabel = (TextView) row.findViewById(R.id.distance_label); if (location != null) { - int dist = (int) (MapUtils.getDistance(location, model - .getLocation().getLatitude(), model.getLocation() + int dist = (int) (MapUtils.getDistance(location, model.getLocation().getLatitude(), model.getLocation() .getLongitude())); - distanceLabel.setText(OsmAndFormatter.getFormattedDistance(dist,(OsmandApplication) getApplication())); + distanceLabel.setText(OsmAndFormatter.getFormattedDistance(dist, (OsmandApplication) getApplication())); } else { distanceLabel.setText(""); //$NON-NLS-1$ } @@ -191,12 +163,12 @@ public class GeoIntentActivity extends OsmandListActivity { return row; } } - - private String getString(MapObject o){ - if(o instanceof Amenity) { + + private String getString(MapObject o) { + if (o instanceof Amenity) { return OsmAndFormatter.getPoiSimpleFormat((Amenity) o, getMyApplication(), false); } - if(o instanceof Street) { + if (o instanceof Street) { return getString(R.string.address) + " " + ((Street) o).getCity().getName() + " " + o.getName(); } return getString(R.string.address) + " : " + o.toString(); @@ -207,7 +179,7 @@ public class GeoIntentActivity extends OsmandListActivity { super.onListItemClick(l, v, position, id); MapObject item = ((MapObjectAdapter) getListAdapter()).getItem(position); OsmandSettings settings = getMyApplication().getSettings(); - settings.setMapLocationToShow(item.getLocation().getLatitude(), item.getLocation().getLongitude(), + settings.setMapLocationToShow(item.getLocation().getLatitude(), item.getLocation().getLongitude(), settings.getLastKnownMapZoom(), getString(item)); //$NON-NLS-1$ MapActivity.launchMapActivityMoveToTop(this); } @@ -226,301 +198,90 @@ public class GeoIntentActivity extends OsmandListActivity { } /** - * Extracts information from geo and map intents: - * + * Extracts information from geo and map intents: + * * geo:47.6,-122.3
- * geo:47.6,-122.3?z=11
- * geo:0,0?q=34.99,-106.61(Treasure)
- * geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA
- * - * @param scheme The intent scheme - * @param data The intent uri + * geo:47.6,-122.3?z=11
+ * geo:0,0?q=34.99,-106.61(Treasure)
+ * geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA
+ * + * @param scheme + * The intent scheme + * @param data + * The intent uri * @return */ - private MyService extract(final String scheme, final Uri data) - { - if ("http".equals(scheme) || "https".equals(scheme)) { + private MyService extract(final String scheme, final Uri data) { + GeoPointParserUtil.GeoParsedPoint p = GeoPointParserUtil.parse(scheme, data.toString()); + if (p.isGeoPoint()) { + if (p.getName() != null) { + return new GeoPointSearch(p.getLat(), p.getLon(), p.getName(), p.getZoom()); + } + return new GeoPointSearch(p.getLat(), p.getLon(), p.getZoom()); + } else { + return new GeoAddressSearch(p.getQuery()); + } + } - final String schemeSpecific = data.getSchemeSpecificPart(); - - if (schemeSpecific == null) { - return null; - } - - final String[] osmandNetSite = { - "//download.osmand.net/go?" - }; - - final String[] osmandNetPattern = { - "lat=(-?\\d{1,3}.\\d+)&lon=(-?\\d{1,3}.\\d+)&z=(\\d{1,2})" - }; - - final String[] openstreetmapOrgSite = { - "//openstreetmap.org/", - "//www.openstreetmap.org/" - }; - - final String[] openstreetmapOrgPattern = { - "(?:.*)(?:map=)(\\d{1,2})/(-?\\d{1,3}.\\d+)/(-?\\d{1,3}.\\d+)(?:.*)" - }; - - final String[] openstreetmapDeSite = { - "//openstreetmap.de/", - "//www.openstreetmap.de/" - }; - - final String[] openstreetmapDePattern = { - "(?:.*)zoom=(\\d{1,2})&lat=(-?\\d{1,3}.\\d+)&lon=(-?\\d{1,3}.\\d+)(?:.*)", - "(?:.*)lat=(-?\\d{1,3}.\\d+)&lon=(-?\\d{1,3}.\\d+)&z(?:oom)?=(\\d{1,2})(?:.*)" - }; - - final String[] googleComSite = { - "//www.google.com/maps/", - "//maps.google.com/maps" - }; - - final String[] googleComPattern = { - "(?:.*)@(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+),(\\d{1,2})z(?:.*)", - "(?:.*)ll=(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+)(?:.+)z=(\\d{1,2})(?:.*)", - "(?:.*)q=([\\-+]?\\d{1,3}.\\d+),([\\-+]?\\d{1,3}.\\d+)(?:.*)&z=(\\d{1,2})", - "(?:.*)q=loc:(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+)&z=(\\d{1,2})(?:.*)" - }; - - final String[] yandexRuSite = { - "//maps.yandex.ru/" - }; - - final String[] yandexRuPattern = { - "(?:.*)ll=(-?\\d{1,3}.\\d+),(-?\\d{1,3}.\\d+)(?:.+)z=(\\d{1,2})(?:.*)" - }; - - final String sites[][] = { - osmandNetSite, - openstreetmapOrgSite, - openstreetmapDeSite, - googleComSite, - yandexRuSite - }; - - final String patterns[][] = { - osmandNetPattern, - openstreetmapOrgPattern, - openstreetmapDePattern, - googleComPattern, - yandexRuPattern - }; - - for (int s = 0; s < sites.length; s++) - { - for (int si = 0; si < sites[s].length; si++) - { - if (schemeSpecific.startsWith(sites[s][si])) { - for (int p = 0; p < patterns[s].length; p++) - { - String subString = schemeSpecific.substring(sites[s][si].length()); - - if (subString.equals("")) - { - subString = data.getFragment(); - } - - final Matcher matcher = Pattern.compile(patterns[s][p]).matcher(subString); - - if (matcher.matches()) { - try { - - final double lat; - final double lon; - final int zoom; - - //check sequence of values - if (!matcher.group(3).contains(".")) - { - lat = Double.valueOf(matcher.group(1)); - lon = Double.valueOf(matcher.group(2)); - zoom = Integer.valueOf(matcher.group(3)); - } - else - { - zoom = Integer.valueOf(matcher.group(1)); - lat = Double.valueOf(matcher.group(2)); - lon = Double.valueOf(matcher.group(3)); - } - - return new GeoPointSearch(lat, lon, zoom); - } - catch (NumberFormatException e) - { - return null; - } - } - } - break; - } - } - } - - String q = null; - String parameter = data.getQueryParameter("q"); - if (parameter == null) - { - parameter = data.getQueryParameter("daddr"); - } - if (parameter != null) - { - q = parameter.split(" ")[0]; - } - if (q.indexOf(',') != -1) - { - int i = q.indexOf(','); - String lat = q.substring(0, i); - String lon = q.substring(i + 1); - if (lat.indexOf(':') != -1) - { - i = lat.indexOf(':'); - lat = lat.substring(i + 1); - } - try - { - double llat = Double.parseDouble(lat.trim()); - double llon = Double.parseDouble(lon.trim()); - return new GeoPointSearch(llat, llon); - } - catch (NumberFormatException e) - { - return null; - } - } - else - { - return null; - } - } - if ("geo".equals(scheme) || "osmand.geo".equals(scheme)) - { - //geo: - final String schemeSpecific = data.getSchemeSpecificPart(); - if (schemeSpecific == null) - { - return null; - } - if (schemeSpecific.startsWith("0,0?q=")) - { - //geo:0,0?q=34.99,-106.61(Treasure) - //geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA - final String query = schemeSpecific.substring("0,0?q=".length()); - - final Matcher matcher = Pattern.compile("([\\-0-9.]+),([\\-0-9.]+)(?:,[\\-0-9.]+)?\\((.+?)\\)").matcher(query); - if (matcher.matches()) - { - final double lat = Double.valueOf(matcher.group(1)); - final double lon = Double.valueOf(matcher.group(2)); - final String name = matcher.group(3); - - return new GeoPointSearch(lat, lon, name); - } - else - { - //we suppose it's a search - return new GeoAddressSearch(query); - } - } - else - { - //geo:47.6,-122.3 - //geo:47.6,-122.3?z=11 - //allow for http://tools.ietf.org/html/rfc5870 (geo uri) , just ignore everything after ';' - final String pattern = "([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?z=([0-9]+))?(?:;.*)?"; - int indexQ = schemeSpecific.indexOf("&q"); - final Matcher matcher; - if (indexQ != -1){ - final String schemeQ = schemeSpecific.substring(0,indexQ); - matcher = Pattern.compile(pattern).matcher(schemeQ); - } else { - matcher = Pattern.compile(pattern).matcher(schemeSpecific); - } - - final String pattern2 = "([\\-0-9.]+),([\\-0-9.]+)(?:.*)"; //c:geo - final Matcher matcher2 = Pattern.compile(pattern2).matcher(schemeSpecific); - - if (matcher.matches()) - { - final double lat = Double.valueOf(matcher.group(1)); - final double lon = Double.valueOf(matcher.group(2)); - if (matcher.group(4) == null) - { - return new GeoPointSearch(lat, lon); - } - else - { - return new GeoPointSearch(lat, lon, Integer.valueOf(matcher.group(4))); - } - } else if (matcher2.matches()) { - final double lat = Double.valueOf(matcher2.group(1)); - final double lon = Double.valueOf(matcher2.group(2)); - return new GeoPointSearch(lat, lon); - } else { - return null; - } - } - } - return null; - } - - private final class GeoAddressSearch implements MyService { + private final class GeoAddressSearch implements MyService { private List elements; public GeoAddressSearch(String query) { - query = query.replaceAll("%20", ",").replaceAll("%0A",",") - .replaceAll("\n",",").replaceAll("\t",",") + query = query.replaceAll("%20", ",").replaceAll("%0A", ",").replaceAll("\n", ",").replaceAll("\t", ",") .replaceAll(" ", ","); System.out.println(query); - //String is split on each comma - String[] s = query.split(","); - + // String is split on each comma + String[] s = query.substring(query.indexOf("q=") + 2).split(","); + elements = new ArrayList(); - for (int i = 0; i q = new ArrayList(elements); MapObject geo = checkGeoPoint(); - if(geo != null) { + if (geo != null) { return new ExecutionResult(Collections.singleton(geo)); } @@ -565,29 +326,29 @@ public class GeoIntentActivity extends OsmandListActivity { } } } - if(cityIds.isEmpty()) { + if (cityIds.isEmpty()) { return new ExecutionResult(allStreets); } final List connectedStreets = new ArrayList(); Iterator p = allStreets.iterator(); - while(p.hasNext()) { + while (p.hasNext()) { Street s = p.next(); - if(cityIds.contains(s.getCity().getId())) { + if (cityIds.contains(s.getCity().getId())) { connectedStreets.add(s); } else { boolean tooFar = true; - for(City c : cityIds.valueCollection()) { - if(MapUtils.getDistance(c.getLocation(), s.getLocation()) < 50000) { + for (City c : cityIds.valueCollection()) { + if (MapUtils.getDistance(c.getLocation(), s.getLocation()) < 50000) { tooFar = false; break; } } - if(tooFar) { + if (tooFar) { p.remove(); } } } - if(connectedStreets.isEmpty()) { + if (connectedStreets.isEmpty()) { List all = new ArrayList(); all.addAll(cityIds.valueCollection()); all.addAll(allStreets); @@ -604,7 +365,7 @@ public class GeoIntentActivity extends OsmandListActivity { List foundCountries = new ArrayList(); RegionAddressRepository country; Iterator it = q.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { String maybeCountry = it.next(); country = resourceManager.getRegionRepository(maybeCountry); if (country != null) { @@ -620,41 +381,37 @@ public class GeoIntentActivity extends OsmandListActivity { return countriesToSearch; } - } - private static class GeoPointSearch implements MyService { - private final MapObject point; - private final int zoom; + @SuppressWarnings("unused") + private static class GeoPointSearch implements MyService { + private final MapObject point; + private final int zoom; - public GeoPointSearch(double lat , double lon) - { - this(lat, lon, ExecutionResult.NO_ZOOM); - } - - public GeoPointSearch(double lat , double lon, int zoom) - { - this(lat, lon, "Lat: " + lat + ",Lon: " + lon, zoom); - } - - public GeoPointSearch(double lat , double lon, String name ) - { - this(lat, lon, name,ExecutionResult.NO_ZOOM); - } - - public GeoPointSearch(double lat , double lon, String name, int zoom ) - { - final Amenity amenity = new Amenity(); - amenity.setLocation(lat, lon); - amenity.setName(name); - amenity.setType(AmenityType.USER_DEFINED); - amenity.setSubType(""); - - this.point = amenity; - this.zoom = zoom; + public GeoPointSearch(double lat, double lon) { + this(lat, lon, ExecutionResult.NO_ZOOM); } - @Override + public GeoPointSearch(double lat, double lon, int zoom) { + this(lat, lon, "Lat: " + lat + ",Lon: " + lon, zoom); + } + + public GeoPointSearch(double lat, double lon, String name) { + this(lat, lon, name, ExecutionResult.NO_ZOOM); + } + + public GeoPointSearch(double lat, double lon, String name, int zoom) { + final Amenity amenity = new Amenity(); + amenity.setLocation(lat, lon); + amenity.setName(name); + amenity.setType(AmenityType.USER_DEFINED); + amenity.setSubType(""); + + this.point = amenity; + this.zoom = zoom; + } + + @Override public ExecutionResult execute() { if (point != null) { return new ExecutionResult(Collections.singletonList(point), zoom); @@ -665,57 +422,45 @@ public class GeoIntentActivity extends OsmandListActivity { } - private static class ExecutionResult - { - public static final int NO_ZOOM = -1; - public static final ExecutionResult EMPTY = new ExecutionResult(new ArrayList(), NO_ZOOM); + private static class ExecutionResult { + public static final int NO_ZOOM = -1; + public static final ExecutionResult EMPTY = new ExecutionResult(new ArrayList(), NO_ZOOM); - private final Collection mapObjects; - private final int zoom; + private final Collection mapObjects; + private final int zoom; - public ExecutionResult(final Collection mapObjects) - { - this(mapObjects, NO_ZOOM); - } + public ExecutionResult(final Collection mapObjects) { + this(mapObjects, NO_ZOOM); + } - public ExecutionResult(final Collection mapObjects, final int zoom) - { - this.mapObjects = mapObjects; - this.zoom = zoom; - } + public ExecutionResult(final Collection mapObjects, final int zoom) { + this.mapObjects = mapObjects; + this.zoom = zoom; + } - public boolean isEmpty() - { - return mapObjects.isEmpty(); - } + public boolean isEmpty() { + return mapObjects.isEmpty(); + } - public boolean hasZoom() - { - return zoom != NO_ZOOM; - } + public boolean hasZoom() { + return zoom != NO_ZOOM; + } - public Collection getMapObjects() - { - return mapObjects; - } + public Collection getMapObjects() { + return mapObjects; + } - public int getZoom() - { - return zoom; - } + public int getZoom() { + return zoom; + } - @Override - public String toString() - { - return "ExecutionResult{" + - "mapObjects=" + mapObjects + - ", zoom=" + zoom + - '}'; - } - } + @Override + public String toString() { + return "ExecutionResult{" + "mapObjects=" + mapObjects + ", zoom=" + zoom + '}'; + } + } - private static interface MyService - { + private static interface MyService { public ExecutionResult execute(); } } diff --git a/SherlockBar/.classpath b/SherlockBar/.classpath index 7bc01d9a9c..51769745b2 100644 --- a/SherlockBar/.classpath +++ b/SherlockBar/.classpath @@ -1,9 +1,9 @@ - - + +