From d39ad7780351a495db9d0d16bc37c305b435b7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=BDdila?= Date: Thu, 9 Nov 2023 14:29:50 +0100 Subject: [PATCH] version 1.0.0 (#14) * implemented enhanced proximity modes * updated proximity api * added adjustQuery * updated dependencies * adjustQuery for react * cleanup * added clearMap and clearList methods * updated deps * refactored proximity code to separate file * fixed icon fallback * added more POI icons * fixed computing bbox * removed fetch credentials * updated dependencies --- examples/maplibregl/AppMapLibreGl.svelte | 7 +- examples/standalone/maplibregl.html | 5 + package-lock.json | 468 +++++++++++------------ package.json | 28 +- public/icons/clinic.svg | 1 + public/icons/hardware.svg | 8 + public/icons/mountain.svg | 1 - public/icons/mountain_range.svg | 24 ++ public/icons/ocean.svg | 11 + public/icons/parking_space.svg | 1 + public/icons/peak.svg | 2 +- public/icons/playground.svg | 18 +- public/icons/river.svg | 11 + public/icons/sea.svg | 11 + public/icons/stream.svg | 11 + public/icons/vending_machine.svg | 22 ++ public/icons/water.svg | 11 + src/FeatureItem.svelte | 6 +- src/GeocodingControl.svelte | 239 ++++++------ src/MapLibreBasedGeocodingControl.ts | 8 + src/geoUtils.ts | 24 ++ src/leaflet-controller.ts | 45 +-- src/leaflet.ts | 8 + src/maplibregl-controller.ts | 45 +-- src/openlayers-controller.ts | 47 +-- src/openlayers.ts | 8 + src/proximity.ts | 86 +++++ src/react.ts | 6 +- src/types.ts | 98 +++-- src/vanilla.ts | 8 + 30 files changed, 761 insertions(+), 507 deletions(-) create mode 100644 public/icons/clinic.svg create mode 100644 public/icons/hardware.svg delete mode 100644 public/icons/mountain.svg create mode 100644 public/icons/mountain_range.svg create mode 100644 public/icons/ocean.svg create mode 100644 public/icons/parking_space.svg create mode 100644 public/icons/river.svg create mode 100644 public/icons/sea.svg create mode 100644 public/icons/stream.svg create mode 100644 public/icons/vending_machine.svg create mode 100644 public/icons/water.svg create mode 100644 src/geoUtils.ts create mode 100644 src/proximity.ts diff --git a/examples/maplibregl/AppMapLibreGl.svelte b/examples/maplibregl/AppMapLibreGl.svelte index 129b948..761678d 100644 --- a/examples/maplibregl/AppMapLibreGl.svelte +++ b/examples/maplibregl/AppMapLibreGl.svelte @@ -31,7 +31,12 @@ // types: ["poi"], // fetchParameters: { credentials: "include" }, iconsBaseUrl: "/icons/", - }) + proximity: [ + { type: "map-center", minZoom: 12 }, + { type: "client-geolocation", minZoom: 8 }, + { type: "server-geolocation", minZoom: 8 }, + ], + }), ); map.addControl(new NavigationControl({})); diff --git a/examples/standalone/maplibregl.html b/examples/standalone/maplibregl.html index bf3280e..e320ccd 100644 --- a/examples/standalone/maplibregl.html +++ b/examples/standalone/maplibregl.html @@ -46,6 +46,11 @@ style: "https://api.maptiler.com/maps/streets/style.json?key=" + apiKey, center: [16.3, 49.2], // starting position [lng, lat] zoom: 7, + proximity: [ + { type: "map-center", minZoom: 12 }, + { type: "client-geolocation" }, + { type: "server-geolocation" }, + ], }); const gc = new maplibreglMaptilerGeocoder.GeocodingControl({ diff --git a/package-lock.json b/package-lock.json index 0bd41e2..7475017 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,44 +1,44 @@ { "name": "@maptiler/geocoding-control", - "version": "0.0.99", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@maptiler/geocoding-control", - "version": "0.0.99", + "version": "1.0.0", "license": "BSD-3-Clause", "devDependencies": { - "@maptiler/sdk": "^1.1.2", + "@maptiler/sdk": "^1.2.0", "@sveltejs/package": "^2.2.2", - "@sveltejs/vite-plugin-svelte": "^2.4.5", + "@sveltejs/vite-plugin-svelte": "^2.5.0", "@tsconfig/svelte": "^5.0.2", "@turf/buffer": "^6.5.0", "@turf/difference": "^6.5.0", "@turf/union": "^6.5.0", - "@types/geojson": "^7946.0.10", - "@types/leaflet": "^1.9.4", - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", - "concurrently": "^8.2.1", + "@types/geojson": "^7946.0.13", + "@types/leaflet": "^1.9.8", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "concurrently": "^8.2.2", "dotenv": "^16.3.1", "esm-env": "^1.0.0", "leaflet": "^1.9.4", - "maplibre-gl": "^3.3.1", + "maplibre-gl": "^3.5.2", "prettier": "^3.0.3", "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-svelte": "^3.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", "renamer": "^4.0.0", - "replace-in-file": "^7.0.1", - "sass": "^1.66.1", - "svelte": "^4.2.0", - "svelte-check": "^3.5.1", + "replace-in-file": "^7.0.2", + "sass": "^1.69.5", + "svelte": "^4.2.2", + "svelte-check": "^3.5.2", "svelte-preprocess": "^5.0.4", "tslib": "^2.6.2", "typescript": "^5.2.2", - "vite": "^4.4.9" + "vite": "^4.5.0" }, "peerDependencies": { "@maptiler/sdk": "^1", @@ -621,9 +621,9 @@ } }, "node_modules/@maplibre/maplibre-gl-style-spec": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.0.tgz", - "integrity": "sha512-ZbhX9CTV+Z7vHwkRIasDOwTSzr76e8Q6a55RMsAibjyX6+P0ZNL1qAKNzOjjBDP3+aEfNMl7hHo5knuY6pTAUQ==", + "version": "19.3.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", + "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", "dev": true, "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", @@ -640,66 +640,29 @@ } }, "node_modules/@maptiler/client": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@maptiler/client/-/client-1.5.0.tgz", - "integrity": "sha512-7YL2SJ3VantBnwuly5333PIHx1ihUpNBiMC5iiQtYFfhceSaFpJPe7G6ANpPxG4iENVLW9hFRQERC5sGwvjAJw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@maptiler/client/-/client-1.7.0.tgz", + "integrity": "sha512-FcxZSzsducRSCtoLoz7BwdQfYkLWCaEw8npe2MJM7xnqBtFyQVc2ZdIWKc5H1SPmhEc55I9igvBnpzeGgliQNQ==", "dev": true, "dependencies": { - "@types/geojson": "^7946.0.10" + "@rollup/pluginutils": "^5.0.5", + "@types/geojson": "^7946.0.10", + "web-merc-projection": "^1.3.2" } }, "node_modules/@maptiler/sdk": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@maptiler/sdk/-/sdk-1.1.2.tgz", - "integrity": "sha512-8PlmrnML24kSFvnw7t4NrAWfumvpqxzLZUN5Lvf7hMxHCowkkkxYDO8vUgEBx7FpA0/8MVOMfpi+cAQSdbVbSw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@maptiler/sdk/-/sdk-1.2.0.tgz", + "integrity": "sha512-DNqrMnyApbhewUa7PdnXk5t4bu6M5cfGPNvwga08yj73Gbs+K1bbxhh0taLRqvkjxOmlsacDXCrW4UXlEHOc3w==", "dev": true, "dependencies": { - "@maptiler/client": "^1.5.0", + "@maptiler/client": "^1.7.0", "events": "^3.3.0", "js-base64": "^3.7.4", - "maplibre-gl": "3.1.0", + "maplibre-gl": "3.5.2", "uuid": "^9.0.0" } }, - "node_modules/@maptiler/sdk/node_modules/maplibre-gl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.1.0.tgz", - "integrity": "sha512-KFarVUUszCEucPwnGsFJtPMQBg/F6lg+SPDmTztKUD/n0YShETjIOdNmm5jpxacEX3+dq50MzlqDr6VH+RtDDA==", - "dev": true, - "dependencies": { - "@mapbox/geojson-rewind": "^0.5.2", - "@mapbox/jsonlint-lines-primitives": "^2.0.2", - "@mapbox/point-geometry": "^0.1.0", - "@mapbox/tiny-sdf": "^2.0.6", - "@mapbox/unitbezier": "^0.0.1", - "@mapbox/vector-tile": "^1.3.1", - "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^19.2.1", - "@types/geojson": "^7946.0.10", - "@types/mapbox__point-geometry": "^0.1.2", - "@types/mapbox__vector-tile": "^1.3.0", - "@types/pbf": "^3.0.2", - "earcut": "^2.2.4", - "geojson-vt": "^3.2.1", - "gl-matrix": "^3.4.3", - "global-prefix": "^3.0.0", - "kdbush": "^4.0.2", - "murmurhash-js": "^1.0.0", - "pbf": "^3.2.1", - "potpack": "^2.0.0", - "quickselect": "^2.0.0", - "supercluster": "^8.0.1", - "tinyqueue": "^2.0.3", - "vt-pbf": "^3.1.3" - }, - "engines": { - "node": ">=16.14.0", - "npm": ">=8.1.0" - }, - "funding": { - "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -742,6 +705,34 @@ "optional": true, "peer": true }, + "node_modules/@rollup/pluginutils": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", + "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/@sveltejs/package": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.2.2.tgz", @@ -765,16 +756,16 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.5.tgz", - "integrity": "sha512-UJKsFNwhzCVuiZd06jM/psscyNJNDwjQC+qIeb7GBJK9iWeQCcIyfcPWDvbCudfcJggY9jtxJeeaZH7uny93FQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.0.tgz", + "integrity": "sha512-FxLZLVfFA2soGw7ej8Ohuav7+AOsJILiPlL8FgY5MABDDmDqb637o8Xd/QGkrXLC1qXyG1bnteOw5Z5yrA2lHA==", "dev": true, "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^1.0.3", + "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", - "magic-string": "^0.30.2", + "magic-string": "^0.30.3", "svelte-hmr": "^0.15.3", "vitefu": "^0.2.4" }, @@ -782,14 +773,14 @@ "node": "^14.18.0 || >= 16" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0", + "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.3.tgz", - "integrity": "sha512-Khdl5jmmPN6SUsVuqSXatKpQTMIifoQPDanaxC84m9JxIibWvSABJyHpyys0Z+1yYrxY5TTEQm+6elh0XCMaOA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.4.tgz", + "integrity": "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==", "dev": true, "dependencies": { "debug": "^4.3.4" @@ -947,30 +938,30 @@ "dev": true }, "node_modules/@types/geojson": { - "version": "7946.0.10", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", - "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", + "version": "7946.0.13", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz", + "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==", "dev": true }, "node_modules/@types/leaflet": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-kfwgQf4eOxoe/tD9CaKQrBKHbc7VpyfJOG5sxsQtkH+ML9xYa8hUC3UMa0wU1pKfciJtO0pU9g9XbWhPo7iBCA==", + "version": "1.9.8", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.8.tgz", + "integrity": "sha512-EXdsL4EhoUtGm2GC2ZYtXn+Fzc6pluVgagvo2VC1RHWToLGlTRwVYoDpqS/7QXa01rmDyBjJk3Catpf60VMkwg==", "dev": true, "dependencies": { "@types/geojson": "*" } }, "node_modules/@types/mapbox__point-geometry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz", - "integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.3.tgz", + "integrity": "sha512-2W46IOXlu7vC8m3+M5rDqSnuY22GFxxx3xhkoyqyPWrD+eP2iAwNst0A1+umLYjCTJMJTSpiofphn9h9k+Kw+w==", "dev": true }, "node_modules/@types/mapbox__vector-tile": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz", - "integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.3.tgz", + "integrity": "sha512-d263B3KCQtXKVZMHpMJrEW5EeLBsQ8jvAS9nhpUKC5hHIlQaACG9PWkW8qxEeNuceo9120AwPjeS91uNa4ltqA==", "dev": true, "dependencies": { "@types/geojson": "*", @@ -979,9 +970,9 @@ } }, "node_modules/@types/pbf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", - "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.4.tgz", + "integrity": "sha512-SOFlLGZkLbEXJRwcWCqeP/Koyaf/uAqLXHUsdo/nMfjLsNd8kqauwHe9GBOljSmpcHp/LC6kOjo3SidGjNirVA==", "dev": true }, "node_modules/@types/prop-types": { @@ -997,9 +988,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "version": "18.2.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", + "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -1008,9 +999,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", - "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "version": "18.2.15", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz", + "integrity": "sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==", "dev": true, "dependencies": { "@types/react": "*" @@ -1023,9 +1014,9 @@ "dev": true }, "node_modules/@types/supercluster": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.0.tgz", - "integrity": "sha512-6JapQ2GmEkH66r23BK49I+u6zczVDGTtiJEVvKDYZVSm/vepWaJuTq6BXzJ6I4agG5s8vA1KM7m/gXWDg03O4Q==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.2.tgz", + "integrity": "sha512-qMhofL945Z4njQUuntadexAgPtpiBC014WvVqU70Prj42LC77Xgmz04us7hSMmwjs7KbgAwGBmje+FSOvDbP0Q==", "dev": true, "dependencies": { "@types/geojson": "*" @@ -1434,9 +1425,9 @@ "dev": true }, "node_modules/concurrently": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", - "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", "dev": true, "dependencies": { "chalk": "^4.1.2", @@ -2228,9 +2219,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -2253,9 +2244,9 @@ "peer": true }, "node_modules/maplibre-gl": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.3.1.tgz", - "integrity": "sha512-SfRq9bT68GytDzCOG0IoTGg2rASbgdYunW/6xhnp55QuLmwG1M/YOlXxqHaphwia7kZbMvBOocvY0fp5yfTjZA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.5.2.tgz", + "integrity": "sha512-deqYA/RiEyXMGroZMDbOWNQTLnFsxREC+mDkQnuyCUNdBWm1KHafsXJYZP7rlLa5RLQNq05IAUAizY9aHTpIUw==", "dev": true, "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", @@ -2265,12 +2256,12 @@ "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^19.3.0", - "@types/geojson": "^7946.0.10", - "@types/mapbox__point-geometry": "^0.1.2", - "@types/mapbox__vector-tile": "^1.3.0", - "@types/pbf": "^3.0.2", - "@types/supercluster": "^7.1.0", + "@maplibre/maplibre-gl-style-spec": "^19.3.3", + "@types/geojson": "^7946.0.12", + "@types/mapbox__point-geometry": "^0.1.3", + "@types/mapbox__vector-tile": "^1.3.3", + "@types/pbf": "^3.0.4", + "@types/supercluster": "^7.1.2", "earcut": "^2.2.4", "geojson-vt": "^3.2.1", "gl-matrix": "^3.4.3", @@ -2780,9 +2771,9 @@ } }, "node_modules/replace-in-file": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-7.0.1.tgz", - "integrity": "sha512-KbhgPq04eA+TxXuUxpgWIH9k/TjF+28ofon2PXP7vq6izAILhxOtksCVcLuuQLtyjouBaPdlH6RJYYcSPVxCOA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-7.0.2.tgz", + "integrity": "sha512-tPG+Qmqf+x2Rf1WVdb/9B5tFIf6KJ5hs3fgxh1OTzPRUugPPvyAva7NvCJtnSpmyq6r+ABYcuUOqZkm6yzGSUw==", "dev": true, "dependencies": { "chalk": "^4.1.2", @@ -2964,9 +2955,9 @@ } }, "node_modules/sass": { - "version": "1.66.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", - "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", + "version": "1.69.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", + "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -3208,9 +3199,9 @@ } }, "node_modules/svelte": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.0.tgz", - "integrity": "sha512-kVsdPjDbLrv74SmLSUzAsBGquMs4MPgWGkGLpH+PjOYnFOziAvENVzgJmyOCV2gntxE32aNm8/sqNKD6LbIpeQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.2.tgz", + "integrity": "sha512-My2tytF2e2NnHSpn2M7/3VdXT4JdTglYVUuSuK/mXL2XtulPYbeBfl8Dm1QiaKRn0zoULRnL+EtfZHHP0k4H3A==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", @@ -3224,7 +3215,7 @@ "estree-walker": "^3.0.3", "is-reference": "^3.0.1", "locate-character": "^3.0.0", - "magic-string": "^0.30.0", + "magic-string": "^0.30.4", "periscopic": "^3.1.0" }, "engines": { @@ -3232,9 +3223,9 @@ } }, "node_modules/svelte-check": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.5.1.tgz", - "integrity": "sha512-+Zb4iHxAhdUtcUg/WJPRjlS1RJalIsWAe9Mz6G1zyznSs7dDkT7VUBdXc3q7Iwg49O/VrZgyJRvOJkjuBfKjFA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.5.2.tgz", + "integrity": "sha512-5a/YWbiH4c+AqAUP+0VneiV5bP8YOk9JL3jwvN+k2PEPLgpu85bjQc5eE67+eIZBBwUEJzmO3I92OqKcqbp3fw==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", @@ -3493,9 +3484,9 @@ } }, "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -3572,6 +3563,12 @@ "pbf": "^3.2.1" } }, + "node_modules/web-merc-projection": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/web-merc-projection/-/web-merc-projection-1.3.2.tgz", + "integrity": "sha512-GYvU+9i2J8Ipz7OvArGDltfUQahp9JA6Yta9PI8cMbMcqZs+i2GmsPjw81mTOKRCWqvaAwdLbux8LgG74ibZbw==", + "dev": true + }, "node_modules/web-worker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", @@ -4007,9 +4004,9 @@ "dev": true }, "@maplibre/maplibre-gl-style-spec": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.0.tgz", - "integrity": "sha512-ZbhX9CTV+Z7vHwkRIasDOwTSzr76e8Q6a55RMsAibjyX6+P0ZNL1qAKNzOjjBDP3+aEfNMl7hHo5knuY6pTAUQ==", + "version": "19.3.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", + "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", "dev": true, "requires": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", @@ -4021,59 +4018,27 @@ } }, "@maptiler/client": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@maptiler/client/-/client-1.5.0.tgz", - "integrity": "sha512-7YL2SJ3VantBnwuly5333PIHx1ihUpNBiMC5iiQtYFfhceSaFpJPe7G6ANpPxG4iENVLW9hFRQERC5sGwvjAJw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@maptiler/client/-/client-1.7.0.tgz", + "integrity": "sha512-FcxZSzsducRSCtoLoz7BwdQfYkLWCaEw8npe2MJM7xnqBtFyQVc2ZdIWKc5H1SPmhEc55I9igvBnpzeGgliQNQ==", "dev": true, "requires": { - "@types/geojson": "^7946.0.10" + "@rollup/pluginutils": "^5.0.5", + "@types/geojson": "^7946.0.10", + "web-merc-projection": "^1.3.2" } }, "@maptiler/sdk": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@maptiler/sdk/-/sdk-1.1.2.tgz", - "integrity": "sha512-8PlmrnML24kSFvnw7t4NrAWfumvpqxzLZUN5Lvf7hMxHCowkkkxYDO8vUgEBx7FpA0/8MVOMfpi+cAQSdbVbSw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@maptiler/sdk/-/sdk-1.2.0.tgz", + "integrity": "sha512-DNqrMnyApbhewUa7PdnXk5t4bu6M5cfGPNvwga08yj73Gbs+K1bbxhh0taLRqvkjxOmlsacDXCrW4UXlEHOc3w==", "dev": true, "requires": { - "@maptiler/client": "^1.5.0", + "@maptiler/client": "^1.7.0", "events": "^3.3.0", "js-base64": "^3.7.4", - "maplibre-gl": "3.1.0", + "maplibre-gl": "3.5.2", "uuid": "^9.0.0" - }, - "dependencies": { - "maplibre-gl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.1.0.tgz", - "integrity": "sha512-KFarVUUszCEucPwnGsFJtPMQBg/F6lg+SPDmTztKUD/n0YShETjIOdNmm5jpxacEX3+dq50MzlqDr6VH+RtDDA==", - "dev": true, - "requires": { - "@mapbox/geojson-rewind": "^0.5.2", - "@mapbox/jsonlint-lines-primitives": "^2.0.2", - "@mapbox/point-geometry": "^0.1.0", - "@mapbox/tiny-sdf": "^2.0.6", - "@mapbox/unitbezier": "^0.0.1", - "@mapbox/vector-tile": "^1.3.1", - "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^19.2.1", - "@types/geojson": "^7946.0.10", - "@types/mapbox__point-geometry": "^0.1.2", - "@types/mapbox__vector-tile": "^1.3.0", - "@types/pbf": "^3.0.2", - "earcut": "^2.2.4", - "geojson-vt": "^3.2.1", - "gl-matrix": "^3.4.3", - "global-prefix": "^3.0.0", - "kdbush": "^4.0.2", - "murmurhash-js": "^1.0.0", - "pbf": "^3.2.1", - "potpack": "^2.0.0", - "quickselect": "^2.0.0", - "supercluster": "^8.0.1", - "tinyqueue": "^2.0.3", - "vt-pbf": "^3.1.3" - } - } } }, "@nodelib/fs.scandir": { @@ -4109,6 +4074,25 @@ "optional": true, "peer": true }, + "@rollup/pluginutils": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", + "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "dependencies": { + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + } + } + }, "@sveltejs/package": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.2.2.tgz", @@ -4123,24 +4107,24 @@ } }, "@sveltejs/vite-plugin-svelte": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.5.tgz", - "integrity": "sha512-UJKsFNwhzCVuiZd06jM/psscyNJNDwjQC+qIeb7GBJK9iWeQCcIyfcPWDvbCudfcJggY9jtxJeeaZH7uny93FQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.0.tgz", + "integrity": "sha512-FxLZLVfFA2soGw7ej8Ohuav7+AOsJILiPlL8FgY5MABDDmDqb637o8Xd/QGkrXLC1qXyG1bnteOw5Z5yrA2lHA==", "dev": true, "requires": { - "@sveltejs/vite-plugin-svelte-inspector": "^1.0.3", + "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", - "magic-string": "^0.30.2", + "magic-string": "^0.30.3", "svelte-hmr": "^0.15.3", "vitefu": "^0.2.4" } }, "@sveltejs/vite-plugin-svelte-inspector": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.3.tgz", - "integrity": "sha512-Khdl5jmmPN6SUsVuqSXatKpQTMIifoQPDanaxC84m9JxIibWvSABJyHpyys0Z+1yYrxY5TTEQm+6elh0XCMaOA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.4.tgz", + "integrity": "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==", "dev": true, "requires": { "debug": "^4.3.4" @@ -4260,30 +4244,30 @@ "dev": true }, "@types/geojson": { - "version": "7946.0.10", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", - "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", + "version": "7946.0.13", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz", + "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==", "dev": true }, "@types/leaflet": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-kfwgQf4eOxoe/tD9CaKQrBKHbc7VpyfJOG5sxsQtkH+ML9xYa8hUC3UMa0wU1pKfciJtO0pU9g9XbWhPo7iBCA==", + "version": "1.9.8", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.8.tgz", + "integrity": "sha512-EXdsL4EhoUtGm2GC2ZYtXn+Fzc6pluVgagvo2VC1RHWToLGlTRwVYoDpqS/7QXa01rmDyBjJk3Catpf60VMkwg==", "dev": true, "requires": { "@types/geojson": "*" } }, "@types/mapbox__point-geometry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz", - "integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.3.tgz", + "integrity": "sha512-2W46IOXlu7vC8m3+M5rDqSnuY22GFxxx3xhkoyqyPWrD+eP2iAwNst0A1+umLYjCTJMJTSpiofphn9h9k+Kw+w==", "dev": true }, "@types/mapbox__vector-tile": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz", - "integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.3.tgz", + "integrity": "sha512-d263B3KCQtXKVZMHpMJrEW5EeLBsQ8jvAS9nhpUKC5hHIlQaACG9PWkW8qxEeNuceo9120AwPjeS91uNa4ltqA==", "dev": true, "requires": { "@types/geojson": "*", @@ -4292,9 +4276,9 @@ } }, "@types/pbf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", - "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.4.tgz", + "integrity": "sha512-SOFlLGZkLbEXJRwcWCqeP/Koyaf/uAqLXHUsdo/nMfjLsNd8kqauwHe9GBOljSmpcHp/LC6kOjo3SidGjNirVA==", "dev": true }, "@types/prop-types": { @@ -4310,9 +4294,9 @@ "dev": true }, "@types/react": { - "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "version": "18.2.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", + "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", "dev": true, "requires": { "@types/prop-types": "*", @@ -4321,9 +4305,9 @@ } }, "@types/react-dom": { - "version": "18.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", - "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "version": "18.2.15", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.15.tgz", + "integrity": "sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==", "dev": true, "requires": { "@types/react": "*" @@ -4336,9 +4320,9 @@ "dev": true }, "@types/supercluster": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.0.tgz", - "integrity": "sha512-6JapQ2GmEkH66r23BK49I+u6zczVDGTtiJEVvKDYZVSm/vepWaJuTq6BXzJ6I4agG5s8vA1KM7m/gXWDg03O4Q==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.2.tgz", + "integrity": "sha512-qMhofL945Z4njQUuntadexAgPtpiBC014WvVqU70Prj42LC77Xgmz04us7hSMmwjs7KbgAwGBmje+FSOvDbP0Q==", "dev": true, "requires": { "@types/geojson": "*" @@ -4658,9 +4642,9 @@ "dev": true }, "concurrently": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", - "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", + "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", "dev": true, "requires": { "chalk": "^4.1.2", @@ -5268,9 +5252,9 @@ } }, "magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "requires": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -5292,9 +5276,9 @@ "peer": true }, "maplibre-gl": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.3.1.tgz", - "integrity": "sha512-SfRq9bT68GytDzCOG0IoTGg2rASbgdYunW/6xhnp55QuLmwG1M/YOlXxqHaphwia7kZbMvBOocvY0fp5yfTjZA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.5.2.tgz", + "integrity": "sha512-deqYA/RiEyXMGroZMDbOWNQTLnFsxREC+mDkQnuyCUNdBWm1KHafsXJYZP7rlLa5RLQNq05IAUAizY9aHTpIUw==", "dev": true, "requires": { "@mapbox/geojson-rewind": "^0.5.2", @@ -5304,12 +5288,12 @@ "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^19.3.0", - "@types/geojson": "^7946.0.10", - "@types/mapbox__point-geometry": "^0.1.2", - "@types/mapbox__vector-tile": "^1.3.0", - "@types/pbf": "^3.0.2", - "@types/supercluster": "^7.1.0", + "@maplibre/maplibre-gl-style-spec": "^19.3.3", + "@types/geojson": "^7946.0.12", + "@types/mapbox__point-geometry": "^0.1.3", + "@types/mapbox__vector-tile": "^1.3.3", + "@types/pbf": "^3.0.4", + "@types/supercluster": "^7.1.2", "earcut": "^2.2.4", "geojson-vt": "^3.2.1", "gl-matrix": "^3.4.3", @@ -5671,9 +5655,9 @@ } }, "replace-in-file": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-7.0.1.tgz", - "integrity": "sha512-KbhgPq04eA+TxXuUxpgWIH9k/TjF+28ofon2PXP7vq6izAILhxOtksCVcLuuQLtyjouBaPdlH6RJYYcSPVxCOA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-7.0.2.tgz", + "integrity": "sha512-tPG+Qmqf+x2Rf1WVdb/9B5tFIf6KJ5hs3fgxh1OTzPRUugPPvyAva7NvCJtnSpmyq6r+ABYcuUOqZkm6yzGSUw==", "dev": true, "requires": { "chalk": "^4.1.2", @@ -5805,9 +5789,9 @@ } }, "sass": { - "version": "1.66.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", - "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", + "version": "1.69.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", + "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", @@ -5991,9 +5975,9 @@ } }, "svelte": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.0.tgz", - "integrity": "sha512-kVsdPjDbLrv74SmLSUzAsBGquMs4MPgWGkGLpH+PjOYnFOziAvENVzgJmyOCV2gntxE32aNm8/sqNKD6LbIpeQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.2.tgz", + "integrity": "sha512-My2tytF2e2NnHSpn2M7/3VdXT4JdTglYVUuSuK/mXL2XtulPYbeBfl8Dm1QiaKRn0zoULRnL+EtfZHHP0k4H3A==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.1", @@ -6007,7 +5991,7 @@ "estree-walker": "^3.0.3", "is-reference": "^3.0.1", "locate-character": "^3.0.0", - "magic-string": "^0.30.0", + "magic-string": "^0.30.4", "periscopic": "^3.1.0" }, "dependencies": { @@ -6020,9 +6004,9 @@ } }, "svelte-check": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.5.1.tgz", - "integrity": "sha512-+Zb4iHxAhdUtcUg/WJPRjlS1RJalIsWAe9Mz6G1zyznSs7dDkT7VUBdXc3q7Iwg49O/VrZgyJRvOJkjuBfKjFA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.5.2.tgz", + "integrity": "sha512-5a/YWbiH4c+AqAUP+0VneiV5bP8YOk9JL3jwvN+k2PEPLgpu85bjQc5eE67+eIZBBwUEJzmO3I92OqKcqbp3fw==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.17", @@ -6181,9 +6165,9 @@ "dev": true }, "vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", "dev": true, "requires": { "esbuild": "^0.18.10", @@ -6210,6 +6194,12 @@ "pbf": "^3.2.1" } }, + "web-merc-projection": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/web-merc-projection/-/web-merc-projection-1.3.2.tgz", + "integrity": "sha512-GYvU+9i2J8Ipz7OvArGDltfUQahp9JA6Yta9PI8cMbMcqZs+i2GmsPjw81mTOKRCWqvaAwdLbux8LgG74ibZbw==", + "dev": true + }, "web-worker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", diff --git a/package.json b/package.json index f5bca89..4d9a0be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@maptiler/geocoding-control", - "version": "0.0.100", + "version": "1.0.0", "description": "The Javascript & TypeScript Map Control component for MapTiler Geocoding service. Easy to be integrated into any JavaScript mapping application.", "type": "module", "author": { @@ -97,36 +97,36 @@ "./svelte/*": "./svelte/*" }, "devDependencies": { - "@maptiler/sdk": "^1.1.2", + "@maptiler/sdk": "^1.2.0", "@sveltejs/package": "^2.2.2", - "@sveltejs/vite-plugin-svelte": "^2.4.5", + "@sveltejs/vite-plugin-svelte": "^2.5.0", "@tsconfig/svelte": "^5.0.2", "@turf/buffer": "^6.5.0", "@turf/difference": "^6.5.0", "@turf/union": "^6.5.0", - "@types/geojson": "^7946.0.10", - "@types/leaflet": "^1.9.4", - "@types/react": "^18.2.21", - "@types/react-dom": "^18.2.7", - "concurrently": "^8.2.1", + "@types/geojson": "^7946.0.13", + "@types/leaflet": "^1.9.8", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "concurrently": "^8.2.2", "dotenv": "^16.3.1", "esm-env": "^1.0.0", "leaflet": "^1.9.4", - "maplibre-gl": "^3.3.1", + "maplibre-gl": "^3.5.2", "prettier": "^3.0.3", "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-svelte": "^3.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", "renamer": "^4.0.0", - "replace-in-file": "^7.0.1", - "sass": "^1.66.1", - "svelte": "^4.2.0", - "svelte-check": "^3.5.1", + "replace-in-file": "^7.0.2", + "sass": "^1.69.5", + "svelte": "^4.2.2", + "svelte-check": "^3.5.2", "svelte-preprocess": "^5.0.4", "tslib": "^2.6.2", "typescript": "^5.2.2", - "vite": "^4.4.9" + "vite": "^4.5.0" }, "peerDependencies": { "@maptiler/sdk": "^1", diff --git a/public/icons/clinic.svg b/public/icons/clinic.svg new file mode 100644 index 0000000..c8b3ed3 --- /dev/null +++ b/public/icons/clinic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/hardware.svg b/public/icons/hardware.svg new file mode 100644 index 0000000..d04f8cf --- /dev/null +++ b/public/icons/hardware.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/icons/mountain.svg b/public/icons/mountain.svg deleted file mode 100644 index 68d7bec..0000000 --- a/public/icons/mountain.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/icons/mountain_range.svg b/public/icons/mountain_range.svg new file mode 100644 index 0000000..5167a56 --- /dev/null +++ b/public/icons/mountain_range.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/icons/ocean.svg b/public/icons/ocean.svg new file mode 100644 index 0000000..f2671c5 --- /dev/null +++ b/public/icons/ocean.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icons/parking_space.svg b/public/icons/parking_space.svg new file mode 100644 index 0000000..15f496c --- /dev/null +++ b/public/icons/parking_space.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/peak.svg b/public/icons/peak.svg index 1907fba..68d7bec 100644 --- a/public/icons/peak.svg +++ b/public/icons/peak.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/icons/playground.svg b/public/icons/playground.svg index 7fc1755..8778d1b 100644 --- a/public/icons/playground.svg +++ b/public/icons/playground.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/public/icons/river.svg b/public/icons/river.svg new file mode 100644 index 0000000..7cf3c75 --- /dev/null +++ b/public/icons/river.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/public/icons/sea.svg b/public/icons/sea.svg new file mode 100644 index 0000000..f2671c5 --- /dev/null +++ b/public/icons/sea.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/icons/stream.svg b/public/icons/stream.svg new file mode 100644 index 0000000..7cf3c75 --- /dev/null +++ b/public/icons/stream.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/public/icons/vending_machine.svg b/public/icons/vending_machine.svg new file mode 100644 index 0000000..81525a5 --- /dev/null +++ b/public/icons/vending_machine.svg @@ -0,0 +1,22 @@ + + + + + + + hardware-cabinet + + + + + + + + + + + hardware-cabinet + + + + diff --git a/public/icons/water.svg b/public/icons/water.svg new file mode 100644 index 0000000..f2671c5 --- /dev/null +++ b/public/icons/water.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/FeatureItem.svelte b/src/FeatureItem.svelte index 7b2b2be..68af5e3 100644 --- a/src/FeatureItem.svelte +++ b/src/FeatureItem.svelte @@ -17,9 +17,13 @@ let imageUrl: string | undefined; + let loadIconAttempt = 0; + $: index = categories?.length ?? 0; $: { + loadIconAttempt; + do { index--; @@ -40,7 +44,7 @@ missingIconsCache.add(imageUrl); } - index--; + loadIconAttempt++; } diff --git a/src/GeocodingControl.svelte b/src/GeocodingControl.svelte index ec6aa57..4719d46 100644 --- a/src/GeocodingControl.svelte +++ b/src/GeocodingControl.svelte @@ -1,23 +1,24 @@ diff --git a/src/MapLibreBasedGeocodingControl.ts b/src/MapLibreBasedGeocodingControl.ts index 2614ba7..9ab40f2 100644 --- a/src/MapLibreBasedGeocodingControl.ts +++ b/src/MapLibreBasedGeocodingControl.ts @@ -154,6 +154,14 @@ export abstract class MapLibreBasedGeocodingControl< this.#gc?.setQuery(value, submit); } + clearMap() { + this.#gc?.clearMap(); + } + + clearList() { + this.#gc?.clearList(); + } + setReverseMode(value: boolean) { this.#gc?.$set({ reverseActive: value }); } diff --git a/src/geoUtils.ts b/src/geoUtils.ts new file mode 100644 index 0000000..3241c4a --- /dev/null +++ b/src/geoUtils.ts @@ -0,0 +1,24 @@ +import type { BBox } from "./types"; + +// taken from Leaflet +export function wrapNum( + x: number, + range: [number, number], + includeMax: boolean, +) { + const max = range[1], + min = range[0], + d = max - min; + + return x === max && includeMax ? x : ((((x - min) % d) + d) % d) + min; +} + +export function unwrapBbox(bbox0: BBox): BBox { + const bbox = [...bbox0] satisfies BBox; + + if (bbox[2] < bbox[0]) { + bbox[2] += 360; + } + + return bbox; +} diff --git a/src/leaflet-controller.ts b/src/leaflet-controller.ts index 41929d8..56960df 100644 --- a/src/leaflet-controller.ts +++ b/src/leaflet-controller.ts @@ -9,7 +9,7 @@ import type { GeoJSON } from "geojson"; import * as L from "leaflet"; import MarkerIcon from "./MarkerIcon.svelte"; import { setMask } from "./mask"; -import type { Feature, MapController, MapEvent, Proximity } from "./types"; +import type { BBox, Feature, MapController, MapEvent, Position } from "./types"; export function createLeafletMapController( map: L.Map, @@ -38,8 +38,6 @@ export function createLeafletMapController( ) { let eventHandler: ((e: MapEvent) => void) | undefined; - let prevProximity: Proximity = undefined; - let markers: L.Marker[] = []; let selectedMarker: L.Marker | undefined; @@ -51,21 +49,6 @@ export function createLeafletMapController( interactive: false, }).addTo(map); - const handleMoveEnd = () => { - let c: L.LatLng; - - const proximity = - map.getZoom() > 10 - ? ([(c = map.getCenter().wrap()).lng, c.lat] as [number, number]) - : undefined; - - if (prevProximity !== proximity) { - prevProximity = proximity; - - eventHandler?.({ type: "proximityChange", proximity }); - } - }; - const handleMapClick = (e: L.LeafletMouseEvent) => { eventHandler?.({ type: "mapClick", @@ -95,31 +78,19 @@ export function createLeafletMapController( if (handler) { eventHandler = handler; - map.on("moveend", handleMoveEnd); - - handleMoveEnd(); - map.on("click", handleMapClick); } else { - map.off("moveend", handleMoveEnd); - - eventHandler?.({ type: "proximityChange", proximity: undefined }); - eventHandler = undefined; map.off("click", handleMapClick); } }, - flyTo(center: [number, number], zoom: number) { + flyTo(center: Position, zoom: number) { map.flyTo([center[1], center[0]], zoom, { duration: 2, ...flyToOptions }); }, - fitBounds( - bbox: [number, number, number, number], - padding: number, - maxZoom: number, - ): void { + fitBounds(bbox: BBox, padding: number, maxZoom: number): void { map.flyToBounds( [ [bbox[1], bbox[0]], @@ -133,13 +104,13 @@ export function createLeafletMapController( map.getContainer().style.cursor = reverse ? "crosshair" : ""; }, - setReverseMarker(coordinates?: [number, number]) { + setReverseMarker(coordinates?: Position) { if (!marker) { return; } const latLng = - coordinates && ([coordinates[1], coordinates[0]] as [number, number]); + coordinates && ([coordinates[1], coordinates[0]] as Position); if (reverseMarker) { if (!latLng) { @@ -303,5 +274,11 @@ export function createLeafletMapController( selectedMarker?.getElement()?.classList.toggle("marker-selected", true); }, + + getCenterAndZoom() { + const c = map.getCenter(); + + return [map.getZoom(), c.lng, c.lat]; + }, } satisfies MapController; } diff --git a/src/leaflet.ts b/src/leaflet.ts index a9f17ae..d7b63e3 100644 --- a/src/leaflet.ts +++ b/src/leaflet.ts @@ -122,6 +122,14 @@ export class GeocodingControl extends L.Control { this.#gc?.setQuery(value, submit); } + clearMap() { + this.#gc?.clearMap(); + } + + clearList() { + this.#gc?.clearList(); + } + focus() { this.#gc?.focus(); } diff --git a/src/maplibregl-controller.ts b/src/maplibregl-controller.ts index 46c2514..40a147f 100644 --- a/src/maplibregl-controller.ts +++ b/src/maplibregl-controller.ts @@ -13,14 +13,14 @@ import type { FlyToOptions, GeoJSONSource, LineLayerSpecification, - LngLat, Map, MapMouseEvent, Marker, } from "maplibre-gl"; import MarkerIcon from "./MarkerIcon.svelte"; import { setMask } from "./mask"; -import type { Feature, MapController, MapEvent, Proximity } from "./types.js"; +import type { BBox, Position } from "./types"; +import type { Feature, MapController, MapEvent } from "./types.js"; type MapLibreGL = Pick; @@ -64,8 +64,6 @@ export function createMapLibreGlMapController( ) { let eventHandler: ((e: MapEvent) => void) | undefined; - let prevProximity: Proximity = undefined; - let markers: Marker[] = []; let selectedMarker: maplibregl.Marker | undefined; @@ -114,21 +112,6 @@ export function createMapLibreGlMapController( }); }; - const handleMoveEnd = () => { - let c: LngLat; - - const proximity = - map.getZoom() > 9 - ? ([(c = map.getCenter().wrap()).lng, c.lat] as [number, number]) - : undefined; - - if (prevProximity !== proximity) { - prevProximity = proximity; - - eventHandler?.({ type: "proximityChange", proximity }); - } - }; - function createMarker(interactive = false) { if (!maplibregl) { throw new Error(); @@ -153,31 +136,19 @@ export function createMapLibreGlMapController( if (handler) { eventHandler = handler; - map.on("moveend", handleMoveEnd); - - handleMoveEnd(); - map.on("click", handleMapClick); } else { - map.off("moveend", handleMoveEnd); - - eventHandler?.({ type: "proximityChange", proximity: undefined }); - eventHandler = undefined; map.off("click", handleMapClick); } }, - flyTo(center: [number, number], zoom: number): void { + flyTo(center: Position, zoom: number): void { map.flyTo({ center, zoom, ...flyToOptions }); }, - fitBounds( - bbox: [number, number, number, number], - padding: number, - maxZoom: number, - ): void { + fitBounds(bbox: BBox, padding: number, maxZoom: number): void { map.fitBounds( [ [bbox[0], bbox[1]], @@ -191,7 +162,7 @@ export function createMapLibreGlMapController( map.getCanvasContainer().style.cursor = reverse ? "crosshair" : ""; }, - setReverseMarker(coordinates?: [number, number]) { + setReverseMarker(coordinates?: Position) { if (!maplibregl || !marker) { return; } @@ -366,5 +337,11 @@ export function createMapLibreGlMapController( selectedMarker?.getElement().classList.toggle("marker-selected", true); }, + + getCenterAndZoom() { + const c = map.getCenter(); + + return [map.getZoom(), c.lng, c.lat]; + }, } satisfies MapController; } diff --git a/src/openlayers-controller.ts b/src/openlayers-controller.ts index c031692..f482608 100644 --- a/src/openlayers-controller.ts +++ b/src/openlayers-controller.ts @@ -23,7 +23,13 @@ import Style, { type StyleLike } from "ol/style/Style"; import Text from "ol/style/Text"; import type { FlatStyleLike } from "ol/style/flat"; import { setMask } from "./mask"; -import type { Feature as FeatureType, MapController, MapEvent } from "./types"; +import type { + BBox, + Feature as FeatureType, + MapController, + MapEvent, + Position, +} from "./types"; const EPSG_4326 = "EPSG:4326"; @@ -162,17 +168,6 @@ export function createOpenLayersMapController( return geometry.transform(EPSG_4326, map.getView().getProjection()); } - const handleMoveEnd = () => { - const center = map.getView().getCenter(); - - const proximity = - center && map.getView().getZoom()! > 10 - ? (toLonLat(center, map.getView().getProjection()) as [number, number]) - : undefined; - - eventHandler?.({ type: "proximityChange", proximity }); - }; - const handleMapClick = (e: MapBrowserEvent) => { eventHandler?.({ type: "mapClick", @@ -187,18 +182,14 @@ export function createOpenLayersMapController( setEventHandler(handler: undefined | ((e: MapEvent) => void)): void { if (handler) { eventHandler = handler; - map.on("moveend", handleMoveEnd); - handleMoveEnd(); map.on("click", handleMapClick); } else { - map.un("moveend", handleMoveEnd); - eventHandler?.({ type: "proximityChange", proximity: undefined }); eventHandler = undefined; map.un("click", handleMapClick); } }, - flyTo(center: [number, number], zoom: number) { + flyTo(center: Position, zoom: number) { map.getView().animate({ center: fromLonLat(center, map.getView().getProjection()), zoom, @@ -207,11 +198,7 @@ export function createOpenLayersMapController( }); }, - fitBounds( - bbox: [number, number, number, number], - padding: number, - maxZoom: number, - ): void { + fitBounds(bbox: BBox, padding: number, maxZoom: number): void { map .getView() .fit(transformExtent(bbox, EPSG_4326, map.getView().getProjection()), { @@ -228,7 +215,7 @@ export function createOpenLayersMapController( map.getTargetElement().style.cursor = reverse ? "crosshair" : ""; }, - setReverseMarker(coordinates?: [number, number]) { + setReverseMarker(coordinates?: Position) { if (reverseMarker) { if (!coordinates) { source.removeFeature(reverseMarker); @@ -399,5 +386,19 @@ export function createOpenLayersMapController( prevSelected = index; }, + + getCenterAndZoom() { + const view = map.getView(); + + const center = view.getCenter(); + + const zoom = view.getZoom(); + + if (!center || zoom === undefined) { + return undefined; + } + + return [zoom, ...(toLonLat(center, view.getProjection()) as Position)]; + }, } satisfies MapController; } diff --git a/src/openlayers.ts b/src/openlayers.ts index 1bb1096..8f8ab56 100644 --- a/src/openlayers.ts +++ b/src/openlayers.ts @@ -178,6 +178,14 @@ export class GeocodingControl extends Control { this.#gc?.setQuery(value, submit); } + clearMap() { + this.#gc?.clearMap(); + } + + clearList() { + this.#gc?.clearList(); + } + focus() { this.#gc?.focus(); } diff --git a/src/proximity.ts b/src/proximity.ts new file mode 100644 index 0000000..2451e9f --- /dev/null +++ b/src/proximity.ts @@ -0,0 +1,86 @@ +import type { MapController, ProximityRule } from "./types"; + +let cachedLocation: { time: number; coords: undefined | string } | undefined; + +export async function getProximity( + mapController: MapController | undefined, + proximity: ProximityRule[] | null | undefined, + ac: AbortController, +) { + const centerAndZoom = mapController?.getCenterAndZoom(); + + for (const rule of proximity ?? []) { + if ( + centerAndZoom && + ((rule.minZoom != undefined && rule.minZoom > centerAndZoom[0]) || + (rule.maxZoom != undefined && rule.maxZoom < centerAndZoom[0])) + ) { + continue; + } + + if (rule.type === "fixed") { + return rule.coordinates.join(","); + } + + cg: if (rule.type === "client-geolocation") { + if ( + cachedLocation && + rule.cachedLocationExpiry && + cachedLocation.time + rule.cachedLocationExpiry > Date.now() + ) { + if (!cachedLocation.coords) { + break cg; + } + + return cachedLocation.coords; + } + + let coords: string | undefined; + + try { + coords = await new Promise((resolve, reject) => { + ac.signal.addEventListener("abort", () => { + reject(Error("aborted")); + }); + + navigator.geolocation.getCurrentPosition( + (pos) => { + resolve( + [pos.coords.longitude, pos.coords.latitude] + .map((c) => c.toFixed(6)) + .join(","), + ); + }, + (err) => { + reject(err); + }, + rule, + ); + }); + + return coords; + } catch { + // ignore + } finally { + if (rule.cachedLocationExpiry) { + cachedLocation = { + time: Date.now(), + coords, + }; + } + } + + if (ac.signal.aborted) { + return; + } + } + + if (rule.type === "server-geolocation") { + return "ip"; + } + + if (centerAndZoom && rule.type === "map-center") { + return centerAndZoom[1].toFixed(6) + "," + centerAndZoom[2].toFixed(6); + } + } +} diff --git a/src/react.ts b/src/react.ts index 81f1bce..ace344d 100644 --- a/src/react.ts +++ b/src/react.ts @@ -57,7 +57,7 @@ const propertyNames = [ "showFullGeometry", "showPlaceType", "showResultsWhileTyping", - "trackProximity", + "adjustUrlQuery", "types", "zoom", "mapController", @@ -80,6 +80,8 @@ export type Methods = { blur(): void; focus(): void; setQuery(value: string, submit?: boolean): void; + clearMap(): void; + clearList(): void; }; const ReactGeocodingControl = forwardRef(function ReactGeocodingControl( @@ -138,6 +140,8 @@ const ReactGeocodingControl = forwardRef(function ReactGeocodingControl( useImperativeHandle(ref, () => ({ setQuery: (value: string, submit = true) => controlRef.current?.setQuery(value, submit), + clearMap: () => controlRef.current?.clearMap(), + clearList: () => controlRef.current?.clearList(), focus: () => controlRef.current?.focus(), blur: () => controlRef.current?.blur(), })); diff --git a/src/types.ts b/src/types.ts index b0f509b..a9d9a24 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,16 +1,16 @@ -import type { - Feature as FeatureType, - GeoJsonProperties, - Geometry, -} from "geojson"; +import type { Feature as FeatureType, Geometry } from "geojson"; + +export type BBox = [minx: number, miny: number, maxx: number, maxy: number]; + +export type Position = [x: number, y: number]; export type Feature = FeatureType & { id: string; text: string; place_name: string; place_type: string[]; - center: [number, number]; - bbox: [number, number, number, number]; + center: Position; + bbox: BBox; address?: string; matching_text?: string; }; @@ -21,11 +21,7 @@ export type FeatureCollection = { }; export type MapEvent = - | { - type: "proximityChange"; - proximity: [number, number] | undefined; - } - | { type: "mapClick"; coordinates: [number, number] } + | { type: "mapClick"; coordinates: Position } | { type: "markerClick"; id: string } | { type: "markerMouseEnter"; id: string } | { type: "markerMouseLeave"; id: string }; @@ -33,13 +29,9 @@ export type MapEvent = export type MapController = { setEventHandler(handler: undefined | ((e: MapEvent) => void)): void; - flyTo(center: [number, number], zoom: number): void; + flyTo(center: Position, zoom: number): void; - fitBounds( - bbox: [number, number, number, number], - padding: number, - maxZoom: number, - ): void; + fitBounds(bbox: BBox, padding: number, maxZoom: number): void; indicateReverse(reverse: boolean): void; @@ -48,12 +40,43 @@ export type MapController = { picked: Feature | undefined, ): void; - setReverseMarker(coordinates?: [number, number]): void; + setReverseMarker(coordinates?: Position): void; setSelectedMarker(index: number): void; + + getCenterAndZoom(): [zoom: number, lon: number, lat: number] | undefined; }; -export type Proximity = [number, number] | undefined; +export type ProximityRule = { + /** minimal map zoom for the rule to be used */ + minZoom?: number; + + /** maximal map zoom for the rule to be used */ + maxZoom?: number; +} & ( + | { + /** fixed proximity */ + type: "fixed"; + + /** coordinates of the fixed proximity */ + coordinates: Position; + } + | { + /** use map center coordinates for the proximity */ + type: "map-center"; + } + | { + /** resolve proximity by geolocating IP of the geocoding API call */ + type: "server-geolocation"; + } + | ({ + /** use browser's geolocation API for proximity. If it fails, following proximity rules are iterated. */ + type: "client-geolocation"; + + /** how long should the geolocation result be cached, in milliseconds */ + cachedLocationExpiry?: number; + } & PositionOptions) +); export type ControlOptions = { /** @@ -70,10 +93,12 @@ export type ControlOptions = { debounceSearch?: number; /** - * A proximity argument: this is a geographical point given as an object with latitude and longitude properties. - * Search results closer to this point will be given higher priority. + * Search results closer to the proximity point will be given higher priority. First matching rule from the array will be used. + * Set to `undefined` or `null` to disable proximity. + * + * @default [{ type: "server-geolocation" }] */ - proximity?: [number, number]; + proximity?: ProximityRule[] | null | undefined; /** * Override the default placeholder attribute value. @@ -96,13 +121,6 @@ export type ControlOptions = { */ noResultsMessage?: string; - /** - * If true, the geocoder proximity will automatically update based on the map view. - * - * @default true - */ - trackProximity?: boolean; - /** * Minimum number of characters to enter before results are shown. * @@ -113,8 +131,10 @@ export type ControlOptions = { /** * A bounding box argument: this is a bounding box given as an array in the format [minX, minY, maxX, maxY]. * Search results will be limited to the bounding box. + * + * @default undefined */ - bbox?: [number, number, number, number]; + bbox?: BBox; /** * Maximum number of results to show. @@ -127,9 +147,12 @@ export type ControlOptions = { * Specify the language to use for response text and query result weighting. * Options are IETF language tags comprised of a mandatory ISO 639-1 language code and optionally one or more IETF subtags for country or script. * More than one value can also be specified, separated by commas. + * Set to `null` or empty string for disabling language-specific searching. * Defaults to the browser's language settings. + * + * @default undefined */ - language?: string | string[]; + language?: string | string[] | null; /** * If `false`, indicates that search will only occur on enter key press. @@ -191,6 +214,8 @@ export type ControlOptions = { /** * Class of the root element. + * + * @default undefined */ class?: string; @@ -230,8 +255,6 @@ export type ControlOptions = { */ showPlaceType?: false | "always" | "ifNeeded"; - showIcons?: boolean; - /** * Set to `true` to show full feature geometry of the chosen result. Otherwise only marker will be shown. * @@ -274,6 +297,13 @@ export type ControlOptions = { */ iconsBaseUrl?: string; + /** + * Function to adjust URL search parameters. + * + * @default empty function + */ + adjustUrlQuery?: (sp: URLSearchParams) => void; + // TODO - missing but useful from maplibre-gl-geocoder // popup // If true, a Popup will be added to the map when clicking on a marker using a default set of popup options. If the value is an object, the popup will be constructed using these options. If false, no popup will be added to the map. Requires that options.maplibregl also be set. (optional, default true) // render // A function that specifies how the results should be rendered in the dropdown menu. This function should accepts a single Carmen GeoJSON object as input and return a string. Any HTML in the returned string will be rendered. diff --git a/src/vanilla.ts b/src/vanilla.ts index 43c5d48..074f3ce 100644 --- a/src/vanilla.ts +++ b/src/vanilla.ts @@ -42,6 +42,14 @@ export class GeocodingControl extends EventTarget { this.#gc?.setQuery(value, submit); } + clearMap() { + this.#gc?.clearMap(); + } + + clearList() { + this.#gc?.clearList(); + } + focus() { this.#gc?.focus(); }