Index: /trunk/linux/latest/usr/share/applications/josm-latest.desktop
===================================================================
--- /trunk/linux/latest/usr/share/applications/josm-latest.desktop (revision 10629)
+++ /trunk/linux/latest/usr/share/applications/josm-latest.desktop (revision 10630)
@@ -8,5 +8,5 @@
Exec=josm-latest %F
Terminal=false
-MimeType=application/x-osm+xml;application/x-gpx+xml;
+MimeType=application/x-osm+xml;application/x-gpx+xml;x-scheme-handler/geo;
StartupNotify=true
Categories=Education;Geoscience;Maps;
Index: /trunk/linux/tested/usr/share/applications/josm.desktop
===================================================================
--- /trunk/linux/tested/usr/share/applications/josm.desktop (revision 10629)
+++ /trunk/linux/tested/usr/share/applications/josm.desktop (revision 10630)
@@ -8,5 +8,5 @@
Exec=josm %F
Terminal=false
-MimeType=application/x-osm+xml;application/x-gpx+xml;
+MimeType=application/x-osm+xml;application/x-gpx+xml;x-scheme-handler/geo;
StartupNotify=true
Categories=Education;Geoscience;Maps;
Index: /trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java (revision 10629)
+++ /trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java (revision 10630)
@@ -24,4 +24,5 @@
import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadGeoUrlTask;
import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
@@ -68,4 +69,5 @@
addDownloadTaskClass(DownloadOsmChangeTask.class);
addDownloadTaskClass(DownloadOsmUrlTask.class);
+ addDownloadTaskClass(DownloadGeoUrlTask.class);
addDownloadTaskClass(DownloadOsmIdTask.class);
addDownloadTaskClass(DownloadOsmCompressedTask.class);
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGeoUrlTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGeoUrlTask.java (revision 10630)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGeoUrlTask.java (revision 10630)
@@ -0,0 +1,30 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.downloadtasks;
+
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.GeoUrlToBounds;
+
+import java.util.concurrent.Future;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Task allowing to download a Geo URL (as specified in RFC 5870).
+ */
+public class DownloadGeoUrlTask extends DownloadOsmTask {
+
+ @Override
+ public Future> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
+ return download(newLayer, GeoUrlToBounds.parse(url), null);
+ }
+
+ @Override
+ public String[] getPatterns() {
+ return new String[]{GeoUrlToBounds.PATTERN.toString()};
+ }
+
+ @Override
+ public String getTitle() {
+ return tr("Download Geo URL");
+ }
+}
Index: /trunk/src/org/openstreetmap/josm/tools/GeoUrlToBounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/GeoUrlToBounds.java (revision 10630)
+++ /trunk/src/org/openstreetmap/josm/tools/GeoUrlToBounds.java (revision 10630)
@@ -0,0 +1,57 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Parses a Geo URL (as specified in RFC 5870) into {@link Bounds}.
+ */
+public final class GeoUrlToBounds {
+
+ public static final Pattern PATTERN = Pattern.compile("geo:(?[0-9.]+),(?[0-9.]+)(\\?z=(?[0-9]+))?");
+
+ private GeoUrlToBounds() {
+ // Hide default constructor for utils classes
+ }
+
+ /**
+ * Parses a Geo URL (as specified in RFC 5870) into {@link Bounds}.
+ * @param url the URL to be parsed
+ * @return the parsed {@link Bounds}
+ */
+ public static Bounds parse(final String url) {
+ CheckParameterUtil.ensureParameterNotNull(url, "url");
+ final Matcher m = PATTERN.matcher(url);
+ if (m.matches()) {
+ final double lat, lon;
+ final int zoom;
+ try {
+ lat = Double.parseDouble(m.group("lat"));
+ } catch (NumberFormatException e) {
+ Main.warn(tr("URL does not contain valid {0}", tr("latitude")), e);
+ return null;
+ }
+ try {
+ lon = Double.parseDouble(m.group("lon"));
+ } catch (NumberFormatException e) {
+ Main.warn(tr("URL does not contain valid {0}", tr("longitude")), e);
+ return null;
+ }
+ try {
+ zoom = m.group("zoom") != null ? Integer.parseInt(m.group("zoom")) : 18;
+ } catch (NumberFormatException e) {
+ Main.warn(tr("URL does not contain valid {0}", tr("zoom")), e);
+ return null;
+ }
+ return OsmUrlToBounds.positionToBounds(lat, lon, zoom);
+ } else {
+ return null;
+ }
+ }
+}
Index: /trunk/test/unit/org/openstreetmap/josm/tools/GeoUrlToBoundsTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/tools/GeoUrlToBoundsTest.java (revision 10630)
+++ /trunk/test/unit/org/openstreetmap/josm/tools/GeoUrlToBoundsTest.java (revision 10630)
@@ -0,0 +1,53 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools;
+
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests of {@link GeoUrlToBoundsTest} class.
+ */
+public class GeoUrlToBoundsTest {
+
+ /**
+ * Tests parsing Geo URLs with the zoom specified.
+ */
+ @Test
+ public void testParse() {
+ assertThat(
+ GeoUrlToBounds.parse("geo:12.34,56.78?z=9"),
+ is(OsmUrlToBounds.positionToBounds(12.34, 56.78, 9))
+ );
+ }
+
+ /**
+ * Tests parsing Geo URLs without the zoom parameter.
+ */
+ @Test
+ public void testParseWithoutZoom() {
+ assertThat(
+ GeoUrlToBounds.parse("geo:12.34,56.78"),
+ is(OsmUrlToBounds.positionToBounds(12.34, 56.78, 18))
+ );
+ }
+
+ /**
+ * Tests parsing invalid Geo URL.
+ */
+ @Test
+ public void testInvalid() {
+ assertThat(GeoUrlToBounds.parse("geo:foo"), nullValue());
+ assertThat(GeoUrlToBounds.parse("geo:foo,bar"), nullValue());
+ }
+
+ /**
+ * Tests parsing null.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testNull() {
+ GeoUrlToBounds.parse(null);
+ }
+}