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 <a href="https://tools.ietf.org/html/rfc5870">RFC 5870</a>).
+ */
+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 <a href="https://tools.ietf.org/html/rfc5870">RFC 5870</a>) into {@link Bounds}.
+ */
+public final class GeoUrlToBounds {
+
+    public static final Pattern PATTERN = Pattern.compile("geo:(?<lat>[0-9.]+),(?<lon>[0-9.]+)(\\?z=(?<zoom>[0-9]+))?");
+
+    private GeoUrlToBounds() {
+        // Hide default constructor for utils classes
+    }
+
+    /**
+     * Parses a Geo URL (as specified in <a href="https://tools.ietf.org/html/rfc5870">RFC 5870</a>) 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;
+        }
+    }
+}
