From ef458540c0e2ad12fbd934e72d87e8e58628ec80 Mon Sep 17 00:00:00 2001 From: Benji Rus Date: Wed, 6 May 2026 00:17:50 +0200 Subject: [PATCH] Add Geo protocol support Basically for easy redirect to your default android map app like organicmaps coMaps etc, i dont know why but i was getting lat lon fliped, then i change utils.js but i dont know if it is the best --- src/assets/javascripts/services.js | 98 ++++++++++++++++++++++++++++++ src/assets/javascripts/utils.js | 2 +- src/config.json | 9 ++- 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/assets/javascripts/services.js b/src/assets/javascripts/services.js index f3a1bbc4..f3e75346 100644 --- a/src/assets/javascripts/services.js +++ b/src/assets/javascripts/services.js @@ -201,6 +201,104 @@ function rewrite(url, originUrl, frontend, randomInstance, type) { if (query) return `${randomInstance}/search?query=${query}${mapCentre}&${utils.prefsEncoded(prefs)}` return `${randomInstance}/${mapCentre}&${utils.prefsEncoded(prefs)}` } + case "geo": { + if (originUrl && originUrl.host === "earth.google.com") return null + + // Manejo especial para URLs de consent.google.com + if (url.host.includes("consent.google.com") && url.searchParams.has("continue")) { + const continueUrl = decodeURIComponent(url.searchParams.get("continue")) + try { + const innerUrl = new URL(continueUrl) + if (innerUrl.searchParams.has("q")) { + const qParam = innerUrl.searchParams.get("q") + const coordMatch = qParam.match(/^(-?\d+\.?\d*),(-?\d+\.?\d*)/) + if (coordMatch) { + const [, lat, lon] = coordMatch + return `geo:${lat},${lon}?z=15` + } + } + if (innerUrl.searchParams.has("ll")) { + const [lat, lon] = innerUrl.searchParams.get("ll").split(",") + return `geo:${lat},${lon}?z=15` + } + } catch (e) { + // Si no se puede parsear, continuar con la lógica normal + } + } + + let mapCentre = "" + const mapCentreData = utils.convertMapCentre(url) + if (mapCentreData.zoom && mapCentreData.lon && mapCentreData.lat) { + mapCentre = `geo:${mapCentreData.lat},${mapCentreData.lon}?z=${mapCentreData.zoom}` + } + + if (url.pathname.includes("/embed")) { + const query = utils.getQuery(url) + let { coordinate } = utils.addressToLatLng(query) + if (coordinate) { + const [lat, lon] = coordinate.split(",") + return `geo:${lat},${lon}?z=15` + } + return mapCentre || null + } + + if (url.pathname.includes("/dir")) { + const regex1 = /\/dir\/([^@/]+)\/([^@/]+)\/@-?\d[0-9.]*,-?\d[0-9.]*,\d{1,2}[.z]/.exec(url.pathname) + const regex2 = /\/dir\/([^@/]+)\//.exec(url.pathname) + if (regex1) { + const origin = utils.addressToLatLng(decodeURIComponent(regex1[1])).coordinate ?? "" + if (origin) { + const [lat, lon] = origin.split(",") + return `geo:${lat},${lon}?z=15` + } + } else if (regex2) { + const origin = utils.addressToLatLng(decodeURIComponent(regex2[1])).coordinate ?? "" + if (origin) { + const [lat, lon] = origin.split(",") + return `geo:${lat},${lon}?z=15` + } + } else { + const origin = utils.addressToLatLng(url.searchParams.get("origin")).coordinate ?? "" + if (origin) { + const [lat, lon] = origin.split(",") + return `geo:${lat},${lon}?z=15` + } + } + return mapCentre || null + } + + const placeRegex = /\/place\/(.*?)\// + if (url.pathname.match(placeRegex)) { + const query = url.pathname.match(placeRegex)[1] + const { coordinate } = utils.addressToLatLng(decodeURIComponent(query)) + if (coordinate) { + const [lat, lon] = coordinate.split(",") + return `geo:${lat},${lon}?z=15` + } + return mapCentre || null + } + + if (url.searchParams.has("ll")) { + const [mlat, mlon] = url.searchParams.get("ll").split(",") + return `geo:${mlat},${mlon}?z=15` + } + + if (url.searchParams.has("viewpoint")) { + const [mlat, mlon] = url.searchParams.get("viewpoint").split(",") + return `geo:${mlat},${mlon}?z=15` + } + + if (url.searchParams.has("q")) { + const qParam = url.searchParams.get("q") + const coordMatch = qParam.match(/^(-?\d+\.?\d*),(-?\d+\.?\d*)/) + if (coordMatch) { + const [, lat, lon] = coordMatch + return `geo:${lat},${lon}?z=15` + } + } + + return mapCentre || null + } case "phantom": case "breezeWiki": { let wiki, diff --git a/src/assets/javascripts/utils.js b/src/assets/javascripts/utils.js index 1f5db8d6..2a94f822 100644 --- a/src/assets/javascripts/utils.js +++ b/src/assets/javascripts/utils.js @@ -203,7 +203,7 @@ function convertMapCentre(url) { let [lat, lon, zoom] = [null, null, null] const reg = url.pathname.match(/@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/) if (reg) { - ;[, lon, lat, zoom] = reg + ;[, lat, lon, zoom] = reg } else if (url.searchParams.has("center")) { // Set map centre if present ;[lat, lon] = url.searchParams.get("center").split(",") diff --git a/src/config.json b/src/config.json index 6f3fb2c8..52279e04 100644 --- a/src/config.json +++ b/src/config.json @@ -1288,12 +1288,19 @@ "instanceList": true, "embeddable": true, "url": "https://www.openstreetmap.org/" + }, + "geo": { + "name": "Geo Protocol", + "instanceList": false, + "embeddable": false, + "url": "geo://" } }, "targets": [ "^https?:\\/{2}maps\\.libredirect\\.invalid", "^https?:\\/{2}(www\\.)?maps\\.google(\\.[a-z]{2,3}){1,2}\\/", - "^https?:\\/{2}(www\\.)?google(\\.[a-z]{2,3}){1,2}\\/maps\\/?" + "^https?:\\/{2}(www\\.)?google(\\.[a-z]{2,3}){1,2}\\/maps\\/?" , + "^https?:\\/{2}consent\\.google\\.com.*maps\\.google" ], "name": "Maps", "options": {