From: Marwin Hochfelsner <50826859+hlfan@users.noreply.github.com> Date: Fri, 11 Apr 2025 04:14:21 +0000 (+0200) Subject: Add PWA geo protocol handler X-Git-Tag: live~14^2 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/090c9da0a2d06e05dd07d756773be96a955d695c?ds=inline Add PWA geo protocol handler --- diff --git a/app/assets/favicons/manifest.json.erb b/app/assets/favicons/manifest.json.erb index 2e97cebc3..53fdfcc77 100644 --- a/app/assets/favicons/manifest.json.erb +++ b/app/assets/favicons/manifest.json.erb @@ -14,5 +14,11 @@ "start_url": "/", "theme_color": "#7ebc6f", "background_color": "#fff", - "display": "minimal-ui" + "display": "minimal-ui", + "protocol_handlers": [ + { + "protocol": "geo", + "url": "/?geouri=%s" + } + ] } diff --git a/app/assets/javascripts/osm.js.erb b/app/assets/javascripts/osm.js.erb index 700f9021c..c7887b63d 100644 --- a/app/assets/javascripts/osm.js.erb +++ b/app/assets/javascripts/osm.js.erb @@ -56,6 +56,7 @@ OSM = { mapParams: function (search) { const params = new URLSearchParams(search || location.search), + geoURI = OSM.parseGeoURI(params.get("geouri")), mapParams = {}; if (params.has("mlon") && params.has("mlat")) { @@ -64,6 +65,12 @@ OSM = { mapParams.mlat = parseFloat(params.get("mlat")); mapParams.mrad = parseFloat(params.get("mrad")); } + if (geoURI) { + mapParams.marker = true; + mapParams.mlon = geoURI.coords.lng; + mapParams.mlat = geoURI.coords.lat; + mapParams.mrad = geoURI.uncertainty; + } // Old-style object parameters; still in use for edit links e.g. /edit?way=1234 for (const type of ["node", "way", "relation", "note"]) { @@ -94,6 +101,12 @@ OSM = { mapParams.lon = params.get("mlon"); mapParams.lat = params.get("mlat"); mapParams.zoom = params.get("zoom") || 12; + } else if (geoURI?.uncertainty > 0 && !("zoom" in geoURI)) { + mapParams.bounds = geoURI.coords.toBounds(geoURI.uncertainty * 4); + } else if (geoURI) { + mapParams.lon = geoURI.coords.lng; + mapParams.lat = geoURI.coords.lat; + mapParams.zoom = geoURI.zoom || 12; } else if (loc) { [mapParams.lon, mapParams.lat, mapParams.zoom] = loc; } else if (OSM.home) { diff --git a/test/javascripts/osm_test.js b/test/javascripts/osm_test.js index cac209c0f..8f4471140 100644 --- a/test/javascripts/osm_test.js +++ b/test/javascripts/osm_test.js @@ -73,6 +73,33 @@ describe("OSM", function () { expect(params).to.have.property("zoom", 16); }); + it("parses geoURIs", function () { + const params = OSM.mapParams("?geouri=geo%3A57.6247%2C-3.6845"); + expect(params).to.have.property("lat", 57.6247); + expect(params).to.have.property("lon", -3.6845); + expect(params).to.have.property("mlat", 57.6247); + expect(params).to.have.property("mlon", -3.6845); + expect(params).to.have.property("zoom", 12); + }); + + it("parses zoom in geoURIs", function () { + const params = OSM.mapParams("?geouri=geo%3A57.6247%2C-3.6845%3Fz%3D16"); + expect(params).to.have.property("lat", 57.6247); + expect(params).to.have.property("lon", -3.6845); + expect(params).to.have.property("mlat", 57.6247); + expect(params).to.have.property("mlon", -3.6845); + expect(params).to.have.property("zoom", 16); + }); + + it("parses uncertainty in geoURIs", function () { + const params = OSM.mapParams("?geouri=geo%3A57.6247%2C-3.6845%3Bu%3D100"); + const expected = L.latLngBounds([57.62290336944585, -3.6878552857327764], [57.62649663055414, -3.6811447142672233]); + expect(params).to.have.property("mlat", 57.6247); + expect(params).to.have.property("mlon", -3.6845); + expect(params).to.have.property("mrad", 100); + expect(params).to.have.property("bounds").deep.equal(expected); + }); + it("parses lat/lon/zoom from the hash", function () { location.hash = "#map=16/57.6247/-3.6845"; const params = OSM.mapParams("?");