4 Commits
226 changed files with 1972 additions and 2172 deletions
+2 -3
View File
@@ -70,9 +70,8 @@ This project has been made possible thanks to the following open source projects
- [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree - [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree
- Mapping: - Mapping:
- [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) — beautiful and fast interactive map rendering - [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) — beautiful and fast interactive map rendering
- [GraphHopper](https://github.com/graphhopper/graphhopper) — powerful routing engine - [GraphHopper](https://github.com/graphhopper/graphhopper) — routing engine
- [OpenStreetMap](https://www.openstreetmap.org) — open map data used by most of the map layers, and by the routing engine - [OpenStreetMap](https://www.openstreetmap.org) — map data used by most of the map layers, and by the routing engine
- [Mapterhorn](https://github.com/mapterhorn/mapterhorn) — high-quality open terrain data used by some map layers (including for 3D), and by the routing engine
- Search: - Search:
- [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation - [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation
+67 -70
View File
@@ -20,7 +20,7 @@
"immer": "^10.1.1", "immer": "^10.1.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"mapillary-js": "^4.1.2", "mapillary-js": "^4.1.2",
"maplibre-gl": "^6.0.0", "maplibre-gl": "^5.21.1",
"sanitize-html": "^2.17.0", "sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6" "sortablejs": "^1.15.6"
}, },
@@ -3236,18 +3236,13 @@
} }
}, },
"node_modules/@mapbox/jsonlint-lines-primitives": { "node_modules/@mapbox/jsonlint-lines-primitives": {
"version": "2.0.3", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.3.tgz",
"integrity": "sha512-0SElaV0uMxEnxzBhhX9WTuPyUeMsAN/SS0i16tjuba4/mio63MG9khjC1a0JAiPGXAwvwm4UfHJURCN7nyudQg==",
"license": "MIT",
"engines": { "engines": {
"node": ">= 22" "node": ">= 0.6"
} }
}, },
"node_modules/@mapbox/point-geometry": { "node_modules/@mapbox/point-geometry": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz",
"integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/@mapbox/sphericalmercator": { "node_modules/@mapbox/sphericalmercator": {
@@ -3258,32 +3253,24 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@mapbox/tiny-sdf": { "node_modules/@mapbox/tiny-sdf": {
"version": "2.2.0", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.2.0.tgz",
"integrity": "sha512-LVL4wgI9YAum5V+LNVQO6QgFBPw7/MIIY4XJPNsPDMrjEwcE+JfKk1LuIl8GnF197ejVdC9QdPaxrx5gfgdGXg==",
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/@mapbox/unitbezier": { "node_modules/@mapbox/unitbezier": {
"version": "1.0.0", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-1.0.0.tgz",
"integrity": "sha512-fqd515fjBmANKGGsQ286E2Wvj/XvDFpGzwJxq4CI6jMQue6Oy04uCKp+JWKF00xRTmk6cEu1jPJ9p3xqH8YWqQ==",
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/@mapbox/vector-tile": { "node_modules/@mapbox/vector-tile": {
"version": "3.0.0", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-3.0.0.tgz",
"integrity": "sha512-Qf10S1uIHMk20ri/IVBnpS+esUEkVaR5Hftmz88jTInrpmWgPGJfPe3LVjjlE77trLx8tH6qjTG7uWH9hIq/0Q==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"@mapbox/point-geometry": "~1.1.0", "@mapbox/point-geometry": "~1.1.0",
"@types/geojson": "^7946.0.16", "@types/geojson": "^7946.0.16",
"pbf": "^5.0.0" "pbf": "^4.0.1"
} }
}, },
"node_modules/@mapbox/vector-tile/node_modules/pbf": { "node_modules/@mapbox/vector-tile/node_modules/pbf": {
"version": "5.1.2", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"resolve-protobuf-schema": "^2.1.0" "resolve-protobuf-schema": "^2.1.0"
@@ -3292,13 +3279,18 @@
"pbf": "bin/pbf" "pbf": "bin/pbf"
} }
}, },
"node_modules/@mapbox/whoots-js": {
"version": "3.1.0",
"license": "ISC",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@maplibre/geojson-vt": { "node_modules/@maplibre/geojson-vt": {
"version": "6.1.1", "version": "6.0.4",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.1.1.tgz",
"integrity": "sha512-FVMOcmSP/yqol45t7StApEyTL5/vmqBCuFhH9n+fFuINenhaX+YgHHIt1yJ86S8kln3uJLcMvmEU2cfn6E2eCQ==",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"kdbush": "^4.1.0" "kdbush": "^4.0.2"
} }
}, },
"node_modules/@maplibre/maplibre-gl-geocoder": { "node_modules/@maplibre/maplibre-gl-geocoder": {
@@ -3319,16 +3311,15 @@
} }
}, },
"node_modules/@maplibre/maplibre-gl-style-spec": { "node_modules/@maplibre/maplibre-gl-style-spec": {
"version": "26.2.1", "version": "24.8.1",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-26.2.1.tgz",
"integrity": "sha512-QFKCXkOeSzOr8jF75jm6kySOg+dUvOehPhRi68gcOYPHb7U5JloUq0dJW0Y5/fZV8ygfT0Vp2RWodvq+fyxFWA==",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@mapbox/jsonlint-lines-primitives": "^2.0.3", "@mapbox/jsonlint-lines-primitives": "~2.0.2",
"@mapbox/unitbezier": "^1.0.0", "@mapbox/unitbezier": "^0.0.1",
"json-stringify-pretty-compact": "^4.0.0", "json-stringify-pretty-compact": "^4.0.0",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"quickselect": "^3.0.0", "quickselect": "^3.0.0",
"rw": "^1.3.3",
"tinyqueue": "^3.0.0" "tinyqueue": "^3.0.0"
}, },
"bin": { "bin": {
@@ -3338,29 +3329,31 @@
} }
}, },
"node_modules/@maplibre/mlt": { "node_modules/@maplibre/mlt": {
"version": "1.1.12", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.12.tgz",
"integrity": "sha512-ZeK5w2TTeHOajcLaEQs1KZXw2V9wIKo1PmThlxlsHoXsQsYlBqLJzPOd6tJHRtGTChUY3DPPmjXRArYVvAbmZw==",
"license": "(MIT OR Apache-2.0)", "license": "(MIT OR Apache-2.0)",
"dependencies": { "dependencies": {
"@mapbox/point-geometry": "^1.1.0" "@mapbox/point-geometry": "^1.1.0"
} }
}, },
"node_modules/@maplibre/vt-pbf": { "node_modules/@maplibre/vt-pbf": {
"version": "4.3.2", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.3.2.tgz",
"integrity": "sha512-j6p0AdjvAR19Z3XaCysle7A4ZSo08tYOzxD0Y9NQylwPAkwJJeYub5b2eVucdeDh7erhv69DahoLOevDRERRUw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@mapbox/point-geometry": "^1.1.0", "@mapbox/point-geometry": "^1.1.0",
"@mapbox/vector-tile": "^2.0.4",
"@maplibre/geojson-vt": "^5.0.4",
"@types/geojson": "^7946.0.16", "@types/geojson": "^7946.0.16",
"pbf": "^5.1.0" "@types/supercluster": "^7.1.3",
"pbf": "^4.0.1",
"supercluster": "^8.0.1"
} }
}, },
"node_modules/@maplibre/vt-pbf/node_modules/@maplibre/geojson-vt": {
"version": "5.0.4",
"license": "ISC"
},
"node_modules/@maplibre/vt-pbf/node_modules/pbf": { "node_modules/@maplibre/vt-pbf/node_modules/pbf": {
"version": "5.1.2", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"resolve-protobuf-schema": "^2.1.0" "resolve-protobuf-schema": "^2.1.0"
@@ -4296,6 +4289,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/supercluster": {
"version": "7.1.3",
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/three": { "node_modules/@types/three": {
"version": "0.134.0", "version": "0.134.0",
"license": "MIT" "license": "MIT"
@@ -5720,8 +5720,6 @@
}, },
"node_modules/json-stringify-pretty-compact": { "node_modules/json-stringify-pretty-compact": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz",
"integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/jszip": { "node_modules/jszip": {
@@ -5735,9 +5733,7 @@
} }
}, },
"node_modules/kdbush": { "node_modules/kdbush": {
"version": "4.1.0", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.1.0.tgz",
"integrity": "sha512-e9vurzrXJQrFX6ckpHP3bvj5l+9CnYzkxDNnNQ1h2QTqdWsUAJgXiKdGNcOa1EY85dU8KbQ+z/FdQdB7P+9yfQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/keyv": { "node_modules/keyv": {
@@ -6158,25 +6154,25 @@
"license": "(MIT AND Zlib)" "license": "(MIT AND Zlib)"
}, },
"node_modules/maplibre-gl": { "node_modules/maplibre-gl": {
"version": "6.0.0", "version": "5.22.0",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-6.0.0.tgz",
"integrity": "sha512-1wBgEhzTZfA+cDpFdt0fM1mJA5mJ90fifORJ7D8JcKLJCvPT/iTx9bNxkP7DqEYde65DJd7gE7h83khwNRqdyg==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
"@mapbox/point-geometry": "^1.1.0", "@mapbox/point-geometry": "^1.1.0",
"@mapbox/tiny-sdf": "^2.2.0", "@mapbox/tiny-sdf": "^2.0.7",
"@mapbox/unitbezier": "^1.0.0", "@mapbox/unitbezier": "^0.0.1",
"@mapbox/vector-tile": "^3.0.0", "@mapbox/vector-tile": "^2.0.4",
"@maplibre/geojson-vt": "^6.1.1", "@mapbox/whoots-js": "^3.1.0",
"@maplibre/maplibre-gl-style-spec": "^26.1.0", "@maplibre/geojson-vt": "^6.0.4",
"@maplibre/mlt": "^1.1.12", "@maplibre/maplibre-gl-style-spec": "^24.8.1",
"@maplibre/vt-pbf": "^4.3.2", "@maplibre/mlt": "^1.1.8",
"@maplibre/vt-pbf": "^4.3.0",
"@types/geojson": "^7946.0.16", "@types/geojson": "^7946.0.16",
"earcut": "^3.2.3", "earcut": "^3.0.2",
"gl-matrix": "^3.4.4", "gl-matrix": "^3.4.4",
"kdbush": "^4.1.0", "kdbush": "^4.0.2",
"murmurhash-js": "^1.0.0", "murmurhash-js": "^1.0.0",
"pbf": "^5.1.2", "pbf": "^4.0.1",
"potpack": "^2.1.0", "potpack": "^2.1.0",
"quickselect": "^3.0.0", "quickselect": "^3.0.0",
"tinyqueue": "^3.0.0" "tinyqueue": "^3.0.0"
@@ -6190,15 +6186,11 @@
} }
}, },
"node_modules/maplibre-gl/node_modules/earcut": { "node_modules/maplibre-gl/node_modules/earcut": {
"version": "3.2.3", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.2.3.tgz",
"integrity": "sha512-vnS4AVwp1KHAF13i1vp1/2D5evWy3k5u/iW/B81QVsUZtV8cv2tU0b2VNFlqvh4kYwrFMDdjPCfAmfyJW9y14Q==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/maplibre-gl/node_modules/pbf": { "node_modules/maplibre-gl/node_modules/pbf": {
"version": "5.1.2", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"resolve-protobuf-schema": "^2.1.0" "resolve-protobuf-schema": "^2.1.0"
@@ -6259,8 +6251,6 @@
}, },
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@@ -6795,8 +6785,6 @@
}, },
"node_modules/quickselect": { "node_modules/quickselect": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/rbush": { "node_modules/rbush": {
@@ -6932,6 +6920,10 @@
} }
} }
}, },
"node_modules/rw": {
"version": "1.3.3",
"license": "BSD-3-Clause"
},
"node_modules/rxjs": { "node_modules/rxjs": {
"version": "7.8.2", "version": "7.8.2",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -7165,6 +7157,13 @@
"xtend": "^4.0.0" "xtend": "^4.0.0"
} }
}, },
"node_modules/supercluster": {
"version": "8.0.1",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
}
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7406,8 +7405,6 @@
}, },
"node_modules/tinyqueue": { "node_modules/tinyqueue": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz",
"integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/totalist": { "node_modules/totalist": {
+1 -1
View File
@@ -75,7 +75,7 @@
"immer": "^10.1.1", "immer": "^10.1.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"mapillary-js": "^4.1.2", "mapillary-js": "^4.1.2",
"maplibre-gl": "^6.0.0", "maplibre-gl": "^5.21.1",
"sanitize-html": "^2.17.0", "sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6" "sortablejs": "^1.15.6"
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 KiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

+21 -18
View File
@@ -31,10 +31,10 @@ import bikerouterGravel from './custom/bikerouter-gravel.json';
export const maptilerKeyPlaceHolder = 'MAPTILER_KEY'; export const maptilerKeyPlaceHolder = 'MAPTILER_KEY';
export const basemaps: { [key: string]: string | StyleSpecification } = { export const basemaps: { [key: string]: string | StyleSpecification } = {
libertyTopo: 'https://styles.gpx.studio/liberty-topo.json', maptilerStreets: `https://api.maptiler.com/maps/streets-v4/style.json?key=${maptilerKeyPlaceHolder}`,
libertySatellite: 'https://styles.gpx.studio/liberty-satellite.json', maptilerTopo: `https://api.maptiler.com/maps/topo-v4/style.json?key=${maptilerKeyPlaceHolder}`,
osm: 'https://styles.gpx.studio/osm.json', maptilerOutdoors: `https://api.maptiler.com/maps/outdoor-v4/style.json?key=${maptilerKeyPlaceHolder}`,
osmTopo: 'https://styles.gpx.studio/osm-topo.json', maptilerSatellite: `https://api.maptiler.com/maps/hybrid-v4/style.json?key=${maptilerKeyPlaceHolder}`,
esriSatellite: { esriSatellite: {
version: 8, version: 8,
sources: { sources: {
@@ -799,10 +799,10 @@ export type LayerTreeType = { [key: string]: LayerTreeType | boolean };
export const basemapTree: LayerTreeType = { export const basemapTree: LayerTreeType = {
basemaps: { basemaps: {
world: { world: {
libertyTopo: true, maptilerStreets: true,
libertySatellite: true, maptilerTopo: true,
osm: true, maptilerOutdoors: true,
osmTopo: true, maptilerSatellite: true,
esriSatellite: true, esriSatellite: true,
openStreetMap: true, openStreetMap: true,
openTopoMap: true, openTopoMap: true,
@@ -936,7 +936,7 @@ export const overpassTree: LayerTreeType = {
}; };
// Default basemap used // Default basemap used
export const defaultBasemap = 'libertyTopo'; export const defaultBasemap = 'maptilerStreets';
// Default overlays used (none) // Default overlays used (none)
export const defaultOverlays: LayerTreeType = { export const defaultOverlays: LayerTreeType = {
@@ -1025,10 +1025,10 @@ export const defaultOverpassQueries: LayerTreeType = {
export const defaultBasemapTree: LayerTreeType = { export const defaultBasemapTree: LayerTreeType = {
basemaps: { basemaps: {
world: { world: {
libertyTopo: true, maptilerStreets: true,
libertySatellite: true, maptilerTopo: true,
osm: true, maptilerOutdoors: true,
osmTopo: true, maptilerSatellite: true,
esriSatellite: false, esriSatellite: false,
openStreetMap: true, openStreetMap: true,
openTopoMap: true, openTopoMap: true,
@@ -1168,7 +1168,7 @@ export type CustomLayer = {
maxZoom: number; maxZoom: number;
layerType: 'basemap' | 'overlay'; layerType: 'basemap' | 'overlay';
resourceType: 'raster' | 'vector'; resourceType: 'raster' | 'vector';
value: string | StyleSpecification; value: string | maplibregl.StyleSpecification;
}; };
type OverpassQueryData = { type OverpassQueryData = {
@@ -1449,7 +1449,7 @@ export const overpassQueryData: Record<string, OverpassQueryData> = {
color: 'DarkBlue', color: 'DarkBlue',
}, },
tags: { tags: {
railway: ['station', 'halt'], railway: 'station',
}, },
symbol: 'Ground Transportation', symbol: 'Ground Transportation',
}, },
@@ -1487,11 +1487,14 @@ export const overpassQueryData: Record<string, OverpassQueryData> = {
}; };
export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = { export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = {
'maptiler-dem': {
type: 'raster-dem',
url: `https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=${maptilerKeyPlaceHolder}`,
},
mapterhorn: { mapterhorn: {
type: 'raster-dem', type: 'raster-dem',
url: 'https://tiles.gpx.studio/mapterhorn.json', url: 'https://tiles.mapterhorn.com/tilejson.json',
encoding: 'terrarium',
}, },
}; };
export const defaultTerrainSource = 'mapterhorn'; export const defaultTerrainSource = 'maptiler-dem';
+7 -1
View File
@@ -8,7 +8,7 @@
...others ...others
}: { }: {
iconOnly?: boolean; iconOnly?: boolean;
company?: 'gpx.studio' | 'github' | 'crowdin' | 'facebook' | 'reddit'; company?: 'gpx.studio' | 'maptiler' | 'github' | 'crowdin' | 'facebook' | 'reddit';
[key: string]: any; [key: string]: any;
} = $props(); } = $props();
</script> </script>
@@ -19,6 +19,12 @@
alt="Logo of gpx.studio." alt="Logo of gpx.studio."
{...others} {...others}
/> />
{:else if company === 'maptiler'}
<img
src="{base}/maptiler-logo{mode.current === 'dark' ? '-dark' : ''}.svg"
alt="Logo of Maptiler."
{...others}
/>
{:else if company === 'github'} {:else if company === 'github'}
<svg <svg
role="img" role="img"
+1 -30
View File
@@ -43,8 +43,6 @@
BookOpenText, BookOpenText,
ChartArea, ChartArea,
Maximize, Maximize,
Maximize2,
Minimize2,
} from '@lucide/svelte'; } from '@lucide/svelte';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { editMetadata } from '$lib/components/file-list/metadata/utils.svelte'; import { editMetadata } from '$lib/components/file-list/metadata/utils.svelte';
@@ -72,7 +70,7 @@
import { copied, selection } from '$lib/logic/selection'; import { copied, selection } from '$lib/logic/selection';
import { allHidden } from '$lib/logic/hidden'; import { allHidden } from '$lib/logic/hidden';
import { boundsManager } from '$lib/logic/bounds'; import { boundsManager } from '$lib/logic/bounds';
import { tick, onMount } from 'svelte'; import { tick } from 'svelte';
import { allowedPastes } from '$lib/components/file-list/sortable-file-list'; import { allowedPastes } from '$lib/components/file-list/sortable-file-list';
const { const {
@@ -107,23 +105,6 @@
} }
let layerSettingsOpen = $state(false); let layerSettingsOpen = $state(false);
let fullscreen = $state(false);
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen?.();
} else {
document.exitFullscreen?.();
}
}
onMount(() => {
const handler = () => {
fullscreen = document.fullscreenElement !== null;
};
document.addEventListener('fullscreenchange', handler);
return () => document.removeEventListener('fullscreenchange', handler);
});
</script> </script>
<div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none"> <div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none">
@@ -396,16 +377,6 @@
{i18n._('menu.toggle_3d')} {i18n._('menu.toggle_3d')}
<Shortcut key={i18n._('menu.right_click_drag')} /> <Shortcut key={i18n._('menu.right_click_drag')} />
</Menubar.Item> </Menubar.Item>
<Menubar.Separator />
<Menubar.CheckboxItem checked={fullscreen} onCheckedChange={toggleFullscreen}>
{#if fullscreen}
<Minimize2 size="16" />
{:else}
<Maximize2 size="16" />
{/if}
{i18n._('menu.fullscreen')}
<Shortcut key="F11" />
</Menubar.CheckboxItem>
</Menubar.Content> </Menubar.Content>
</Menubar.Menu> </Menubar.Menu>
<Menubar.Menu> <Menubar.Menu>
@@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
import topoMap from '$lib/assets/img/docs/maps/topo.png?enhanced'; import maptilerTopoMap from '$lib/assets/img/home/maptiler-topo.png?enhanced';
import waymarkedMap from '$lib/assets/img/docs/maps/waymarked.png?enhanced'; import waymarkedMap from '$lib/assets/img/home/waymarked.png?enhanced';
</script> </script>
<div class="relative h-80 aspect-square rounded-2xl shadow-xl overflow-clip"> <div class="relative h-80 aspect-square rounded-2xl shadow-xl overflow-clip">
<enhanced:img src={topoMap} alt="Topo map screenshot." class="absolute" /> <enhanced:img src={maptilerTopoMap} alt="MapTiler Topo map screenshot." class="absolute" />
<enhanced:img <enhanced:img
src={waymarkedMap} src={waymarkedMap}
alt="Waymarked Trails map screenshot." alt="Waymarked Trails map screenshot."
@@ -21,7 +21,6 @@
import { selection } from '$lib/logic/selection'; import { selection } from '$lib/logic/selection';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
import { isSelected, toggle } from '$lib/components/map/layer-control/utils'; import { isSelected, toggle } from '$lib/components/map/layer-control/utils';
import { boundsManager } from '$lib/logic/bounds';
let { let {
useHash = true, useHash = true,
@@ -46,6 +45,26 @@
settings.initialize(); settings.initialize();
function applyOptions() { function applyOptions() {
let downloads: Promise<GPXFile | null>[] = getFilesFromEmbeddingOptions(options).map(
(url) => {
return fetch(url)
.then((response) => response.blob())
.then((blob) => new File([blob], url.split('/').pop() ?? url))
.then(loadFile);
}
);
Promise.all(downloads).then((answers) => {
const files = answers.filter((file) => file !== null) as GPXFile[];
let ids: string[] = [];
files.forEach((file, index) => {
let id = `gpx-${index}-embed`;
file._data.id = id;
ids.push(id);
});
fileStateCollection.setEmbeddedFiles(files);
$fileOrder = ids;
selection.selectAll();
});
if (allowedEmbeddingBasemaps.includes(options.basemap)) { if (allowedEmbeddingBasemaps.includes(options.basemap)) {
$currentBasemap = options.basemap; $currentBasemap = options.basemap;
} }
@@ -71,28 +90,6 @@
].filter((dataset) => dataset !== null) ].filter((dataset) => dataset !== null)
); );
elevationFill.set(options.elevation.fill == 'none' ? undefined : options.elevation.fill); elevationFill.set(options.elevation.fill == 'none' ? undefined : options.elevation.fill);
let downloads: Promise<GPXFile | null>[] = getFilesFromEmbeddingOptions(options).map(
(url) => {
return fetch(url)
.then((response) => response.blob())
.then((blob) => new File([blob], url.split('/').pop() ?? url))
.then(loadFile);
}
);
Promise.all(downloads).then((answers) => {
const files = answers.filter((file) => file !== null) as GPXFile[];
let ids: string[] = [];
files.forEach((file, index) => {
let id = `gpx-${index}-embed`;
file._data.id = id;
ids.push(id);
});
fileStateCollection.setEmbeddedFiles(files);
$fileOrder = ids;
selection.selectAll();
boundsManager.fitBoundsOnLoad(ids);
});
} }
$effect(() => { $effect(() => {
@@ -29,7 +29,7 @@ export const defaultEmbeddingOptions = {
key: '', key: '',
files: [], files: [],
ids: [], ids: [],
basemap: 'libertyTopo', basemap: 'maptilerStreets',
elevation: { elevation: {
show: true, show: true,
height: 170, height: 170,
@@ -126,7 +126,7 @@ export function convertOldEmbeddingOptions(options: URLSearchParams): any {
if (options.has('source')) { if (options.has('source')) {
let basemap = options.get('source')!; let basemap = options.get('source')!;
if (basemap === 'satellite') { if (basemap === 'satellite') {
newOptions.basemap = 'libertySatellite'; newOptions.basemap = 'maptilerSatellite';
} else if (basemap === 'otm') { } else if (basemap === 'otm') {
newOptions.basemap = 'openTopoMap'; newOptions.basemap = 'openTopoMap';
} else if (basemap === 'ohm') { } else if (basemap === 'ohm') {
@@ -2,7 +2,6 @@
import CustomControl from './custom-control'; import CustomControl from './custom-control';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { onMount, type Snippet } from 'svelte'; import { onMount, type Snippet } from 'svelte';
import type { Map } from 'maplibre-gl';
let { let {
position = 'top-right', position = 'top-right',
@@ -18,7 +17,7 @@
let control: CustomControl | null = null; let control: CustomControl | null = null;
onMount(() => { onMount(() => {
map.onLoad((map: Map) => { map.onLoad((map: maplibregl.Map) => {
if (position.includes('right')) container.classList.add('float-right'); if (position.includes('right')) container.classList.add('float-right');
else container.classList.add('float-left'); else container.classList.add('float-left');
container.classList.remove('hidden'); container.classList.remove('hidden');
@@ -74,7 +74,7 @@ export class DistanceMarkers {
layout: { layout: {
'text-field': ['get', 'distance'], 'text-field': ['get', 'distance'],
'text-size': 14, 'text-size': 14,
'text-font': ['Noto Sans Bold'], 'text-font': ['Open Sans Bold'],
}, },
paint: { paint: {
'text-color': 'black', 'text-color': 'black',
@@ -1,10 +1,9 @@
import { MapPopup } from '$lib/components/map/map-popup'; import { MapPopup } from '$lib/components/map/map-popup';
import type { Map } from 'maplibre-gl';
export let waypointPopup: MapPopup | null = null; export let waypointPopup: MapPopup | null = null;
export let trackpointPopup: MapPopup | null = null; export let trackpointPopup: MapPopup | null = null;
export function createPopups(map: Map) { export function createPopups(map: maplibregl.Map) {
removePopups(); removePopups();
waypointPopup = new MapPopup(map, { waypointPopup = new MapPopup(map, {
closeButton: false, closeButton: false,
@@ -1,10 +1,9 @@
import { get, type Readable } from 'svelte/store'; import { get, type Readable } from 'svelte/store';
import { import maplibregl, {
type GeoJSONSource, type GeoJSONSource,
type FilterSpecification, type FilterSpecification,
type MapLayerMouseEvent, type MapLayerMouseEvent,
type MapLayerTouchEvent, type MapLayerTouchEvent,
Point,
} from 'maplibre-gl'; } from 'maplibre-gl';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { waypointPopup, trackpointPopup } from './gpx-layer-popup'; import { waypointPopup, trackpointPopup } from './gpx-layer-popup';
@@ -121,7 +120,7 @@ export class GPXLayer {
selected: boolean = false; selected: boolean = false;
currentWaypointData: GeoJSON.FeatureCollection | null = null; currentWaypointData: GeoJSON.FeatureCollection | null = null;
draggedWaypointIndex: number | null = null; draggedWaypointIndex: number | null = null;
draggingStartingPosition: Point = new Point(0, 0); draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
unsubscribe: Function[] = []; unsubscribe: Function[] = [];
updateBinded: () => void = this.update.bind(this); updateBinded: () => void = this.update.bind(this);
@@ -252,11 +251,11 @@ export class GPXLayer {
source: this.fileId, source: this.fileId,
layout: { layout: {
'text-field': '»', 'text-field': '»',
'text-offset': [0, -0.1], 'text-offset': [0, -0.06],
'text-keep-upright': false, 'text-keep-upright': false,
'text-max-angle': 361, 'text-max-angle': 361,
'text-allow-overlap': true, 'text-allow-overlap': true,
'text-font': ['Noto Sans Bold'], 'text-font': ['Open Sans Bold'],
'symbol-placement': 'line', 'symbol-placement': 'line',
'symbol-spacing': 20, 'symbol-spacing': 20,
}, },
@@ -7,7 +7,6 @@
import { Layers } from '@lucide/svelte'; import { Layers } from '@lucide/svelte';
import { settings } from '$lib/logic/settings'; import { settings } from '$lib/logic/settings';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import type { Map } from 'maplibre-gl';
let container: HTMLDivElement; let container: HTMLDivElement;
let overpassLayer: OverpassLayer; let overpassLayer: OverpassLayer;
@@ -22,7 +21,7 @@
selectedOverpassTree, selectedOverpassTree,
} = settings; } = settings;
map.onLoad((_map: Map) => { map.onLoad((_map: maplibregl.Map) => {
if (overpassLayer) { if (overpassLayer) {
overpassLayer.remove(); overpassLayer.remove();
} }
@@ -15,9 +15,7 @@
poi: PopupItem<any>; poi: PopupItem<any>;
} = $props(); } = $props();
let tags: Record<string, string> = $derived( let tags: Record<string, string> = $derived(poi ? JSON.parse(poi.item.tags) : {});
poi ? (typeof poi.item.tags == 'object' ? poi.item.tags : JSON.parse(poi.item.tags)) : {}
);
let name = $derived.by(() => { let name = $derived.by(() => {
if (poi) { if (poi) {
if (tags.name !== undefined && tags.name !== '') { if (tags.name !== undefined && tags.name !== '') {
@@ -90,14 +88,6 @@
<span class="font-mono">{key}</span> <span class="font-mono">{key}</span>
{#if key === 'website' || key.startsWith('website:') || key.endsWith(':website') || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'} {#if key === 'website' || key.startsWith('website:') || key.endsWith(':website') || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'}
<a href={value} target="_blank" class="text-link underline">{value}</a> <a href={value} target="_blank" class="text-link underline">{value}</a>
{:else if key === 'wikipedia' || key.startsWith('wikipedia:') || key.endsWith(':wikipedia')}
<a
href="https://wikipedia.org/wiki/{value}"
target="_blank"
class="text-link underline"
>
{value}
</a>
{:else if key === 'phone' || key === 'contact:phone'} {:else if key === 'phone' || key === 'contact:phone'}
<a href={'tel:' + value} class="text-link underline">{value}</a> <a href={'tel:' + value} class="text-link underline">{value}</a>
{:else if key === 'email' || key === 'contact:email'} {:else if key === 'email' || key === 'contact:email'}
@@ -6,7 +6,7 @@ import { overpassQueryData } from '$lib/assets/layers';
import { MapPopup } from '$lib/components/map/map-popup'; import { MapPopup } from '$lib/components/map/map-popup';
import { settings } from '$lib/logic/settings'; import { settings } from '$lib/logic/settings';
import { db } from '$lib/db'; import { db } from '$lib/db';
import type { Map as MapLibreMap, GeoJSONSource } from 'maplibre-gl'; import type { GeoJSONSource } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style'; import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager'; import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
import { loadSVGIcon } from '$lib/utils'; import { loadSVGIcon } from '$lib/utils';
@@ -24,11 +24,11 @@ liveQuery(() => db.overpassdata.toArray()).subscribe((pois) => {
}); });
export class OverpassLayer { export class OverpassLayer {
overpassUrl = 'https://overpass.gpx.studio/api/interpreter'; overpassUrl = 'https://overpass.private.coffee/api/interpreter';
minZoom = 12; minZoom = 12;
queryZoom = 12; queryZoom = 12;
expirationTime = 7 * 24 * 3600 * 1000; expirationTime = 7 * 24 * 3600 * 1000;
map: MapLibreMap; map: maplibregl.Map;
layerEventManager: MapLayerEventManager; layerEventManager: MapLayerEventManager;
popup: MapPopup; popup: MapPopup;
@@ -40,7 +40,7 @@ export class OverpassLayer {
updateBinded = this.update.bind(this); updateBinded = this.update.bind(this);
onHoverBinded = this.onHover.bind(this); onHoverBinded = this.onHover.bind(this);
constructor(map: MapLibreMap, layerEventManager: MapLayerEventManager) { constructor(map: maplibregl.Map, layerEventManager: MapLayerEventManager) {
this.map = map; this.map = map;
this.layerEventManager = layerEventManager; this.layerEventManager = layerEventManager;
this.popup = new MapPopup(map, { this.popup = new MapPopup(map, {
@@ -1,19 +1,10 @@
import { fileStateCollection } from '$lib/logic/file-state'; import { fileStateCollection } from '$lib/logic/file-state';
import { import maplibregl from 'maplibre-gl';
LngLatBounds,
MapMouseEvent,
MapTouchEvent,
Point,
type Map,
type MapGeoJSONFeature,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
} from 'maplibre-gl';
type MapLayerMouseEventListener = (e: MapLayerMouseEvent) => void; type MapLayerMouseEventListener = (e: maplibregl.MapLayerMouseEvent) => void;
type MapLayerTouchEventListener = (e: MapLayerTouchEvent) => void; type MapLayerTouchEventListener = (e: maplibregl.MapLayerTouchEvent) => void;
type MapLayerListener = { type MapLayerListener = {
features: MapGeoJSONFeature[]; features: maplibregl.MapGeoJSONFeature[];
mousemoves: MapLayerMouseEventListener[]; mousemoves: MapLayerMouseEventListener[];
mouseenters: MapLayerMouseEventListener[]; mouseenters: MapLayerMouseEventListener[];
mouseleaves: MapLayerMouseEventListener[]; mouseleaves: MapLayerMouseEventListener[];
@@ -24,10 +15,10 @@ type MapLayerListener = {
}; };
export class MapLayerEventManager { export class MapLayerEventManager {
private _map: Map; private _map: maplibregl.Map;
private _listeners: Record<string, MapLayerListener> = {}; private _listeners: Record<string, MapLayerListener> = {};
constructor(map: Map) { constructor(map: maplibregl.Map) {
this._map = map; this._map = map;
this._map.on('mousemove', this._handleMouseMove.bind(this)); this._map.on('mousemove', this._handleMouseMove.bind(this));
this._map.on('click', this._handleMouseClick.bind(this, 'click')); this._map.on('click', this._handleMouseClick.bind(this, 'click'));
@@ -150,8 +141,7 @@ export class MapLayerEventManager {
} }
} }
private _handleMouseMove(e: MapMouseEvent) { private _handleMouseMove(e: maplibregl.MapMouseEvent) {
if (e.originalEvent.buttons > 0) return;
const featuresByLayer = this._getRenderedFeaturesByLayer(e); const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => { Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || []; const features = featuresByLayer[layerId] || [];
@@ -159,20 +149,29 @@ export class MapLayerEventManager {
if ((features.length == 0) != (listener.features.length == 0)) { if ((features.length == 0) != (listener.features.length == 0)) {
if (features.length > 0) { if (features.length > 0) {
if (listener.mouseenters.length > 0) { if (listener.mouseenters.length > 0) {
const event = new MapMouseEvent('mouseenter', e.target, e.originalEvent, { const event = new maplibregl.MapMouseEvent(
features: featuresByLayer[layerId]!, 'mouseenter',
}); e.target,
e.originalEvent,
{
features: featuresByLayer[layerId]!,
}
);
listener.mouseenters.forEach((l) => l(event)); listener.mouseenters.forEach((l) => l(event));
} }
} else { } else {
if (listener.mouseleaves.length > 0) { if (listener.mouseleaves.length > 0) {
const event = new MapMouseEvent('mouseleave', e.target, e.originalEvent); const event = new maplibregl.MapMouseEvent(
'mouseleave',
e.target,
e.originalEvent
);
listener.mouseleaves.forEach((l) => l(event)); listener.mouseleaves.forEach((l) => l(event));
} }
} }
} }
if (features.length > 0 && listener.mousemoves.length > 0) { if (features.length > 0 && listener.mousemoves.length > 0) {
const event = new MapMouseEvent('mousemove', e.target, e.originalEvent, { const event = new maplibregl.MapMouseEvent('mousemove', e.target, e.originalEvent, {
features: featuresByLayer[layerId]!, features: featuresByLayer[layerId]!,
}); });
listener.mousemoves.forEach((l) => l(event)); listener.mousemoves.forEach((l) => l(event));
@@ -181,39 +180,49 @@ export class MapLayerEventManager {
}); });
} }
private _handleMouseClick(type: string, e: MapMouseEvent) { private _handleMouseClick(type: string, e: maplibregl.MapMouseEvent) {
const featuresByLayer = this._getRenderedFeaturesByLayer(e); const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => { Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || []; const features = featuresByLayer[layerId] || [];
const listener = this._listeners[layerId]; const listener = this._listeners[layerId];
if (features.length > 0) { if (features.length > 0) {
if (type === 'click' && listener.clicks.length > 0) { if (type === 'click' && listener.clicks.length > 0) {
const event = new MapMouseEvent('click', e.target, e.originalEvent, { const event = new maplibregl.MapMouseEvent('click', e.target, e.originalEvent, {
features: features, features: features,
}); });
listener.clicks.forEach((l) => l(event)); listener.clicks.forEach((l) => l(event));
} else if (type === 'contextmenu' && listener.contextmenus.length > 0) { } else if (type === 'contextmenu' && listener.contextmenus.length > 0) {
const event = new MapMouseEvent('contextmenu', e.target, e.originalEvent, { const event = new maplibregl.MapMouseEvent(
features: features, 'contextmenu',
}); e.target,
e.originalEvent,
{
features: features,
}
);
listener.contextmenus.forEach((l) => l(event)); listener.contextmenus.forEach((l) => l(event));
} else if (type === 'mousedown' && listener.mousedowns.length > 0) { } else if (type === 'mousedown' && listener.mousedowns.length > 0) {
const event = new MapMouseEvent('mousedown', e.target, e.originalEvent, { const event = new maplibregl.MapMouseEvent(
features: features, 'mousedown',
}); e.target,
e.originalEvent,
{
features: features,
}
);
listener.mousedowns.forEach((l) => l(event)); listener.mousedowns.forEach((l) => l(event));
} }
} }
}); });
} }
private _handleTouchStart(e: MapTouchEvent) { private _handleTouchStart(e: maplibregl.MapTouchEvent) {
const featuresByLayer = this._getRenderedFeaturesByLayer(e); const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => { Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || []; const features = featuresByLayer[layerId] || [];
const listener = this._listeners[layerId]; const listener = this._listeners[layerId];
if (features.length > 0) { if (features.length > 0) {
const event: MapLayerTouchEvent = new MapTouchEvent( const event: maplibregl.MapLayerTouchEvent = new maplibregl.MapTouchEvent(
'touchstart', 'touchstart',
e.target, e.target,
e.originalEvent e.originalEvent
@@ -224,15 +233,18 @@ export class MapLayerEventManager {
}); });
} }
private _getBounds(point: Point) { private _getBounds(point: maplibregl.Point) {
const delta = 30; const delta = 30;
return new LngLatBounds( return new maplibregl.LngLatBounds(
this._map.unproject([point.x - delta, point.y + delta]), this._map.unproject([point.x - delta, point.y + delta]),
this._map.unproject([point.x + delta, point.y - delta]) this._map.unproject([point.x + delta, point.y - delta])
); );
} }
private _filterLayersIntersectingBounds(layerIds: string[], bounds: LngLatBounds): string[] { private _filterLayersIntersectingBounds(
layerIds: string[],
bounds: maplibregl.LngLatBounds
): string[] {
let result = layerIds.filter((layerId) => { let result = layerIds.filter((layerId) => {
if (!this._map.getLayer(layerId)) return false; if (!this._map.getLayer(layerId)) return false;
const fileId = layerId.replace('-waypoints', ''); const fileId = layerId.replace('-waypoints', '');
@@ -248,7 +260,7 @@ export class MapLayerEventManager {
return result; return result;
} }
private _getRenderedFeaturesByLayer(e: MapMouseEvent | MapTouchEvent) { private _getRenderedFeaturesByLayer(e: maplibregl.MapMouseEvent | maplibregl.MapTouchEvent) {
const layerIds = this._filterLayersIntersectingBounds( const layerIds = this._filterLayersIntersectingBounds(
Object.keys(this._listeners), Object.keys(this._listeners),
this._getBounds(e.point) this._getBounds(e.point)
@@ -257,7 +269,7 @@ export class MapLayerEventManager {
layerIds.length > 0 layerIds.length > 0
? this._map.queryRenderedFeatures(e.point, { layers: layerIds }) ? this._map.queryRenderedFeatures(e.point, { layers: layerIds })
: []; : [];
const featuresByLayer: Record<string, MapGeoJSONFeature[]> = {}; const featuresByLayer: Record<string, maplibregl.MapGeoJSONFeature[]> = {};
features.forEach((f) => { features.forEach((f) => {
if (!featuresByLayer[f.layer.id]) { if (!featuresByLayer[f.layer.id]) {
featuresByLayer[f.layer.id] = []; featuresByLayer[f.layer.id] = [];
+8 -8
View File
@@ -1,5 +1,5 @@
import { TrackPoint, Waypoint } from 'gpx'; import { TrackPoint, Waypoint } from 'gpx';
import { LngLat, Map, MapMouseEvent, Popup, type PopupOptions } from 'maplibre-gl'; import maplibregl from 'maplibre-gl';
import { mount, tick, unmount } from 'svelte'; import { mount, tick, unmount } from 'svelte';
import { get, writable, type Writable } from 'svelte/store'; import { get, writable, type Writable } from 'svelte/store';
import MapPopupComponent from '$lib/components/map/MapPopup.svelte'; import MapPopupComponent from '$lib/components/map/MapPopup.svelte';
@@ -11,15 +11,15 @@ export type PopupItem<T = Waypoint | TrackPoint | any> = {
}; };
export class MapPopup { export class MapPopup {
map: Map; map: maplibregl.Map;
popup: Popup; popup: maplibregl.Popup;
item: Writable<PopupItem | null> = writable(null); item: Writable<PopupItem | null> = writable(null);
component: ReturnType<typeof mount>; component: ReturnType<typeof mount>;
maybeHideBinded = this.maybeHide.bind(this); maybeHideBinded = this.maybeHide.bind(this);
constructor(map: Map, options?: PopupOptions) { constructor(map: maplibregl.Map, options?: maplibregl.PopupOptions) {
this.map = map; this.map = map;
this.popup = new Popup(options); this.popup = new maplibregl.Popup(options);
this.component = mount(MapPopupComponent, { this.component = mount(MapPopupComponent, {
target: document.body, target: document.body,
props: { props: {
@@ -51,7 +51,7 @@ export class MapPopup {
this.map.on('mousemove', this.maybeHideBinded); this.map.on('mousemove', this.maybeHideBinded);
} }
maybeHide(e: MapMouseEvent) { maybeHide(e: maplibregl.MapMouseEvent) {
const item = get(this.item); const item = get(this.item);
if (item === null) { if (item === null) {
this.hide(); this.hide();
@@ -75,10 +75,10 @@ export class MapPopup {
getCoordinates() { getCoordinates() {
const item = get(this.item); const item = get(this.item);
if (item === null) { if (item === null) {
return new LngLat(0, 0); return new maplibregl.LngLat(0, 0);
} }
return item.item instanceof Waypoint || item.item instanceof TrackPoint return item.item instanceof Waypoint || item.item instanceof TrackPoint
? item.item.getCoordinates() ? item.item.getCoordinates()
: new LngLat(item.item.lon, item.item.lat); : new maplibregl.LngLat(item.item.lon, item.item.lat);
} }
} }
+1 -3
View File
@@ -1,6 +1,5 @@
import * as maplibregl from 'maplibre-gl'; import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css'; import 'maplibre-gl/dist/maplibre-gl.css';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
import MaplibreGeocoder, { import MaplibreGeocoder, {
type MaplibreGeocoderFeatureResults, type MaplibreGeocoderFeatureResults,
} from '@maplibre/maplibre-gl-geocoder'; } from '@maplibre/maplibre-gl-geocoder';
@@ -40,7 +39,6 @@ export class MapLibreGLMap {
geocoder: boolean, geocoder: boolean,
geolocate: boolean geolocate: boolean
) { ) {
maplibregl.setWorkerUrl(workerUrl);
this._maptilerKey = maptilerKey; this._maptilerKey = maptilerKey;
this._styleManager = new StyleManager(this._mapStore, this._maptilerKey); this._styleManager = new StyleManager(this._mapStore, this._maptilerKey);
const map = new maplibregl.Map({ const map = new maplibregl.Map({
@@ -9,7 +9,6 @@
import { i18n } from '$lib/i18n.svelte'; import { i18n } from '$lib/i18n.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte'; import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
import type { Map } from 'maplibre-gl';
const { streetViewSource } = settings; const { streetViewSource } = settings;
@@ -21,7 +20,7 @@
let container: HTMLElement; let container: HTMLElement;
onMount(() => { onMount(() => {
map.onLoad((map_: Map) => { map.onLoad((map_: maplibregl.Map) => {
googleRedirect = new GoogleRedirect(map_); googleRedirect = new GoogleRedirect(map_);
mapillaryLayer = new MapillaryLayer( mapillaryLayer = new MapillaryLayer(
map_, map_,
@@ -1,11 +1,10 @@
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import type { Map, MapMouseEvent } from 'maplibre-gl';
export class GoogleRedirect { export class GoogleRedirect {
map: Map; map: maplibregl.Map;
enabled = false; enabled = false;
constructor(map: Map) { constructor(map: maplibregl.Map) {
this.map = map; this.map = map;
} }
@@ -25,7 +24,7 @@ export class GoogleRedirect {
this.map.off('click', this.openStreetView); this.map.off('click', this.openStreetView);
} }
openStreetView(e: MapMouseEvent) { openStreetView(e: maplibregl.MapMouseEvent) {
window.open( window.open(
`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${e.lngLat.lat},${e.lngLat.lng}` `https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${e.lngLat.lat},${e.lngLat.lng}`
); );
@@ -1,10 +1,4 @@
import { import maplibregl, { type LayerSpecification, type VectorSourceSpecification } from 'maplibre-gl';
Map,
Marker,
type LayerSpecification,
type MapLayerMouseEvent,
type VectorSourceSpecification,
} from 'maplibre-gl';
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module'; import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
import 'mapillary-js/dist/mapillary.css'; import 'mapillary-js/dist/mapillary.css';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
@@ -49,9 +43,9 @@ const mapillaryImageLayer: LayerSpecification = {
}; };
export class MapillaryLayer { export class MapillaryLayer {
map: Map; map: maplibregl.Map;
layerEventManager: MapLayerEventManager; layerEventManager: MapLayerEventManager;
marker: Marker; marker: maplibregl.Marker;
viewer: Viewer; viewer: Viewer;
active = false; active = false;
@@ -62,7 +56,7 @@ export class MapillaryLayer {
onMouseLeaveBinded = this.onMouseLeave.bind(this); onMouseLeaveBinded = this.onMouseLeave.bind(this);
constructor( constructor(
map: Map, map: maplibregl.Map,
layerEventManager: MapLayerEventManager, layerEventManager: MapLayerEventManager,
container: HTMLElement, container: HTMLElement,
popupOpen: { value: boolean } popupOpen: { value: boolean }
@@ -81,7 +75,7 @@ export class MapillaryLayer {
dot.className = 'maplibregl-user-location-dot'; dot.className = 'maplibregl-user-location-dot';
element.appendChild(dot); element.appendChild(dot);
this.marker = new Marker({ this.marker = new maplibregl.Marker({
rotationAlignment: 'map', rotationAlignment: 'map',
element, element,
}); });
@@ -146,7 +140,7 @@ export class MapillaryLayer {
this.popupOpen.value = false; this.popupOpen.value = false;
} }
onMouseEnter(e: MapLayerMouseEvent) { onMouseEnter(e: maplibregl.MapLayerMouseEvent) {
if ( if (
e.features && e.features &&
e.features.length > 0 && e.features.length > 0 &&
+71 -125
View File
@@ -9,17 +9,10 @@ import {
} from '$lib/assets/layers'; } from '$lib/assets/layers';
import { getLayers } from '$lib/components/map/layer-control/utils'; import { getLayers } from '$lib/components/map/layer-control/utils';
import { i18n } from '$lib/i18n.svelte'; import { i18n } from '$lib/i18n.svelte';
import type {
Map,
GeoJSONSourceSpecification,
LayerSpecification,
StyleSpecification,
} from 'maplibre-gl';
const { currentBasemap, currentOverlays, customLayers, opacities, terrainSource, distanceUnits } = const { currentBasemap, currentOverlays, customLayers, opacities, terrainSource } = settings;
settings;
const emptySource: GeoJSONSourceSpecification = { const emptySource: maplibregl.GeoJSONSourceSpecification = {
type: 'geojson', type: 'geojson',
data: { data: {
type: 'FeatureCollection', type: 'FeatureCollection',
@@ -38,18 +31,18 @@ export const ANCHOR_LAYER_KEY = {
waypoints: 'waypoints-end', waypoints: 'waypoints-end',
routingControls: 'routing-controls-end', routingControls: 'routing-controls-end',
}; };
const anchorLayers: LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({ const anchorLayers: maplibregl.LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
id: id, id: id,
type: 'symbol', type: 'symbol',
source: 'empty-source', source: 'empty-source',
})); }));
export class StyleManager { export class StyleManager {
private _map: Writable<Map | null>; private _map: Writable<maplibregl.Map | null>;
private _maptilerKey: string; private _maptilerKey: string;
private _pastOverlays: Set<string> = new Set(); private _pastOverlays: Set<string> = new Set();
constructor(map: Writable<Map | null>, maptilerKey: string) { constructor(map: Writable<maplibregl.Map | null>, maptilerKey: string) {
this._map = map; this._map = map;
this._maptilerKey = maptilerKey; this._maptilerKey = maptilerKey;
this._map.subscribe((map_) => { this._map.subscribe((map_) => {
@@ -64,28 +57,18 @@ export class StyleManager {
opacities.subscribe(() => this.updateOverlays()); opacities.subscribe(() => this.updateOverlays());
terrainSource.subscribe(() => this.updateTerrain()); terrainSource.subscribe(() => this.updateTerrain());
customLayers.subscribe(() => this.updateBasemap()); customLayers.subscribe(() => this.updateBasemap());
i18n.subscribe(() => this.updateBasemap());
distanceUnits.subscribe(() => {
const map = get(this._map);
if (map && (map.getLayer('contours_m') || map.getLayer('contours_ft'))) {
this.updateBasemap();
}
});
} }
updateBasemap() { updateBasemap() {
const map_ = get(this._map); const map_ = get(this._map);
if (!map_) return; if (!map_) return;
let basemap = get(currentBasemap); this.buildStyle().then((style) => map_.setStyle(style));
this.buildStyle(basemap).then((style) => {
if (get(currentBasemap) === basemap) map_.setStyle(style);
});
} }
async buildStyle(basemap: string): Promise<StyleSpecification> { async buildStyle(): Promise<maplibregl.StyleSpecification> {
const custom = get(customLayers); const custom = get(customLayers);
const style: StyleSpecification = { const style: maplibregl.StyleSpecification = {
version: 8, version: 8,
projection: { projection: {
type: 'globe', type: 'globe',
@@ -96,31 +79,17 @@ export class StyleManager {
layers: [], layers: [],
}; };
let basemap = get(currentBasemap);
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap]; const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
const basemapStyle = await this.get(basemapInfo);
let basemapStyle = basemaps.openStreetMap as StyleSpecification;
try {
basemapStyle = await this.get(basemapInfo);
for (const source in basemapStyle.sources) {
const src = basemapStyle.sources[source];
if (
src &&
typeof src === 'object' &&
'url' in src &&
typeof src.url === 'string' &&
src.url.includes(maptilerKeyPlaceHolder)
) {
src.url = src.url.replace(maptilerKeyPlaceHolder, this._maptilerKey);
}
}
} catch (e) {
console.error(e.message);
}
this.merge(style, basemapStyle); this.merge(style, basemapStyle);
const terrain = this.getCurrentTerrain(); if (this._maptilerKey !== '') {
style.sources[terrain.source] = terrainSources[terrain.source]; const terrain = this.getCurrentTerrain();
style.terrain = terrain.exaggeration > 0 ? terrain : undefined; style.sources[terrain.source] = terrainSources[terrain.source];
style.terrain = terrain.exaggeration > 0 ? terrain : undefined;
}
style.layers.push(...anchorLayers); style.layers.push(...anchorLayers);
@@ -140,58 +109,52 @@ export class StyleManager {
if (!layers[overlay]) { if (!layers[overlay]) {
if (this._pastOverlays.has(overlay)) { if (this._pastOverlays.has(overlay)) {
const overlayInfo = custom[overlay]?.value ?? overlays[overlay]; const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
try { const overlayStyle = await this.get(overlayInfo);
const overlayStyle = await this.get(overlayInfo); for (let layer of overlayStyle.layers ?? []) {
for (let layer of overlayStyle.layers ?? []) { if (map_.getLayer(layer.id)) {
if (map_.getLayer(layer.id)) { map_.removeLayer(layer.id);
map_.removeLayer(layer.id);
}
} }
} catch (e) {
// Should not happen
} }
this._pastOverlays.delete(overlay); this._pastOverlays.delete(overlay);
} }
} else { } else {
const overlayInfo = custom[overlay]?.value ?? overlays[overlay]; const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
try { const overlayStyle = await this.get(overlayInfo);
const overlayStyle = await this.get(overlayInfo); const opacity = overlayOpacities[overlay];
const opacity = overlayOpacities[overlay];
for (let sourceId in overlayStyle.sources) { for (let sourceId in overlayStyle.sources) {
if (!map_.getSource(sourceId)) { if (!map_.getSource(sourceId)) {
map_.addSource(sourceId, overlayStyle.sources[sourceId]); map_.addSource(sourceId, overlayStyle.sources[sourceId]);
}
} }
for (let layer of overlayStyle.layers ?? []) {
if (!map_.getLayer(layer.id)) {
if (opacity !== undefined) {
if (layer.type === 'raster') {
if (!layer.paint) {
layer.paint = {};
}
layer.paint['raster-opacity'] = opacity;
} else if (layer.type === 'hillshade') {
if (!layer.paint) {
layer.paint = {};
}
layer.paint['hillshade-exaggeration'] = opacity / 2;
}
}
map_.addLayer(layer, ANCHOR_LAYER_KEY.overlays);
}
}
this._pastOverlays.add(overlay);
} catch (e) {
console.error(e.message);
} }
for (let layer of overlayStyle.layers ?? []) {
if (!map_.getLayer(layer.id)) {
if (opacity !== undefined) {
if (layer.type === 'raster') {
if (!layer.paint) {
layer.paint = {};
}
layer.paint['raster-opacity'] = opacity;
} else if (layer.type === 'hillshade') {
if (!layer.paint) {
layer.paint = {};
}
layer.paint['hillshade-exaggeration'] = opacity / 2;
}
}
map_.addLayer(layer, ANCHOR_LAYER_KEY.overlays);
}
}
this._pastOverlays.add(overlay);
} }
} }
} catch (e) {} } catch (e) {}
} }
updateTerrain() { updateTerrain() {
if (this._maptilerKey === '') return;
const map_ = get(this._map); const map_ = get(this._map);
if (!map_) return; if (!map_) return;
@@ -209,13 +172,15 @@ export class StyleManager {
} }
} }
async get(styleInfo: StyleSpecification | string): Promise<StyleSpecification> { async get(
styleInfo: maplibregl.StyleSpecification | string
): Promise<maplibregl.StyleSpecification> {
if (typeof styleInfo === 'string') { if (typeof styleInfo === 'string') {
let styleUrl = styleInfo as string; let styleUrl = styleInfo as string;
const response = await fetch(styleUrl, { cache: 'force-cache' }); if (styleUrl.includes(maptilerKeyPlaceHolder)) {
if (!response.ok) { styleUrl = styleUrl.replace(maptilerKeyPlaceHolder, this._maptilerKey);
throw new Error(`HTTP error fetching style "${styleInfo}": ${response.status}`);
} }
const response = await fetch(styleUrl, { cache: 'force-cache' });
const style = await response.json(); const style = await response.json();
return style; return style;
} else { } else {
@@ -223,48 +188,25 @@ export class StyleManager {
} }
} }
merge(style: StyleSpecification, other: StyleSpecification) { merge(style: maplibregl.StyleSpecification, other: maplibregl.StyleSpecification) {
style.sources = { ...style.sources, ...other.sources }; style.sources = { ...style.sources, ...other.sources };
const units = get(distanceUnits);
for (let layer of other.layers ?? []) { for (let layer of other.layers ?? []) {
if ('source' in layer) {
if (layer.source == 'contours_m' && units === 'imperial') continue;
if (layer.source == 'contours_ft' && units !== 'imperial') continue;
}
if (layer.type === 'symbol' && layer.layout && layer.layout['text-field']) { if (layer.type === 'symbol' && layer.layout && layer.layout['text-field']) {
const textField = layer.layout['text-field']; const textField = layer.layout['text-field'];
if (Array.isArray(textField)) { if (
if ( Array.isArray(textField) &&
textField.length == 4 && textField.length >= 2 &&
Array.isArray(textField[3]) && textField[0] === 'coalesce' &&
textField[3][0] === 'coalesce' && Array.isArray(textField[1]) &&
Array.isArray(textField[3][1]) && textField[1][0] === 'get' &&
textField[3][1][0] === 'get' && typeof textField[1][1] === 'string' &&
typeof textField[3][1][1] === 'string' && textField[1][1].startsWith('name')
textField[3][1][1].startsWith('name') ) {
) { layer.layout['text-field'] = [
// OpenFreeMap styles 'coalesce',
layer.layout['text-field'] = [ ['get', `name:${i18n.lang}`],
'coalesce', ['get', 'name'],
['get', `name:${i18n.lang}`], ];
['get', 'name'],
];
}
if (
textField.length == 3 &&
textField[0] === 'coalesce' &&
Array.isArray(textField[1]) &&
textField[1][0] === 'get' &&
typeof textField[1][1] === 'string' &&
textField[1][1].startsWith('name')
) {
// OpenMapTiles styles
layer.layout['text-field'] = [
'coalesce',
['get', `name:${i18n.lang}`],
['get', 'name'],
];
}
} }
} }
style.layers.push(layer); style.layers.push(layer);
@@ -279,6 +221,10 @@ export class StyleManager {
getCurrentTerrain() { getCurrentTerrain() {
const terrain = get(terrainSource); const terrain = get(terrainSource);
const source = terrainSources[terrain];
if (source.url && source.url.includes(maptilerKeyPlaceHolder)) {
source.url = source.url.replace(maptilerKeyPlaceHolder, this._maptilerKey);
}
const map_ = get(this._map); const map_ = get(this._map);
return { return {
source: terrain, source: terrain,
@@ -11,7 +11,7 @@
import Clean from '$lib/components/toolbar/tools/Clean.svelte'; import Clean from '$lib/components/toolbar/tools/Clean.svelte';
import Reduce from '$lib/components/toolbar/tools/reduce/Reduce.svelte'; import Reduce from '$lib/components/toolbar/tools/reduce/Reduce.svelte';
import RoutingControlPopup from '$lib/components/toolbar/tools/routing/RoutingControlPopup.svelte'; import RoutingControlPopup from '$lib/components/toolbar/tools/routing/RoutingControlPopup.svelte';
import { Popup } from 'maplibre-gl'; import maplibregl from 'maplibre-gl';
import { settings } from '$lib/logic/settings'; import { settings } from '$lib/logic/settings';
let { let {
@@ -23,11 +23,11 @@
const { minimizeRoutingMenu } = settings; const { minimizeRoutingMenu } = settings;
let popupElement: HTMLDivElement | undefined = $state(undefined); let popupElement: HTMLDivElement | undefined = $state(undefined);
let popup: Popup | undefined = $derived.by(() => { let popup: maplibregl.Popup | undefined = $derived.by(() => {
if (!popupElement) { if (!popupElement) {
return undefined; return undefined;
} }
let popup = new Popup({ let popup = new maplibregl.Popup({
closeButton: false, closeButton: false,
maxWidth: undefined, maxWidth: undefined,
}); });
@@ -16,7 +16,7 @@
import { getURLForLanguage } from '$lib/utils'; import { getURLForLanguage } from '$lib/utils';
import { Trash2 } from '@lucide/svelte'; import { Trash2 } from '@lucide/svelte';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import type { GeoJSONSource, LngLat } from 'maplibre-gl'; import type { GeoJSONSource } from 'maplibre-gl';
import { selection } from '$lib/logic/selection'; import { selection } from '$lib/logic/selection';
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
@@ -29,7 +29,7 @@
let cleanType = $state(CleanType.INSIDE); let cleanType = $state(CleanType.INSIDE);
let deleteTrackpoints = $state(true); let deleteTrackpoints = $state(true);
let deleteWaypoints = $state(true); let deleteWaypoints = $state(true);
let rectangleCoordinates: LngLat[] = $state([]); let rectangleCoordinates: maplibregl.LngLat[] = $state([]);
$effect(() => { $effect(() => {
if ($map) { if ($map) {
@@ -163,9 +163,6 @@ export class ReducedGPXLayerCollection {
reduce() { reduce() {
let itemsAndPoints = new Map<ListItem, TrackPoint[]>(); let itemsAndPoints = new Map<ListItem, TrackPoint[]>();
this._simplified.forEach(([item, maxPts, points], itemFullId) => { this._simplified.forEach(([item, maxPts, points], itemFullId) => {
if (!get(selection).hasAnyParent(item)) {
return;
}
itemsAndPoints.set( itemsAndPoints.set(
item, item,
points points
@@ -41,7 +41,6 @@
import { fileActions, getFileIds, newGPXFile } from '$lib/logic/file-actions'; import { fileActions, getFileIds, newGPXFile } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { RoutingControls, routingControls } from './routing-controls'; import { RoutingControls, routingControls } from './routing-controls';
import type { Popup } from 'maplibre-gl';
let { let {
minimized = $bindable(false), minimized = $bindable(false),
@@ -52,7 +51,7 @@
}: { }: {
minimized?: boolean; minimized?: boolean;
minimizable?: boolean; minimizable?: boolean;
popup?: Popup; popup?: maplibregl.Popup;
popupElement?: HTMLDivElement; popupElement?: HTMLDivElement;
class?: string; class?: string;
} = $props(); } = $props();
@@ -1,12 +1,10 @@
import { distance, type Coordinates, TrackPoint, TrackSegment, Track, projectedPoint } from 'gpx'; import { distance, type Coordinates, TrackPoint, TrackSegment, Track, projectedPoint } from 'gpx';
import { get, writable, type Readable } from 'svelte/store'; import { get, writable, type Readable } from 'svelte/store';
import { import maplibregl, {
type MapMouseEvent, type MapMouseEvent,
type GeoJSONSource, type GeoJSONSource,
type MapLayerMouseEvent, type MapLayerMouseEvent,
type MapLayerTouchEvent, type MapLayerTouchEvent,
Popup,
Point,
} from 'maplibre-gl'; } from 'maplibre-gl';
import { route } from './routing'; import { route } from './routing';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
@@ -52,18 +50,16 @@ export class RoutingControls {
} }
> = new Map(); > = new Map();
anchors: GeoJSON.Feature<GeoJSON.Point, AnchorProperties>[] = []; anchors: GeoJSON.Feature<GeoJSON.Point, AnchorProperties>[] = [];
popup: Popup; popup: maplibregl.Popup;
popupElement: HTMLElement; popupElement: HTMLElement;
fileUnsubscribe: () => void = () => {}; fileUnsubscribe: () => void = () => {};
unsubscribes: Function[] = []; unsubscribes: Function[] = [];
updateControlsBinded: () => void = this.updateControls.bind(this); updateControlsBinded: () => void = this.updateControls.bind(this);
appendAnchorBinded: (e: MapMouseEvent) => void = this.appendAnchor.bind(this); appendAnchorBinded: (e: MapMouseEvent) => void = this.appendAnchor.bind(this);
addIntermediateAnchorBinded: (e: MapMouseEvent) => void = this.addIntermediateAnchor.bind(this);
draggedAnchorIndex: number | null = null; draggedAnchorIndex: number | null = null;
lastDraggedAnchorEventTime: number = 0; draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
draggingStartingPosition: Point = new Point(0, 0);
onMouseEnterBinded: () => void = this.onMouseEnter.bind(this); onMouseEnterBinded: () => void = this.onMouseEnter.bind(this);
onMouseLeaveBinded: () => void = this.onMouseLeave.bind(this); onMouseLeaveBinded: () => void = this.onMouseLeave.bind(this);
onClickBinded: (e: MapLayerMouseEvent) => void = this.onClick.bind(this); onClickBinded: (e: MapLayerMouseEvent) => void = this.onClick.bind(this);
@@ -82,7 +78,7 @@ export class RoutingControls {
constructor( constructor(
fileId: string, fileId: string,
file: Readable<GPXFileWithStatistics | undefined>, file: Readable<GPXFileWithStatistics | undefined>,
popup: Popup, popup: maplibregl.Popup,
popupElement: HTMLElement popupElement: HTMLElement
) { ) {
this.fileId = fileId; this.fileId = fileId;
@@ -137,7 +133,6 @@ export class RoutingControls {
map_.on('style.load', this.updateControlsBinded); map_.on('style.load', this.updateControlsBinded);
map_.on('click', this.appendAnchorBinded); map_.on('click', this.appendAnchorBinded);
layerEventManager.on('mousemove', this.fileId, this.showTemporaryAnchorBinded); layerEventManager.on('mousemove', this.fileId, this.showTemporaryAnchorBinded);
layerEventManager.on('click', this.fileId, this.addIntermediateAnchorBinded);
this.fileUnsubscribe = this.file.subscribe(this.updateControlsBinded); this.fileUnsubscribe = this.file.subscribe(this.updateControlsBinded);
} }
@@ -185,7 +180,7 @@ export class RoutingControls {
this.layers.forEach((layer, zoom) => { this.layers.forEach((layer, zoom) => {
try { try {
let source = map_.getSource(layer.id) as GeoJSONSource | undefined; let source = map_.getSource(layer.id) as maplibregl.GeoJSONSource | undefined;
if (source) { if (source) {
source.setData({ source.setData({
type: 'FeatureCollection', type: 'FeatureCollection',
@@ -242,7 +237,6 @@ export class RoutingControls {
map_?.off('style.load', this.updateControlsBinded); map_?.off('style.load', this.updateControlsBinded);
map_?.off('click', this.appendAnchorBinded); map_?.off('click', this.appendAnchorBinded);
layerEventManager?.off('mousemove', this.fileId, this.showTemporaryAnchorBinded); layerEventManager?.off('mousemove', this.fileId, this.showTemporaryAnchorBinded);
layerEventManager?.off('click', this.fileId, this.addIntermediateAnchorBinded);
map_?.off('mousemove', this.updateTemporaryAnchorBinded); map_?.off('mousemove', this.updateTemporaryAnchorBinded);
this.layers.forEach((layer) => { this.layers.forEach((layer) => {
@@ -522,24 +516,17 @@ export class RoutingControls {
}); });
} }
async appendAnchor(e: MapMouseEvent) { async appendAnchor(e: maplibregl.MapMouseEvent) {
// Add a new anchor to the end of the last segment // Add a new anchor to the end of the last segment
if (get(streetViewEnabled) && get(streetViewSource) === 'google') { if (get(streetViewEnabled) && get(streetViewSource) === 'google') {
return; return;
} }
if (
this.draggedAnchorIndex !== null ||
Date.now() - this.lastDraggedAnchorEventTime < 100
) {
// Exit if anchor is being dragged
return;
}
if ( if (
e.target.queryRenderedFeatures(e.point, { e.target.queryRenderedFeatures(e.point, {
layers: [this.fileId, ...[...this.layers.values()].map((layer) => layer.id)], layers: [...this.layers.values()].map((layer) => layer.id),
}).length }).length
) { ) {
// Clicked on routing control or layer, ignoring // Clicked on routing control, ignoring
return; return;
} }
this.appendAnchorWithCoordinates({ this.appendAnchorWithCoordinates({
@@ -611,15 +598,6 @@ export class RoutingControls {
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]); await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
} }
addIntermediateAnchor(e: MapMouseEvent) {
e.preventDefault();
if (this.temporaryAnchor !== null) {
this.turnIntoPermanentAnchor();
return;
}
}
getNeighbouringAnchors(anchor: Anchor): [Anchor | null, Anchor | null] { getNeighbouringAnchors(anchor: Anchor): [Anchor | null, Anchor | null] {
let previousAnchor: Anchor | null = null; let previousAnchor: Anchor | null = null;
let nextAnchor: Anchor | null = null; let nextAnchor: Anchor | null = null;
@@ -822,7 +800,7 @@ export class RoutingControls {
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="8" fill="white" stroke="black" stroke-width="2" /> <circle cx="10" cy="10" r="8" fill="white" stroke="black" stroke-width="2" />
</svg>`, </svg>`,
_map.getCanvasContainer().offsetWidth > 1000 ? 56 : 80 _map.getCanvasContainer().offsetWidth > 1000 ? 50 : 80
); );
} }
@@ -840,11 +818,8 @@ export class RoutingControls {
onClick(e: MapLayerMouseEvent) { onClick(e: MapLayerMouseEvent) {
e.preventDefault(); e.preventDefault();
if ( if (this.temporaryAnchor !== null) {
this.draggedAnchorIndex !== null || this.turnIntoPermanentAnchor();
Date.now() - this.lastDraggedAnchorEventTime < 100
) {
// Exit if anchor is being dragged
return; return;
} }
@@ -933,8 +908,6 @@ export class RoutingControls {
lat: e.lngLat.lat, lat: e.lngLat.lat,
lon: e.lngLat.lng, lon: e.lngLat.lng,
}); });
this.lastDraggedAnchorEventTime = Date.now();
} }
onMouseUp(e: MapLayerMouseEvent | MapLayerTouchEvent) { onMouseUp(e: MapLayerMouseEvent | MapLayerTouchEvent) {
@@ -973,7 +946,6 @@ export class RoutingControls {
} }
this.draggedAnchorIndex = null; this.draggedAnchorIndex = null;
this.lastDraggedAnchorEventTime = Date.now();
} }
showTemporaryAnchor(e: MapLayerMouseEvent) { showTemporaryAnchor(e: MapLayerMouseEvent) {
@@ -8,13 +8,13 @@ import { get } from 'svelte/store';
import { fileStateCollection } from '$lib/logic/file-state'; import { fileStateCollection } from '$lib/logic/file-state';
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import type { Map, GeoJSONSource, MapLayerMouseEvent } from 'maplibre-gl'; import type { GeoJSONSource } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style'; import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager'; import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
import { loadSVGIcon } from '$lib/utils'; import { loadSVGIcon } from '$lib/utils';
export class SplitControls { export class SplitControls {
map: Map; map: maplibregl.Map;
layerEventManager: MapLayerEventManager; layerEventManager: MapLayerEventManager;
unsubscribes: Function[] = []; unsubscribes: Function[] = [];
@@ -22,7 +22,7 @@ export class SplitControls {
layerOnMouseLeaveBinded: () => void = this.layerOnMouseLeave.bind(this); layerOnMouseLeaveBinded: () => void = this.layerOnMouseLeave.bind(this);
layerOnClickBinded: (e: any) => void = this.layerOnClick.bind(this); layerOnClickBinded: (e: any) => void = this.layerOnClick.bind(this);
constructor(map: Map, layerEventManager: MapLayerEventManager) { constructor(map: maplibregl.Map, layerEventManager: MapLayerEventManager) {
this.map = map; this.map = map;
this.layerEventManager = layerEventManager; this.layerEventManager = layerEventManager;
loadSVGIcon( loadSVGIcon(
@@ -160,7 +160,7 @@ export class SplitControls {
mapCursor.notify(MapCursorState.SPLIT_CONTROL, false); mapCursor.notify(MapCursorState.SPLIT_CONTROL, false);
} }
layerOnClick(e: MapLayerMouseEvent) { layerOnClick(e: maplibregl.MapLayerMouseEvent) {
let coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates; let coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates;
fileActions.split( fileActions.split(
get(splitAs), get(splitAs),
@@ -16,7 +16,7 @@
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { Marker } from 'maplibre-gl'; import maplibregl from 'maplibre-gl';
import { getSvgForSymbol } from '$lib/components/map/gpx-layer/gpx-layer'; import { getSvgForSymbol } from '$lib/components/map/gpx-layer/gpx-layer';
let props: { let props: {
@@ -41,7 +41,7 @@
}) })
); );
let marker: Marker | null = null; let marker: maplibregl.Marker | null = null;
function reset() { function reset() {
if ($selectedWaypoint) { if ($selectedWaypoint) {
@@ -125,7 +125,7 @@
let element = document.createElement('div'); let element = document.createElement('div');
element.classList.add('w-8', 'h-8'); element.classList.add('w-8', 'h-8');
element.innerHTML = getSvgForSymbol(symbolKey); element.innerHTML = getSvgForSymbol(symbolKey);
marker = new Marker({ marker = new maplibregl.Marker({
element, element,
anchor: 'bottom', anchor: 'bottom',
}) })
+1 -1
View File
@@ -59,7 +59,7 @@ These controls allow you to navigate the map, zoom in and out, and switch betwee
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
Каб кіраваць арыентацыяй і нахілам карты, вы таксама можаце перацягнуць карту, утрымліваючы <kbd>Ctrl</kbd>. Каб кіраваць арыентацыяй і нахілам карты, вы таксама можаце перацягнуць карту, утрымліваючы <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ El botó de capa de mapa permet canviar entre diferents mapes base i alternar ca
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Opcions de vista
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Entra o surt de la vista de mapa en 3D.
Per controlar l'orientació i inclinació del mapa, pots arrossegar el mapa mentre prems <kbd>Ctrl</kbd>. Per controlar l'orientació i inclinació del mapa, pots arrossegar el mapa mentre prems <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ Aquesta eina permet afegir dades d'elevació a traces i [punts d'interès](../gp
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ Tlačítko mapové vrstvy umožňuje přepínat mezi různými podkladovými map
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Možnosti zobrazení
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Zapnout nebo vypnout 3D zobrazení mapy.
Chcete-li ovládat orientaci a náklon mapy, můžete ji také potáhnout s přidržením klávesy <kbd>Ctrl</kbd>. Chcete-li ovládat orientaci a náklon mapy, můžete ji také potáhnout s přidržením klávesy <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ Tento nástroj umožňuje přidat údaje o nadmořské výšce ke stopám a [bod
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ Mit der Schaltfläche Karten-Ebenen können Sie zwischen verschiedenen Basemaps
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Fahre mit der Maus über die Karte, um die <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails-Wanderkarte</a> über der <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a>-Basiskarte anzuzeigen.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Anzeigeoptionen
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Aufrufen oder Beenden der 3D-Kartenansicht.
Um die Ausrichtung und Neigung der Karte zu steuern, können Sie die Karte auch ziehen, während Sie <kbd>die Strg-Taste</kbd> gedrückt halten. Um die Ausrichtung und Neigung der Karte zu steuern, können Sie die Karte auch ziehen, während Sie <kbd>die Strg-Taste</kbd> gedrückt halten.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Vollbildmodus ein- oder ausschalten.
Du kannst auch <kbd>F11</kbd> drücken, um zu wechseln, oder <kbd>Escape</kbd> zum Beenden.
@@ -18,7 +18,7 @@ Mit diesem Tool kannst du Höhendaten zu Routen und [Points of Interest] (../gpx
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Die Höhendaten werden von <a href="https://maptiler.com" target="_blank">MapTiler</a> bereitgestellt.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. Mehr über die Herkunft und Genauigkeit erfährst du in der <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">Dokumentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ Only one basemap can be displayed at a time.
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+2 -7
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -46,9 +46,4 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+2 -2
View File
@@ -13,8 +13,8 @@ Puede usar **gpx.studio** para crear mapas que muestren sus archivos GPX e integ
Todo lo que necesita es: Todo lo que necesita es:
1. Archivos GPX alojados en su servidor o en Google Drive, o accesibles a través de una URL pública; 1. GPX files hosted on your server or on Google Drive, or accessible via a public URL;
2. _Opcional:_ una <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">Tecla MapTiler</a> para cargar mapas MapTiler. 2. _Optional:_ a <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">MapTiler key</a> to load MapTiler maps.
Luego puede jugar con el configurador de abajo para personalizar su mapa y generar el código HTML correspondiente. Luego puede jugar con el configurador de abajo para personalizar su mapa y generar el código HTML correspondiente.
+2 -2
View File
@@ -59,7 +59,7 @@ El botón de capas de mapa le permite cambiar entre diferentes mapas bases y alt
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Pasa el ratón sobre el mapa para que la capa de <a href="https://hiking.waymarkedtrails.org" target="_blank">Caminatas por Sendas Marcadas</a> aparezca superpuesta al mapa base topográfico. Pasa el ratón sobre el mapa para que la capa de <a href="https://hiking.waymarkedtrails.org" target="_blank">Caminatas por Sendas Marcadas</a> aparezca superpuesta al mapa base <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler</a>.
</span> </span>
</div> </div>
@@ -69,4 +69,4 @@ Pueden activarse en la [configuración de capas del mapa](./menu/settings).
En estos ajustes, también puede administrar la opacidad de las capas superpuestas. En estos ajustes, también puede administrar la opacidad de las capas superpuestas.
Para los usuarios avanzados, es posible añadir mapas base y superposiciones personalizadas proporcionando <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a> o URLs <a href="https://docs.mapbox.com/help/glossary/style/" target="_blank">JSON estilo Mapbox</a>. For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.
+1 -6
View File
@@ -3,7 +3,7 @@ title: Opciones de vista
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Entra o sale de la vista 3D del mapa.
Para controlar la orientación e inclinación del mapa, puede arrastrarlo mientras mantiene pulsada la tecla <kbd>Ctrl</kbd>. Para controlar la orientación e inclinación del mapa, puede arrastrarlo mientras mantiene pulsada la tecla <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Pantalla completa
Entrar o salir del modo de pantalla completa.
También puede presionar <kbd>F11</kbd> para alternar, o <kbd>Escape</kbd> para salir.
@@ -18,7 +18,7 @@ Esta herramienta permite añadir datos de elevación a los rastros y [puntos de
<DocsNote> <DocsNote>
Los datos de elevación son proporcionados por <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Los datos de notificación son proporcionados por <a href="https://maptiler.com" target="_blank">MapTiler</a>.
Puede aprender más sobre su origen y precisión en la <a href="https://mapterhorn.com/attribution/" target="_blank">documentación</a>. Puedes aprender más sobre su origen y precisión en la <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentación</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -18,7 +18,7 @@ Para usar esta herramienta, necesita [seleccionar](../files-and-stats) múltiple
<DocsNote> <DocsNote>
Los elementos seleccionados se combinan en el orden en que aparecen en la lista de archivos. Selected items are merged in the order they appear in the files list.
Si es necesario, puede reordenar los elementos arrastrando y soltando. Si es necesario, puede reordenar los elementos arrastrando y soltando.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ Maparen geruzen botoiak mapa-oinarri desberdinen artean aldatzeko aukera ematen
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Ikusteko aukerak
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Aktibatu edo desaktibatu maparen 3D ikuspegia.
Maparen orientazioa eta okertzea kontrolatzeko, mapa ere arrasta dezakezu <kbd> Ctrl</kbd> sakatzen duzun bitartean. Maparen orientazioa eta okertzea kontrolatzeko, mapa ere arrasta dezakezu <kbd> Ctrl</kbd> sakatzen duzun bitartean.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ Tresna honen bidez elebazio datuak gehitzen ahal dira ibilbidetan eta [interesgu
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ Le bouton des couches de la carte vous permet de basculer entre différents fond
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Survolez la carte pour afficher la superposition des chemins de randonnée <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails</a> au fond de carte topographique. Survolez la carte pour afficher la superposition des chemins de randonnée <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails</a> au fond de carte <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a>.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Options d'affichage
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Entrer ou sortir de la vue 3D de la carte.
Pour contrôler l'orientation et l'inclinaison de la carte, vous pouvez également faire glisser la carte tout en maintenant <kbd>Ctrl</kbd>. Pour contrôler l'orientation et l'inclinaison de la carte, vous pouvez également faire glisser la carte tout en maintenant <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Plein écran
Passer en mode plein écran, ou le quitter.
Vous pouvez également appuyer sur <kbd>F11</kbd> pour activer/désactiver le mode plein écran, ou sur <kbd>Échap</kbd> pour quitter.
@@ -18,7 +18,7 @@ Cet outil vous permet d'ajouter des données d'altitude aux traces et aux [point
<DocsNote> <DocsNote>
Les données d'altitude sont fournies par <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Les données d'altitude sont fournies par <a href="https://maptiler.com" target="_blank">MapTiler</a>.
Vous pouvez en apprendre plus sur leur origine et précision dans la <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. Vous pouvez en apprendre plus sur leur origine et précision dans la <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Nézet beállításai
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Lépjen be vagy lépjen ki a 3D térképnézetből.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ Ez az eszköz lehetővé teszi magassági adatok hozzáadását a nyomvonalakhoz
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ Il pulsante dei livelli di mappa consente di passare da una basemap all'altra, e
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: Opzioni di visualizzazione
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Entrare o uscire dalla vista mappa 3D.
Per controllare l'orientamento e l'inclinazione della mappa, puoi anche trascinare la mappa tenendo premuto <kbd>Ctrl</kbd>. Per controllare l'orientamento e l'inclinazione della mappa, puoi anche trascinare la mappa tenendo premuto <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ Questo strumento ti permette di aggiungere dati di altimetria a tracce e [punti
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote> <DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+2 -2
View File
@@ -59,7 +59,7 @@ Met de kaartlagen knop kun je wisselen tussen verschillende basiskaarten, en kaa
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Beweeg over de kaart om de <a href="https://hiking.waymarkedtrails.org" target="_blank">Gemarkeerde sporen wandelen</a> overlay te tonen bovenop de topografische basiskaart. Beweeg over de kaart om de <a href="https://hiking.waymarkedtrails.org" target="_blank">Gemarkeerde sporen wandelen</a> overlay te tonen bovenop de <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
@@ -69,4 +69,4 @@ Ze kunnen worden ingeschakeld in het [map layer settings dialoog](./menu/setting
In deze instellingen kun je ook de transparantie van de lagen beheren. In deze instellingen kun je ook de transparantie van de lagen beheren.
Voor gevorderde gebruikers is het mogelijk om aangepaste basiskaarten en lagen toe te voegen met <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, of <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre-stijl JSON</a> URLs. For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.
+2 -2
View File
@@ -13,9 +13,9 @@ title: Instellingen
Wijzig de eenheden die worden gebruikt om afstanden in de interface weer te geven. Wijzig de eenheden die worden gebruikt om afstanden in de interface weer te geven.
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Snelheidseenheden ### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Snelheids eenheden
Verander de eenheden die worden gebruikt om snelheden in de interface weer te geven. Verander de eenheden die worden gebruikt om velocities in de interface weer te geven.
Je kunt kiezen tussen afstand per uur of minuten per afstand, wat geschikter kan zijn voor het uitvoeren van activiteiten. Je kunt kiezen tussen afstand per uur of minuten per afstand, wat geschikter kan zijn voor het uitvoeren van activiteiten.
### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> Temperatuureenheden ### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> Temperatuureenheden
+1 -6
View File
@@ -3,7 +3,7 @@ title: Bekijk opties
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Voer in of verlaat de 3D-mapweergave.
Om de oriëntatie en kanteling van de kaart te bepalen, kun je ook de kaart slepen terwijl je <kbd>Ctrl</kbd> ingedrukt houdt. Om de oriëntatie en kanteling van de kaart te bepalen, kun je ook de kaart slepen terwijl je <kbd>Ctrl</kbd> ingedrukt houdt.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Volledig scherm
Start of stop volledig scherm modus.
Je kunt ook op <kbd>F11</kbd> drukken om te wisselen, of <kbd>Escape</kbd> om af te sluiten.
@@ -18,7 +18,7 @@ Met dit gereedschap kun je hoogtegegevens toevoegen aan sporen en [interessante
<DocsNote> <DocsNote>
Hoogtegegevens worden verstrekt door <a href="https://maptiler.com" target="_blank">Mapterhorn</a>. Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
Je kunt meer leren over de oorsprong en nauwkeurigheid in de <a href="https://mapterhorn.com/attribution/" target="_blank">documentatie</a>. You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote> </DocsNote>
+1 -1
View File
@@ -59,7 +59,7 @@ The map layers button allows you to switch between different basemaps, and toggl
<DocsLayers /> <DocsLayers />
<span class="text-sm text-center mt-2"> <span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap. Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span> </span>
</div> </div>
+1 -6
View File
@@ -3,7 +3,7 @@ title: View options
--- ---
<script lang="ts"> <script lang="ts">
import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box, Maximize2 } from '@lucide/svelte'; import { ChartArea, ListTree, Map, Layers2, Coins, Milestone, Box } from '@lucide/svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte'; import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script> </script>
@@ -47,8 +47,3 @@ Enter or exit the 3D map view.
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>. To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
</DocsNote> </DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
+3 -3
View File
@@ -1,5 +1,5 @@
--- ---
title: Rens title: Clean
--- ---
<script> <script>
@@ -9,9 +9,9 @@ title: Rens
# <SquareDashedMousePointer size="24" class="inline-block" style="margin-bottom: 5px" /> { title } # <SquareDashedMousePointer size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
Når rensverktøyet er valgt, markeres et område ved å tegne et rektangel på kartet. When the clean tool is selected, dragging the map will create a rectangular selection.
Avhengig av alternativene som er valgt i dialogboksen nedenfor, fjerner slett-knappen GPS-punkter og/eller [interessepunkter POI](../gpx) enten innenfor eller utenfor det merkede området. Depending on the options selected in the dialog shown below, clicking the delete button will remove GPS points and/or [points of interest](../gpx) located either inside or outside the selection.
<div class="flex flex-row justify-center"> <div class="flex flex-row justify-center">
<Clean class="text-foreground p-3 border rounded-md shadow-lg" /> <Clean class="text-foreground p-3 border rounded-md shadow-lg" />

Some files were not shown because too many files have changed in this diff Show More