38 Commits

Author SHA1 Message Date
vcoppe 6a0d434371 Merge branch 'dev' 2026-07-24 19:07:00 +02:00
vcoppe b319440a57 upgrade to maplibre v6 2026-07-24 19:06:39 +02:00
vcoppe b0d78b5f3c Merge branch 'dev' 2026-07-21 12:30:07 +02:00
vcoppe 2e8b2d6f30 add ukrainian 2026-07-21 11:20:31 +02:00
Dobrovolskyi Bohdan 5259d007c9 Fix Locale subscription (#369) 2026-07-21 12:04:42 +02:00
vcoppe cb36725a46 New Crowdin updates (#373)
* New translations en.json (German)

[ci skip]

* New translations view.mdx (German)

[ci skip]
2026-07-21 12:00:16 +02:00
vcoppe deef1bab47 fix embedding playground zoom 2026-07-21 11:11:13 +02:00
Dobrovolskyi Bohdan 108880f8cd Update language on map (#365) 2026-07-14 18:50:51 +02:00
vcoppe 37a659831b New Crowdin updates (#359)
* New translations en.json (Hungarian)

[ci skip]

* New translations en.json (Hungarian)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations file.mdx (Ukrainian)

[ci skip]

* New translations file.mdx (Ukrainian)

[ci skip]

* New translations settings.mdx (Ukrainian)

[ci skip]

* New translations view.mdx (Ukrainian)

[ci skip]

* New translations clean.mdx (Ukrainian)

[ci skip]

* New translations routing.mdx (Ukrainian)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations clean.mdx (Ukrainian)

[ci skip]

* New translations routing.mdx (Ukrainian)

[ci skip]

* New translations extract.mdx (Ukrainian)

[ci skip]

* New translations merge.mdx (Ukrainian)

[ci skip]

* New translations minify.mdx (Ukrainian)

[ci skip]

* New translations poi.mdx (Ukrainian)

[ci skip]

* New translations elevation.mdx (Ukrainian)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations routing.mdx (Ukrainian)

[ci skip]

* New translations scissors.mdx (Ukrainian)

[ci skip]

* New translations time.mdx (Ukrainian)

[ci skip]

* New translations faq.mdx (Ukrainian)

[ci skip]

* New translations en.json (Ukrainian)

[ci skip]

* New translations view.mdx (Ukrainian)

[ci skip]

* New translations faq.mdx (Ukrainian)

[ci skip]

* New translations files-and-stats.mdx (Ukrainian)

[ci skip]

* New translations getting-started.mdx (Ukrainian)

[ci skip]

* New translations gpx.mdx (Ukrainian)

[ci skip]

* New translations integration.mdx (Ukrainian)

[ci skip]

* New translations map-controls.mdx (Ukrainian)

[ci skip]

* New translations menu.mdx (Ukrainian)

[ci skip]

* New translations toolbar.mdx (Ukrainian)

[ci skip]

* New translations en.json (Basque)

[ci skip]
2026-07-14 18:49:25 +02:00
vcoppe fde6bafc10 Merge branch 'dev' 2026-06-18 23:07:43 +02:00
vcoppe 86f4fc3394 New Crowdin updates (#355)
* New translations map-controls.mdx (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations elevation.mdx (Chinese Simplified)

[ci skip]

* New translations settings.mdx (Dutch)

[ci skip]

* New translations en.json (Romanian)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations settings.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations routing.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations faq.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations edit.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Traditional, Hong Kong)

[ci skip]

* New translations edit.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations edit.mdx (Chinese Simplified)

[ci skip]

* New translations files-and-stats.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations getting-started.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations file.mdx (Chinese Traditional, Hong Kong)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]

* New translations en.json (Chinese Simplified)

[ci skip]
2026-06-18 23:07:16 +02:00
vcoppe 565589fc94 improve railway station query 2026-06-18 23:06:38 +02:00
vcoppe 4ef92e5abd update readme 2026-06-06 16:43:38 +02:00
vcoppe 4537ea4730 Merge branch 'dev' 2026-06-03 19:05:25 +02:00
vcoppe 7f8751fa38 turn wikipedia tags into links, closes #354 2026-06-03 19:05:15 +02:00
vcoppe 1954bbd764 Merge branch 'dev' 2026-06-03 18:48:43 +02:00
vcoppe befcba00b4 hopefully more reliable initial fitBounds 2026-06-03 18:48:07 +02:00
vcoppe 9d2da80893 Merge branch 'dev' 2026-05-31 15:26:17 +02:00
vcoppe 043d368c74 Merge branch 'dev' 2026-05-29 08:37:39 +02:00
vcoppe bb11d3375b Merge branch 'dev' 2026-05-28 19:29:34 +02:00
vcoppe bfe5961e27 Merge branch 'dev' 2026-05-21 20:27:41 +02:00
vcoppe 17559913fd Merge branch 'dev' 2026-04-19 16:49:41 +02:00
vcoppe 55590d68a6 Merge branch 'dev' 2026-04-19 16:34:17 +02:00
vcoppe 8e9f16c460 Merge branch 'dev' 2026-04-19 14:47:35 +02:00
vcoppe c60b64f24f Merge branch 'dev' 2026-04-17 22:10:40 +02:00
vcoppe fdb6fe4e52 Merge branch 'dev' 2026-04-17 20:11:25 +02:00
vcoppe 0bf168e67e Merge branch 'dev' 2026-04-09 21:10:56 +02:00
vcoppe d762a45eb9 Merge branch 'dev' 2026-04-09 20:57:30 +02:00
vcoppe 548ab9a459 Merge branch 'dev' 2026-04-07 22:19:15 +02:00
vcoppe 315c1f6a61 Merge branch 'dev' 2026-04-07 22:02:14 +02:00
vcoppe 98257bee12 Merge branch 'dev' 2026-04-06 18:26:22 +02:00
vcoppe 5561b7d9fe Merge branch 'dev' 2026-04-06 14:26:56 +02:00
vcoppe 320887206c Merge branch 'dev' 2026-04-04 23:15:01 +02:00
vcoppe 04a1bf6a55 Merge branch 'dev' 2026-04-03 08:47:57 +02:00
vcoppe 0989371874 Merge branch 'dev' 2026-04-03 08:06:19 +02:00
vcoppe 3dcd6e52d3 Merge branch 'dev' 2026-04-02 22:35:46 +02:00
vcoppe 0f06d0d461 update 2026-04-02 22:23:34 +02:00
vcoppe db33310a10 revert some changes 2026-04-02 22:20:47 +02:00
68 changed files with 1108 additions and 1073 deletions
+3 -2
View File
@@ -70,8 +70,9 @@ This project has been made possible thanks to the following open source projects
- [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree
- Mapping:
- [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) — beautiful and fast interactive map rendering
- [GraphHopper](https://github.com/graphhopper/graphhopper) — routing engine
- [OpenStreetMap](https://www.openstreetmap.org) — map data used by most of the map layers, and by the routing engine
- [GraphHopper](https://github.com/graphhopper/graphhopper) — powerful routing engine
- [OpenStreetMap](https://www.openstreetmap.org) — open map data used by most of the map layers, and by the routing engine
- [Mapterhorn](https://github.com/mapterhorn/mapterhorn) — high-quality open terrain data used by some map layers (including for 3D), and by the routing engine
- Search:
- [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation
+70 -67
View File
@@ -20,7 +20,7 @@
"immer": "^10.1.1",
"jszip": "^3.10.1",
"mapillary-js": "^4.1.2",
"maplibre-gl": "^5.21.1",
"maplibre-gl": "^6.0.0",
"sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6"
},
@@ -3236,13 +3236,18 @@
}
},
"node_modules/@mapbox/jsonlint-lines-primitives": {
"version": "2.0.2",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.3.tgz",
"integrity": "sha512-0SElaV0uMxEnxzBhhX9WTuPyUeMsAN/SS0i16tjuba4/mio63MG9khjC1a0JAiPGXAwvwm4UfHJURCN7nyudQg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
"node": ">= 22"
}
},
"node_modules/@mapbox/point-geometry": {
"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"
},
"node_modules/@mapbox/sphericalmercator": {
@@ -3253,24 +3258,32 @@
"license": "MIT"
},
"node_modules/@mapbox/tiny-sdf": {
"version": "2.0.7",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.2.0.tgz",
"integrity": "sha512-LVL4wgI9YAum5V+LNVQO6QgFBPw7/MIIY4XJPNsPDMrjEwcE+JfKk1LuIl8GnF197ejVdC9QdPaxrx5gfgdGXg==",
"license": "BSD-2-Clause"
},
"node_modules/@mapbox/unitbezier": {
"version": "0.0.1",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-1.0.0.tgz",
"integrity": "sha512-fqd515fjBmANKGGsQ286E2Wvj/XvDFpGzwJxq4CI6jMQue6Oy04uCKp+JWKF00xRTmk6cEu1jPJ9p3xqH8YWqQ==",
"license": "BSD-2-Clause"
},
"node_modules/@mapbox/vector-tile": {
"version": "2.0.4",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-3.0.0.tgz",
"integrity": "sha512-Qf10S1uIHMk20ri/IVBnpS+esUEkVaR5Hftmz88jTInrpmWgPGJfPe3LVjjlE77trLx8tH6qjTG7uWH9hIq/0Q==",
"license": "BSD-3-Clause",
"dependencies": {
"@mapbox/point-geometry": "~1.1.0",
"@types/geojson": "^7946.0.16",
"pbf": "^4.0.1"
"pbf": "^5.0.0"
}
},
"node_modules/@mapbox/vector-tile/node_modules/pbf": {
"version": "4.0.1",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
@@ -3279,18 +3292,13 @@
"pbf": "bin/pbf"
}
},
"node_modules/@mapbox/whoots-js": {
"version": "3.1.0",
"license": "ISC",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@maplibre/geojson-vt": {
"version": "6.0.4",
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.1.1.tgz",
"integrity": "sha512-FVMOcmSP/yqol45t7StApEyTL5/vmqBCuFhH9n+fFuINenhaX+YgHHIt1yJ86S8kln3uJLcMvmEU2cfn6E2eCQ==",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
"kdbush": "^4.1.0"
}
},
"node_modules/@maplibre/maplibre-gl-geocoder": {
@@ -3311,15 +3319,16 @@
}
},
"node_modules/@maplibre/maplibre-gl-style-spec": {
"version": "24.8.1",
"version": "26.2.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",
"dependencies": {
"@mapbox/jsonlint-lines-primitives": "~2.0.2",
"@mapbox/unitbezier": "^0.0.1",
"@mapbox/jsonlint-lines-primitives": "^2.0.3",
"@mapbox/unitbezier": "^1.0.0",
"json-stringify-pretty-compact": "^4.0.0",
"minimist": "^1.2.8",
"quickselect": "^3.0.0",
"rw": "^1.3.3",
"tinyqueue": "^3.0.0"
},
"bin": {
@@ -3329,31 +3338,29 @@
}
},
"node_modules/@maplibre/mlt": {
"version": "1.1.8",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.12.tgz",
"integrity": "sha512-ZeK5w2TTeHOajcLaEQs1KZXw2V9wIKo1PmThlxlsHoXsQsYlBqLJzPOd6tJHRtGTChUY3DPPmjXRArYVvAbmZw==",
"license": "(MIT OR Apache-2.0)",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0"
}
},
"node_modules/@maplibre/vt-pbf": {
"version": "4.3.0",
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.3.2.tgz",
"integrity": "sha512-j6p0AdjvAR19Z3XaCysle7A4ZSo08tYOzxD0Y9NQylwPAkwJJeYub5b2eVucdeDh7erhv69DahoLOevDRERRUw==",
"license": "MIT",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0",
"@mapbox/vector-tile": "^2.0.4",
"@maplibre/geojson-vt": "^5.0.4",
"@types/geojson": "^7946.0.16",
"@types/supercluster": "^7.1.3",
"pbf": "^4.0.1",
"supercluster": "^8.0.1"
"pbf": "^5.1.0"
}
},
"node_modules/@maplibre/vt-pbf/node_modules/@maplibre/geojson-vt": {
"version": "5.0.4",
"license": "ISC"
},
"node_modules/@maplibre/vt-pbf/node_modules/pbf": {
"version": "4.0.1",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
@@ -4289,13 +4296,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/supercluster": {
"version": "7.1.3",
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/three": {
"version": "0.134.0",
"license": "MIT"
@@ -5720,6 +5720,8 @@
},
"node_modules/json-stringify-pretty-compact": {
"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"
},
"node_modules/jszip": {
@@ -5733,7 +5735,9 @@
}
},
"node_modules/kdbush": {
"version": "4.0.2",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.1.0.tgz",
"integrity": "sha512-e9vurzrXJQrFX6ckpHP3bvj5l+9CnYzkxDNnNQ1h2QTqdWsUAJgXiKdGNcOa1EY85dU8KbQ+z/FdQdB7P+9yfQ==",
"license": "ISC"
},
"node_modules/keyv": {
@@ -6154,25 +6158,25 @@
"license": "(MIT AND Zlib)"
},
"node_modules/maplibre-gl": {
"version": "5.22.0",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-6.0.0.tgz",
"integrity": "sha512-1wBgEhzTZfA+cDpFdt0fM1mJA5mJ90fifORJ7D8JcKLJCvPT/iTx9bNxkP7DqEYde65DJd7gE7h83khwNRqdyg==",
"license": "BSD-3-Clause",
"dependencies": {
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
"@mapbox/point-geometry": "^1.1.0",
"@mapbox/tiny-sdf": "^2.0.7",
"@mapbox/unitbezier": "^0.0.1",
"@mapbox/vector-tile": "^2.0.4",
"@mapbox/whoots-js": "^3.1.0",
"@maplibre/geojson-vt": "^6.0.4",
"@maplibre/maplibre-gl-style-spec": "^24.8.1",
"@maplibre/mlt": "^1.1.8",
"@maplibre/vt-pbf": "^4.3.0",
"@mapbox/tiny-sdf": "^2.2.0",
"@mapbox/unitbezier": "^1.0.0",
"@mapbox/vector-tile": "^3.0.0",
"@maplibre/geojson-vt": "^6.1.1",
"@maplibre/maplibre-gl-style-spec": "^26.1.0",
"@maplibre/mlt": "^1.1.12",
"@maplibre/vt-pbf": "^4.3.2",
"@types/geojson": "^7946.0.16",
"earcut": "^3.0.2",
"earcut": "^3.2.3",
"gl-matrix": "^3.4.4",
"kdbush": "^4.0.2",
"kdbush": "^4.1.0",
"murmurhash-js": "^1.0.0",
"pbf": "^4.0.1",
"pbf": "^5.1.2",
"potpack": "^2.1.0",
"quickselect": "^3.0.0",
"tinyqueue": "^3.0.0"
@@ -6186,11 +6190,15 @@
}
},
"node_modules/maplibre-gl/node_modules/earcut": {
"version": "3.0.2",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.2.3.tgz",
"integrity": "sha512-vnS4AVwp1KHAF13i1vp1/2D5evWy3k5u/iW/B81QVsUZtV8cv2tU0b2VNFlqvh4kYwrFMDdjPCfAmfyJW9y14Q==",
"license": "ISC"
},
"node_modules/maplibre-gl/node_modules/pbf": {
"version": "4.0.1",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
@@ -6251,6 +6259,8 @@
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -6785,6 +6795,8 @@
},
"node_modules/quickselect": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
"license": "ISC"
},
"node_modules/rbush": {
@@ -6920,10 +6932,6 @@
}
}
},
"node_modules/rw": {
"version": "1.3.3",
"license": "BSD-3-Clause"
},
"node_modules/rxjs": {
"version": "7.8.2",
"license": "Apache-2.0",
@@ -7157,13 +7165,6 @@
"xtend": "^4.0.0"
}
},
"node_modules/supercluster": {
"version": "8.0.1",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7405,6 +7406,8 @@
},
"node_modules/tinyqueue": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz",
"integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==",
"license": "ISC"
},
"node_modules/totalist": {
+1 -1
View File
@@ -75,7 +75,7 @@
"immer": "^10.1.1",
"jszip": "^3.10.1",
"mapillary-js": "^4.1.2",
"maplibre-gl": "^5.21.1",
"maplibre-gl": "^6.0.0",
"sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6"
}
+2 -2
View File
@@ -1168,7 +1168,7 @@ export type CustomLayer = {
maxZoom: number;
layerType: 'basemap' | 'overlay';
resourceType: 'raster' | 'vector';
value: string | maplibregl.StyleSpecification;
value: string | StyleSpecification;
};
type OverpassQueryData = {
@@ -1449,7 +1449,7 @@ export const overpassQueryData: Record<string, OverpassQueryData> = {
color: 'DarkBlue',
},
tags: {
railway: 'station',
railway: ['station', 'halt'],
},
symbol: 'Ground Transportation',
},
@@ -21,6 +21,7 @@
import { selection } from '$lib/logic/selection';
import { untrack } from 'svelte';
import { isSelected, toggle } from '$lib/components/map/layer-control/utils';
import { boundsManager } from '$lib/logic/bounds';
let {
useHash = true,
@@ -45,26 +46,6 @@
settings.initialize();
function applyOptions() {
let downloads: Promise<GPXFile | null>[] = getFilesFromEmbeddingOptions(options).map(
(url) => {
return fetch(url)
.then((response) => response.blob())
.then((blob) => new File([blob], url.split('/').pop() ?? url))
.then(loadFile);
}
);
Promise.all(downloads).then((answers) => {
const files = answers.filter((file) => file !== null) as GPXFile[];
let ids: string[] = [];
files.forEach((file, index) => {
let id = `gpx-${index}-embed`;
file._data.id = id;
ids.push(id);
});
fileStateCollection.setEmbeddedFiles(files);
$fileOrder = ids;
selection.selectAll();
});
if (allowedEmbeddingBasemaps.includes(options.basemap)) {
$currentBasemap = options.basemap;
}
@@ -90,6 +71,28 @@
].filter((dataset) => dataset !== null)
);
elevationFill.set(options.elevation.fill == 'none' ? undefined : options.elevation.fill);
let downloads: Promise<GPXFile | null>[] = getFilesFromEmbeddingOptions(options).map(
(url) => {
return fetch(url)
.then((response) => response.blob())
.then((blob) => new File([blob], url.split('/').pop() ?? url))
.then(loadFile);
}
);
Promise.all(downloads).then((answers) => {
const files = answers.filter((file) => file !== null) as GPXFile[];
let ids: string[] = [];
files.forEach((file, index) => {
let id = `gpx-${index}-embed`;
file._data.id = id;
ids.push(id);
});
fileStateCollection.setEmbeddedFiles(files);
$fileOrder = ids;
selection.selectAll();
boundsManager.fitBoundsOnLoad(ids);
});
}
$effect(() => {
@@ -2,6 +2,7 @@
import CustomControl from './custom-control';
import { map } from '$lib/components/map/map';
import { onMount, type Snippet } from 'svelte';
import type { Map } from 'maplibre-gl';
let {
position = 'top-right',
@@ -17,7 +18,7 @@
let control: CustomControl | null = null;
onMount(() => {
map.onLoad((map: maplibregl.Map) => {
map.onLoad((map: Map) => {
if (position.includes('right')) container.classList.add('float-right');
else container.classList.add('float-left');
container.classList.remove('hidden');
@@ -1,9 +1,10 @@
import { MapPopup } from '$lib/components/map/map-popup';
import type { Map } from 'maplibre-gl';
export let waypointPopup: MapPopup | null = null;
export let trackpointPopup: MapPopup | null = null;
export function createPopups(map: maplibregl.Map) {
export function createPopups(map: Map) {
removePopups();
waypointPopup = new MapPopup(map, {
closeButton: false,
@@ -1,9 +1,10 @@
import { get, type Readable } from 'svelte/store';
import maplibregl, {
import {
type GeoJSONSource,
type FilterSpecification,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
Point,
} from 'maplibre-gl';
import { map } from '$lib/components/map/map';
import { waypointPopup, trackpointPopup } from './gpx-layer-popup';
@@ -120,7 +121,7 @@ export class GPXLayer {
selected: boolean = false;
currentWaypointData: GeoJSON.FeatureCollection | null = null;
draggedWaypointIndex: number | null = null;
draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
draggingStartingPosition: Point = new Point(0, 0);
unsubscribe: Function[] = [];
updateBinded: () => void = this.update.bind(this);
@@ -7,6 +7,7 @@
import { Layers } from '@lucide/svelte';
import { settings } from '$lib/logic/settings';
import { map } from '$lib/components/map/map';
import type { Map } from 'maplibre-gl';
let container: HTMLDivElement;
let overpassLayer: OverpassLayer;
@@ -21,7 +22,7 @@
selectedOverpassTree,
} = settings;
map.onLoad((_map: maplibregl.Map) => {
map.onLoad((_map: Map) => {
if (overpassLayer) {
overpassLayer.remove();
}
@@ -15,7 +15,9 @@
poi: PopupItem<any>;
} = $props();
let tags: Record<string, string> = $derived(poi ? JSON.parse(poi.item.tags) : {});
let tags: Record<string, string> = $derived(
poi ? (typeof poi.item.tags == 'object' ? poi.item.tags : JSON.parse(poi.item.tags)) : {}
);
let name = $derived.by(() => {
if (poi) {
if (tags.name !== undefined && tags.name !== '') {
@@ -88,6 +90,14 @@
<span class="font-mono">{key}</span>
{#if key === 'website' || key.startsWith('website:') || key.endsWith(':website') || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'}
<a href={value} target="_blank" class="text-link underline">{value}</a>
{:else if key === 'wikipedia' || key.startsWith('wikipedia:') || key.endsWith(':wikipedia')}
<a
href="https://wikipedia.org/wiki/{value}"
target="_blank"
class="text-link underline"
>
{value}
</a>
{:else if key === 'phone' || key === 'contact:phone'}
<a href={'tel:' + value} class="text-link underline">{value}</a>
{:else if key === 'email' || key === 'contact:email'}
@@ -6,7 +6,7 @@ import { overpassQueryData } from '$lib/assets/layers';
import { MapPopup } from '$lib/components/map/map-popup';
import { settings } from '$lib/logic/settings';
import { db } from '$lib/db';
import type { GeoJSONSource } from 'maplibre-gl';
import type { Map as MapLibreMap, GeoJSONSource } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
import { loadSVGIcon } from '$lib/utils';
@@ -28,7 +28,7 @@ export class OverpassLayer {
minZoom = 12;
queryZoom = 12;
expirationTime = 7 * 24 * 3600 * 1000;
map: maplibregl.Map;
map: MapLibreMap;
layerEventManager: MapLayerEventManager;
popup: MapPopup;
@@ -40,7 +40,7 @@ export class OverpassLayer {
updateBinded = this.update.bind(this);
onHoverBinded = this.onHover.bind(this);
constructor(map: maplibregl.Map, layerEventManager: MapLayerEventManager) {
constructor(map: MapLibreMap, layerEventManager: MapLayerEventManager) {
this.map = map;
this.layerEventManager = layerEventManager;
this.popup = new MapPopup(map, {
@@ -1,10 +1,19 @@
import { fileStateCollection } from '$lib/logic/file-state';
import maplibregl from 'maplibre-gl';
import {
LngLatBounds,
MapMouseEvent,
MapTouchEvent,
Point,
type Map,
type MapGeoJSONFeature,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
} from 'maplibre-gl';
type MapLayerMouseEventListener = (e: maplibregl.MapLayerMouseEvent) => void;
type MapLayerTouchEventListener = (e: maplibregl.MapLayerTouchEvent) => void;
type MapLayerMouseEventListener = (e: MapLayerMouseEvent) => void;
type MapLayerTouchEventListener = (e: MapLayerTouchEvent) => void;
type MapLayerListener = {
features: maplibregl.MapGeoJSONFeature[];
features: MapGeoJSONFeature[];
mousemoves: MapLayerMouseEventListener[];
mouseenters: MapLayerMouseEventListener[];
mouseleaves: MapLayerMouseEventListener[];
@@ -15,10 +24,10 @@ type MapLayerListener = {
};
export class MapLayerEventManager {
private _map: maplibregl.Map;
private _map: Map;
private _listeners: Record<string, MapLayerListener> = {};
constructor(map: maplibregl.Map) {
constructor(map: Map) {
this._map = map;
this._map.on('mousemove', this._handleMouseMove.bind(this));
this._map.on('click', this._handleMouseClick.bind(this, 'click'));
@@ -141,7 +150,7 @@ export class MapLayerEventManager {
}
}
private _handleMouseMove(e: maplibregl.MapMouseEvent) {
private _handleMouseMove(e: MapMouseEvent) {
if (e.originalEvent.buttons > 0) return;
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => {
@@ -150,29 +159,20 @@ export class MapLayerEventManager {
if ((features.length == 0) != (listener.features.length == 0)) {
if (features.length > 0) {
if (listener.mouseenters.length > 0) {
const event = new maplibregl.MapMouseEvent(
'mouseenter',
e.target,
e.originalEvent,
{
const event = new MapMouseEvent('mouseenter', e.target, e.originalEvent, {
features: featuresByLayer[layerId]!,
}
);
});
listener.mouseenters.forEach((l) => l(event));
}
} else {
if (listener.mouseleaves.length > 0) {
const event = new maplibregl.MapMouseEvent(
'mouseleave',
e.target,
e.originalEvent
);
const event = new MapMouseEvent('mouseleave', e.target, e.originalEvent);
listener.mouseleaves.forEach((l) => l(event));
}
}
}
if (features.length > 0 && listener.mousemoves.length > 0) {
const event = new maplibregl.MapMouseEvent('mousemove', e.target, e.originalEvent, {
const event = new MapMouseEvent('mousemove', e.target, e.originalEvent, {
features: featuresByLayer[layerId]!,
});
listener.mousemoves.forEach((l) => l(event));
@@ -181,49 +181,39 @@ export class MapLayerEventManager {
});
}
private _handleMouseClick(type: string, e: maplibregl.MapMouseEvent) {
private _handleMouseClick(type: string, e: MapMouseEvent) {
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || [];
const listener = this._listeners[layerId];
if (features.length > 0) {
if (type === 'click' && listener.clicks.length > 0) {
const event = new maplibregl.MapMouseEvent('click', e.target, e.originalEvent, {
const event = new MapMouseEvent('click', e.target, e.originalEvent, {
features: features,
});
listener.clicks.forEach((l) => l(event));
} else if (type === 'contextmenu' && listener.contextmenus.length > 0) {
const event = new maplibregl.MapMouseEvent(
'contextmenu',
e.target,
e.originalEvent,
{
const event = new MapMouseEvent('contextmenu', e.target, e.originalEvent, {
features: features,
}
);
});
listener.contextmenus.forEach((l) => l(event));
} else if (type === 'mousedown' && listener.mousedowns.length > 0) {
const event = new maplibregl.MapMouseEvent(
'mousedown',
e.target,
e.originalEvent,
{
const event = new MapMouseEvent('mousedown', e.target, e.originalEvent, {
features: features,
}
);
});
listener.mousedowns.forEach((l) => l(event));
}
}
});
}
private _handleTouchStart(e: maplibregl.MapTouchEvent) {
private _handleTouchStart(e: MapTouchEvent) {
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || [];
const listener = this._listeners[layerId];
if (features.length > 0) {
const event: maplibregl.MapLayerTouchEvent = new maplibregl.MapTouchEvent(
const event: MapLayerTouchEvent = new MapTouchEvent(
'touchstart',
e.target,
e.originalEvent
@@ -234,18 +224,15 @@ export class MapLayerEventManager {
});
}
private _getBounds(point: maplibregl.Point) {
private _getBounds(point: Point) {
const delta = 30;
return new maplibregl.LngLatBounds(
return new LngLatBounds(
this._map.unproject([point.x - delta, point.y + delta]),
this._map.unproject([point.x + delta, point.y - delta])
);
}
private _filterLayersIntersectingBounds(
layerIds: string[],
bounds: maplibregl.LngLatBounds
): string[] {
private _filterLayersIntersectingBounds(layerIds: string[], bounds: LngLatBounds): string[] {
let result = layerIds.filter((layerId) => {
if (!this._map.getLayer(layerId)) return false;
const fileId = layerId.replace('-waypoints', '');
@@ -261,7 +248,7 @@ export class MapLayerEventManager {
return result;
}
private _getRenderedFeaturesByLayer(e: maplibregl.MapMouseEvent | maplibregl.MapTouchEvent) {
private _getRenderedFeaturesByLayer(e: MapMouseEvent | MapTouchEvent) {
const layerIds = this._filterLayersIntersectingBounds(
Object.keys(this._listeners),
this._getBounds(e.point)
@@ -270,7 +257,7 @@ export class MapLayerEventManager {
layerIds.length > 0
? this._map.queryRenderedFeatures(e.point, { layers: layerIds })
: [];
const featuresByLayer: Record<string, maplibregl.MapGeoJSONFeature[]> = {};
const featuresByLayer: Record<string, MapGeoJSONFeature[]> = {};
features.forEach((f) => {
if (!featuresByLayer[f.layer.id]) {
featuresByLayer[f.layer.id] = [];
+8 -8
View File
@@ -1,5 +1,5 @@
import { TrackPoint, Waypoint } from 'gpx';
import maplibregl from 'maplibre-gl';
import { LngLat, Map, MapMouseEvent, Popup, type PopupOptions } from 'maplibre-gl';
import { mount, tick, unmount } from 'svelte';
import { get, writable, type Writable } from 'svelte/store';
import MapPopupComponent from '$lib/components/map/MapPopup.svelte';
@@ -11,15 +11,15 @@ export type PopupItem<T = Waypoint | TrackPoint | any> = {
};
export class MapPopup {
map: maplibregl.Map;
popup: maplibregl.Popup;
map: Map;
popup: Popup;
item: Writable<PopupItem | null> = writable(null);
component: ReturnType<typeof mount>;
maybeHideBinded = this.maybeHide.bind(this);
constructor(map: maplibregl.Map, options?: maplibregl.PopupOptions) {
constructor(map: Map, options?: PopupOptions) {
this.map = map;
this.popup = new maplibregl.Popup(options);
this.popup = new Popup(options);
this.component = mount(MapPopupComponent, {
target: document.body,
props: {
@@ -51,7 +51,7 @@ export class MapPopup {
this.map.on('mousemove', this.maybeHideBinded);
}
maybeHide(e: maplibregl.MapMouseEvent) {
maybeHide(e: MapMouseEvent) {
const item = get(this.item);
if (item === null) {
this.hide();
@@ -75,10 +75,10 @@ export class MapPopup {
getCoordinates() {
const item = get(this.item);
if (item === null) {
return new maplibregl.LngLat(0, 0);
return new LngLat(0, 0);
}
return item.item instanceof Waypoint || item.item instanceof TrackPoint
? item.item.getCoordinates()
: new maplibregl.LngLat(item.item.lon, item.item.lat);
: new LngLat(item.item.lon, item.item.lat);
}
}
+3 -1
View File
@@ -1,5 +1,6 @@
import maplibregl from 'maplibre-gl';
import * as maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
import MaplibreGeocoder, {
type MaplibreGeocoderFeatureResults,
} from '@maplibre/maplibre-gl-geocoder';
@@ -39,6 +40,7 @@ export class MapLibreGLMap {
geocoder: boolean,
geolocate: boolean
) {
maplibregl.setWorkerUrl(workerUrl);
this._maptilerKey = maptilerKey;
this._styleManager = new StyleManager(this._mapStore, this._maptilerKey);
const map = new maplibregl.Map({
@@ -9,6 +9,7 @@
import { i18n } from '$lib/i18n.svelte';
import { onMount } from 'svelte';
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
import type { Map } from 'maplibre-gl';
const { streetViewSource } = settings;
@@ -20,7 +21,7 @@
let container: HTMLElement;
onMount(() => {
map.onLoad((map_: maplibregl.Map) => {
map.onLoad((map_: Map) => {
googleRedirect = new GoogleRedirect(map_);
mapillaryLayer = new MapillaryLayer(
map_,
@@ -1,10 +1,11 @@
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import type { Map, MapMouseEvent } from 'maplibre-gl';
export class GoogleRedirect {
map: maplibregl.Map;
map: Map;
enabled = false;
constructor(map: maplibregl.Map) {
constructor(map: Map) {
this.map = map;
}
@@ -24,7 +25,7 @@ export class GoogleRedirect {
this.map.off('click', this.openStreetView);
}
openStreetView(e: maplibregl.MapMouseEvent) {
openStreetView(e: MapMouseEvent) {
window.open(
`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${e.lngLat.lat},${e.lngLat.lng}`
);
@@ -1,4 +1,10 @@
import maplibregl, { type LayerSpecification, type VectorSourceSpecification } from 'maplibre-gl';
import {
Map,
Marker,
type LayerSpecification,
type MapLayerMouseEvent,
type VectorSourceSpecification,
} from 'maplibre-gl';
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
import 'mapillary-js/dist/mapillary.css';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
@@ -43,9 +49,9 @@ const mapillaryImageLayer: LayerSpecification = {
};
export class MapillaryLayer {
map: maplibregl.Map;
map: Map;
layerEventManager: MapLayerEventManager;
marker: maplibregl.Marker;
marker: Marker;
viewer: Viewer;
active = false;
@@ -56,7 +62,7 @@ export class MapillaryLayer {
onMouseLeaveBinded = this.onMouseLeave.bind(this);
constructor(
map: maplibregl.Map,
map: Map,
layerEventManager: MapLayerEventManager,
container: HTMLElement,
popupOpen: { value: boolean }
@@ -75,7 +81,7 @@ export class MapillaryLayer {
dot.className = 'maplibregl-user-location-dot';
element.appendChild(dot);
this.marker = new maplibregl.Marker({
this.marker = new Marker({
rotationAlignment: 'map',
element,
});
@@ -140,7 +146,7 @@ export class MapillaryLayer {
this.popupOpen.value = false;
}
onMouseEnter(e: maplibregl.MapLayerMouseEvent) {
onMouseEnter(e: MapLayerMouseEvent) {
if (
e.features &&
e.features.length > 0 &&
+16 -11
View File
@@ -9,11 +9,17 @@ import {
} from '$lib/assets/layers';
import { getLayers } from '$lib/components/map/layer-control/utils';
import { i18n } from '$lib/i18n.svelte';
import type {
Map,
GeoJSONSourceSpecification,
LayerSpecification,
StyleSpecification,
} from 'maplibre-gl';
const { currentBasemap, currentOverlays, customLayers, opacities, terrainSource, distanceUnits } =
settings;
const emptySource: maplibregl.GeoJSONSourceSpecification = {
const emptySource: GeoJSONSourceSpecification = {
type: 'geojson',
data: {
type: 'FeatureCollection',
@@ -32,18 +38,18 @@ export const ANCHOR_LAYER_KEY = {
waypoints: 'waypoints-end',
routingControls: 'routing-controls-end',
};
const anchorLayers: maplibregl.LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
const anchorLayers: LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
id: id,
type: 'symbol',
source: 'empty-source',
}));
export class StyleManager {
private _map: Writable<maplibregl.Map | null>;
private _map: Writable<Map | null>;
private _maptilerKey: string;
private _pastOverlays: Set<string> = new Set();
constructor(map: Writable<maplibregl.Map | null>, maptilerKey: string) {
constructor(map: Writable<Map | null>, maptilerKey: string) {
this._map = map;
this._maptilerKey = maptilerKey;
this._map.subscribe((map_) => {
@@ -58,6 +64,7 @@ export class StyleManager {
opacities.subscribe(() => this.updateOverlays());
terrainSource.subscribe(() => this.updateTerrain());
customLayers.subscribe(() => this.updateBasemap());
i18n.subscribe(() => this.updateBasemap());
distanceUnits.subscribe(() => {
const map = get(this._map);
if (map && (map.getLayer('contours_m') || map.getLayer('contours_ft'))) {
@@ -75,10 +82,10 @@ export class StyleManager {
});
}
async buildStyle(basemap: string): Promise<maplibregl.StyleSpecification> {
async buildStyle(basemap: string): Promise<StyleSpecification> {
const custom = get(customLayers);
const style: maplibregl.StyleSpecification = {
const style: StyleSpecification = {
version: 8,
projection: {
type: 'globe',
@@ -91,7 +98,7 @@ export class StyleManager {
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
let basemapStyle = basemaps.openStreetMap as maplibregl.StyleSpecification;
let basemapStyle = basemaps.openStreetMap as StyleSpecification;
try {
basemapStyle = await this.get(basemapInfo);
for (const source in basemapStyle.sources) {
@@ -202,9 +209,7 @@ export class StyleManager {
}
}
async get(
styleInfo: maplibregl.StyleSpecification | string
): Promise<maplibregl.StyleSpecification> {
async get(styleInfo: StyleSpecification | string): Promise<StyleSpecification> {
if (typeof styleInfo === 'string') {
let styleUrl = styleInfo as string;
const response = await fetch(styleUrl, { cache: 'force-cache' });
@@ -218,7 +223,7 @@ export class StyleManager {
}
}
merge(style: maplibregl.StyleSpecification, other: maplibregl.StyleSpecification) {
merge(style: StyleSpecification, other: StyleSpecification) {
style.sources = { ...style.sources, ...other.sources };
const units = get(distanceUnits);
for (let layer of other.layers ?? []) {
@@ -11,7 +11,7 @@
import Clean from '$lib/components/toolbar/tools/Clean.svelte';
import Reduce from '$lib/components/toolbar/tools/reduce/Reduce.svelte';
import RoutingControlPopup from '$lib/components/toolbar/tools/routing/RoutingControlPopup.svelte';
import maplibregl from 'maplibre-gl';
import { Popup } from 'maplibre-gl';
import { settings } from '$lib/logic/settings';
let {
@@ -23,11 +23,11 @@
const { minimizeRoutingMenu } = settings;
let popupElement: HTMLDivElement | undefined = $state(undefined);
let popup: maplibregl.Popup | undefined = $derived.by(() => {
let popup: Popup | undefined = $derived.by(() => {
if (!popupElement) {
return undefined;
}
let popup = new maplibregl.Popup({
let popup = new Popup({
closeButton: false,
maxWidth: undefined,
});
@@ -16,7 +16,7 @@
import { getURLForLanguage } from '$lib/utils';
import { Trash2 } from '@lucide/svelte';
import { map } from '$lib/components/map/map';
import type { GeoJSONSource } from 'maplibre-gl';
import type { GeoJSONSource, LngLat } from 'maplibre-gl';
import { selection } from '$lib/logic/selection';
import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
@@ -29,7 +29,7 @@
let cleanType = $state(CleanType.INSIDE);
let deleteTrackpoints = $state(true);
let deleteWaypoints = $state(true);
let rectangleCoordinates: maplibregl.LngLat[] = $state([]);
let rectangleCoordinates: LngLat[] = $state([]);
$effect(() => {
if ($map) {
@@ -41,6 +41,7 @@
import { fileActions, getFileIds, newGPXFile } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { RoutingControls, routingControls } from './routing-controls';
import type { Popup } from 'maplibre-gl';
let {
minimized = $bindable(false),
@@ -51,7 +52,7 @@
}: {
minimized?: boolean;
minimizable?: boolean;
popup?: maplibregl.Popup;
popup?: Popup;
popupElement?: HTMLDivElement;
class?: string;
} = $props();
@@ -1,10 +1,12 @@
import { distance, type Coordinates, TrackPoint, TrackSegment, Track, projectedPoint } from 'gpx';
import { get, writable, type Readable } from 'svelte/store';
import maplibregl, {
import {
type MapMouseEvent,
type GeoJSONSource,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
Popup,
Point,
} from 'maplibre-gl';
import { route } from './routing';
import { toast } from 'svelte-sonner';
@@ -50,7 +52,7 @@ export class RoutingControls {
}
> = new Map();
anchors: GeoJSON.Feature<GeoJSON.Point, AnchorProperties>[] = [];
popup: maplibregl.Popup;
popup: Popup;
popupElement: HTMLElement;
fileUnsubscribe: () => void = () => {};
unsubscribes: Function[] = [];
@@ -61,7 +63,7 @@ export class RoutingControls {
draggedAnchorIndex: number | null = null;
lastDraggedAnchorEventTime: number = 0;
draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
draggingStartingPosition: Point = new Point(0, 0);
onMouseEnterBinded: () => void = this.onMouseEnter.bind(this);
onMouseLeaveBinded: () => void = this.onMouseLeave.bind(this);
onClickBinded: (e: MapLayerMouseEvent) => void = this.onClick.bind(this);
@@ -80,7 +82,7 @@ export class RoutingControls {
constructor(
fileId: string,
file: Readable<GPXFileWithStatistics | undefined>,
popup: maplibregl.Popup,
popup: Popup,
popupElement: HTMLElement
) {
this.fileId = fileId;
@@ -183,7 +185,7 @@ export class RoutingControls {
this.layers.forEach((layer, zoom) => {
try {
let source = map_.getSource(layer.id) as maplibregl.GeoJSONSource | undefined;
let source = map_.getSource(layer.id) as GeoJSONSource | undefined;
if (source) {
source.setData({
type: 'FeatureCollection',
@@ -520,7 +522,7 @@ export class RoutingControls {
});
}
async appendAnchor(e: maplibregl.MapMouseEvent) {
async appendAnchor(e: MapMouseEvent) {
// Add a new anchor to the end of the last segment
if (get(streetViewEnabled) && get(streetViewSource) === 'google') {
return;
@@ -609,7 +611,7 @@ export class RoutingControls {
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
}
addIntermediateAnchor(e: maplibregl.MapMouseEvent) {
addIntermediateAnchor(e: MapMouseEvent) {
e.preventDefault();
if (this.temporaryAnchor !== null) {
@@ -8,13 +8,13 @@ import { get } from 'svelte/store';
import { fileStateCollection } from '$lib/logic/file-state';
import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import type { GeoJSONSource } from 'maplibre-gl';
import type { Map, GeoJSONSource, MapLayerMouseEvent } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
import { loadSVGIcon } from '$lib/utils';
export class SplitControls {
map: maplibregl.Map;
map: Map;
layerEventManager: MapLayerEventManager;
unsubscribes: Function[] = [];
@@ -22,7 +22,7 @@ export class SplitControls {
layerOnMouseLeaveBinded: () => void = this.layerOnMouseLeave.bind(this);
layerOnClickBinded: (e: any) => void = this.layerOnClick.bind(this);
constructor(map: maplibregl.Map, layerEventManager: MapLayerEventManager) {
constructor(map: Map, layerEventManager: MapLayerEventManager) {
this.map = map;
this.layerEventManager = layerEventManager;
loadSVGIcon(
@@ -160,7 +160,7 @@ export class SplitControls {
mapCursor.notify(MapCursorState.SPLIT_CONTROL, false);
}
layerOnClick(e: maplibregl.MapLayerMouseEvent) {
layerOnClick(e: MapLayerMouseEvent) {
let coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates;
fileActions.split(
get(splitAs),
@@ -16,7 +16,7 @@
import { fileActions } from '$lib/logic/file-actions';
import { map } from '$lib/components/map/map';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import maplibregl from 'maplibre-gl';
import { Marker } from 'maplibre-gl';
import { getSvgForSymbol } from '$lib/components/map/gpx-layer/gpx-layer';
let props: {
@@ -41,7 +41,7 @@
})
);
let marker: maplibregl.Marker | null = null;
let marker: Marker | null = null;
function reset() {
if ($selectedWaypoint) {
@@ -125,7 +125,7 @@
let element = document.createElement('div');
element.classList.add('w-8', 'h-8');
element.innerHTML = getSvgForSymbol(symbolKey);
marker = new maplibregl.Marker({
marker = new Marker({
element,
anchor: 'bottom',
})
+2 -2
View File
@@ -50,5 +50,5 @@ Um die Ausrichtung und Neigung der Karte zu steuern, können Sie die Karte auch
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
Vollbildmodus ein- oder ausschalten.
Du kannst auch <kbd>F11</kbd> drücken, um zu wechseln, oder <kbd>Escape</kbd> zum Beenden.
+1 -1
View File
@@ -15,7 +15,7 @@ Wijzig de eenheden die worden gebruikt om afstanden in de interface weer te geve
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Snelheidseenheden
Verander de eenheden die worden gebruikt om velocities in de interface weer te geven.
Verander de eenheden die worden gebruikt om snelheden in de interface weer te geven.
Je kunt kiezen tussen afstand per uur of minuten per afstand, wat geschikter kan zijn voor het uitvoeren van activiteiten.
### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> Temperatuureenheden
+15 -15
View File
@@ -1,5 +1,5 @@
---
title: FAQ
title: Часті питання
---
<script>
@@ -8,28 +8,28 @@ title: FAQ
# { title }
### Do I need to donate to use the website?
### Чи потрібно робити пожертву, щоб користуватися сайтом?
No.
The website is free to use and always will be (as long as it is financially sustainable).
However, donations are appreciated and help keep the website running.
Ні.
Сайтом можна користуватися безкоштовно, і так буде завжди (доки це фінансово можливо).
Проте ми вдячні за пожертви, вони допомагають підтримувати роботу сайту.
### Why is this route chosen over that one? _Or_ how can I add something to the map?
### Чому вибрано саме цей маршрут, а не інший? **Або** як додати щось на карту?
**gpx.studio** uses data from <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>, which is an open and collaborative world map.
This means you can contribute to the map by adding or editing data on OpenStreetMap.
**gpx.studio** використовує дані <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>, який є відкритими картами світу, що створюється спільнотою.
Тобто ви можете покращувати карту, додаючи або редагуючи дані в OpenStreetMap.
If you have never contributed to OpenStreetMap before, here is how you can suggest changes:
Якщо ви ще ніколи не долучалися до OpenStreetMap, ось як можна запропонувати зміни:
1. Go to the location where you want to add or edit data on the <a href="https://www.openstreetmap.org/" target="_blank">map</a>.
2. Use the <button>Query features</button> tool on the right to inspect the existing data.
3. Right-click on the location and select <button>Add a note here</button>.
4. Explain what is incorrect or missing in the note and click <button>Add note</button> to submit it.
1. Перейдіть до місця на <a href="https://www.openstreetmap.org/" target="_blank">карті</a>, де хочете додати або відредагувати дані.
2. Скористайтеся інструментом <button>Запитати об’єкти</button> праворуч, щоб переглянути наявні дані.
3. Клацніть правою кнопкою миші в потрібному місці та виберіть <button>Додати примітку тут</button>.
4. У примітці вкажіть, що потрібно виправити або додати, і натисніть <button>Додати примітку</button>, щоб надіслати її.
Someone more experienced with OpenStreetMap will then review your note and make the necessary changes.
Потім досвідченіший учасник OpenStreetMap перегляне вашу примітку й внесе потрібні зміни.
<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>.
Докладніше про те, як долучитися до OpenStreetMap, можна дізнатися <a href="https://wiki.openstreetmap.org/wiki/How_to_contribute" target="_blank">тут</a>.
</DocsNote>
+16 -16
View File
@@ -54,32 +54,32 @@ title: Файли та статистика
Крім того, у дереві файлів можна переглядати [треки, сегменти та цікаві місця](./gpx), що містяться у файлах, за допомогою розгортальних розділів.
Ви також можете застосовувати [дії редагування](./menu/edit) та [інструменти](./toolbar) до елементів внутрішніх файлів.
Furthermore, you can drag and drop the inner items to reorder them, or move them in the hierarchy or even to another file.
Крім того, внутрішні елементи можна перетягувати, щоб змінювати їхній порядок, переміщувати в ієрархії або навіть переносити до іншого файлу.
<DocsNote>
The size of the file list can be adjusted by dragging the separator between the map and the file list.
Розмір списку файлів можна налаштувати, перетягнувши розділювач між картою та списком файлів.
</DocsNote>
## Elevation profile and statistics
## Профіль висоти та статистика
At the bottom of the interface, you can find the elevation profile and statistics for the current selection.
У нижній частині інтерфейсу можна знайти профіль висоти та статистику для поточного виділення.
<DocsNote>
The size of the elevation profile can be adjusted by dragging the separator between the map and the elevation profile.
Розмір профілю висоти можна змінити, перетягнувши розділювач між картою та профілем висоти.
</DocsNote>
### Interactive statistics
### Інтерактивна статистика
When hovering over the elevation profile, a tooltip will show statistics at the cursor position.
Під час наведення на профіль висоти підказка показує статистику в позиції курсора.
To get the statistics for a specific section of the elevation profile, you can drag a selection rectangle on the profile.
Click on the profile to reset the selection.
Щоб отримати статистику для певної ділянки профілю висоти, можна створити прямокутне виділення на профілі.
Клацніть на профілі, щоб скинути виділення.
You can also use the mouse wheel to zoom in and out on the elevation profile, and move left and right by dragging the profile while holding the <kbd>Shift</kbd> key.
Також можна використовувати колесо миші, щоб наближати й віддаляти профіль висоти, а також переміщатися ліворуч і праворуч, перетягуючи профіль із затиснутою клавішею <kbd>Shift</kbd>.
<div class="h-48 w-full">
<ElevationProfile
@@ -98,12 +98,12 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
/>
</div>
### Additional data
### Додаткові дані
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:
За допомогою кнопки <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> у правому нижньому куті профілю висоти можна за бажанням розфарбувати профіль висоти за:
- **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.
This is only available for files created with **gpx.studio**.
- даними про **ухил**, обчисленими з даних висоти; або
- даними про **покриття** чи **категорію дороги** з тегів <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> і <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">highway</a>.
Це доступно лише для файлів, створених у **gpx.studio**.
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
Якщо вибраний трек містить відповідні дані, на профілі висоти також можна відобразити **швидкість**, **пульс**, **каденс**, **температуру** та **потужність**.
+17 -17
View File
@@ -1,5 +1,5 @@
---
title: Getting started
title: Перші кроки
---
<script lang="ts">
@@ -8,30 +8,30 @@ title: Getting started
# { title }
Welcome to the official guide for **gpx.studio**!
This guide will walk you through all the components and tools of the interface, helping you become a proficient user of the application.
Ласкаво просимо до офіційного посібника **gpx.studio**!
Цей посібник проведе вас через усі компоненти й інструменти інтерфейсу та допоможе впевнено користуватися застосунком.
<DocsImage src="getting-started/interface" alt="The gpx.studio interface." />
<DocsImage src="getting-started/interface" alt="Інтерфейс gpx.studio." />
As shown in the screenshot above, the interface is divided into four main sections organized around the map.
Before we dive into the details of each section, let's have a quick overview of the interface.
Як показано на знімку екрана вище, інтерфейс поділено на чотири основні розділи, розташовані навколо карти.
Перед тим, як перейти до деталей кожного розділу, коротко оглянемо інтерфейс.
## 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.
У верхній частині інтерфейсу розташоване [головне меню](./menu).
Тут можна виконувати типові дії: відкривати, закривати й експортувати файли, скасовувати та повторювати дії, а також змінювати налаштування застосунку.
## Файли та статистика
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.
In the [dedicated section](./files-and-stats), we will explain how to select multiple files and switch to a tree layout for advanced file management.
У нижній частині інтерфейсу розташований список файлів, відкритих у застосунку.
Клацніть на файл, щоб вибрати його й показати статистику під списком.
В [окремому розділі](./files-and-stats) ми пояснимо, як вибирати кілька файлів і перемикатися на деревоподібне відображення для розширеного керування файлами.
## Toolbar
## Панель інструментів
On the left side of the interface, you will find the [toolbar](./toolbar), which contains all the tools you can use to edit your files.
У лівій частині інтерфейсу розташована [панель інструментів](./toolbar) з усіма інструментами для редагування файлів.
## 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.
Нарешті, у правій частині інтерфейсу розташовані елементи [керування картою](./map-controls).
Вони дають змогу переміщатися картою, наближати й віддаляти її, а також перемикатися між різними стилями карти.
+17 -17
View File
@@ -1,5 +1,5 @@
---
title: GPX file format
title: Формат GPX-файлу
---
<script>
@@ -8,27 +8,27 @@ title: GPX file format
# { title }
The <a href="https://www.topografix.com/gpx.asp" target="_blank">GPX file format</a> is an open standard for exchanging GPS data between applications and GPS devices.
It essentially consists of a series of GPS points encoding one or multiple GPS traces, and, optionally, some points of interest.
<a href="https://www.topografix.com/gpx.asp" target="_blank">Формат GPX-файлу</a> це відкритий стандарт для обміну GPS-даними між застосунками та GPS-пристроями.
По суті, він складається з набору GPS-точок, які описують один або кілька GPS-треків, а також, за бажанням, точки інтересу.
GPX files may also contain metadata, of which the **name** and **description** fields are the most useful for users.
GPX-файли також можуть містити метадані, серед яких для користувачів найкорисніші поля **назва** та **опис**.
### <Waypoints size="16" class="inline-block" style="margin-bottom: 2px" /> Tracks, segments, and GPS points
### <Waypoints size="16" class="inline-block" style="margin-bottom: 2px" /> Треки, сегменти та GPS-точки
As mentioned above, a GPX file can contain multiple GPS traces.
These are organized in a hierarchical structure, with tracks at the top level.
Як згадано вище, GPX-файл може містити кілька GPS-треків.
Вони організовані в ієрархічну структуру, де треки розташовані на верхньому рівні.
- A **track** is made of a sequence of disconnected segments.
Furthermore, it can contain metadata such as a **name**, a **description**, and **appearance properties**.
- A **segment** is a sequence of GPS points that form a continuous path.
- A **GPS point** is a location with a latitude, a longitude, and optionally a timestamp and an altitude.
Some devices also store additional information such as heart rate, cadence, temperature, and power.
- **Трек** складається з послідовності окремих сегментів.
Крім того, він може містити метадані, такі як **назва**, **опис** і **властивості вигляду**.
- **Сегмент** — це послідовність GPS-точок, які утворюють безперервний шлях.
- **GPS-точка** — це місце з широтою, довготою, також додатково часовою міткою й висотою.
Деякі пристрої також зберігають додаткову інформацію, такі як пульс, каденс, температуру та потужність.
In most cases, GPX files contain a single track with a single segment.
However, the hierarchy described above allows for more advanced use cases, such as planning multi-day trips with several variants for each day.
У більшості випадків GPX-файли містять один трек з одним сегментом.
Однак описана вище ієрархія дає змогу використовувати складніші сценарії, наприклад планувати багатоденні подорожі з кількома варіантами маршруту на кожен день.
### <MapPin size="16" class="inline-block" style="margin-bottom: 2px" /> Points of interest
### <MapPin size="16" class="inline-block" style="margin-bottom: 2px" /> Точки інтересу
**Points of interest** (technically called _waypoints_) represent locations of interest to show either on a GPS device or on a digital map.
**Точки інтересу** (технічно вони називаються **waypoints**) позначають цікаві місця, які можна показувати на GPS-пристрої або цифровій карті.
In addition to its coordinates, a point of interest can have a **name** and a **description**.
Окрім координат, точка інтересу може мати **назву** та **опис**.
+7 -7
View File
@@ -1,5 +1,5 @@
---
title: Integration
title: Інтеграція
---
<script>
@@ -9,18 +9,18 @@ title: Integration
# { title }
You can use **gpx.studio** to create maps showing your GPX files and embed them in your website.
Ви можете використовувати **gpx.studio**, щоб створювати карти з вашими GPX-файлами та вбудовувати їх на свій сайт.
All you need is:
Все, що вам потрібно:
1. GPX files hosted on your server or on Google Drive, or accessible via a public URL;
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.
1. GPX-файли, розміщені на вашому сервері чи Google Drive або доступні за публічною URL-адресою;
2. _Необов’язково:_ <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">ключ MapTiler</a> для завантаження карт MapTiler.
You can then play with the configurator below to customize your map and generate the corresponding HTML code.
Після цього можна скористатися конфігуратором нижче, щоб налаштувати карту та згенерувати відповідний HTML-код.
<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.
На вашому сервері потрібно буде налаштувати заголовки <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">Cross-Origin Resource Sharing (CORS)</a>, щоб дозволити <b>gpx.studio</b> завантажувати ваші GPX-файли.
</DocsNote>
+28 -28
View File
@@ -1,5 +1,5 @@
---
title: Map controls
title: Керування картою
---
<script>
@@ -10,63 +10,63 @@ title: Map controls
# { title }
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.
Елементи керування картою розташовані в правій частині інтерфейсу.
Вони дають змогу переміщатися картою, наближати й віддаляти її, а також перемикатися між різними стилями карти.
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Карта навігації
The controls at the top allow you to zoom in <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> and out <Minus size="16" class="inline-block" style="margin-bottom: 2px" />, and to change the orientation and tilt of the map <Compass size="16" class="inline-block" style="margin-bottom: 2px" />.
Елементи керування вгорі дають змогу наближати <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> і віддаляти <Minus size="16" class="inline-block" style="margin-bottom: 2px" /> карту, а також змінювати її орієнтацію та нахил <Compass size="16" class="inline-block" style="margin-bottom: 2px" />.
<DocsNote>
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
Щоб керувати орієнтацією та нахилом карти, також можна перетягувати карту, утримуючи <kbd>Ctrl</kbd>.
</DocsNote>
### <Search size="16" class="inline-block" style="margin-bottom: 2px" /> Search bar
### <Search size="16" class="inline-block" style="margin-bottom: 2px" /> Панель пошуку
You can use the search bar to look for an address and navigate to it on the map.
Рядок пошуку можна використовувати, щоб знайти адресу та перейти до неї на карті.
### <LocateFixed size="16" class="inline-block" style="margin-bottom: 2px" /> Locate button
### <LocateFixed size="16" class="inline-block" style="margin-bottom: 2px" /> Кнопка визначення місцезнаходження
The locate button centers the map on your current location.
Кнопка визначення місцезнаходження центрує карту на вашому поточному місці.
<DocsNote>
This only works if you have allowed your browser and <b>gpx.studio</b> to access your location.
Це працює лише тоді, коли ви дозволили браузеру та <b>gpx.studio</b> доступ до свого місцезнаходження.
</DocsNote>
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Street view
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Перегляд вулиць
This button can be used to enable street view mode on the map.
Depending on the street view source chosen in the [settings](./menu/settings), street view imagery can be accessed differently.
Ця кнопка вмикає режим перегляду вулиць на карті.
Залежно від джерела перегляду вулиць, вибраного в [налаштуваннях](./menu/settings), зображення перегляду вулиць відкриваються по-різному.
- <a href="https://www.mapillary.com/" target="_blank">Mapillary</a>: the street view coverage will appear as green lines on the map. When zoomed in enough, green dots will show the exact locations where street view imagery is available. Hovering over a green dot will show the street view image at that location.
- <a href="https://www.google.com/streetview/" target="_blank">Google Street View</a>: click on the map to open a new tab with the street view imagery at that location.
- <a href="https://www.mapillary.com/" target="_blank">Mapillary</a>: покриття перегляду вулиць відображатиметься на карті зеленими лініями. За достатнього наближення зелені точки показуватимуть точні місця, де доступні зображення перегляду вулиць. Наведення на зелену точку покаже зображення перегляду вулиць у цьому місці.
- <a href="https://www.google.com/streetview/" target="_blank">Google Street View</a>: клацніть на карті, щоб відкрити нову вкладку із зображенням перегляду вулиць у цьому місці.
### <Layers size="16" class="inline-block" style="margin-bottom: 2px" /> Map layers
### <Layers size="16" class="inline-block" style="margin-bottom: 2px" /> Шари карти
The map layers button allows you to switch between different basemaps, and toggle map overlays and categories of points of interest.
Кнопка шарів карти дає змогу перемикатися між різними базовими картами, а також показувати або сховати накладені шари карти й категорії точок інтересу.
- **Basemaps** are background maps that present the main geographic features of the world.
Depending on their purpose, basemaps have different styles and levels of detail.
Only one basemap can be displayed at a time.
- **Overlays** are additional layers that can be displayed on top of the basemap to provide complementary information.
- **Points of interest** can be added to the map to show different categories of places, such as shops, restaurants, or accommodations.
- **Базові карти** — це фонові карти, які показують основні географічні об’єкти світу.
Залежно від призначення, базові карти мають різні стилі та рівні деталізації.
Одночасно може відображатися лише одна базова карта.
- **Накладені шари** — це додаткові шари, які можна відображати поверх базової карти для надання додаткової інформації.
- **Точки інтересу** можна додавати на карту, щоб показувати різні категорії місць, наприклад магазини, ресторани або житло.
<div class="flex flex-col items-center">
<DocsLayers />
<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.
Наведіть курсор на карту, щоб показати накладений шар <a href="https://hiking.waymarkedtrails.org" target="_blank">пішохідних маршрутів Waymarked Trails</a> поверх топографічної базової карти.
</span>
</div>
A large collection of global and local basemaps and overlays is available in **gpx.studio**, as well as a selection of point-of-interest categories.
They can be enabled in the [map layer settings dialog](./menu/settings).
У **gpx.studio** доступна велика колекція глобальних і локальних базових карт та накладених шарів, а також добірка категорій точок інтересу.
Їх можна ввімкнути в діалоговому вікні [налаштувань шарів карти](./menu/settings).
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.
Для досвідчених користувачів є можливість додавати власні базові карти та накладені шари, указавши URL-адреси <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> або <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre JSON</a>.
+3 -3
View File
@@ -1,5 +1,5 @@
---
title: Menu
title: Меню
---
<script lang="ts">
@@ -8,10 +8,10 @@ title: Menu
# { title }
The main menu, located at the top of the interface, provides access to actions, options, and settings divided into several categories, explained separately in the following sections.
У верхній частині інтерфейсу розташоване головне меню. Воно дає доступ до дій, параметрів і налаштувань, поділених на кілька категорій, які описано нижче.
<DocsNote>
Most of the menu actions can also be performed using the keyboard shortcuts displayed in the menu.
Для більшості дій у меню також доступні комбінації клавіш, які показано поруч із відповідними пунктами меню.
</DocsNote>
+16 -16
View File
@@ -1,5 +1,5 @@
---
title: File actions
title: Дії з файлом
---
<script lang="ts">
@@ -9,41 +9,41 @@ title: File actions
# { 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" /> Відкрити...
Відкрити файли з комп'ютера.
<DocsNote>
You can also drag and drop files directly from your file system into the window.
Ви також можете перетягувати файли безпосередньо з файлової системи у вікно.
</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">
+19 -19
View File
@@ -1,5 +1,5 @@
---
title: Settings
title: Налаштування
---
<script lang="ts">
@@ -9,22 +9,22 @@ title: Settings
# { 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>
@@ -34,17 +34,17 @@ Change the language used in the interface.
</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).
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>.
Learn more about how to use the street view control in the [map controls section](../map-controls).
Змінити джерело, що використовується для [панелі перегляду вулиці](../map-controls).
За замовчуванням використовується <a href="https://www.mapillary.com" target="_blank">Mapillary</a>, але ви також можете скористатися <a href="https://www.google.com/streetview/" target="_blank">Google Street View</a>.
Дізнатися більше про те, як використовувати контроль над вулицею в [панелі перегляду вулиці](../map-controls).
### <Layers size="16" class="inline-block" style="margin-bottom: 2px" /> Map layers...
### <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).
+22 -22
View File
@@ -1,5 +1,5 @@
---
title: View options
title: Параметри виду
---
<script lang="ts">
@@ -9,46 +9,46 @@ title: View options
# { 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" /> Перемкнути 3D
Enter or exit the 3D map view.
Увімкнути або вимкнути режим 3D-карти.
<DocsNote>
To control the orientation and tilt of the map, you can also drag the map while holding <kbd>Ctrl</kbd>.
Щоб керувати орієнтацією та нахилом карти, також можна перетягувати карту, утримуючи <kbd>Ctrl</kbd>.
</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>, щоб вийти.
+5 -5
View File
@@ -1,5 +1,5 @@
---
title: Toolbar
title: Панель інструментів
---
<script lang="ts">
@@ -18,8 +18,8 @@ title: Toolbar
# { title }
The toolbar is located on the left side of the map and is the heart of the application, as it provides access to the main features of **gpx.studio**.
Each tool is represented by an icon and can be activated by clicking on it.
Панель інструментів розташована ліворуч від карти та є серцем застосунку, адже надає доступ до основних можливостей **gpx.studio**.
Кожен інструмент має значок, за якою його можна активувати.
<div class="flex flex-row justify-center text-foreground">
<div>
@@ -27,6 +27,6 @@ Each tool is represented by an icon and can be activated by clicking on it.
</div>
</div>
As with [edit actions](./menu/edit), most tools can be applied to multiple files at once and to [inner tracks and segments](./gpx).
Як і [дії редагування](./menu/edit), більшість інструментів можна застосовувати одразу до кількох файлів, а також до [вкладених треків і сегментів](./gpx).
The next sections describe each tool in detail.
У наступних розділах кожен інструмент описано докладно.
+3 -3
View File
@@ -1,5 +1,5 @@
---
title: Clean
title: Очищення
---
<script>
@@ -9,9 +9,9 @@ title: Clean
# <SquareDashedMousePointer size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
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.
Залежно від параметрів, вибраних у показаному нижче діалоговому вікні, натискання кнопки видалення прибере GPS-точки та/або [точки інтересу](../gpx), розташовані всередині або поза межами виділення.
<div class="flex flex-row justify-center">
<Clean class="text-foreground p-3 border rounded-md shadow-lg" />
@@ -1,5 +1,5 @@
---
title: Elevation
title: Висота
---
<script>
@@ -10,7 +10,7 @@ title: Elevation
# <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.
Цей інструмент дає змогу додати дані висоти до треків і [точок інтересу](../gpx) або замінити наявні дані.
<div class="flex flex-row justify-center">
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
@@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](..
<DocsNote>
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>.
Дані висоти надає <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>.
Докладніше про походження цих даних і їхню точність можна дізнатися в <a href="https://mapterhorn.com/attribution/" target="_blank">документації</a>.
</DocsNote>
+5 -5
View File
@@ -1,5 +1,5 @@
---
title: Extract
title: Виокремлення
---
<script>
@@ -10,17 +10,17 @@ title: Extract
# <Ungroup size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
This tool allows you to extract [tracks (or segments)](../gpx) from files (or tracks) containing multiple of them.
Цей інструмент дає змогу виокремити [треки (або сегменти)](../gpx) з файлів (або треків), у яких міститься кілька таких елементів.
<div class="flex flex-row justify-center">
<Extract class="text-foreground p-3 border rounded-md shadow-lg" />
</div>
Applying the tool to a file containing multiple tracks will create a new file for each of the tracks it contains.
Similarly, applying the tool to a track containing multiple segments will create (in the same file) a new track for each of the segments it contains.
Якщо застосувати інструмент до файлу, який містить кілька треків, для кожного з них буде створено окремий файл.
Так само, якщо застосувати інструмент до треку, який містить кілька сегментів, буде створено новий трек (у тому самому файлі) для кожного з цих сегментів.
<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.
Під час виокремлення треків із файлу, що містить <a href="../gpx">точки інтересу</a>, інструмент автоматично призначить кожну точку інтересу до найближчого до неї треку.
</DocsNote>
+7 -7
View File
@@ -1,5 +1,5 @@
---
title: Merge
title: Об’єднання
---
<script>
@@ -10,16 +10,16 @@ title: Merge
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
To use this tool, you need to [select](../files-and-stats) multiple files, [tracks, or segments](../gpx).
Щоб скористатися цим інструментом, потрібно [вибрати](../files-and-stats) кілька файлів, [треків або сегментів](../gpx).
- If your goal is to create a single continuous trace from your selection, use the **Connect the traces** option and validate.
- The second option can be used to create or manage files with multiple [tracks or segments](../gpx).
Merging files (or tracks) will result in a single file (or track) containing all tracks (or segments) from the selection.
- Якщо потрібно створити один суцільний трек із вибраного, виберіть параметр **З’єднати треки** та підтвердьте.
- Другий параметр дає змогу створювати та керувати файлами з кількома [треками або сегментами](../gpx).
Після об’єднання файлів (або треків) буде створено один файл (або трек), який міститиме всі вибрані треки (або сегменти).
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
Вибрані елементи об’єднуються в тому порядку, у якому вони відображаються у списку файлів.
За потреби змініть порядок елементів перетягуванням.
</DocsNote>
+5 -5
View File
@@ -1,5 +1,5 @@
---
title: Minify
title: Зменшення
---
<script>
@@ -10,9 +10,9 @@ title: Minify
# <Funnel size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
This tool can be used to reduce the number of GPS points in a trace, which can be useful for decreasing its size.
Цей інструмент дає змогу зменшити кількість GPS-точок у треку, що допомагає зменшити розмір файлу.
You can adjust the tolerance of the simplification algorithm using the slider, and see the number of points that will be kept, as well as the simplified trace on the map.
За допомогою повзунка можна налаштувати рівень спрощення, а також побачити кількість точок, які буде збережено, і спрощений трек на карті.
<div class="flex flex-row justify-center">
<Reduce class="text-foreground p-3 border rounded-md shadow-lg" />
@@ -20,7 +20,7 @@ You can adjust the tolerance of the simplification algorithm using the slider, a
<DocsNote>
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>.
Рівень спрощення визначає максимальне допустиме відхилення спрощеного треку від оригінального.
Докладніше про алгоритм спрощення можна прочитати <a href="https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm" target="_blank">тут</a>.
</DocsNote>
+9 -9
View File
@@ -1,5 +1,5 @@
---
title: Points of interest
title: Точки інтересу
---
<script>
@@ -9,19 +9,19 @@ title: Points of interest
# <MapPin size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
[Points of interest](../gpx) can be added to GPX files to mark locations of interest on the map and display them on your GPS device.
Точки інтересу(../gpx) можна додавати до GPX-файлів, щоб позначати цікаві місця на карті та відображати їх на GPS-пристрої.
### Creating a point of interest
### Створити точку інтересу
To create a point of interest, fill in the form shown below.
You can choose the location of the point of interest either by clicking on the map or by entering the coordinates manually.
Validate the form when you are done.
Щоб додати точку інтересу, заповніть форму нижче.
Щоб указати розташування точки інтересу, клацніть на карті або введіть координати вручну.
Після заповнення збережіть форму.
<div class="flex flex-row justify-center">
<Waypoint class="text-foreground p-3 border rounded-md shadow-lg" />
</div>
### 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.
If you only need to move the point of interest, you can drag it to the desired location.
Форму вище також можна використовувати для редагування наявної точки інтересу після її вибору на карті.
Якщо потрібно лише перемістити точку інтересу, перетягніть її в потрібне місце.
+34 -34
View File
@@ -1,5 +1,5 @@
---
title: Route planning and editing
title: Планування та редагування маршруту
---
<script>
@@ -11,74 +11,74 @@ title: Route planning and editing
# <Pencil size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
The route planning and editing tool allows you to create and edit routes by placing or moving anchor points on the map.
Інструмент планування та редагування маршруту дає змогу створювати й редагувати маршрути, розміщуючи або переміщуючи точки на карті.
## Settings
## Налаштування
As shown below, the tool dialog contains a few settings to control the routing behavior.
You can minimize the dialog to save space by clicking on <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>.
Як показано нижче, діалогове вікно інструмент містить кілька параметрів, які можна контролювати поведінку побудови маршруту.
Щоб звільнити місце, діалогове вікно можна згорнути, натиснувши <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>.
<div class="flex flex-row justify-center">
<Routing minimizable={false} class="text-foreground p-3 border rounded-md shadow-lg" />
</div>
### <Route size="16" class="inline-block" style="margin-bottom: 2px" /> Routing
### <Route size="16" class="inline-block" style="margin-bottom: 2px" /> Побудова маршруту
When routing is enabled, anchor points placed or moved on the map will be connected by a route calculated on the <a href="https://www.openstreetmap.org" target="_blank">OpenStreetMap</a> road network.
Disable routing to connect anchor points with straight lines.
This setting can also be toggled by pressing <kbd>F5</kbd>.
Якщо побудову маршруту ввімкнено, точки, які ви розміщуєте або переміщуєте на карті, з’єднуються маршрутом, розрахованим за дорожньою мережею <a href="https://www.openstreetmap.org" target="_blank">OpenStreetMap</a>.
Вимкніть побудову маршруту, щоб з’єднувати точки прямими лініями.
Це налаштування також можна перемкнути, натиснувши <kbd>F5</kbd>.
### <Bike size="16" class="inline-block" style="margin-bottom: 2px" /> Activity
### <Bike size="16" class="inline-block" style="margin-bottom: 2px" /> Активність
Select the activity type to tailor the routes for.
Виберіть тип активності, для якої прокладати маршрути.
### <TriangleAlert size="16" class="inline-block" style="margin-bottom: 2px" /> Allow private roads
### <TriangleAlert size="16" class="inline-block" style="margin-bottom: 2px" /> Дозволити приватні дороги
When enabled, the routing engine will consider private roads when computing routes.
Якщо цей параметр увімкнено, приватні дороги враховуватимуться під час побудови маршрутів.
<DocsNote type="warning">
Only use this option if you have local knowledge of the area and have permission to use the roads in question.
Використовуйте цей параметр лише тоді, коли добре знаєте місцевість і маєте дозвіл користуватися відповідними дорогами.
</DocsNote>
## Plotting and editing routes
## Прокладання та редагування маршрутів
Creating a route or extending an existing one is as simple as clicking on the map to place a new anchor point.
Щоб створити маршрут або продовжити наявний, достатньо клацнути на карті й додати нову точку.
You can also drag an existing anchor point to reroute the segment connecting it with the previous and next anchor point.
Наявну точку також можна перетягнути, щоб перебудувати сегмент між нею та попередньою і наступною точками.
Furthermore, new anchor points can be inserted between existing ones by hovering over the segment connecting them and dragging the anchor point that appears to the desired location.
On touch devices, you can tap on the segment to insert a new anchor point.
Нові точки також можна додавати між наявними: наведіть курсор на сегмент, який їх з’єднує, і перетягніть точку, що з’явиться, у потрібне місце.
На пристроях із сенсорним екраном торкніться сегмента, щоб вставити нову точку.
<DocsNote>
When editing imported GPX files, an initial set of anchor points is created automatically.
To ease the editing process, the more the map is zoomed in, the more anchor points are displayed.
This allows the route to be edited at different levels of detail.
Під час редагування імпортованих GPX-файлів початковий набір точок створюється автоматично.
Щоб полегшити редагування, що більше наближено карту, то більше точок відображається.
Завдяки цьому маршрут можна редагувати з різною деталізацією.
</DocsNote>
Finally, you can delete anchor points by clicking on them and selecting <button><Trash2 size="16" class="inline-block" style="margin-bottom: 4px" /> Delete</button> from the context menu.
Нарешті, щоб видалити точку, клацніть на неї та виберіть <button><Trash2 size="16" class="inline-block" style="margin-bottom: 4px" /> Видалити</button> у контекстному меню.
<DocsImage src="tools/routing" alt="Anchor points allow you to easily edit a route." />
<DocsImage src="tools/routing" alt="Опорні точки спрощують редагування маршруту." />
## Additional tools
## Додаткові інструменти
The following tools automate some common route modification operations.
Інструменти нижче автоматизують деякі типові дії з редагування маршруту.
### <ArrowRightLeft size="16" class="inline-block" style="margin-bottom: 2px" /> Reverse
### <ArrowRightLeft size="16" class="inline-block" style="margin-bottom: 2px" /> Розвернути
Reverse the direction of the route.
Змінити напрямок маршруту.
### <House size="16" class="inline-block" style="margin-bottom: 2px" /> Back to start
### <House size="16" class="inline-block" style="margin-bottom: 2px" /> До початку маршруту
Connect the last point of the route with the starting point, using the chosen routing settings.
Замкнути маршрут до початкової точки з урахуванням вибраних налаштувань побудови маршруту.
### <Repeat size="16" class="inline-block" style="margin-bottom: 2px" /> Round trip
### <Repeat size="16" class="inline-block" style="margin-bottom: 2px" /> Маршрут туди й назад
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" /> Змінити початкову точку кільцевого маршруту
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.
Коли кінцева точка маршруту достатньо близько до початкової, можна змінити початок кільцевого маршруту: клацніть будь-яку точку й виберіть <button><CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> Почати кільцевий маршрут тут</button> у контекстному меню.
+12 -12
View File
@@ -1,5 +1,5 @@
---
title: Crop and split
title: Обрізання та розділення
---
<script>
@@ -10,23 +10,23 @@ title: Crop and split
# <ScissorsIcon size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
## Crop
## Обрізання
Using the slider, you can define the part of the selected trace that you want to keep.
The start and end markers on the map and the [statistics and elevation profile](../files-and-stats) are updated in real time to reflect the selection.
Alternatively, you can drag a selection rectangle directly on the elevation profile.
Validate the selection when you are satisfied with the result.
За допомогою повзунка можна визначити частину вибраного треку, яку потрібно залишити.
Початкова й кінцева позначки на карті, а також [статистика та профіль висоти](../files-and-stats) оновлюються в реальному часі відповідно до вибраної частини.
Також можна виділити потрібну частину, перетягнувши прямокутник безпосередньо на профілі висоти.
Коли результат вас влаштовує, підтвердьте вибір.
<div class="flex flex-row justify-center">
<Scissors class="text-foreground p-3 border rounded-md shadow-lg" />
</div>
## Split
## Розділення
To split the selected trace into two parts, click on one of the split markers displayed along the trace.
To split at a specific point of your choice, hover over the trace on the map.
Scissors will appear at the cursor position, showing that you can split the trace at that point.
Щоб розділити вибраний трек на дві частини, клацніть одну з позначок розділення, показаних уздовж треку.
Щоб розділити трек у потрібному місці, наведіть курсор на трек на карті.
На місці курсора з’явиться значок ножиць, який вказує, що тут можна розділити трек.
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).
Ви можете розділити трек на два GPX-файли або залишити розділені частини в тому самому файлі як [треки чи сегменти](../gpx).
<DocsImage src="tools/split" alt="Hovering over the selected trace turns your cursor into scissors." />
<DocsImage src="tools/split" alt="При наведенні на вибраний трек курсор змінюється на значок ножиць." />
+6 -6
View File
@@ -1,5 +1,5 @@
---
title: Time
title: Час
---
<script>
@@ -10,18 +10,18 @@ title: Time
# <CalendarClock size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
This tool allows you to change or add timestamps to a trace.
You simply need to use the form shown below and validate it when you are done.
Цей інструмент дає змогу змінювати або додавати часові мітки до треку.
Достатньо заповнити форму нижче й підтвердити її після завершення.
<div class="flex flex-row justify-center">
<Time class="text-foreground p-3 border rounded-md shadow-lg" />
</div>
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.
Коли ви змінюєте швидкість, час руху у формі відповідно оновлюється, і навпаки.
Аналогічно, під час зміни часу початку час завершення оновлюється, щоб загальна тривалість залишалася незмінною, і навпаки.
<DocsNote>
When using this tool with existing timestamps, changing the time or speed will simply shift, stretch, or compress them accordingly.
Якщо в треку вже є часові мітки, зміна часу або швидкості лише зсуне, розтягне чи стисне їх відповідно.
</DocsNote>
+2 -2
View File
@@ -1,5 +1,5 @@
---
title: FAQ
title: 常見問題
---
<script>
@@ -8,7 +8,7 @@ title: FAQ
# { title }
### Do I need to donate to use the website?
### 需要捐贈才能使用這網站嗎?
No.
The website is free to use and always will be (as long as it is financially sustainable).
@@ -1,5 +1,5 @@
---
title: Files and statistics
title: 檔案和統計
---
<script lang="ts">
@@ -19,7 +19,7 @@ title: Files and statistics
# { title }
## File list
## 檔案列表
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.
@@ -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).
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
## 檔案和統計
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.
+35 -35
View File
@@ -10,87 +10,87 @@ title: Edit actions
# { title }
與文件操作不同,編輯操作可能會修改目前選定文件的內容。
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_.
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.
若啟用檔案 [樹形佈局](../files-and-stats),操作也可作用於相關 [軌跡、路段和興趣點](../gpx)
在文件中,所有可通過以上操作修改的項目被稱為 _檔案項_。
注意,除復原和重做外,其餘操作也可通過右鍵點選檔案項來喚出操作菜單。
### <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>
This action is only available when the tree layout of the files list is enabled.
Additionally, the selection must be a single file.
此操作僅在啟用樹形佈局時可用,
所選內容必須是一個檔案。
</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>
This action is only available when the tree layout of the files list is enabled.
Additionally, the selection must be a single track.
此操作僅在啟用樹形佈局時可用,
且所選內容必須是單條軌跡。
</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>
This action is only available when the tree layout of the files list is enabled.
此操作僅在啟用樹形佈局時可用,
</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>
This action is only available when the tree layout of the files list is enabled.
此操作僅在啟用樹形佈局時可用,
</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>
This action is only available when the tree layout of the files list is enabled.
此操作僅在啟用樹形佈局時可用,
</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.
刪除所選檔案項。
+18 -18
View File
@@ -1,5 +1,5 @@
---
title: File actions
title: 檔案
---
<script lang="ts">
@@ -9,44 +9,44 @@ title: File actions
# { 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>
You can also drag and drop files directly from your file system into the window.
支援將檔案直接拖放到窗口中。
</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">
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>
+2 -2
View File
@@ -1,5 +1,5 @@
---
title: Settings
title: 設定
---
<script lang="ts">
@@ -9,7 +9,7 @@ title: Settings
# { 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.
@@ -13,7 +13,7 @@ title: Route planning and editing
The route planning and editing tool allows you to create and edit routes by placing or moving anchor points on the map.
## Settings
## 設定
As shown below, the tool dialog contains a few settings to control the routing behavior.
You can minimize the dialog to save space by clicking on <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>.
+1 -1
View File
@@ -59,7 +59,7 @@ title: 地图控件
<DocsLayers />
<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.
鼠标悬停在地图上,可在地形图底图上方显示 <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails 徒步路线</a> 叠加层。
</span>
</div>
+2 -2
View File
@@ -19,11 +19,11 @@ title: 编辑
撤销或重做最后一次执行的操作。
仅适用于在界面上直接进行的所有操作,不适用于显示选项、应用设置或地图导航。
### <Info size="16" class="inline-block" style="margin-bottom: 2px" /> 信息
### <Info size="16" class="inline-block" style="margin-bottom: 2px" /> 信息
用于查看或编辑所选文件项的名称和说明信息。
### <PaintBucket size="16" class="inline-block" style="margin-bottom: 2px" /> 外观
### <PaintBucket size="16" class="inline-block" style="margin-bottom: 2px" /> 外观
用于调整所选文件项在地图上显示的轨迹颜色、不透明度和线宽。
@@ -18,7 +18,7 @@ title: 请求海拔数据
<DocsNote>
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>.
海拔数据来自 <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>
查阅 <a href="https://mapterhorn.com/attribution/" target="_blank">官方文档</a> 以了解海拔数据来源及其准确度。
</DocsNote>
+8
View File
@@ -1,3 +1,5 @@
import { writable } from 'svelte/store';
type Dictionary = {
[key: string]: string | Dictionary;
};
@@ -10,6 +12,7 @@ function getDateFormatter(locale: string) {
}
class Locale {
private _store = writable(this);
private _lang = $state('');
private _isLoadingInitial = $state(true);
private _isLoading = $state(true);
@@ -38,6 +41,7 @@ class Locale {
}
import(`../locales/${this._lang}.json`).then((module) => {
this.dictionary = module.default;
this._store.set(this);
if (this._isLoadingInitial) {
this._isLoadingInitial = false;
}
@@ -67,6 +71,10 @@ class Locale {
public get df() {
return this._df;
}
public subscribe(run: (value: Locale) => void, invalidate?: (value?: Locale) => void) {
return this._store.subscribe(run, invalidate);
}
}
export const i18n = new Locale();
+1
View File
@@ -10,5 +10,6 @@ export const languages: Record<string, string> = {
nl: 'Nederlands',
'pt-BR': 'Português (Brasil)',
tr: 'Türkçe',
uk: 'Українська',
zh: '简体中文',
};
+5 -5
View File
@@ -1,6 +1,6 @@
import { get } from 'svelte/store';
import { selection } from '$lib/logic/selection';
import maplibregl from 'maplibre-gl';
import { LngLatBounds } from 'maplibre-gl';
import { ListFileItem, ListWaypointItem } from '$lib/components/file-list/file-list';
import { fileStateCollection, GPXFileStateCollectionObserver } from '$lib/logic/file-state';
import { gpxStatistics } from '$lib/logic/statistics';
@@ -10,7 +10,7 @@ import type { Coordinates } from 'gpx';
import { page } from '$app/state';
export class BoundsManager {
private _bounds: maplibregl.LngLatBounds = new maplibregl.LngLatBounds();
private _bounds: LngLatBounds = new LngLatBounds();
private _files: Set<string> = new Set();
private _fileStateCollectionObserver: GPXFileStateCollectionObserver | null = null;
private _unsubscribes: (() => void)[] = [];
@@ -75,7 +75,7 @@ export class BoundsManager {
this._unsubscribes.push(
map.subscribe((map_) => {
if (!map_) return;
map_.fitBounds(this._bounds, { padding: 80, linear: true, easing: () => 1 });
map_.fitBounds(this._bounds, { padding: 80, linear: true, animate: false });
this.reset();
})
);
@@ -87,12 +87,12 @@ export class BoundsManager {
}
this._unsubscribes.forEach((unsubscribe) => unsubscribe());
this._unsubscribes = [];
this._bounds = new maplibregl.LngLatBounds([180, 90, -180, -90]);
this._bounds = new LngLatBounds([180, 90, -180, -90]);
}
centerMapOnSelection() {
let selected = get(selection).getSelected();
let bounds = new maplibregl.LngLatBounds();
let bounds = new LngLatBounds();
if (selected.find((item) => item instanceof ListWaypointItem)) {
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
+6 -6
View File
@@ -1,16 +1,16 @@
import { ListItem, ListLevel } from '$lib/components/file-list/file-list';
import { GPXFile, GPXStatistics, GPXStatisticsGroup, type Track } from 'gpx';
import maplibregl from 'maplibre-gl';
import { LngLatBounds } from 'maplibre-gl';
export class GPXStatisticsTree {
level: ListLevel;
statistics: {
[key: string]: GPXStatisticsTree | GPXStatistics;
} = {};
wptBounds: maplibregl.LngLatBounds;
wptBounds: LngLatBounds;
constructor(element: GPXFile | Track) {
this.wptBounds = new maplibregl.LngLatBounds();
this.wptBounds = new LngLatBounds();
if (element instanceof GPXFile) {
this.level = ListLevel.FILE;
element.children.forEach((child, index) => {
@@ -49,11 +49,11 @@ export class GPXStatisticsTree {
return statistics;
}
intersectsBBox(bounds: maplibregl.LngLatBounds): boolean {
intersectsBBox(bounds: LngLatBounds): boolean {
for (let key in this.statistics) {
const stats = this.statistics[key];
if (stats instanceof GPXStatistics) {
const bbox = new maplibregl.LngLatBounds(
const bbox = new LngLatBounds(
stats.global.bounds.southWest,
stats.global.bounds.northEast
);
@@ -67,7 +67,7 @@ export class GPXStatisticsTree {
return false;
}
intersectsWaypointBBox(bounds: maplibregl.LngLatBounds): boolean {
intersectsWaypointBBox(bounds: LngLatBounds): boolean {
return !this.wptBounds.isEmpty() && this.wptBounds.intersects(bounds);
}
}
+4 -4
View File
@@ -3,7 +3,7 @@ import { twMerge } from 'tailwind-merge';
import { base } from '$app/paths';
import { languages } from '$lib/languages';
import { TrackPoint, Waypoint, type Coordinates, crossarcDistance, distance, GPXFile } from 'gpx';
import maplibregl from 'maplibre-gl';
import { Map as MapLibreMap, LngLatBounds } from 'maplibre-gl';
import { pointToTile, pointToTileFraction } from '@mapbox/tilebelt';
import type { GPXStatisticsTree } from '$lib/logic/statistics-tree';
import { ListTrackSegmentItem } from '$lib/components/file-list/file-list';
@@ -58,7 +58,7 @@ export function getClosestTrackSegments(
let segmentBounds = segmentStatistics.global.bounds;
let northEast = segmentBounds.northEast;
let southWest = segmentBounds.southWest;
let bounds = new maplibregl.LngLatBounds(southWest, northEast);
let bounds = new LngLatBounds(southWest, northEast);
if (bounds.contains(point)) {
segmentBoundsDistances.push([0, trackIndex, segmentIndex]);
} else {
@@ -106,7 +106,7 @@ export function getElevation(
let coordinates = points.map((point) =>
point instanceof TrackPoint || point instanceof Waypoint ? point.getCoordinates() : point
);
let bbox = new maplibregl.LngLatBounds();
let bbox = new LngLatBounds();
coordinates.forEach((coord) => bbox.extend(coord));
let tiles = coordinates.map((coord) => pointToTile(coord.lon, coord.lat, ELEVATION_ZOOM));
@@ -193,7 +193,7 @@ export function getElevation(
);
}
export function loadSVGIcon(map: maplibregl.Map, id: string, svg: string, size: number = 100) {
export function loadSVGIcon(map: MapLibreMap, id: string, svg: string, size: number = 100) {
if (!map.hasImage(id)) {
let icon = new Image(size, size);
icon.onload = () => {
+3 -3
View File
@@ -36,7 +36,7 @@
"switch_basemap": "Zur vorherigen Basemap wechseln",
"toggle_overlays": "Overlay umschalten",
"toggle_3d": "3D umschalten",
"fullscreen": "Full screen",
"fullscreen": "Vollbildmodus",
"settings": "Einstellungen",
"distance_units": "Entfernungseinheiten",
"metric": "Metrisch",
@@ -235,7 +235,7 @@
},
"elevation": {
"button": "Höhendaten anfragen",
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapterhorn.",
"help": "Das Anfordern von Höhendaten löscht die vorhandenen Höhendaten, falls vorhanden, und ersetzt diese durch Daten von Mapterhorn.",
"help_no_selection": "Wählen Sie ein Datei-Element, um Höhendaten anzufordern."
},
"waypoint": {
@@ -305,7 +305,7 @@
"united_kingdom": "Großbritannien",
"united_states": "USA",
"libertyTopo": "Liberty Topo",
"libertySatellite": "Liberty Satellite",
"libertySatellite": "Liberty Satellit",
"osm": "OpenMapTiles OSM",
"osmTopo": "OpenMapTiles OSM Topo",
"esriSatellite": "Esri Satellite",
+18 -18
View File
@@ -36,7 +36,7 @@
"switch_basemap": "Aldatu aurreko mapa erabiltzera",
"toggle_overlays": "Txandakatu geruzak",
"toggle_3d": "Txandakatu 3D",
"fullscreen": "Full screen",
"fullscreen": "Pantaila osoa",
"settings": "Ezarpenak",
"distance_units": "Distantzia unitateak",
"metric": "Metrikoa",
@@ -64,7 +64,7 @@
"ctrl": "Ctrl",
"click": "Klik",
"drag": "Arrastatu",
"right_click_drag": "Right-click drag",
"right_click_drag": "Eskuin klik eta errestan eraman",
"metadata": {
"button": "Informazioa...",
"name": "Izena",
@@ -192,8 +192,8 @@
"from": "Hasiera puntua errepide hurbilenetik oso hurrun dago",
"via": "Puntua errepide hurbilenetik oso hurrun dago",
"to": "Bukaera puntua errepide hurbilenetik oso hurrun dago",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"distance": "Bukaera-puntua hasiera-puntutik urrutiegi dago",
"connection": "Ez da konexiorik topatu puntuen artean",
"timeout": "Ibilbidea kalkulatzea luzeegi joan da, saiatu hurbilago dauden puntuak gehitzen"
}
},
@@ -235,7 +235,7 @@
},
"elevation": {
"button": "Eskatu altueraren datuak",
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapterhorn.",
"help": "Kota-datuak eskatzeak lehendik dauden kota-datuak ezabatuko ditu, halakorik balego, eta Mapterhorn-eko datuekin ordezkatuko dira.",
"help_no_selection": "Aukeratu fitxategi bat altuera datuak eskatzeko."
},
"waypoint": {
@@ -277,7 +277,7 @@
"new": "Geruza pertsonalizatu berria",
"edit": "Editatu geruza pertsonalizatua",
"urls": "URLa(k)",
"url_placeholder": "WMTS, WMS or MapLibre style JSON",
"url_placeholder": "WMTS, WMS edo MapLibre estiloko JSON",
"max_zoom": "Zoom max",
"layer_type": "Geruza mota",
"basemap": "Oinarrizko-mapa",
@@ -305,7 +305,7 @@
"united_kingdom": "Erresuma Batua",
"united_states": "Ameriketako Estatu Batuak",
"libertyTopo": "Liberty Topo",
"libertySatellite": "Liberty Satellite",
"libertySatellite": "Liberty Satelitea",
"osm": "OpenMapTiles OSM",
"osmTopo": "OpenMapTiles OSM Topo",
"esriSatellite": "Esri Satellite",
@@ -494,7 +494,7 @@
"email": "Eposta",
"contribute": "Lagundu",
"supported_by": "hauek lagunduta",
"features": "Features",
"features": "Funtzioak",
"route_planning": "Bideak planifikatzea",
"route_planning_description": "OpenStreetMapen datuetan oinarritutako interfaze erabilterraza kirol bakoitzerako ibilbideak sortzeko.",
"file_processing": "Fitxategien prozesaketa aurreratua",
@@ -503,15 +503,15 @@
"maps_description": "Oinarrizko mapa, geruza eta interes-puntuen bilduma zabala. Zure aire-libreko ekintzak planifikatzen lagunduko dizu!",
"data_visualization": "Datuak bistaratzea",
"data_visualization_description": "Grabatutako ekintzak edo etorkizuneko zure bideak aztertzeko altuera-profil interaktiboa.",
"philosophy": "Philosophy",
"foss": "Free, ad-free and open source",
"foss_description": "The website is free to use, without ads, and the source code is publicly available on GitHub.",
"privacy": "Privacy-friendly",
"privacy_description": "Your GPX files never leave your browser. No tracking, no data collection.",
"community": "Made possible by the community",
"community_description": "gpx.studio has an amazing community that has covered its costs through donations for years, while shaping the project through feature suggestions, bug reports, and translations into many languages.",
"support_button": "Support gpx.studio on Open Collective",
"translate_button": "Help translate the website on Crowdin"
"philosophy": "Filosofia",
"foss": "Doakoa, propagandarik gabe eta kode irekikoa",
"foss_description": "Webgunea doakoa da, iragarkirik gabe, eta iturburu-kodea publikoki eskuragarri dago GitHub-en.",
"privacy": "Pribatutasuna zaintzen du",
"privacy_description": "Zure GPX fitxategiak ez dira inoiz zure nabigatzailetik irteten. Ez dago jarraipenik, ez datu-bilketarik.",
"community": "Komunitateak posible egin du",
"community_description": "gpx.studio-k komunitate harrigarri bat du, urte luzez dohaintzen bidez bere kostuak estali dituena, proiektuaren ezaugarri-iradokizunen, akatsen txostenen eta hizkuntza askotarako itzulpenen bidez moldatu dena.",
"support_button": "Lagundu gpx.studio Open Collectiveren bidez",
"translate_button": "Lagundu webgunea itzultzen Crowdin-en"
},
"docs": {
"translate": "Lagundu itzulpenarekin Crowdinen",
@@ -536,7 +536,7 @@
},
"embedding": {
"title": "Sortu zure mapa",
"maptiler_key": "MapTiler key (optional, only required for MapTiler maps)",
"maptiler_key": "MapTiler gakoa (aukeran, bakarrik behar da MapTiler mapetan)",
"file_urls": "Fitxategien URLak (komarekin banatuta)",
"drive_ids": "Google Drive fitxategien IDak (komarekin banatuta)",
"basemap": "Oinarrizko-mapa",
+23 -23
View File
@@ -28,15 +28,15 @@
"undo": "Visszavonás ",
"redo": "Újra",
"delete": "Törlés",
"delete_all": "Delete all",
"delete_all": "Összes törlése",
"select_all": "Összes kijelölése",
"view": "Nézet",
"elevation_profile": "Magassági profil",
"tree_file_view": "File tree",
"tree_file_view": "Adat-fa nézet",
"switch_basemap": "Váltás az előző alaptérképre",
"toggle_overlays": "Átfedés váltása",
"toggle_3d": "3D nézet bekapcsolása",
"fullscreen": "Full screen",
"fullscreen": "Teljes képernyő",
"settings": "Beállítások",
"distance_units": "Távolságmérés mértékegységei",
"metric": "Metrikus",
@@ -64,7 +64,7 @@
"ctrl": "Ctrl",
"click": "Kattints",
"drag": "Húzza",
"right_click_drag": "Right-click drag",
"right_click_drag": "Jobb kattintásos mozgatás",
"metadata": {
"button": "Infó...",
"name": "Név",
@@ -82,7 +82,7 @@
"center": "Középre ",
"open_in": "Megnyitás itt ",
"copy_coordinates": "Koordináták másolása",
"edit_osm": "Edit in OpenStreetMap"
"edit_osm": "Szerkesztés OpenStreetMap-ben"
},
"toolbar": {
"routing": {
@@ -192,8 +192,8 @@
"from": "A kiindulási pont túl messze van a legközelebbi úttól",
"via": "A köztes pont túl messze van a legközelebbi úttól",
"to": "A végpont túl messze van a legközelebbi úttól",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"distance": "A végpont túl messze van a kezdőponttól",
"connection": "Nem található kapcsolat a két pont között",
"timeout": "Az útvonal kiszámítása túl sokáig tartott. Próbáljon meg közelebbi pontokat adni egymáshoz"
}
},
@@ -224,18 +224,18 @@
"help_merge_traces": "A kiválasztott útvonalak összekapcsolása egyetlen folyamatos útvonalat hoz létre.",
"help_cannot_merge_traces": "Kiválasztásának több útvonalat kell tartalmaznia ahhoz, hogy összekapcsolják őket.",
"help_merge_contents": "A kiválasztott elemek tartalmának egyesítésével az összes tartalom az első elemen belül csoportosul.",
"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."
"help_cannot_merge_contents": "A kijelölésnek több tételt kell tartalmaznia, ahhoz hogy egybevonható legyen.",
"selection_tip": "Tipp: használd a {KEYBOARD_SHORTCUT}, hogy hozzá adj a kijelöléshez."
},
"extract": {
"tooltip": "Extract contents to separate items",
"button": "Extract",
"help": "Extracting the contents of the selected items will create a separate item for each of their contents.",
"tooltip": "Tartalom szétrobbantása különálló elemekké",
"button": "Szétrobbant",
"help": "A kijelölt tartalmak szétrobbantása különálló elemeket hoz létre minden egyes elemből.",
"help_invalid_selection": "Több nyomvonalat kell tartalmazzon a kijelölés a kinyeréshez."
},
"elevation": {
"button": "Magassági információk lekérése",
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapterhorn.",
"help": "A \"Magassági adatok lekérése\" törölni fogja a meglévő magassági adatokat és lecseréli a Mapterhorn által szolgáltatott adatokra.",
"help_no_selection": "Select a file item to request elevation data."
},
"waypoint": {
@@ -286,7 +286,7 @@
"update": "Réteg feltöltése"
},
"opacity": "Átfedés átlátszósága",
"terrain": "Terrain source",
"terrain": "Domborzat forrása",
"label": {
"basemaps": "Alaptérkép",
"overlays": "Térkép rétegek",
@@ -305,7 +305,7 @@
"united_kingdom": "Anglia",
"united_states": "Amerika",
"libertyTopo": "Liberty Topo",
"libertySatellite": "Liberty Satellite",
"libertySatellite": "Liberty Műhold",
"osm": "OpenMapTiles OSM",
"osmTopo": "OpenMapTiles OSM Topo",
"esriSatellite": "Esri Satellite",
@@ -325,7 +325,7 @@
"ignFrScan25": "IGN SCAN25",
"ignFrSatellite": "IGN Műhold",
"ignEs": "IGN Topo",
"ignEsSatellite": "IGN Satellite",
"ignEsSatellite": "IGN Műhold",
"ordnanceSurvey": "Hadifelmérés",
"norwayTopo": "Norvégia topográfiai térképe 4",
"finlandTopo": "Lantmäteriverket Tereptérkép",
@@ -333,7 +333,7 @@
"usgs": "USGS",
"bikerouterGravel": "kerékpár és terepkerékpár út",
"cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "Mapterhorn Hillshade",
"mapterhornHillshade": "Mapterhorn Árnyékolt Domborzat",
"openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "swisstopo Lejtő",
"swisstopoHiking": "swisstopo Túra",
@@ -363,7 +363,7 @@
"water": "Víz",
"shower": "Zuhanyozó",
"shelter": "Menedék",
"cemetery": "Cemetery",
"cemetery": "Temető / Sírkert",
"motorized": "Autók és Motorok",
"fuel-station": "Benzinkút",
"parking": "Parkoló",
@@ -374,11 +374,11 @@
"viewpoint": "Kilátó",
"hotel": "Hotel",
"campsite": "Kemping",
"hut": "Hut",
"hut": "Kunyhó",
"picnic": "Piknikező hely",
"summit": "Csúcs",
"pass": "Pass",
"climbing": "Climbing",
"pass": "Hágó",
"climbing": "Mászás",
"bicycle": "Kerékpár",
"bicycle-parking": "Kerékpár parkoló",
"bicycle-rental": "Kerékpár bérélés",
@@ -401,12 +401,12 @@
"temperature": "Hőmérséklet",
"speed": "Sebesség",
"pace": "Tempó",
"heartrate": "Heart rate",
"heartrate": "Pulzusszám",
"cadence": "Lépés/Pedál ütem",
"power": "Erő",
"slope": "Erőkifejtési szintkép színekkel",
"surface": "Szintkép",
"highway": "Category",
"highway": "Kategória",
"time": "Idő",
"moving": "Moving",
"total": "Összes",
+22 -22
View File
@@ -28,7 +28,7 @@
"undo": "Anulează",
"redo": "Refă",
"delete": "Șterge",
"delete_all": "Delete all",
"delete_all": "Șterge tot",
"select_all": "Selectează tot",
"view": "Vizualizare",
"elevation_profile": "Profil de altitudine",
@@ -36,7 +36,7 @@
"switch_basemap": "Comutați la harta de bază anterioară",
"toggle_overlays": "Comută suprapunerile",
"toggle_3d": "Comută 3D",
"fullscreen": "Full screen",
"fullscreen": "Ecran complet",
"settings": "Setări",
"distance_units": "Unități de distanță",
"metric": "Metric",
@@ -62,46 +62,46 @@
"more": "Mai multe...",
"donate": "Donați",
"ctrl": "Ctrl",
"click": "Click",
"click": "Clic",
"drag": "Drag",
"right_click_drag": "Right-click drag",
"metadata": {
"button": "Info...",
"name": "Name",
"button": "Informații...",
"name": "Nume",
"description": "Descriere",
"save": "Save"
"save": "Salvează"
},
"style": {
"button": "Aspect...",
"color": "Color",
"color": "Culoare",
"opacity": "Opacitate",
"width": "Width"
"width": "Lățime"
},
"hide": "Ascunde",
"unhide": "Dezvăluie",
"center": "Center",
"open_in": "Open in",
"center": "Centrează",
"open_in": "Deschide în",
"copy_coordinates": "Copiază coordonatele",
"edit_osm": "Edit in OpenStreetMap"
"edit_osm": "Editează în OpenStreetMap"
},
"toolbar": {
"routing": {
"tooltip": "Planifică sau editează o rută",
"activity": "Activitate",
"use_routing": "Rutare",
"use_routing_tooltip": "Connect anchor points via road network, or in a straight line if disabled",
"allow_private": "Allow private roads",
"use_routing_tooltip": "Conectează puncte de ancorare prin rețeaua rutieră sau în linie dreaptă dacă este dezactivată",
"allow_private": "Permite drumuri private",
"reverse": {
"button": "Reverse",
"button": "Inversează",
"tooltip": "Reverse the direction of the route"
},
"route_back_to_start": {
"button": "Back to start",
"tooltip": "Connect the last point of the route with the starting point"
"button": "Înapoi la punctul de plecare",
"tooltip": "Conectează ultimul punct al rutei cu punctul de plecare"
},
"round_trip": {
"button": "Round trip",
"tooltip": "Return to the starting point by the same route"
"button": "Călătorie dus-întors",
"tooltip": "Întoarce-te la punctul de plecare pe aceeași rută"
},
"start_loop_here": "Start loop here",
"help_no_file": "Select a trace to use the routing tool, or click on the map to start creating a new route.",
@@ -120,7 +120,7 @@
"unknown": "Necunoscut",
"paved": "Asfaltat",
"unpaved": "Unpaved",
"asphalt": "Asphalt",
"asphalt": "Asfalt",
"concrete": "Concrete",
"cobblestone": "Pavaj",
"paving_stones": "Pavaj din pietre",
@@ -140,11 +140,11 @@
"grass": "Iarbă",
"grass_paver": "Pavaj cu iarbă",
"clay": "Clay",
"stone": "Stone"
"stone": "Piatră"
},
"highway": {
"unknown": "Unknown",
"motorway": "Highway",
"unknown": "Necunoscut",
"motorway": "Autostradă",
"motorway_link": "Highway link",
"trunk": "Primary road",
"trunk_link": "Primary road link",
+24 -24
View File
@@ -13,7 +13,7 @@
"new_track": "Новий трек",
"new_segment": "Новий сегмент",
"open": "Відкрити...",
"duplicate": "Дублікат",
"duplicate": "Дублювати",
"copy": "Копіювати",
"paste": "Вставити",
"cut": "Вирізати",
@@ -33,10 +33,10 @@
"view": "Вигляд",
"elevation_profile": "Профіль рельєфу",
"tree_file_view": "Дерево файлів",
"switch_basemap": ерехід до попередньої базової карти",
"toggle_overlays": "Перемикання накладок",
"switch_basemap": "Попередня базова карта",
"toggle_overlays": "Перемкнути накладені шари",
"toggle_3d": "Перемикнути 3D",
"fullscreen": "Full screen",
"fullscreen": "На весь екран",
"settings": "Налаштування",
"distance_units": "Одиниці виміру відстані",
"metric": "Метричні",
@@ -62,7 +62,7 @@
"more": "Більше...",
"donate": "Пожертвувати",
"ctrl": "Ctrl",
"click": "Клац",
"click": "Клік мишею",
"drag": "Перетягти",
"right_click_drag": "Перетягування правою кнопкою миші",
"metadata": {
@@ -74,12 +74,12 @@
"style": {
"button": "Зовнішність...",
"color": "Колір",
"opacity": "Непрозорість",
"opacity": "Прозорість",
"width": "Ширина"
},
"hide": "Приховати",
"unhide": "Показати",
"center": "Центр",
"center": "По центру",
"open_in": "Відкрити в",
"copy_coordinates": "Копіювати координати",
"edit_osm": "Редагувати в OpenStreetMap"
@@ -92,7 +92,7 @@
"use_routing_tooltip": "З'єднати опорні точки через мережу доріг або по прямій лінії, якщо вони недоступні",
"allow_private": "Дозволити приватні дороги",
"reverse": {
"button": "У зворотньому порядку",
"button": "У зворотньому напрямку",
"tooltip": "Змінити напрямок маршруту"
},
"route_back_to_start": {
@@ -200,29 +200,29 @@
"scissors": {
"tooltip": "Обрізати або розділити",
"crop": "Обрізати",
"split_as": "Розділити слід на",
"help_invalid_selection": "Виберіть слід для обрізання чи розділення.",
"split_as": "Розділити трек на",
"help_invalid_selection": "Виберіть трек для обрізання або розділення.",
"help": "Використовуйте повзунок, щоб обрізати слід, або розділіть його, клацнувши на один з маркерів розбиття або на самому маршруті."
},
"time": {
"tooltip": "Керування даними часу",
"tooltip": "Керувати даними часу",
"start": "Початок",
"end": "Кінець",
"total_time": "Час руху",
"pick_date": "Оберіть дату",
"artificial": "Створюйте реалістичні дані часу",
"artificial": "Створити реалістичні дані часу",
"update": "Оновити дані часу",
"help": "Скористайтеся формою, щоб встановити нові дані часу.",
"help_invalid_selection": "Виберіть один трек для керування його часовими даними."
},
"merge": {
"merge_traces": "З'єднайте треки",
"merge_traces": "З'єднати треки",
"merge_contents": "Об'єднати вміст та зберегти треки від'єднаними",
"merge_selection": "Об'єднати вибрані",
"remove_gaps": "Видалити проміжки часу між слідами",
"tooltip": "Об'єднати елементи",
"help_merge_traces": "Об'єднання вибраних слідів створить один безперервний слід.",
"help_cannot_merge_traces": "Ваш вибір повинен містити декілька слідів для їх об'єднання.",
"help_cannot_merge_traces": "Щоб з’єднати треки, вибір має містити кілька треків.",
"help_merge_contents": "Об'єднання вмісту вибраних елементів згрупує все у першому елементі.",
"help_cannot_merge_contents": "Ваш вибір має містити декілька елементів для об'єднання їх вмісту.",
"selection_tip": "Порада: використовуйте {KEYBOARD_SHORTCUT}, щоб додати елементи до виділення."
@@ -235,11 +235,11 @@
},
"elevation": {
"button": "Запит даних висот",
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapterhorn.",
"help": "Запит даних висот призведе до видалення наявних даних висот, якщо вони є, і замінить їх даними з Mapterhorn.",
"help_no_selection": "Виберіть елемент файлу, щоб запросити дані про висоту."
},
"waypoint": {
"tooltip": "Створення та редагування визначних місць",
"tooltip": "Створити та редагувати точки інтересу",
"icon": "Іконка",
"link": "Посилання",
"longitude": "Довгота",
@@ -255,17 +255,17 @@
"number_of_points": "Кількість точок GPS",
"button": "Мінімізувати",
"help": "Використовуйте повзунок, щоб вибрати кількість точок GPS, які потрібно зберегти.",
"help_no_selection": "Оберіть слід для зменшення кількості його GPS точок."
"help_no_selection": "Виберіть трек, щоб зменшити кількість його GPS-точок."
},
"clean": {
"tooltip": "Очистити GPS точки та точки інтересів, використовуючи прямокутний вибір",
"delete_trackpoints": "Видалити точки GPS",
"delete_waypoints": "Видалити цікаві місця",
"delete_inside": "Видалити всередині виділення",
"delete_outside": "Видалити зовнішній вибір",
"delete_outside": "Видалити за межами виділення",
"button": "Видалити",
"help": "Виберіть прямокутну область на карті, щоб видалити точки GPS та точки інтересу.",
"help_no_selection": "Виберіть слід, щоб очистити точки GPS та точки інтересу."
"help_no_selection": "Виберіть трек для очищення GPS-точок і точок інтересу."
}
},
"layers": {
@@ -281,15 +281,15 @@
"max_zoom": "Максимальний зум",
"layer_type": "Тип шару",
"basemap": "Базова карта",
"overlay": "Накладання",
"overlay": "Накладений шар",
"create": "Створити шар",
"update": "Оновити шар"
},
"opacity": "Непрозорість накладання",
"opacity": "Прозорість накладеного шару",
"terrain": "Джерело інформації про місцевість",
"label": {
"basemaps": "Базові карти",
"overlays": "Накладання",
"overlays": "Накладені шари",
"custom": "Користувацька",
"world": "Світ",
"countries": "Країни",
@@ -396,7 +396,7 @@
},
"quantities": {
"distance": "Відстань",
"elevation": "Підвищення",
"elevation": "Висота",
"elevation_gain_loss": "Набір і втрата висоти",
"temperature": "Температура",
"speed": "Швидкість",
@@ -404,7 +404,7 @@
"heartrate": "Пульс",
"cadence": "Каденс",
"power": "Потужність",
"slope": "Схил",
"slope": "Ухил",
"surface": "Поверхня",
"highway": "Категорія",
"time": "Час",
+433 -433
View File
@@ -2,308 +2,308 @@
"metadata": {
"home_title": "線上 GPX 檔案編輯器",
"app_title": "app",
"embed_title": "",
"help_title": "",
"404_title": "page not found",
"description": "。"
"embed_title": "線上 GPX 檔案編輯器",
"help_title": "幫助",
"404_title": "無法找到相關頁面",
"description": "線上查看、編輯和建立 GPX 檔案,包含高級路線規劃、檔案管理器、精美的地圖和詳細的資料可視化功能。"
},
"menu": {
"new": "New",
"new_file": "New file",
"new_track": "New track",
"new_segment": "New segment",
"open": "Open...",
"duplicate": "Duplicate",
"copy": "Copy",
"paste": "Paste",
"new": "新建",
"new_file": "新增檔案",
"new_track": "新增路徑",
"new_segment": "新增路段",
"open": "開啟...",
"duplicate": "建立副本",
"copy": "複製",
"paste": "貼上",
"cut": "剪下",
"export": "匯出……",
"export_all": "匯出所有……",
"export_options": "Export options",
"support_message": "The tool is free to use, but not free to run. Please consider supporting the website if you use it frequently. Thank you!",
"support_button": "Help keep the website free",
"download_file": "Download file",
"download_files": "Download files",
"edit": "Edit",
"undo": "Undo",
"redo": "Redo",
"delete": "Delete",
"delete_all": "Delete all",
"select_all": "Select all",
"view": "View",
"elevation_profile": "Elevation profile",
"tree_file_view": "File tree",
"switch_basemap": "Switch to previous basemap",
"toggle_overlays": "Toggle overlays",
"toggle_3d": "Toggle 3D",
"fullscreen": "Full screen",
"settings": "Settings",
"distance_units": "Distance units",
"metric": "Metric",
"imperial": "Imperial",
"nautical": "Nautical",
"velocity_units": "Velocity units",
"temperature_units": "Temperature units",
"celsius": "Celsius",
"fahrenheit": "Fahrenheit",
"language": "Language",
"mode": "Theme",
"system": "System",
"light": "Light",
"dark": "Dark",
"export_options": "匯出選項",
"support_message": "本工具免費使用,但運行此網站有成本。若您經常使用,請考慮捐贈以支持我們。非常感謝!",
"support_button": "幫助網站保持免費",
"download_file": "下載檔案",
"download_files": "下載所有檔案",
"edit": "編輯",
"undo": "復原",
"redo": "重做",
"delete": "刪除",
"delete_all": "全部刪除",
"select_all": "全選",
"view": "顯示",
"elevation_profile": "海拔剖面圖",
"tree_file_view": "檔案樹狀圖",
"switch_basemap": "切換到上一個底圖",
"toggle_overlays": "切換疊加層",
"toggle_3d": "切換三維檢視",
"fullscreen": "全螢幕",
"settings": "設定",
"distance_units": "距離單位",
"metric": "公制",
"imperial": "英制",
"nautical": "航海",
"velocity_units": "速度單位",
"temperature_units": "溫度單位",
"celsius": "攝氏",
"fahrenheit": "華氏",
"language": "語言",
"mode": "主題",
"system": "系統",
"light": "淺色",
"dark": "深色",
"street_view_source": "街景原始檔",
"mapillary": "Mapillary",
"google": "Google",
"toggle_street_view": "Street view",
"layers": "Map layers...",
"distance_markers": "Distance markers",
"direction_markers": "Direction arrows",
"help": "Help",
"more": "More...",
"donate": "Donate",
"toggle_street_view": "街景",
"layers": "地圖圖層...",
"distance_markers": "距離標記",
"direction_markers": "方向箭頭",
"help": "幫助",
"more": "更多...",
"donate": "捐贈",
"ctrl": "Ctrl",
"click": "Click",
"drag": "Drag",
"right_click_drag": "Right-click drag",
"click": "點選",
"drag": "拖動",
"right_click_drag": "右鍵拖動",
"metadata": {
"button": "Info...",
"name": "Name",
"description": "Description",
"save": "Save"
"button": "資訊...",
"name": "名稱",
"description": "說明",
"save": "保存"
},
"style": {
"button": "Appearance...",
"color": "Color",
"opacity": "Opacity",
"width": "Width"
"button": "外觀...",
"color": "配色",
"opacity": "透明度",
"width": "闊度"
},
"hide": "Hide",
"unhide": "Unhide",
"center": "Center",
"open_in": "Open in",
"copy_coordinates": "Copy coordinates",
"edit_osm": "Edit in OpenStreetMap"
"hide": "隱藏",
"unhide": "取消隱藏",
"center": "置中",
"open_in": "打開於",
"copy_coordinates": "複製座標",
"edit_osm": " OpenStreetMap 中編輯"
},
"toolbar": {
"routing": {
"tooltip": "Plan or edit a route",
"activity": "Activity",
"use_routing": "Routing",
"use_routing_tooltip": "Connect anchor points via road network, or in a straight line if disabled",
"allow_private": "Allow private roads",
"tooltip": "規劃或編輯路線",
"activity": "活動",
"use_routing": "路線",
"use_routing_tooltip": "通過路網連接錨點,若停用用直線連接",
"allow_private": "允許私家路",
"reverse": {
"button": "Reverse",
"tooltip": "Reverse the direction of the route"
"button": "反向",
"tooltip": "反轉路線方向"
},
"route_back_to_start": {
"button": "Back to start",
"tooltip": "Connect the last point of the route with the starting point"
"button": "返回起點",
"tooltip": "連接路線的起點與終點"
},
"round_trip": {
"button": "Round trip",
"tooltip": "Return to the starting point by the same route"
"button": "往返路線",
"tooltip": "按原路返回起點"
},
"start_loop_here": "Start loop here",
"help_no_file": "Select a trace to use the routing tool, or click on the map to start creating a new route.",
"help": "Click on the map to add a new anchor point, or drag existing ones to change the route.",
"start_loop_here": "在此開始循環",
"help_no_file": "選擇軌跡進行編輯,或在地圖上點選以建立新路線。",
"help": "點選地圖以加入新錨點,或拖動現有錨點以改變路線。",
"activities": {
"bike": "Bike",
"racing_bike": "Road bike",
"gravel_bike": "Gravel bike",
"mountain_bike": "Mountain bike",
"foot": "Run/hike",
"motorcycle": "Motorcycle",
"water": "Water",
"railway": "Railway"
"bike": "單車",
"racing_bike": "公路單車",
"gravel_bike": "礫石單車",
"mountain_bike": "越野單車",
"foot": "跑步/遠足",
"motorcycle": "電單車",
"water": "水上活動",
"railway": "鐵路"
},
"surface": {
"unknown": "Unknown",
"paved": "Paved",
"unpaved": "Unpaved",
"asphalt": "Asphalt",
"concrete": "Concrete",
"cobblestone": "Cobblestone",
"unknown": "未知",
"paved": "鋪砌路面",
"unpaved": "未鋪砌路面",
"asphalt": "瀝青路",
"concrete": "混凝土",
"cobblestone": "鵝卵石",
"paving_stones": "鋪路石",
"sett": "石板",
"metal": "Metal",
"wood": "Wood",
"compacted": "Compacted gravel",
"fine_gravel": "Fine gravel",
"gravel": "Gravel",
"pebblestone": "Pebblestone",
"rock": "Rock",
"dirt": "Dirt",
"ground": "Ground",
"earth": "Earth",
"mud": "Mud",
"sand": "Sand",
"grass": "Grass",
"grass_paver": "Grass paver",
"clay": "Clay",
"stone": "Stone"
"metal": "金屬",
"wood": "木材",
"compacted": "壓實的礫石",
"fine_gravel": "細礫",
"gravel": "砂礫",
"pebblestone": "卵石",
"rock": "岩石",
"dirt": "泥土",
"ground": "地面",
"earth": "土地",
"mud": "泥地",
"sand": "沙粒",
"grass": "草地",
"grass_paver": "草坪",
"clay": "黏土",
"stone": "石頭"
},
"highway": {
"unknown": "Unknown",
"motorway": "Highway",
"motorway_link": "Highway link",
"trunk": "Primary road",
"trunk_link": "Primary road link",
"primary": "Primary road",
"primary_link": "Primary road link",
"secondary": "Secondary road",
"secondary_link": "Secondary road link",
"tertiary": "Tertiary road",
"tertiary_link": "Tertiary road link",
"unclassified": "Minor road",
"residential": "Residential road",
"living_street": "Living street",
"service": "Service road",
"track": "Track",
"footway": "Footway",
"path": "Path",
"pedestrian": "Pedestrian",
"cycleway": "Cycleway",
"steps": "Steps",
"road": "Road",
"bridleway": "Horseriding path",
"platform": "Platform",
"unknown": "未知類型",
"motorway": "高速公路",
"motorway_link": "高速公路引道",
"trunk": "快速公路",
"trunk_link": "快速公路連接路",
"primary": "快速公路",
"primary_link": "快速公路連接路",
"secondary": "主要道路",
"secondary_link": "主要道路連接路",
"tertiary": "支路",
"tertiary_link": "支路連接路",
"unclassified": "小路",
"residential": "居住區道路",
"living_street": "住宅街道",
"service": "輔助道路",
"track": "小徑(未鋪設道路)",
"footway": "",
"path": "小徑",
"pedestrian": "行人路",
"cycleway": "單車徑",
"steps": "石級",
"road": "道路",
"bridleway": "馬道",
"platform": "停靠站台",
"raceway": "競賽賽道",
"rest_area": "Rest area",
"abandoned": "Abandoned",
"services": "Services",
"corridor": "Corridor",
"bus_stop": "Bus stop",
"busway": "Busway",
"elevator": "Elevator",
"via_ferrata": "Via ferrata",
"proposed": "已規劃但未興建的道路",
"construction": "Road under construction"
"rest_area": "停車區",
"abandoned": "廢棄道路",
"services": "服務區",
"corridor": "走廊",
"bus_stop": "巴士站",
"busway": "巴士線",
"elevator": "升降機",
"via_ferrata": "鐵鎖攀岩",
"proposed": "未興建的道路",
"construction": "興建中的道路"
},
"sac_scale": {
"hiking": "遠足",
"mountain_hiking": "登山遠足",
"demanding_mountain_hiking": "Demanding mountain hiking",
"demanding_mountain_hiking": "高難度登山路徑 (T3級)",
"alpine_hiking": "高山遠足",
"demanding_alpine_hiking": "Demanding alpine hiking",
"difficult_alpine_hiking": "Difficult alpine hiking"
"demanding_alpine_hiking": "高難度登山路徑 (T5級)",
"difficult_alpine_hiking": "高難度登山路徑 (T6級)"
},
"mtb_scale": "MTB scale",
"mtb_scale": "越野單車徑難度分級",
"error": {
"from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together"
"from": "起點離最近的道路太遠",
"via": "途徑點離最近的道路太遠",
"to": "終點離最近的道路太遠",
"distance": "起點到終點的距離太遠",
"connection": "找不到連接途徑點的路線",
"timeout": "軌跡計算耗時太長,請嘗試減少點與點的距離"
}
},
"scissors": {
"tooltip": "Crop or split",
"crop": "Crop",
"split_as": "Split the trace into",
"help_invalid_selection": "Select a trace to crop or split.",
"help": "Use the slider to crop the trace, or split it by clicking on one of the split markers or on the trace itself."
"tooltip": "裁剪或拆分",
"crop": "裁剪",
"split_as": "將軌跡拆分為",
"help_invalid_selection": "須先選擇要裁剪或拆分的軌跡。",
"help": "移動滑塊以確認裁剪範圍,或點選軌跡上的分割標記以拆分。"
},
"time": {
"tooltip": "Manage time data",
"start": "Start",
"end": "End",
"total_time": "Moving time",
"pick_date": "Pick a date",
"artificial": "Create realistic time data",
"update": "Update time data",
"help": "Use the form to set new time data.",
"help_invalid_selection": "Select a single trace to manage its time data."
"tooltip": "管理時間資料",
"start": "開始",
"end": "結束",
"total_time": "移動時間",
"pick_date": "選擇日期",
"artificial": "建立實際時間資料",
"update": "更新時間資料",
"help": "使用表單設定新的時間資料。",
"help_invalid_selection": "選擇一個軌跡來管理時間資料。"
},
"merge": {
"merge_traces": "Connect the traces",
"merge_contents": "Merge the contents and keep the traces disconnected",
"merge_selection": "Merge selection",
"remove_gaps": "Remove time gaps between traces",
"tooltip": "Merge items together",
"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_merge_contents": "Merging the contents of the selected items will group all the contents inside the first item.",
"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."
"merge_traces": "合併為一條連續軌跡",
"merge_contents": "合併但保持軌跡獨立",
"merge_selection": "合併",
"remove_gaps": "刪除軌跡的時間間隔",
"tooltip": "合併項目",
"help_merge_traces": "連接所選內容並建立一個連續的軌跡。",
"help_cannot_merge_traces": "須先選擇多個檔案以合併。",
"help_merge_contents": "合併所選內容並將結果儲存於第一個檔案。",
"help_cannot_merge_contents": "須先選擇多個檔案以合併。",
"selection_tip": "可使用 {KEYBOARD_SHORTCUT} 新增項目至選擇中。"
},
"extract": {
"tooltip": "Extract contents to separate items",
"button": "Extract",
"help": "Extracting the contents of the selected items will create a separate item for each of their contents.",
"help_invalid_selection": "Your selection must contain items with multiple traces to extract them."
"tooltip": "提取為多個獨立項目",
"button": "提取",
"help": "該操作將為每個軌跡建立一個單獨的檔案。",
"help_invalid_selection": "須先選擇包含多個軌跡的檔案以提取。"
},
"elevation": {
"button": "Request elevation data",
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapterhorn.",
"help_no_selection": "Select a file item to request elevation data."
"button": "請求海拔資料",
"help": "請求成功後將移除原有的海拔資料,並使用 Mapterhorn 的海拔資料替換原有資料。",
"help_no_selection": "選擇要請求海拔資料的檔案。"
},
"waypoint": {
"tooltip": "Create and edit points of interest",
"icon": "Icon",
"link": "Link",
"longitude": "Longitude",
"latitude": "Latitude",
"create": "Create point of interest",
"add": "Add point of interest to file",
"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_no_selection": "Select a file to create or edit points of interest."
"tooltip": "建立或編輯興趣點",
"icon": "圖示",
"link": "連結",
"longitude": "經度",
"latitude": "緯度",
"create": "新增興趣點",
"add": "將興趣點加入到檔案",
"help": "通過表單建立新興趣點,或點選現有興趣點以編輯。 點選地圖並填充坐標點,或拖動興趣點以移動坐標。",
"help_no_selection": "選擇檔案以建立或編輯興趣點。"
},
"reduce": {
"tooltip": "Reduce the number of GPS points",
"tolerance": "Tolerance",
"number_of_points": "Number of GPS points",
"tooltip": "精簡 GPS 點數量",
"tolerance": "最大間距",
"number_of_points": "GPS 點數量",
"button": "簡化",
"help": "Use the slider to choose the number of GPS points to keep.",
"help_no_selection": "Select a trace to reduce the number of its GPS points."
"help": "移動滑塊以調整要保留的 GPS 點數量。",
"help_no_selection": "選擇一個軌跡以減少其 GPS 點的數量。"
},
"clean": {
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
"delete_trackpoints": "Delete GPS points",
"delete_waypoints": "Delete points of interest",
"delete_inside": "Delete inside selection",
"delete_outside": "Delete outside selection",
"button": "Delete",
"help": "Select a rectangle area on the map to remove GPS points and points of interest.",
"help_no_selection": "Select a trace to clean GPS points and points of interest."
"tooltip": "使用矩形選區清除項目",
"delete_trackpoints": "刪除 GPS 點",
"delete_waypoints": "刪除興趣點",
"delete_inside": "清除選區內部項目",
"delete_outside": "清除選區外的項目",
"button": "刪除",
"help": "在地圖上繪製矩形選區以清除。",
"help_no_selection": "選擇一個軌跡以清除其 GPS 點和興趣點。"
}
},
"layers": {
"settings": "Layer settings",
"settings_help": "Select the map layers you want to show in the interface, add custom ones, and adjust their settings.",
"selection": "Layer selection",
"settings": "圖層設定",
"settings_help": "選擇要在介面中顯示的地圖圖層,或加入自訂圖層,並作出必要調整。",
"selection": "選擇圖層",
"custom_layers": {
"title": "Custom layers",
"new": "New custom layer",
"edit": "Edit custom layer",
"urls": "URL(s)",
"url_placeholder": "WMTS, WMS or MapLibre style JSON",
"max_zoom": "Max zoom",
"layer_type": "Layer type",
"basemap": "Basemap",
"overlay": "Overlay",
"create": "Create layer",
"update": "Update layer"
"title": "自訂圖層",
"new": "新建自訂圖層",
"edit": "編輯自訂圖層",
"urls": "URL",
"url_placeholder": "WMTSWMS MapLibre style JSON",
"max_zoom": "最大縮放等級",
"layer_type": "圖層類型",
"basemap": "底圖",
"overlay": "疊加層",
"create": "新增圖層",
"update": "更新圖層"
},
"opacity": "Overlay opacity",
"terrain": "Terrain source",
"opacity": "圖層透明度",
"terrain": "地形來源",
"label": {
"basemaps": "Basemaps",
"overlays": "Overlays",
"custom": "Custom",
"world": "World",
"countries": "Countries",
"belgium": "Belgium",
"bulgaria": "Bulgaria",
"finland": "Finland",
"france": "France",
"new_zealand": "New Zealand",
"norway": "Norway",
"spain": "Spain",
"sweden": "Sweden",
"switzerland": "Switzerland",
"united_kingdom": "United Kingdom",
"united_states": "United States",
"basemaps": "底圖",
"overlays": "疊加層",
"custom": "自訂",
"world": "世界",
"countries": "國家/地區",
"belgium": "比利時",
"bulgaria": "保加利亞",
"finland": "芬蘭",
"france": "法國",
"new_zealand": "紐西蘭",
"norway": "挪威",
"spain": "西班牙",
"sweden": "瑞典",
"switzerland": "瑞士",
"united_kingdom": "英國",
"united_states": "美國",
"libertyTopo": "Liberty Topo",
"libertySatellite": "Liberty Satellite",
"osm": "OpenMapTiles OSM",
@@ -316,108 +316,108 @@
"utagawaVTT": "UtagawaMTB",
"linz": "LINZ Topo",
"linzTopo": "LINZ Topo50",
"swisstopoRaster": "swisstopo Raster",
"swisstopoVector": "swisstopo Vector",
"swisstopoSatellite": "swisstopo Satellite",
"swisstopoRaster": "swisstopo 柵格",
"swisstopoVector": "swisstopo 向量",
"swisstopoSatellite": "swisstopo 衛星地圖",
"ignBe": "IGN Topo",
"ignFrPlan": "IGN Plan",
"ignFrTopo": "IGN Topo",
"ignFrScan25": "IGN SCAN25",
"ignFrSatellite": "IGN Satellite",
"ignFrSatellite": "IGN 衛星地圖",
"ignEs": "IGN Topo",
"ignEsSatellite": "IGN Satellite",
"ordnanceSurvey": "Ordnance Survey",
"ordnanceSurvey": "Ordnance Survey(英國地形測量局)",
"norwayTopo": "Topografisk Norgeskart 4",
"finlandTopo": "Lantmäteriverket Terrängkarta",
"finlandTopo": "Lantmteriverket Terrngkarta",
"bgMountains": "BGMountains",
"usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "Mapterhorn Hillshade",
"openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "swisstopo Slope",
"swisstopoHiking": "swisstopo Hiking",
"swisstopoHikingClosures": "swisstopo Hiking Closures",
"swisstopoCycling": "swisstopo Cycling",
"swisstopoCyclingClosures": "swisstopo Cycling Closures",
"swisstopoMountainBike": "swisstopo MTB",
"swisstopoMountainBikeClosures": "swisstopo MTB Closures",
"swisstopoSkiTouring": "swisstopo Ski Touring",
"swisstopoSlope": "swisstopo 地形",
"swisstopoHiking": "swisstopo 遠足",
"swisstopoHikingClosures": "swisstopo 登山封閉路線",
"swisstopoCycling": "swisstopo 單車",
"swisstopoCyclingClosures": "swisstopo 單車封閉路線",
"swisstopoMountainBike": "swisstopo 越野單車",
"swisstopoMountainBikeClosures": "swisstopo 越野單車封閉路線",
"swisstopoSkiTouring": "swisstopo 滑雪巡遊",
"ignFrCadastre": "IGN Cadastre",
"ignSlope": "IGN Slope",
"ignSkiTouring": "IGN Ski Touring",
"waymarked_trails": "Waymarked Trails",
"waymarkedTrailsHiking": "Hiking",
"waymarkedTrailsCycling": "Cycling",
"waymarkedTrailsMTB": "MTB",
"waymarkedTrailsSkating": "Skating",
"waymarkedTrailsHorseRiding": "Horse Riding",
"waymarkedTrailsWinter": "Winter",
"points_of_interest": "Points of interest",
"food": "Food",
"bakery": "Bakery",
"food-store": "Food Store",
"eat-and-drink": "Eat and Drink",
"amenities": "Amenities",
"toilets": "Toilets",
"water": "Water",
"shower": "Shower",
"shelter": "Shelter",
"cemetery": "Cemetery",
"motorized": "Cars and Motorcycles",
"fuel-station": "Fuel Station",
"parking": "Parking",
"garage": "Garage",
"barrier": "Barrier",
"tourism": "Tourism",
"attraction": "Attraction",
"viewpoint": "Viewpoint",
"hotel": "Hotel",
"campsite": "Campsite",
"hut": "Hut",
"picnic": "Picnic Area",
"summit": "Summit",
"pass": "Pass",
"climbing": "Climbing",
"bicycle": "Bicycle",
"bicycle-parking": "Bicycle Parking",
"bicycle-rental": "Bicycle Rental",
"bicycle-shop": "Bicycle Shop",
"public-transport": "Public Transport",
"railway-station": "Railway Station",
"tram-stop": "Tram Stop",
"bus-stop": "Bus Stop",
"ferry": "Ferry",
"ignSlope": "IGN 地形",
"ignSkiTouring": "IGN 滑雪巡遊",
"waymarked_trails": "標記路線",
"waymarkedTrailsHiking": "遠足",
"waymarkedTrailsCycling": "單車",
"waymarkedTrailsMTB": "越野單車",
"waymarkedTrailsSkating": "滑冰",
"waymarkedTrailsHorseRiding": "騎馬",
"waymarkedTrailsWinter": "冬季路線",
"points_of_interest": "興趣點",
"food": "食物",
"bakery": "麵包店",
"food-store": "食品店",
"eat-and-drink": "餐飲店",
"amenities": "便利設施",
"toilets": "廁所",
"water": "飲用水",
"shower": "淋浴",
"shelter": "庇護所",
"cemetery": "墓地",
"motorized": "汽車和電單車",
"fuel-station": "油站",
"parking": "停車場",
"garage": "車庫",
"barrier": "障礙物",
"tourism": "旅游",
"attraction": "景點",
"viewpoint": "觀景台",
"hotel": "酒店",
"campsite": "營地",
"hut": "小屋",
"picnic": "野餐區",
"summit": "頂峰",
"pass": "山坳",
"climbing": "攀爬",
"bicycle": "單車",
"bicycle-parking": "單車架",
"bicycle-rental": "單車出租店",
"bicycle-shop": "單車店",
"public-transport": "公共交通",
"railway-station": "火車站",
"tram-stop": "電車站",
"bus-stop": "巴士站",
"ferry": "渡口",
"mapterhorn": "Mapterhorn"
}
},
"chart": {
"settings": "Elevation profile settings"
"settings": "海拔剖面圖設定"
},
"quantities": {
"distance": "Distance",
"elevation": "Elevation",
"elevation_gain_loss": "Elevation gain and loss",
"temperature": "Temperature",
"speed": "Speed",
"pace": "Pace",
"heartrate": "Heart rate",
"cadence": "Cadence",
"power": "Power",
"slope": "Slope",
"surface": "Surface",
"highway": "Category",
"time": "Time",
"moving": "Moving",
"total": "Total",
"osm_extensions": "OpenStreetMap data"
"distance": "距離",
"elevation": "海拔",
"elevation_gain_loss": "累計爬升和下降",
"temperature": "温度",
"speed": "速度",
"pace": "配速",
"heartrate": "心率",
"cadence": "踏頻",
"power": "功率",
"slope": "坡度",
"surface": "路面",
"highway": "類型",
"time": "時間",
"moving": "運動",
"total": "全部",
"osm_extensions": "OpenStreetMap 資料"
},
"units": {
"meters": "m",
"feet": "ft",
"kilometers": "km",
"miles": "mi",
"nautical_miles": "nm",
"meters": "",
"feet": "英呎",
"kilometers": "公里",
"miles": "英里",
"nautical_miles": "海里",
"celsius": "°C",
"fahrenheit": "°F",
"kilometers_per_hour": "km/h",
@@ -425,136 +425,136 @@
"minutes_per_kilometer": "min/km",
"minutes_per_mile": "min/mi",
"minutes_per_nautical_mile": "min/nm",
"knots": "kn",
"knots": "",
"heartrate": "bpm",
"cadence": "rpm",
"power": "W"
},
"gpx": {
"file": "File",
"files": "Files",
"track": "Track",
"tracks": "Tracks",
"segment": "Segment",
"segments": "Segments",
"waypoint": "Point of interest",
"waypoints": "Points of interest",
"file": "檔案",
"files": "檔案",
"track": "軌跡",
"tracks": "軌跡",
"segment": "路段",
"segments": "路段",
"waypoint": "興趣點",
"waypoints": "興趣點",
"symbol": {
"alert": "Alert",
"anchor": "Anchor",
"bank": "Bank",
"beach": "Beach",
"bike_trail": "Bike Trail",
"binoculars": "Binoculars",
"bridge": "Bridge",
"building": "Building",
"campground": "Campsite",
"car": "Car",
"car_repair": "Garage",
"convenience_store": "Convenience Store",
"crossing": "Crossing",
"department_store": "Department Store",
"drinking_water": "Water",
"exit": "Exit",
"lodge": "Hut",
"lodging": "Accommodation",
"forest": "Forest",
"gas_station": "Fuel Station",
"ground_transportation": "Ground Transportation",
"hotel": "Hotel",
"house": "House",
"information": "Information",
"park": "Park",
"parking_area": "Parking",
"pharmacy": "Pharmacy",
"picnic_area": "Picnic Area",
"restaurant": "Restaurant",
"restricted_area": "Restricted Area",
"restroom": "Toilets",
"road": "Road",
"scenic_area": "Scenic Area",
"shelter": "Shelter",
"shopping_center": "Shopping Center",
"shower": "Shower",
"summit": "Summit",
"telephone": "Telephone",
"tunnel": "Tunnel",
"water_source": "Water Source"
"alert": "警告",
"anchor": "錨點",
"bank": "銀行",
"beach": "海灘",
"bike_trail": "單車徑",
"binoculars": "望遠鏡",
"bridge": "",
"building": "大廈",
"campground": "營地",
"car": "車輛",
"car_repair": "車庫",
"convenience_store": "便利店",
"crossing": "交叉路口",
"department_store": "百貨店",
"drinking_water": "飲用水",
"exit": "出口",
"lodge": "小屋",
"lodging": "住宿",
"forest": "森林",
"gas_station": "油站",
"ground_transportation": "地面交通",
"hotel": "酒店",
"house": "住宅",
"information": "資訊",
"park": "公園",
"parking_area": "停車場",
"pharmacy": "藥房",
"picnic_area": "野餐區",
"restaurant": "餐廳",
"restricted_area": "管制區域",
"restroom": "廁所",
"road": "道路",
"scenic_area": "景區",
"shelter": "庇護所",
"shopping_center": "購物中心",
"shower": "淋浴",
"summit": "山峰",
"telephone": "電話",
"tunnel": "隧道",
"water_source": "水源"
}
},
"homepage": {
"website": "Website",
"home": "Home",
"app": "App",
"contact": "Contact",
"website": "官方網站",
"home": "首頁",
"app": "應用程式",
"contact": "聯絡我們",
"reddit": "Reddit",
"facebook": "Facebook",
"github": "GitHub",
"crowdin": "Crowdin",
"email": "Email",
"contribute": "Contribute",
"supported_by": "supported by",
"features": "Features",
"route_planning": "Route planning",
"route_planning_description": "An intuitive interface to create itineraries tailored to each sport, based on OpenStreetMap data.",
"file_processing": "Advanced file processing",
"file_processing_description": "A suite of tools for performing all common file processing tasks, and which can be applied to multiple files at once.",
"maps": "Global and local maps",
"maps_description": "A large collection of basemaps, overlays and points of interest to help you craft your next outdoor adventure, or visualize your latest achievement.",
"data_visualization": "Data visualization",
"data_visualization_description": "An interactive elevation profile with detailed statistics to analyze recorded activities and future objectives.",
"philosophy": "Philosophy",
"foss": "Free, ad-free and open source",
"foss_description": "The website is free to use, without ads, and the source code is publicly available on GitHub.",
"privacy": "Privacy-friendly",
"privacy_description": "Your GPX files never leave your browser. No tracking, no data collection.",
"community": "Made possible by the community",
"community_description": "gpx.studio has an amazing community that has covered its costs through donations for years, while shaping the project through feature suggestions, bug reports, and translations into many languages.",
"support_button": "Support gpx.studio on Open Collective",
"translate_button": "Help translate the website on Crowdin"
"email": "電郵",
"contribute": "參與貢獻",
"supported_by": "技術支援",
"features": "功能",
"route_planning": "路線規劃",
"route_planning_description": "基於 OpenStreetMap 數據,在直觀的介面中為每項運動建立量身定製的行程。",
"file_processing": "高級檔案處理",
"file_processing_description": "一系列常見的檔案處理工具,支援對多個檔案同時進行操作。",
"maps": "全球和本地地圖",
"maps_description": "內建大量地圖底圖、疊加圖層和興趣點,用於幫助規劃戶外冒險或可視化成果。",
"data_visualization": "數據可視化",
"data_visualization_description": "可互動的海拔剖面圖,帶有詳細的統計數據,用於分析已記錄的活動和規劃中的目標。",
"philosophy": "宗旨",
"foss": "免費、無廣告、開源",
"foss_description": "此網站可自由使用,無廣告,原始碼可在 GitHub 上公開查閱。",
"privacy": "注重隱私",
"privacy_description": "你的 GPX 檔案永遠不會離開你的瀏覽器。我們不會跟蹤使用者的使用行為,也不會收集使用者產生的資料。",
"community": "由社區驅動",
"community_description": "gpx.studio 有一個絕讚的社區,它通過社區成員的捐助持續營運。它通過社區的力量,不斷增加新的功能、修復 bug,並支援多種語言。",
"support_button": " Open Collective 上支持 gpx.studio",
"translate_button": " Crowdin 上協助翻譯"
},
"docs": {
"translate": "Improve the translation on Crowdin",
"answer_not_found": "Did not find what you were looking for?",
"ask_on_reddit": "Ask the community on Reddit",
"translate": " Crowdin 上改進此翻譯",
"answer_not_found": "找不到您想要的內容?",
"ask_on_reddit": " Reddit 上詢問社區",
"search": {
"search": "Search",
"clear": "Clear",
"cancel": "Cancel",
"recent": "Recent searches",
"no_recent": "No recent searches",
"save": "Save this search",
"remove": "Remove this search from history",
"favorites": "Favorites",
"remove_favorite": "Remove this search from favorites",
"to_select": "to select",
"to_navigate": "to navigate",
"to_close": "to close",
"no_results": "No results for",
"no_results_suggestion": "Try searching for"
"search": "搜尋",
"clear": "清除",
"cancel": "取消",
"recent": "最近搜尋",
"no_recent": "沒有近期的搜尋紀錄",
"save": "保存至搜尋歷史",
"remove": "從搜尋歷史中移除",
"favorites": "我的最愛",
"remove_favorite": "取消收藏",
"to_select": "選擇",
"to_navigate": "切換",
"to_close": "退出",
"no_results": "沒有找到相關資料:",
"no_results_suggestion": "請嘗試以下關鍵詞:"
}
},
"embedding": {
"title": "Create your own map",
"maptiler_key": "MapTiler key (optional, only required for MapTiler maps)",
"file_urls": "File URLs (separated by commas)",
"drive_ids": "Google Drive file IDs (separated by commas)",
"basemap": "Basemap",
"height": "Height",
"fill_by": "Fill by",
"none": "None",
"show_controls": "Show controls",
"manual_camera": "Manual camera",
"manual_camera_description": "You can move the map below to adjust the camera position.",
"latitude": "Latitude",
"longitude": "Longitude",
"zoom": "Zoom",
"pitch": "Pitch",
"bearing": "Bearing",
"preview": "Preview",
"code": "Integration code"
"title": "建立您的地圖",
"maptiler_key": "MapTiler key (可選,僅在使用 MapTiler 地圖時需要提供)",
"file_urls": "檔案連結(英文逗號分隔)",
"drive_ids": "Google 雲端硬碟檔案 IDs(英文逗號分隔)",
"basemap": "底圖",
"height": "高度",
"fill_by": "填充方式",
"none": "無填充",
"show_controls": "顯示控制項",
"manual_camera": "手動調整視角",
"manual_camera_description": "移動下方地圖以調整相機位置。",
"latitude": "緯度",
"longitude": "經度",
"zoom": "縮放",
"pitch": "傾角",
"bearing": "方位",
"preview": "預覽",
"code": "整合代碼"
},
"webgl2_required": "WebGL 2 is required to display the map.",
"enable_webgl2": "Learn how to enable WebGL 2 in your browser",
"page_not_found": "page not found"
"webgl2_required": "須先啟用 WebGL 2 才能顯示地圖。",
"enable_webgl2": "學習如何在瀏覽器中啟用 WebGL 2",
"page_not_found": "無法找到相關頁面"
}
+14 -14
View File
@@ -156,7 +156,7 @@
"tertiary_link": "乡道/支路的连接路段",
"unclassified": "小型道路",
"residential": "居住区道路",
"living_street": "生活性街道",
"living_street": "住宅街道",
"service": "服务性道路",
"track": "小径(未铺设道路)",
"footway": "步行道路",
@@ -187,7 +187,7 @@
"demanding_alpine_hiking": "相对简单的攀爬部分,UIAA I-II 级(T5",
"difficult_alpine_hiking": "更长的攀爬部分,UIAA II 级(T6"
},
"mtb_scale": "山地地形",
"mtb_scale": "山地自行车难度分级",
"error": {
"from": "起点离最近的道路太远",
"via": "途径点离最近的道路太远",
@@ -222,9 +222,9 @@
"remove_gaps": "删除轨迹间的时间间隔",
"tooltip": "合并要素",
"help_merge_traces": "连接所选内容并生成一个连续轨迹。",
"help_cannot_merge_traces": "须先选择多个文件以合并",
"help_cannot_merge_traces": "须先选择多个文件以合并",
"help_merge_contents": "合并所选内容并将结果存储于第一个文件。",
"help_cannot_merge_contents": "须先选择多个文件以合并",
"help_cannot_merge_contents": "须先选择多个文件以合并",
"selection_tip": "可使用 {KEYBOARD_SHORTCUT} 进行多选。"
},
"extract": {
@@ -235,7 +235,7 @@
},
"elevation": {
"button": "请求海拔数据",
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapterhorn.",
"help": "请求成功后将移除原有的海拔数据,并使用 Mapterhorn 的海拔数据替换原有数据。",
"help_no_selection": "选择要请求海拔数据的文件。"
},
"waypoint": {
@@ -264,8 +264,8 @@
"delete_inside": "清除选区内部要素",
"delete_outside": "清除选区外部要素",
"button": "删除",
"help": "在地图上绘制矩形选区以清除",
"help_no_selection": "选择一个轨迹以清除其 GPS 点和兴趣点"
"help": "在地图上绘制矩形选区以清除",
"help_no_selection": "选择一个轨迹以清除其 GPS 点和兴趣点"
}
},
"layers": {
@@ -277,7 +277,7 @@
"new": "新建自定义图层",
"edit": "编辑自定义图层",
"urls": "URL(s)",
"url_placeholder": "WMTSWMS 或 MapLibre style JSON",
"url_placeholder": "WMTSWMS 或 MapLibre style JSON",
"max_zoom": "最大缩放等级",
"layer_type": "图层类型",
"basemap": "底图",
@@ -333,7 +333,7 @@
"usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "山体阴影",
"mapterhornHillshade": "Mapterhorn Hillshade",
"openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "Swisstopo Slope",
"swisstopoHiking": "Swisstopo Hiking",
@@ -377,12 +377,12 @@
"hut": "小屋",
"picnic": "野餐区",
"summit": "顶峰",
"pass": "关卡",
"pass": "山坳",
"climbing": "攀爬",
"bicycle": "自行车",
"bicycle-parking": "停车区",
"bicycle-rental": "出租",
"bicycle-shop": "车店",
"bicycle-parking": "自行车停车区",
"bicycle-rental": "自行车出租",
"bicycle-shop": "自行车店",
"public-transport": "公共交通",
"railway-station": "火车站",
"tram-stop": "有轨电车站",
@@ -445,7 +445,7 @@
"bank": "银行",
"beach": "海滩",
"bike_trail": "自行车道",
"binoculars": "观察点",
"binoculars": "望远镜",
"bridge": "桥",
"building": "建筑物",
"campground": "营地",