]> git.openstreetmap.org Git - rails.git/commitdiff
Add PWA geo protocol handler
authorMarwin Hochfelsner <50826859+hlfan@users.noreply.github.com>
Fri, 11 Apr 2025 04:14:21 +0000 (06:14 +0200)
committerMarwin Hochfelsner <50826859+hlfan@users.noreply.github.com>
Fri, 25 Apr 2025 17:41:15 +0000 (19:41 +0200)
app/assets/favicons/manifest.json.erb
app/assets/javascripts/osm.js.erb
test/javascripts/osm_test.js

index 2e97cebc3247e3f4ac25aa90401d67dec766422c..53fdfcc77378f605fee759f10fc0408fb83748f9 100644 (file)
        "start_url": "/",
        "theme_color": "#7ebc6f",
        "background_color": "#fff",
-       "display": "minimal-ui"
+       "display": "minimal-ui",
+       "protocol_handlers": [
+               {
+                       "protocol": "geo",
+                       "url": "/?geouri=%s"
+               }
+       ]
 }
index 700f9021c2f54091c863839c3643f5cbd4ec85be..c7887b63dcbb35bd89855c32d6d1de8368f37587 100644 (file)
@@ -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) {
index cac209c0f3c411be9fd3ac6e29d4dcd47d857d61..8f4471140d21e59e8002f6fc596af464d9d03389 100644 (file)
@@ -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("?");