mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-27 02:27:18 +00:00
Compare commits
44
Commits
main
..
2975648484
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2975648484 | ||
|
|
29e420a794 | ||
|
|
254d98004d | ||
|
|
f78bb14ea9 | ||
|
|
c76360630b | ||
|
|
99890fe6da | ||
|
|
8a4721f7fc | ||
|
|
c29733091b | ||
|
|
b06800e2fe | ||
|
|
deaf5e0926 | ||
|
|
8e5beaabe9 | ||
|
|
8a38627467 | ||
|
|
ceadc7d1b5 | ||
|
|
383d21a4a1 | ||
|
|
153ecb9765 | ||
|
|
d911761e17 | ||
|
|
7540565d79 | ||
|
|
01332e7a03 | ||
|
|
1aabfb4584 | ||
|
|
44d76966e2 | ||
|
|
1722520d23 | ||
|
|
8e99ed2689 | ||
|
|
4f88fe179a | ||
|
|
b13602b33e | ||
|
|
8138fe780b | ||
|
|
f4d6cd9cc3 | ||
|
|
902107c36b | ||
|
|
ea8e8bc1e3 | ||
|
|
c89a6148f2 | ||
|
|
fa732b0343 | ||
|
|
142ee61484 | ||
|
|
873059cfcc | ||
|
|
9e380e597e | ||
|
|
f4dc516fe5 | ||
|
|
bca6c32193 | ||
|
|
9f52d4d60d | ||
|
|
a1475ab7ba | ||
|
|
0987c6a72e | ||
|
|
a02de61d0a | ||
|
|
75e477ba52 | ||
|
|
b72cebc186 | ||
|
|
5dd53cd9eb | ||
|
|
2c82444832 | ||
|
|
93ac92969d |
No files matched your search
Generated
+67
-70
@@ -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": {
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 !== '') {
|
||||||
|
|||||||
@@ -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';
|
||||||
@@ -28,7 +28,7 @@ export class OverpassLayer {
|
|||||||
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,7 +141,7 @@ export class MapLayerEventManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleMouseMove(e: MapMouseEvent) {
|
private _handleMouseMove(e: maplibregl.MapMouseEvent) {
|
||||||
if (e.originalEvent.buttons > 0) return;
|
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) => {
|
||||||
@@ -159,20 +150,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 +181,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 +234,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 +261,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 +270,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] = [];
|
||||||
|
|||||||
@@ -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,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 &&
|
||||||
|
|||||||
@@ -9,17 +9,11 @@ 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, distanceUnits } =
|
||||||
settings;
|
settings;
|
||||||
|
|
||||||
const emptySource: GeoJSONSourceSpecification = {
|
const emptySource: maplibregl.GeoJSONSourceSpecification = {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
data: {
|
data: {
|
||||||
type: 'FeatureCollection',
|
type: 'FeatureCollection',
|
||||||
@@ -38,18 +32,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_) => {
|
||||||
@@ -82,10 +76,10 @@ export class StyleManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildStyle(basemap: string): Promise<StyleSpecification> {
|
async buildStyle(basemap: string): 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',
|
||||||
@@ -98,7 +92,7 @@ export class StyleManager {
|
|||||||
|
|
||||||
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
|
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
|
||||||
|
|
||||||
let basemapStyle = basemaps.openStreetMap as StyleSpecification;
|
let basemapStyle = basemaps.openStreetMap as maplibregl.StyleSpecification;
|
||||||
try {
|
try {
|
||||||
basemapStyle = await this.get(basemapInfo);
|
basemapStyle = await this.get(basemapInfo);
|
||||||
for (const source in basemapStyle.sources) {
|
for (const source in basemapStyle.sources) {
|
||||||
@@ -209,7 +203,9 @@ 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' });
|
const response = await fetch(styleUrl, { cache: 'force-cache' });
|
||||||
@@ -223,7 +219,7 @@ 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);
|
const units = get(distanceUnits);
|
||||||
for (let layer of other.layers ?? []) {
|
for (let layer of other.layers ?? []) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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,7 +50,7 @@ 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[] = [];
|
||||||
@@ -63,7 +61,7 @@ export class RoutingControls {
|
|||||||
|
|
||||||
draggedAnchorIndex: number | null = null;
|
draggedAnchorIndex: number | null = null;
|
||||||
lastDraggedAnchorEventTime: number = 0;
|
lastDraggedAnchorEventTime: number = 0;
|
||||||
draggingStartingPosition: Point = new Point(0, 0);
|
draggingStartingPosition: maplibregl.Point = new maplibregl.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 +80,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;
|
||||||
@@ -185,7 +183,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',
|
||||||
@@ -522,7 +520,7 @@ 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;
|
||||||
@@ -611,7 +609,7 @@ export class RoutingControls {
|
|||||||
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
|
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
|
||||||
}
|
}
|
||||||
|
|
||||||
addIntermediateAnchor(e: MapMouseEvent) {
|
addIntermediateAnchor(e: maplibregl.MapMouseEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (this.temporaryAnchor !== null) {
|
if (this.temporaryAnchor !== null) {
|
||||||
|
|||||||
@@ -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',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ 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>.
|
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>.
|
||||||
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://mapterhorn.com/attribution/" target="_blank">Dokumentation</a>.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -13,8 +13,8 @@ title: Integrazioa
|
|||||||
|
|
||||||
Behar duzun guztia hau da:
|
Behar duzun guztia hau da:
|
||||||
|
|
||||||
1. GPX files hosted on your server or on Google Drive, or accessible via a public URL;
|
1. Zure zerbitzarian edo Google Drive-n ostatatutako GPX fitxategiak, edo URL publiko baten bidez eskura daitezke;
|
||||||
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.
|
2. _Aukerakoa:_ <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">MapTiler tekla</a> MapTiler mapak kargatzeko.
|
||||||
|
|
||||||
Ondoren, konfiguratzailearekin jolastu dezakezu zure mapa pertsonalizatzeko eta dagokion HTML kodea sortzeko.
|
Ondoren, konfiguratzailearekin jolastu dezakezu zure mapa pertsonalizatzeko eta dagokion HTML kodea sortzeko.
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
Pasa ezazu maparen gainean <a href="https://hiking.waymarkedtrails.org" target="_blank">markatutako mendi-ibiliak</a> gainjartzeko oinarrizko mapa topografikoaren gainean.
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -69,4 +69,4 @@ Global eta tokiko mapa oinarri bilduma handia dago **gpx.studio**-n eskuragarri,
|
|||||||
|
|
||||||
Ezarpen horietan, gainjartzeen opakutasuna ere kudeatu dezakezu.
|
Ezarpen horietan, gainjartzeen opakutasuna ere kudeatu dezakezu.
|
||||||
|
|
||||||
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.
|
Erabiltzaile aurreratuentzat, oinarrizko mapa pertsonalizatuak eta gainjartzeak gehi daitezke <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> edo <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>https:///malibrea-spec.org/malibrea-spec. target="_blank">MapLibre estiloko JSON</a> URLak.
|
||||||
@@ -48,7 +48,6 @@ Maparen orientazioa eta okertzea kontrolatzeko, mapa ere arrasta dezakezu <kbd>
|
|||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
|
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Pantaila osoa
|
||||||
|
|
||||||
Enter or exit full screen mode.
|
Sartu edo irten pantaila osoko moduan.<kbd>F11</kbd> ere saka dezakezu txandakatzeko, edo <kbd>Ihes</kbd> irteteko.
|
||||||
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>.
|
Altueraren datuak <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>k ematen ditu.
|
||||||
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>.
|
Haren jatorriari eta zehaztasunari buruz gehiago jakin dezakezu <a href="https://mapterhorn.com/attribution/" target="_blank">dokumentazioan</a>.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -18,8 +18,8 @@ Tresna hau erabiltzeko [hautatu](../files-and-stats) behar duzu hainbat fitxateg
|
|||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
Selected items are merged in the order they appear in the files list.
|
Hautatutako elementuak fitxategien zerrendan agertzen diren ordenan batzen dira.
|
||||||
Reorder items by drag-and-drop if needed.
|
Berrantolatu elementuak arrastatu eta jareginez, behar izanez gero.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ title: Stijging
|
|||||||
|
|
||||||
# <MountainSnow size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
|
# <MountainSnow size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
|
||||||
|
|
||||||
Met dit gereedschap kun je hoogtegegevens toevoegen aan sporen en [interessante punten](../gpx), of de bestaande gegevens vervangen.
|
Met deze tool kunt u hoogtegegevens toevoegen aan sporen en [punten van belang](../gpx) of de bestaande gegevens vervangen.
|
||||||
|
|
||||||
<div class="flex flex-row justify-center">
|
<div class="flex flex-row justify-center">
|
||||||
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
|
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ Someone more experienced with OpenStreetMap will then review your note and make
|
|||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
More information on how to contribute to OpenStreetMap can be found <a href="https://wiki.openstreetmap.org/wiki/How_to_contribute" target="_blank">here</a>.
|
Mais informações sobre como contribuir para o OpenStreetMap podem ser encontradas <a href="https://wiki.openstreetmap.org/wiki/How_to_contribute" target="_blank">aqui</a>.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Files and statistics
|
title: Ficheiros e estatísticas
|
||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -19,7 +19,7 @@ title: Files and statistics
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
## File list
|
## Lista de ficheiros
|
||||||
|
|
||||||
Once you have [opened](./menu/file) files, they will be shown as tabs in the file list located at the bottom of the map.
|
Once you have [opened](./menu/file) files, they will be shown as tabs in the file list located at the bottom of the map.
|
||||||
You can reorder them by dragging and dropping the tabs.
|
You can reorder them by dragging and dropping the tabs.
|
||||||
@@ -103,7 +103,7 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** or **category** data coming from <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>'s <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> and <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">highway</a> tags.
|
- **superfície** ou **categoria** dados obtidos de <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> e <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">autoestrada</a> etiquetas.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
|
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
|
||||||
@@ -21,7 +21,7 @@ Before we dive into the details of each section, let's have a quick overview of
|
|||||||
At the top of the interface, you will find the [main menu](./menu).
|
At the top of the interface, you will find the [main menu](./menu).
|
||||||
This is where you can access common actions such as opening, closing, and exporting files, undoing and redoing actions, and adjusting the application settings.
|
This is where you can access common actions such as opening, closing, and exporting files, undoing and redoing actions, and adjusting the application settings.
|
||||||
|
|
||||||
## Files and statistics
|
## Ficheiros e estatísticas
|
||||||
|
|
||||||
At the bottom of the interface, you will find the list of files currently open in the application.
|
At the bottom of the interface, you will find the list of files currently open in the application.
|
||||||
You can click on a file to select it and display its statistics below the list.
|
You can click on a file to select it and display its statistics below the list.
|
||||||
@@ -34,4 +34,4 @@ On the left side of the interface, you will find the [toolbar](./toolbar), which
|
|||||||
## Map controls
|
## Map controls
|
||||||
|
|
||||||
Finally, on the right side of the interface, you will find the [map controls](./map-controls).
|
Finally, on the right side of the interface, you will find the [map controls](./map-controls).
|
||||||
These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
|
Estes controles permitem navegar pelo mapa, ampliar, reduzir e alternar entre diferentes estilos de mapa.
|
||||||
@@ -20,7 +20,7 @@ You can then play with the configurator below to customize your map and generate
|
|||||||
|
|
||||||
<DocsNote type="warning">
|
<DocsNote type="warning">
|
||||||
|
|
||||||
You will need to set up <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">Cross-Origin Resource Sharing (CORS)</a> headers on your server to allow <b>gpx.studio</b> to load your GPX files.
|
Precisará configurar <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">cabeçalhos de partilha de recursos entre origens (CORS)</a> no seu servidor para permitir que <b>gpx. tudio</b> para carregar os seus ficheiros GPX.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ title: Map controls
|
|||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
The map controls are located on the right side of the interface.
|
The map controls are located on the right side of the interface.
|
||||||
These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
|
Estes controles permitem navegar pelo mapa, ampliar, reduzir e alternar entre diferentes estilos de mapa.
|
||||||
|
|
||||||
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
|
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
|
||||||
|
|
||||||
@@ -69,4 +69,4 @@ They can be enabled in the [map layer settings dialog](./menu/settings).
|
|||||||
|
|
||||||
In these settings, you can also manage the opacity of the overlays.
|
In these settings, you can also manage the opacity of the overlays.
|
||||||
|
|
||||||
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.
|
Para utilizadores avançados, é possível adicionar maps de base e sobreposições personalizados, fornecendo <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>, ou <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre com estrutura JSON</a> URLs.
|
||||||
@@ -11,7 +11,7 @@ title: Edit actions
|
|||||||
|
|
||||||
Unlike the file actions, the edit actions can potentially modify the content of the currently selected files.
|
Unlike the file actions, the edit actions can potentially modify the content of the currently selected files.
|
||||||
Moreover, when the tree layout of the files list is enabled (see [Files and statistics](../files-and-stats)), they can also be applied to [tracks, segments, and points of interest](../gpx).
|
Moreover, when the tree layout of the files list is enabled (see [Files and statistics](../files-and-stats)), they can also be applied to [tracks, segments, and points of interest](../gpx).
|
||||||
Therefore, we will refer to the elements that can be modified by these actions as _file items_.
|
Portanto, vamos referir-nos aos elementos que podem ser modificados por essas acções como _itens de ficheiro_.
|
||||||
Note that except for the undo and redo actions, the edit actions are also accessible through the context menu (right-click) of the file items.
|
Note that except for the undo and redo actions, the edit actions are also accessible through the context menu (right-click) of the file items.
|
||||||
|
|
||||||
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Undo and redo
|
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Undo and redo
|
||||||
|
|||||||
@@ -47,6 +47,6 @@ Open the export dialog to save all files to your computer.
|
|||||||
|
|
||||||
<DocsNote type="warning">
|
<DocsNote type="warning">
|
||||||
|
|
||||||
If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
|
Se o seu download não começar depois de clicar no botão de descarregar, verifique as configurações do seu navegador para permitir descarregar do <b>gpx.studio</b>.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -51,4 +51,4 @@ To control the orientation and tilt of the map, you can also drag the map while
|
|||||||
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
|
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
|
||||||
|
|
||||||
Enter or exit full screen mode.
|
Enter or exit full screen mode.
|
||||||
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
|
Também pode pressionar <kbd>F11</kbd> para alternar, ou <kbd>Escape</kbd> para sair.
|
||||||
@@ -11,7 +11,7 @@ title: Clean
|
|||||||
|
|
||||||
When the clean tool is selected, dragging the map will create a rectangular selection.
|
When the clean tool is selected, dragging the map will create a rectangular selection.
|
||||||
|
|
||||||
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.
|
Dependendo das opções selecionadas no diálogo mostrado abaixo, Clicar no botão apagar irá remover pontos de GPS e/ou [pontos de interesse](../gpx) localizados dentro ou fora da selecção.
|
||||||
|
|
||||||
<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" />
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ title: Elevação
|
|||||||
|
|
||||||
# <MountainSnow size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
|
# <MountainSnow size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
|
||||||
|
|
||||||
This tool allows you to add elevation data to traces and [points of interest](../gpx), or to replace the existing data.
|
Esta ferramenta permite adicionar dados de elevação a rastros e [pontos de interesse](../gpx), ou substituir os dados existentes.
|
||||||
|
|
||||||
<div class="flex flex-row justify-center">
|
<div class="flex flex-row justify-center">
|
||||||
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
|
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ Similarly, applying the tool to a track containing multiple segments will create
|
|||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
When extracting the tracks from a file containing <a href="../gpx">points of interest</a>, the tool will automatically assign each point of interest to the track it is closest to.
|
Ao extrair as trilhas de um ficheiro que contém <a href="../gpx">pontos de interesse</a>, a ferramenta atribuirá automaticamente cada ponto de interesse para a faixa à qual está mais próximo.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -19,7 +19,7 @@ To use this tool, you need to [select](../files-and-stats) multiple files, [trac
|
|||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
Selected items are merged in the order they appear in the files list.
|
Selected items are merged in the order they appear in the files list.
|
||||||
Reorder items by drag-and-drop if needed.
|
Reordenar itens por arrastar e soltar, se necessário.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ You can adjust the tolerance of the simplification algorithm using the slider, a
|
|||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
The tolerance value represents the maximum distance allowed between the original trace and the simplified trace.
|
The tolerance value represents the maximum distance allowed between the original trace and the simplified trace.
|
||||||
You can read more about the algorithm used <a href="https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm" target="_blank">here</a>.
|
Pode ler mais sobre o algoritmo usado <a href="https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm" target="_blank">aqui</a>.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Points of interest
|
title: Pontos de interesse
|
||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -24,4 +24,4 @@ Validate the form when you are done.
|
|||||||
### Editing a point of interest
|
### Editing a point of interest
|
||||||
|
|
||||||
The form above can also be used to edit an existing point of interest after selecting it on the map.
|
The form above can also be used to edit an existing point of interest after selecting it on the map.
|
||||||
If you only need to move the point of interest, you can drag it to the desired location.
|
Se só precisar mover o ponto de interesse, pode arrastá-lo para o local desejado.
|
||||||
@@ -81,4 +81,4 @@ Return to the starting point by the same route.
|
|||||||
|
|
||||||
### <CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> Change the start of the loop
|
### <CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> Change the start of the loop
|
||||||
|
|
||||||
When the end point of the route is close enough to the start, you can change the start of the loop by clicking on any anchor point and selecting <button><CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> Start loop here</button> from the context menu.
|
Quando o ponto final da rota é suficientemente próximo do início, pode alterar o início do laço clicando em qualquer ponto de âncora e selecionando <button><CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> início círculo aqui</button> no menu de contexto.
|
||||||
@@ -29,4 +29,4 @@ Scissors will appear at the cursor position, showing that you can split the trac
|
|||||||
|
|
||||||
You can choose to split the trace into two GPX files, or to keep the split parts in the same file as [tracks or segments](../gpx).
|
You can choose to split the trace into two GPX files, or to keep the split parts in the same file as [tracks or segments](../gpx).
|
||||||
|
|
||||||
<DocsImage src="tools/split" alt="Hovering over the selected trace turns your cursor into scissors." />
|
<DocsImage src="tools/split" alt="Passar o rato sobre o rastro selecionado transforma o cursor numa tesoura." />
|
||||||
@@ -18,7 +18,7 @@ You simply need to use the form shown below and validate it when you are done.
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
When you edit the speed, the moving time is adapted accordingly in the form, and vice versa.
|
When you edit the speed, the moving time is adapted accordingly in the form, and vice versa.
|
||||||
Similarly, when you edit the start time, the end time is updated to keep the same total duration, and vice versa.
|
Da mesma forma, quando edita o tempo de partida o tempo de chegada é actualizado.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
|
|||||||
@@ -9,88 +9,88 @@ title: Редактировать действия
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
Unlike the file actions, the edit actions can potentially modify the content of the currently selected files.
|
В отличие от действий с файлами действия редактирования могут изменить содержимое выделенных файлов.
|
||||||
Moreover, when the tree layout of the files list is enabled (see [Files and statistics](../files-and-stats)), they can also be applied to [tracks, segments, and points of interest](../gpx).
|
Более того, когда включено отображение списка файлов в виде дерева (см. [Файлы и статистика](../files-and-stats)), они также могут быть применены к [трекам, звеньям и интересным точкам](../gpx).
|
||||||
Therefore, we will refer to the elements that can be modified by these actions as _file items_.
|
Таким образом, мы будем ссылаться на элементы, которые могут быть изменены этими действиями как _файловые единицы_.
|
||||||
Note that except for the undo and redo actions, the edit actions are also accessible through the context menu (right-click) of the file items.
|
Обратите внимание, что за исключением действий отмены и повтора, действия редактирования также доступны через контекстное меню (щелчок правой кнопкой мыши) файловых единиц.
|
||||||
|
|
||||||
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Undo and redo
|
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Отменить и повторить
|
||||||
|
|
||||||
Using these buttons, you can undo or redo the last actions you performed.
|
С помощью этих кнопок можно отменить или повторить последние выполненные действия.
|
||||||
This applies to all actions of the interface but not to view options, application settings, or map navigation.
|
Это применимо ко всему поведению интерфейса кроме параметров просмотра, настроек приложения или перемещению по карте.
|
||||||
|
|
||||||
### <Info size="16" class="inline-block" style="margin-bottom: 2px" /> Info...
|
### <Info size="16" class="inline-block" style="margin-bottom: 2px" />Информация...
|
||||||
|
|
||||||
Open the information dialog of the currently selected file item, where you can see and edit its name and description.
|
Открывает информационный диалог выбранного в данный момент файла, где вы можете посмотреть и отредактировать его имя и описание.
|
||||||
|
|
||||||
### <PaintBucket size="16" class="inline-block" style="margin-bottom: 2px" /> Appearance...
|
### <PaintBucket size="16" class="inline-block" style="margin-bottom: 2px" />Внешнее представление...
|
||||||
|
|
||||||
Open the appearance dialog, where you can change the color, opacity, and width of the selected file items on the map.
|
Открывает диалог внешнего представления, где можно изменить цвет, прозрачность и ширину выделенных файловых элементов на карте.
|
||||||
|
|
||||||
### <EyeOff size="16" class="inline-block" style="margin-bottom: 2px" /> Hide/unhide
|
### <EyeOff size="16" class="inline-block" style="margin-bottom: 2px" /> Скрыть/показать
|
||||||
|
|
||||||
Toggle the visibility of the selected file items on the map.
|
Переключить видимость выбранных файлов на карте.
|
||||||
|
|
||||||
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New track
|
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" />Новый маршрут
|
||||||
|
|
||||||
Create a new track in the selected file.
|
Создать новый маршрут в выбранном файле.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
This action is only available when the tree layout of the files list is enabled.
|
Это действие доступно только при включенном отображении списка файлов в виде дерева.
|
||||||
Additionally, the selection must be a single file.
|
Кроме того, должен быть выделен только один файл.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New segment
|
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" />Новый отрезок
|
||||||
|
|
||||||
Create a new segment in the selected track.
|
Создать новый отрезок на выбранном маршруте.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
This action is only available when the tree layout of the files list is enabled.
|
Это действие доступно только при включенном отображении списка файлов в виде дерева.
|
||||||
Additionally, the selection must be a single track.
|
Кроме того, должен быть выделен только один маршрут.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <FileStack size="16" class="inline-block" style="margin-bottom: 2px" /> Select all
|
### <FileStack size="16" class="inline-block" style="margin-bottom: 2px" />Выбрать всё
|
||||||
|
|
||||||
Add all file items in the current hierarchy level to the selection.
|
Добавить все файлы текущего уровня иерархии к выделению.
|
||||||
|
|
||||||
### <Maximize size="16" class="inline-block" style="margin-bottom: 2px" /> Center
|
### <Maximize size="16" class="inline-block" style="margin-bottom: 2px" />По центру
|
||||||
|
|
||||||
Center the map on the selected file items.
|
Выровнять карту по центру на выбранных файловых единицах.
|
||||||
|
|
||||||
### <ClipboardCopy size="16" class="inline-block" style="margin-bottom: 2px" /> Copy
|
### <ClipboardCopy size="16" class="inline-block" style="margin-bottom: 2px" /> Копировать
|
||||||
|
|
||||||
Copy the selected file items to the clipboard.
|
Скопировать выбранные файловые единицы в буфер обмена.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
This action is only available when the tree layout of the files list is enabled.
|
Это действие доступно только при включенном отображении списка файлов в виде дерева.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Scissors size="16" class="inline-block" style="margin-bottom: 2px" /> Cut
|
### <Scissors size="16" class="inline-block" style="margin-bottom: 2px" /> Вырезать
|
||||||
|
|
||||||
Cut the selected file items to the clipboard.
|
Вырезать выбранные файлы в буфер обмена.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
This action is only available when the tree layout of the files list is enabled.
|
Это действие доступно только при включенном отображении списка файлов в виде дерева.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <ClipboardPaste size="16" class="inline-block" style="margin-bottom: 2px" /> Paste
|
### <ClipboardPaste size="16" class="inline-block" style="margin-bottom: 2px" />Вставить
|
||||||
|
|
||||||
Paste the file items from the clipboard to the current hierarchy level if they are compatible with it.
|
Вставить файлы из буфера обмена на текущий уровень иерархии, если они совместимы с ним.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
This action is only available when the tree layout of the files list is enabled.
|
Это действие доступно только при включенном отображении списка файлов в виде дерева.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Trash2 size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
|
### <Trash2 size="16" class="inline-block" style="margin-bottom: 2px" />Удалить
|
||||||
|
|
||||||
Delete the selected file items.
|
Удалить выбранные файловые единицы.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: File actions
|
title: Действия с файлами
|
||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -9,44 +9,44 @@ title: File actions
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
The file actions menu contains a set of pretty self-explanatory file operations.
|
Меню действий с файлами включает в себя список вполне понятных операций с файлами.
|
||||||
|
|
||||||
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New
|
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> Новый
|
||||||
|
|
||||||
Create a new empty file.
|
Создание нового пустого файла.
|
||||||
|
|
||||||
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Open...
|
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Открыть...
|
||||||
|
|
||||||
Open files from your computer.
|
Открыть файлы с вашего компьютера.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
You can also drag and drop files directly from your file system into the window.
|
Также Вы можете перетаскивать файлы прямо из файловой системы в окно.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Copy size="16" class="inline-block" style="margin-bottom: 2px" /> Duplicate
|
### <Copy size="16" class="inline-block" style="margin-bottom: 2px" /> Создать копию
|
||||||
|
|
||||||
Create a copy of the currently selected files.
|
Создать копию выделенных файлов.
|
||||||
|
|
||||||
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
|
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" />Удалить
|
||||||
|
|
||||||
Delete the currently selected files.
|
Удаление выбранных файлов.
|
||||||
|
|
||||||
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete all
|
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" />Удалить всё
|
||||||
|
|
||||||
Delete all files.
|
Удаление всех файлов.
|
||||||
|
|
||||||
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Export...
|
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Выгрузить...
|
||||||
|
|
||||||
Open the export dialog to save the currently selected files to your computer.
|
Открывает диалог для сохранения выделенных файлов на ваш компьютер.
|
||||||
|
|
||||||
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Export all...
|
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Выгрузить все файлы...
|
||||||
|
|
||||||
Open the export dialog to save all files to your computer.
|
Открывает окно выгрузки в котором можно сохранить все файлы на ваш компьютер.
|
||||||
|
|
||||||
<DocsNote type="warning">
|
<DocsNote type="warning">
|
||||||
|
|
||||||
If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
|
Если загрузка не начинается после нажатия на кнопку загрузки, пожалуйста, проверьте настройки обозревателя и предоставьте необходимые разрешения на загрузку файлов с <b>gpx.studio</b>.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Settings
|
title: Настройки
|
||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -9,42 +9,42 @@ title: Settings
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" /> Distance units
|
### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" />Единицы измерения расстояния
|
||||||
|
|
||||||
Change the units used to display distances in the interface.
|
Изменение отображаемых единиц измерения расстояния.
|
||||||
|
|
||||||
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Velocity units
|
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" />Единицы измерения скорости
|
||||||
|
|
||||||
Change the units used to display velocities in the interface.
|
Изменение единиц измерения, используемых для отображения скорости.
|
||||||
You can choose between distance per hour or minutes per distance, which can be more suitable for running activities.
|
Вы можете выбрать между отображением расстояния в час или минут, затраченных на преодоление расстояния, что больше подходит для беговых мероприятий.
|
||||||
|
|
||||||
### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> Temperature units
|
### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />Единицы температуры
|
||||||
|
|
||||||
Change the units used to display temperatures in the interface.
|
Изменение единиц, используемых для отображения температуры.
|
||||||
|
|
||||||
### <Languages size="16" class="inline-block" style="margin-bottom: 2px" /> Language
|
### <Languages size="16" class="inline-block" style="margin-bottom: 2px" />Язык
|
||||||
|
|
||||||
Change the language used in the interface.
|
Изменение языка, используемого в интерфейсе.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
Вы можете внести свой вклад, добавив или улучшив переводы в нашем проекте <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin</a>.
|
Вы можете внести свой вклад, добавив или улучшив переводы в нашем проекте <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin</a>.
|
||||||
Если вы хотите начать перевод на новый язык, пожалуйста, <a href="#contact">свяжитесь с</a>.
|
Если Вы хотите начать перевод на новый язык, пожалуйста, <a href="#contact">свяжитесь с нами</a>.
|
||||||
Любая помощь очень ценится!
|
Любая помощь очень ценится!
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Sun size="16" class="inline-block" style="margin-bottom: 2px" /> Theme
|
### <Sun size="16" class="inline-block" style="margin-bottom: 2px" />Тема оформления
|
||||||
|
|
||||||
Change the theme used in the interface.
|
Изменение используемой в интерфейсе темы оформления.
|
||||||
|
|
||||||
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Street view source
|
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" />Источник для уличного вида
|
||||||
|
|
||||||
Change the source used for the [street view control](../map-controls).
|
Изменить источник, используемый для [отображения уличного вида](../map-controls).
|
||||||
The default one is <a href="https://www.mapillary.com" target="_blank">Mapillary</a>, but you can also use <a href="https://www.google.com/streetview/" target="_blank">Google Street View</a>.
|
По умолчанию используется <a href="https://www.mapillary.com" target="_blank">Mapillary</a>, но Вы также можете использовать <a href="https://www.google.com/streetview/" target="_blank">Уличный Вид Гугла</a>.
|
||||||
Learn more about how to use the street view control in the [map controls section](../map-controls).
|
Узнайте больше о том, как использовать управление уличным видом в [разделе управления картой](../map-controls).
|
||||||
|
|
||||||
### <Layers size="16" class="inline-block" style="margin-bottom: 2px" /> Слои карты...
|
### <Layers size="16" class="inline-block" style="margin-bottom: 2px" /> Слои карты...
|
||||||
|
|
||||||
Open a dialog where you can enable or disable map layers, add custom ones, change the opacity of overlays, and more.
|
Открыть диалог, в котором можно включить или отключить слои карт, добавить пользовательские слои, изменить непрозрачность наслоений и многое другое.
|
||||||
More information about map layers can be found in the [map controls section](../map-controls).
|
Более подробную информацию о слоях карт можно найти в разделе [управление картой](../map-controls).
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: View options
|
title: Настройки просмотра
|
||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -9,38 +9,38 @@ title: View options
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
This menu provides options to rearrange the interface and the map view.
|
Это меню позволяет изменить отображение интерфейса и карты.
|
||||||
|
|
||||||
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> Elevation profile
|
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" />Профиль рельефа
|
||||||
|
|
||||||
Hide the elevation profile to make room for the map, or show it to inspect the current selection.
|
Скрыть профиль высоты, чтобы освободить место для карты, либо отобразить его для изучения текущего выделения.
|
||||||
|
|
||||||
### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" /> File tree
|
### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" />Дерево файлов
|
||||||
|
|
||||||
Toggle the tree layout for the [file list](../files-and-stats).
|
Переключить отображение [списка файлов](../files-and-stats) в виде дерева.
|
||||||
Эта раскладка идеально подходит для управления большим количеством открытых файлов, так как она упорядочивает их в вертикальный список справа от карты.
|
Эта раскладка идеально подходит для управления большим количеством открытых файлов, так как она упорядочивает их в вертикальный список справа от карты.
|
||||||
In addition, the file tree view enables you to inspect the [tracks, segments, and points of interest](../gpx) contained inside the files through collapsible sections.
|
Кроме того, древовидное представление файлов даёт Вам возможность исследовать [маршруты, отрезки и интересные точки](../gpx), содержащиеся в файлах через сворачивающиеся разделы.
|
||||||
|
|
||||||
### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> Switch to previous basemap
|
### <Map size="16" class="inline-block" style="margin-bottom: 2px" />Переключиться на предыдущую основную карту
|
||||||
|
|
||||||
Change the basemap to the one previously selected through the [map layer control](../map-controls).
|
Изменить основную карту на ранее выбранную через [управление слоями карты](../map-controls).
|
||||||
|
|
||||||
### <Layers2 size="16" class="inline-block" style="margin-bottom: 2px" /> Toggle overlays
|
### <Layers2 size="16" class="inline-block" style="margin-bottom: 2px" /> Переключение наслоений
|
||||||
|
|
||||||
Toggle the visibility of the map overlays selected through the [map layer control](../map-controls).
|
Переключить видимость наслоений карты, выбранных через [управление слоями карты](../map-controls).
|
||||||
|
|
||||||
### <Coins size="16" class="inline-block" style="margin-bottom: 2px" /> Distance markers
|
### <Coins size="16" class="inline-block" style="margin-bottom: 2px" />Метки расстояния
|
||||||
|
|
||||||
Toggle the visibility of distance markers on the map.
|
Переключить видимость меток расстояния на карте.
|
||||||
They are displayed for the current selection, like the [elevation profile](../files-and-stats).
|
Они отображаются для текущего выделения, так же как и [профиль высоты](../files-and-stats).
|
||||||
|
|
||||||
### <Milestone size="16" class="inline-block" style="margin-bottom: 2px" /> Direction arrows
|
### <Milestone size="16" class="inline-block" style="margin-bottom: 2px" />Стрелки направлений
|
||||||
|
|
||||||
Toggle the visibility of direction arrows on the map.
|
Переключить отображение стрелок направлений на карте.
|
||||||
|
|
||||||
### <Box size="16" class="inline-block" style="margin-bottom: 2px" /> Toggle 3D
|
### <Box size="16" class="inline-block" style="margin-bottom: 2px" /> Переключить 3-мерный вид
|
||||||
|
|
||||||
Enter or exit the 3D map view.
|
Войти или выйти из 3-мерного режима отображения карты.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ Enter or exit the 3D map view.
|
|||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
|
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> На весь экран
|
||||||
|
|
||||||
Enter or exit full screen mode.
|
Вход или выход из полноэкранного режима.
|
||||||
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
|
Вы также можете нажать <kbd>F11</kbd> для переключения или <kbd>Escape</kbd> чтобы выйти.
|
||||||
@@ -13,7 +13,7 @@ title: Планирование и редактирование маршрута
|
|||||||
|
|
||||||
Инструмент для планирования и редактирования маршрутов позволяет создавать и редактировать маршруты, размещая или перемещая точки привязки на карте.
|
Инструмент для планирования и редактирования маршрутов позволяет создавать и редактировать маршруты, размещая или перемещая точки привязки на карте.
|
||||||
|
|
||||||
## Settings
|
## Настройки
|
||||||
|
|
||||||
Как показано ниже, диалоговое окно инструмента содержит несколько настроек для управления поведением маршрутизации.
|
Как показано ниже, диалоговое окно инструмента содержит несколько настроек для управления поведением маршрутизации.
|
||||||
Вы можете минимизировать диалоговое окно для сохранения места, нажав <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>.
|
Вы можете минимизировать диалоговое окно для сохранения места, нажав <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>.
|
||||||
@@ -71,7 +71,7 @@ title: Планирование и редактирование маршрута
|
|||||||
|
|
||||||
Изменить направление маршрута на противоположное.
|
Изменить направление маршрута на противоположное.
|
||||||
|
|
||||||
### <House size="16" class="inline-block" style="margin-bottom: 2px" /> Back to start
|
### <House size="16" class="inline-block" style="margin-bottom: 2px" /> Вернуться в начало
|
||||||
|
|
||||||
Подсоедините последнюю точку маршрута к начальной точке, используя выбранные параметры маршрутизации.
|
Подсоедините последнюю точку маршрута к начальной точке, используя выбранные параметры маршрутизации.
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ title: 檔案和統計
|
|||||||
|
|
||||||
Once you have [opened](./menu/file) files, they will be shown as tabs in the file list located at the bottom of the map.
|
Once you have [opened](./menu/file) files, they will be shown as tabs in the file list located at the bottom of the map.
|
||||||
You can reorder them by dragging and dropping the tabs.
|
You can reorder them by dragging and dropping the tabs.
|
||||||
And when many files are open, you can scroll through the list of tabs to navigate between them.
|
當開啟的檔案較多時,也可以捲動分頁清單,在不同檔案之間切換。
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ title: 設定
|
|||||||
|
|
||||||
### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" /> 距離單位
|
### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" /> 距離單位
|
||||||
|
|
||||||
Change the units used to display distances in the interface.
|
變更介面中顯示距離時所使用的單位。
|
||||||
|
|
||||||
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Velocity units
|
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Velocity units
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: View options
|
title: 檢視選項
|
||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -9,38 +9,38 @@ title: View options
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
This menu provides options to rearrange the interface and the map view.
|
此選單提供重新排列介面與地圖檢視方式的選項。
|
||||||
|
|
||||||
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> Elevation profile
|
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> 高度剖面圖
|
||||||
|
|
||||||
Hide the elevation profile to make room for the map, or show it to inspect the current selection.
|
隱藏高度剖面圖以騰出更多地圖空間,或顯示高度剖面圖以查看目前的選取內容。
|
||||||
|
|
||||||
### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" /> File tree
|
### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" /> 檔案樹狀結構
|
||||||
|
|
||||||
Toggle the tree layout for the [file list](../files-and-stats).
|
切換[檔案清單](../files-and-stats)的樹狀版面配置。
|
||||||
This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map.
|
This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map.
|
||||||
In addition, the file tree view enables you to inspect the [tracks, segments, and points of interest](../gpx) contained inside the files through collapsible sections.
|
此外,檔案樹狀檢視可讓你透過可收合的區段,查看檔案中包含的[軌跡、區段和興趣點](../gpx)。
|
||||||
|
|
||||||
### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> Switch to previous basemap
|
### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> 切換至上一個底圖
|
||||||
|
|
||||||
Change the basemap to the one previously selected through the [map layer control](../map-controls).
|
將底圖變更為先前透過[地圖圖層控制項](../map-controls)選取的底圖。
|
||||||
|
|
||||||
### <Layers2 size="16" class="inline-block" style="margin-bottom: 2px" /> Toggle overlays
|
### <Layers2 size="16" class="inline-block" style="margin-bottom: 2px" /> 切換疊加圖層
|
||||||
|
|
||||||
Toggle the visibility of the map overlays selected through the [map layer control](../map-controls).
|
切換透過[地圖圖層控制項](../map-controls)選取之地圖疊加圖層的顯示狀態。
|
||||||
|
|
||||||
### <Coins size="16" class="inline-block" style="margin-bottom: 2px" /> Distance markers
|
### <Coins size="16" class="inline-block" style="margin-bottom: 2px" /> 距離標記
|
||||||
|
|
||||||
Toggle the visibility of distance markers on the map.
|
切換地圖上距離標記的顯示狀態。
|
||||||
They are displayed for the current selection, like the [elevation profile](../files-and-stats).
|
距離標記會針對目前的選取內容顯示,就像[高度剖面圖](../files-and-stats)一樣。
|
||||||
|
|
||||||
### <Milestone size="16" class="inline-block" style="margin-bottom: 2px" /> Direction arrows
|
### <Milestone size="16" class="inline-block" style="margin-bottom: 2px" /> 方向箭頭
|
||||||
|
|
||||||
Toggle the visibility of direction arrows on the map.
|
切換地圖上方向箭頭的顯示狀態。
|
||||||
|
|
||||||
### <Box size="16" class="inline-block" style="margin-bottom: 2px" /> Toggle 3D
|
### <Box size="16" class="inline-block" style="margin-bottom: 2px" /> 切換 3D
|
||||||
|
|
||||||
Enter or exit the 3D map view.
|
進入或離開 3D 地圖檢視。
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ To control the orientation and tilt of the map, you can also drag the map while
|
|||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
|
||||||
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
|
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> 全螢幕
|
||||||
|
|
||||||
Enter or exit full screen mode.
|
進入或離開全螢幕模式。
|
||||||
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
|
你也可以按下 <kbd>F11</kbd> 來切換,或按下 <kbd>Escape</kbd> 離開。
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { selection } from '$lib/logic/selection';
|
import { selection } from '$lib/logic/selection';
|
||||||
import { LngLatBounds } from 'maplibre-gl';
|
import maplibregl from 'maplibre-gl';
|
||||||
import { ListFileItem, ListWaypointItem } from '$lib/components/file-list/file-list';
|
import { ListFileItem, ListWaypointItem } from '$lib/components/file-list/file-list';
|
||||||
import { fileStateCollection, GPXFileStateCollectionObserver } from '$lib/logic/file-state';
|
import { fileStateCollection, GPXFileStateCollectionObserver } from '$lib/logic/file-state';
|
||||||
import { gpxStatistics } from '$lib/logic/statistics';
|
import { gpxStatistics } from '$lib/logic/statistics';
|
||||||
@@ -10,7 +10,7 @@ import type { Coordinates } from 'gpx';
|
|||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
export class BoundsManager {
|
export class BoundsManager {
|
||||||
private _bounds: LngLatBounds = new LngLatBounds();
|
private _bounds: maplibregl.LngLatBounds = new maplibregl.LngLatBounds();
|
||||||
private _files: Set<string> = new Set();
|
private _files: Set<string> = new Set();
|
||||||
private _fileStateCollectionObserver: GPXFileStateCollectionObserver | null = null;
|
private _fileStateCollectionObserver: GPXFileStateCollectionObserver | null = null;
|
||||||
private _unsubscribes: (() => void)[] = [];
|
private _unsubscribes: (() => void)[] = [];
|
||||||
@@ -87,12 +87,12 @@ export class BoundsManager {
|
|||||||
}
|
}
|
||||||
this._unsubscribes.forEach((unsubscribe) => unsubscribe());
|
this._unsubscribes.forEach((unsubscribe) => unsubscribe());
|
||||||
this._unsubscribes = [];
|
this._unsubscribes = [];
|
||||||
this._bounds = new LngLatBounds([180, 90, -180, -90]);
|
this._bounds = new maplibregl.LngLatBounds([180, 90, -180, -90]);
|
||||||
}
|
}
|
||||||
|
|
||||||
centerMapOnSelection() {
|
centerMapOnSelection() {
|
||||||
let selected = get(selection).getSelected();
|
let selected = get(selection).getSelected();
|
||||||
let bounds = new LngLatBounds();
|
let bounds = new maplibregl.LngLatBounds();
|
||||||
|
|
||||||
if (selected.find((item) => item instanceof ListWaypointItem)) {
|
if (selected.find((item) => item instanceof ListWaypointItem)) {
|
||||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { ListItem, ListLevel } from '$lib/components/file-list/file-list';
|
import { ListItem, ListLevel } from '$lib/components/file-list/file-list';
|
||||||
import { GPXFile, GPXStatistics, GPXStatisticsGroup, type Track } from 'gpx';
|
import { GPXFile, GPXStatistics, GPXStatisticsGroup, type Track } from 'gpx';
|
||||||
import { LngLatBounds } from 'maplibre-gl';
|
import maplibregl from 'maplibre-gl';
|
||||||
|
|
||||||
export class GPXStatisticsTree {
|
export class GPXStatisticsTree {
|
||||||
level: ListLevel;
|
level: ListLevel;
|
||||||
statistics: {
|
statistics: {
|
||||||
[key: string]: GPXStatisticsTree | GPXStatistics;
|
[key: string]: GPXStatisticsTree | GPXStatistics;
|
||||||
} = {};
|
} = {};
|
||||||
wptBounds: LngLatBounds;
|
wptBounds: maplibregl.LngLatBounds;
|
||||||
|
|
||||||
constructor(element: GPXFile | Track) {
|
constructor(element: GPXFile | Track) {
|
||||||
this.wptBounds = new LngLatBounds();
|
this.wptBounds = new maplibregl.LngLatBounds();
|
||||||
if (element instanceof GPXFile) {
|
if (element instanceof GPXFile) {
|
||||||
this.level = ListLevel.FILE;
|
this.level = ListLevel.FILE;
|
||||||
element.children.forEach((child, index) => {
|
element.children.forEach((child, index) => {
|
||||||
@@ -49,11 +49,11 @@ export class GPXStatisticsTree {
|
|||||||
return statistics;
|
return statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
intersectsBBox(bounds: LngLatBounds): boolean {
|
intersectsBBox(bounds: maplibregl.LngLatBounds): boolean {
|
||||||
for (let key in this.statistics) {
|
for (let key in this.statistics) {
|
||||||
const stats = this.statistics[key];
|
const stats = this.statistics[key];
|
||||||
if (stats instanceof GPXStatistics) {
|
if (stats instanceof GPXStatistics) {
|
||||||
const bbox = new LngLatBounds(
|
const bbox = new maplibregl.LngLatBounds(
|
||||||
stats.global.bounds.southWest,
|
stats.global.bounds.southWest,
|
||||||
stats.global.bounds.northEast
|
stats.global.bounds.northEast
|
||||||
);
|
);
|
||||||
@@ -67,7 +67,7 @@ export class GPXStatisticsTree {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
intersectsWaypointBBox(bounds: LngLatBounds): boolean {
|
intersectsWaypointBBox(bounds: maplibregl.LngLatBounds): boolean {
|
||||||
return !this.wptBounds.isEmpty() && this.wptBounds.intersects(bounds);
|
return !this.wptBounds.isEmpty() && this.wptBounds.intersects(bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { twMerge } from 'tailwind-merge';
|
|||||||
import { base } from '$app/paths';
|
import { base } from '$app/paths';
|
||||||
import { languages } from '$lib/languages';
|
import { languages } from '$lib/languages';
|
||||||
import { TrackPoint, Waypoint, type Coordinates, crossarcDistance, distance, GPXFile } from 'gpx';
|
import { TrackPoint, Waypoint, type Coordinates, crossarcDistance, distance, GPXFile } from 'gpx';
|
||||||
import { Map as MapLibreMap, LngLatBounds } from 'maplibre-gl';
|
import maplibregl from 'maplibre-gl';
|
||||||
import { pointToTile, pointToTileFraction } from '@mapbox/tilebelt';
|
import { pointToTile, pointToTileFraction } from '@mapbox/tilebelt';
|
||||||
import type { GPXStatisticsTree } from '$lib/logic/statistics-tree';
|
import type { GPXStatisticsTree } from '$lib/logic/statistics-tree';
|
||||||
import { ListTrackSegmentItem } from '$lib/components/file-list/file-list';
|
import { ListTrackSegmentItem } from '$lib/components/file-list/file-list';
|
||||||
@@ -58,7 +58,7 @@ export function getClosestTrackSegments(
|
|||||||
let segmentBounds = segmentStatistics.global.bounds;
|
let segmentBounds = segmentStatistics.global.bounds;
|
||||||
let northEast = segmentBounds.northEast;
|
let northEast = segmentBounds.northEast;
|
||||||
let southWest = segmentBounds.southWest;
|
let southWest = segmentBounds.southWest;
|
||||||
let bounds = new LngLatBounds(southWest, northEast);
|
let bounds = new maplibregl.LngLatBounds(southWest, northEast);
|
||||||
if (bounds.contains(point)) {
|
if (bounds.contains(point)) {
|
||||||
segmentBoundsDistances.push([0, trackIndex, segmentIndex]);
|
segmentBoundsDistances.push([0, trackIndex, segmentIndex]);
|
||||||
} else {
|
} else {
|
||||||
@@ -106,7 +106,7 @@ export function getElevation(
|
|||||||
let coordinates = points.map((point) =>
|
let coordinates = points.map((point) =>
|
||||||
point instanceof TrackPoint || point instanceof Waypoint ? point.getCoordinates() : point
|
point instanceof TrackPoint || point instanceof Waypoint ? point.getCoordinates() : point
|
||||||
);
|
);
|
||||||
let bbox = new LngLatBounds();
|
let bbox = new maplibregl.LngLatBounds();
|
||||||
coordinates.forEach((coord) => bbox.extend(coord));
|
coordinates.forEach((coord) => bbox.extend(coord));
|
||||||
|
|
||||||
let tiles = coordinates.map((coord) => pointToTile(coord.lon, coord.lat, ELEVATION_ZOOM));
|
let tiles = coordinates.map((coord) => pointToTile(coord.lon, coord.lat, ELEVATION_ZOOM));
|
||||||
@@ -193,7 +193,7 @@ export function getElevation(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadSVGIcon(map: MapLibreMap, id: string, svg: string, size: number = 100) {
|
export function loadSVGIcon(map: maplibregl.Map, id: string, svg: string, size: number = 100) {
|
||||||
if (!map.hasImage(id)) {
|
if (!map.hasImage(id)) {
|
||||||
let icon = new Image(size, size);
|
let icon = new Image(size, size);
|
||||||
icon.onload = () => {
|
icon.onload = () => {
|
||||||
|
|||||||
@@ -163,7 +163,7 @@
|
|||||||
"path": "Sendero",
|
"path": "Sendero",
|
||||||
"pedestrian": "Peatonal",
|
"pedestrian": "Peatonal",
|
||||||
"cycleway": "Ciclovía",
|
"cycleway": "Ciclovía",
|
||||||
"steps": "Escalones",
|
"steps": "Pasos",
|
||||||
"road": "Carretera",
|
"road": "Carretera",
|
||||||
"bridleway": "Ruta ecuestre",
|
"bridleway": "Ruta ecuestre",
|
||||||
"platform": "Plataforma",
|
"platform": "Plataforma",
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
"extract": {
|
"extract": {
|
||||||
"tooltip": "Extraer contenidos en elementos separados",
|
"tooltip": "Extraer contenidos en elementos separados",
|
||||||
"button": "Extraer",
|
"button": "Extraer",
|
||||||
"help": "Al extraer los contenidos de los elementos seleccionados creará un elemento separado para cada uno.",
|
"help": "La extracción del contenido de los elementos seleccionados creará un elemento separado para cada uno de sus contenidos.",
|
||||||
"help_invalid_selection": "Su selección debe contener elementos con múltiples trazas para extraerlos."
|
"help_invalid_selection": "Su selección debe contener elementos con múltiples trazas para extraerlos."
|
||||||
},
|
},
|
||||||
"elevation": {
|
"elevation": {
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"home_title": "az online GPX szerkesztő",
|
"home_title": "az online GPX szerkesztő",
|
||||||
"app_title": "app",
|
"app_title": "app",
|
||||||
"embed_title": "online útvonal (GPX fájl) szerkesztő",
|
"embed_title": "az online GPX szerkesztő",
|
||||||
"help_title": "súgó",
|
"help_title": "súgó",
|
||||||
"404_title": "oldal nem található",
|
"404_title": "oldal nem található",
|
||||||
"description": "GPX fájlok online szerkesztése és létrehozása fejlett útvonal tervezési képességekkel és fájlfeldolgozó eszközökkel, gyönyörű térképekkel és részletekkel."
|
"description": "GPX fájlok online megtekintése, szerkesztése és létrehozása fejlett útvonal tervezési képességekkel és fájlfeldolgozó eszközökkel, gyönyörű térképekkel és részletes adatmegjelenítésekkel."
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"new": "Új.",
|
"new": "Új",
|
||||||
"new_file": "Új fájl ",
|
"new_file": "Új fájl ",
|
||||||
"new_track": "Új útvonal",
|
"new_track": "Új útvonal",
|
||||||
"new_segment": "Új szakasz",
|
"new_segment": "Új szakasz",
|
||||||
@@ -504,7 +504,7 @@
|
|||||||
"data_visualization": "Adatvizualizáció",
|
"data_visualization": "Adatvizualizáció",
|
||||||
"data_visualization_description": "Interaktív magassági profil részletes statisztikákkal a rögzített tevékenységek és a jövőbeni célok elemzéséhez.",
|
"data_visualization_description": "Interaktív magassági profil részletes statisztikákkal a rögzített tevékenységek és a jövőbeni célok elemzéséhez.",
|
||||||
"philosophy": "Philosophy",
|
"philosophy": "Philosophy",
|
||||||
"foss": "Free, ad-free and open source",
|
"foss": "Ingyenes, reklámmentes és nyílt forráskódú",
|
||||||
"foss_description": "The website is free to use, without ads, and the source code is publicly available on GitHub.",
|
"foss_description": "The website is free to use, without ads, and the source code is publicly available on GitHub.",
|
||||||
"privacy": "Privacy-friendly",
|
"privacy": "Privacy-friendly",
|
||||||
"privacy_description": "Your GPX files never leave your browser. No tracking, no data collection.",
|
"privacy_description": "Your GPX files never leave your browser. No tracking, no data collection.",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"export": "Exporteren...",
|
"export": "Exporteren...",
|
||||||
"export_all": "Alles exporteren...",
|
"export_all": "Alles exporteren...",
|
||||||
"export_options": "Exporteer instellingen",
|
"export_options": "Exporteer instellingen",
|
||||||
"support_message": "Het gereedschap is gratis te gebruiken, maar is niet gratis om te onderhouden. Overweeg om de website te ondersteunen als je hem vaak gebruikt. Bedankt!",
|
"support_message": "De tool is gratis te gebruiken, maar is niet gratis om te onderhouden. Overweeg om de website te ondersteunen als je hem vaak gebruikt. Bedankt!",
|
||||||
"support_button": "Help de website gratis te houden",
|
"support_button": "Help de website gratis te houden",
|
||||||
"download_file": "Bestand downloaden",
|
"download_file": "Bestand downloaden",
|
||||||
"download_files": "Bestanden downloaden",
|
"download_files": "Bestanden downloaden",
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
"ctrl": "Ctrl",
|
"ctrl": "Ctrl",
|
||||||
"click": "Clique",
|
"click": "Clique",
|
||||||
"drag": "Arrastar",
|
"drag": "Arrastar",
|
||||||
"right_click_drag": "Right-click drag",
|
"right_click_drag": "Clique direito arraste",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"button": "Informações...",
|
"button": "Informações...",
|
||||||
"name": "Nome",
|
"name": "Nome",
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
},
|
},
|
||||||
"sac_scale": {
|
"sac_scale": {
|
||||||
"hiking": "Caminhada",
|
"hiking": "Caminhada",
|
||||||
"mountain_hiking": "Mountain hiking",
|
"mountain_hiking": "",
|
||||||
"demanding_mountain_hiking": "Demanding mountain hiking",
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
"alpine_hiking": "Alpine hiking",
|
"alpine_hiking": "Alpine hiking",
|
||||||
"demanding_alpine_hiking": "Demanding alpine hiking",
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
@@ -222,8 +222,8 @@
|
|||||||
"remove_gaps": "Remove time gaps between traces",
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "A sua seleção deve conter vários traços para conectá-los.",
|
||||||
"help_merge_contents": "Merging the contents of the selected items will group all the contents inside the first item.",
|
"help_merge_contents": "Fundir o conteúdo dos itens selecionados agrupará todo o conteúdo no“item”.",
|
||||||
"help_cannot_merge_contents": "Your selection must contain several items to merge their contents.",
|
"help_cannot_merge_contents": "Your selection must contain several items to merge their contents.",
|
||||||
"selection_tip": "Tip: use {KEYBOARD_SHORTCUT} to add items to the selection."
|
"selection_tip": "Tip: use {KEYBOARD_SHORTCUT} to add items to the selection."
|
||||||
},
|
},
|
||||||
@@ -239,14 +239,14 @@
|
|||||||
"help_no_selection": "Select a file item to request elevation data."
|
"help_no_selection": "Select a file item to request elevation data."
|
||||||
},
|
},
|
||||||
"waypoint": {
|
"waypoint": {
|
||||||
"tooltip": "Create and edit points of interest",
|
"tooltip": "Criar ponto de interesse",
|
||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
"link": "Link",
|
"link": "Ligação",
|
||||||
"longitude": "Longitude",
|
"longitude": "Longitude",
|
||||||
"latitude": "Latitude",
|
"latitude": "Latitude",
|
||||||
"create": "Criar ponto de interesse",
|
"create": "Criar ponto de interesse",
|
||||||
"add": "Adicionar ponto de interesse no ficheiro",
|
"add": "Adicionar ponto de interesse no ficheiro",
|
||||||
"help": "Fill in the form to create a new point of interest, or click on an existing one to edit it. Click on the map to fill the coordinates, or drag points of interest to move them.",
|
"help": "Preencha o formulário para criar um ponto de interesse, ou clique em um já existente para editá-lo. Clique no mapa para preencher as coordenadas ou arraste pontos de interesse para movê-las.",
|
||||||
"help_no_selection": "Select a file to create or edit points of interest."
|
"help_no_selection": "Select a file to create or edit points of interest."
|
||||||
},
|
},
|
||||||
"reduce": {
|
"reduce": {
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
"help_no_selection": "Select a trace to reduce the number of its GPS points."
|
"help_no_selection": "Select a trace to reduce the number of its GPS points."
|
||||||
},
|
},
|
||||||
"clean": {
|
"clean": {
|
||||||
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
|
"tooltip": "Limpar pontos de GPS e pontos de interesse com uma seleção de retângulo",
|
||||||
"delete_trackpoints": "Excluir pontos GPS",
|
"delete_trackpoints": "Excluir pontos GPS",
|
||||||
"delete_waypoints": "Excluir pontos de interesse",
|
"delete_waypoints": "Excluir pontos de interesse",
|
||||||
"delete_inside": "Excluir na seleção",
|
"delete_inside": "Excluir na seleção",
|
||||||
@@ -552,7 +552,7 @@
|
|||||||
"pitch": "Pitch",
|
"pitch": "Pitch",
|
||||||
"bearing": "Bearing",
|
"bearing": "Bearing",
|
||||||
"preview": "Prévia",
|
"preview": "Prévia",
|
||||||
"code": "Integration code"
|
"code": "Código de integração"
|
||||||
},
|
},
|
||||||
"webgl2_required": "WebGL 2 é requerido para exibir o mapa.",
|
"webgl2_required": "WebGL 2 é requerido para exibir o mapa.",
|
||||||
"enable_webgl2": "Aprender como ativar WebGL 2 no seu navegador",
|
"enable_webgl2": "Aprender como ativar WebGL 2 no seu navegador",
|
||||||
|
|||||||
Reference in new issue
Block a user