55 Commits

Author SHA1 Message Date
vcoppe
7d3423f9ad New translations settings.mdx (Greek) 2026-04-02 18:54:06 +02:00
vcoppe
e077de9f48 remove obsolete files 2026-04-02 18:47:59 +02:00
vcoppe
7586f03998 New Crowdin updates (#307)
* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Vietnamese)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Thai)

* New translations en.json (Latvian)

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

* New translations en.json (Serbian (Latin))

* New translations funding.mdx (Dutch)

* New translations en.json (Dutch)

* New translations en.json (Spanish)

* New translations en.json (Basque)

* New translations en.json (Dutch)

* New translations en.json (Catalan)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Belarusian)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Korean)

* New translations en.json (Lithuanian)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Vietnamese)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Thai)

* New translations en.json (Latvian)

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

* New translations en.json (Serbian (Latin))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* New translations files-and-stats.mdx (Chinese Simplified)

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

* New translations files-and-stats.mdx (Portuguese, Brazilian)

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

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

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

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

* New translations files-and-stats.mdx (Serbian (Latin))

* New translations integration.mdx (Romanian)

* New translations integration.mdx (French)

* New translations integration.mdx (Spanish)

* New translations integration.mdx (Belarusian)

* New translations integration.mdx (Catalan)

* New translations integration.mdx (Czech)

* New translations integration.mdx (Danish)

* New translations integration.mdx (German)

* New translations integration.mdx (Greek)

* New translations integration.mdx (Basque)

* New translations integration.mdx (Finnish)

* New translations integration.mdx (Hebrew)

* New translations integration.mdx (Hungarian)

* New translations integration.mdx (Italian)

* New translations integration.mdx (Korean)

* New translations integration.mdx (Lithuanian)

* New translations integration.mdx (Dutch)

* New translations integration.mdx (Norwegian)

* New translations integration.mdx (Polish)

* New translations integration.mdx (Portuguese)

* New translations integration.mdx (Russian)

* New translations integration.mdx (Swedish)

* New translations integration.mdx (Turkish)

* New translations integration.mdx (Ukrainian)

* New translations integration.mdx (Chinese Simplified)

* New translations integration.mdx (Vietnamese)

* New translations integration.mdx (Portuguese, Brazilian)

* New translations integration.mdx (Indonesian)

* New translations integration.mdx (Thai)

* New translations integration.mdx (Latvian)

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

* New translations integration.mdx (Serbian (Latin))

* New translations merge.mdx (Romanian)

* New translations merge.mdx (French)

* New translations merge.mdx (Spanish)

* New translations merge.mdx (Belarusian)

* New translations merge.mdx (Catalan)

* New translations merge.mdx (Czech)

* New translations merge.mdx (Danish)

* New translations merge.mdx (German)

* New translations merge.mdx (Greek)

* New translations merge.mdx (Basque)

* New translations merge.mdx (Finnish)

* New translations merge.mdx (Hebrew)

* New translations merge.mdx (Hungarian)

* New translations merge.mdx (Italian)

* New translations merge.mdx (Korean)

* New translations merge.mdx (Lithuanian)

* New translations merge.mdx (Dutch)

* New translations merge.mdx (Norwegian)

* New translations merge.mdx (Polish)

* New translations merge.mdx (Portuguese)

* New translations merge.mdx (Russian)

* New translations merge.mdx (Swedish)

* New translations merge.mdx (Turkish)

* New translations merge.mdx (Ukrainian)

* New translations merge.mdx (Chinese Simplified)

* New translations merge.mdx (Vietnamese)

* New translations merge.mdx (Portuguese, Brazilian)

* New translations merge.mdx (Indonesian)

* New translations merge.mdx (Thai)

* New translations merge.mdx (Latvian)

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

* New translations merge.mdx (Serbian (Latin))

* New translations map-controls.mdx (Romanian)

* New translations map-controls.mdx (French)

* New translations map-controls.mdx (Spanish)

* New translations map-controls.mdx (Belarusian)

* New translations map-controls.mdx (Catalan)

* New translations map-controls.mdx (Czech)

* New translations map-controls.mdx (Danish)

* New translations map-controls.mdx (German)

* New translations map-controls.mdx (Greek)

* New translations map-controls.mdx (Basque)

* New translations map-controls.mdx (Finnish)

* New translations map-controls.mdx (Hebrew)

* New translations map-controls.mdx (Hungarian)

* New translations map-controls.mdx (Italian)

* New translations map-controls.mdx (Korean)

* New translations map-controls.mdx (Lithuanian)

* New translations map-controls.mdx (Dutch)

* New translations map-controls.mdx (Norwegian)

* New translations map-controls.mdx (Polish)

* New translations map-controls.mdx (Portuguese)

* New translations map-controls.mdx (Russian)

* New translations map-controls.mdx (Swedish)

* New translations map-controls.mdx (Turkish)

* New translations map-controls.mdx (Ukrainian)

* New translations map-controls.mdx (Chinese Simplified)

* New translations map-controls.mdx (Vietnamese)

* New translations map-controls.mdx (Portuguese, Brazilian)

* New translations map-controls.mdx (Indonesian)

* New translations map-controls.mdx (Thai)

* New translations map-controls.mdx (Latvian)

* New translations map-controls.mdx (Chinese Traditional, Hong Kong)

* New translations map-controls.mdx (Serbian (Latin))

* New translations en.json (French)

* New translations integration.mdx (French)

* New translations map-controls.mdx (French)

* New translations merge.mdx (French)

* New translations elevation.mdx (French)

* New translations en.json (Basque)

* New translations en.json (Dutch)

* New translations en.json (Catalan)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Belarusian)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Korean)

* New translations en.json (Lithuanian)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Vietnamese)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Thai)

* New translations en.json (Latvian)

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

* New translations en.json (Serbian (Latin))

* New translations integration.mdx (Dutch)

* New translations map-controls.mdx (Spanish)

* New translations map-controls.mdx (Dutch)

* New translations merge.mdx (Dutch)

* New translations en.json (Basque)

* New translations en.json (Dutch)

* New translations en.json (Catalan)

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Belarusian)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Korean)

* New translations en.json (Lithuanian)

* New translations en.json (Norwegian)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Vietnamese)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Thai)

* New translations en.json (Latvian)

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

* New translations en.json (Serbian (Latin))

* New translations en.json (Dutch)

* New translations en.json (French)

* New translations en.json (Spanish)
2026-04-02 18:43:41 +02:00
vcoppe
af8c22dcda redirect to app from image 2026-04-02 18:41:49 +02:00
vcoppe
3dce5dc617 improve filtering to always show layers in the same order 2026-04-01 09:01:01 +02:00
vcoppe
84b90e1026 remove unused import 2026-04-01 08:36:33 +02:00
vcoppe
d507586eed fix small shift 2026-04-01 08:33:17 +02:00
vcoppe
57afaedf83 rephrasing 2026-03-29 23:22:36 +02:00
vcoppe
48063b9066 allow line breaks in buttons 2026-03-29 23:06:59 +02:00
vcoppe
452d356599 rephrase 2026-03-29 22:56:48 +02:00
vcoppe
25eda8041e slight rephrasing 2026-03-29 22:38:31 +02:00
vcoppe
ae4d5356eb fix color 2026-03-29 22:31:57 +02:00
vcoppe
3343bb906e format for crowdin 2026-03-29 20:34:52 +02:00
vcoppe
7b17900160 simplify styling 2026-03-29 20:21:52 +02:00
vcoppe
d5f1fe1c7b finish homepage 2026-03-29 20:04:38 +02:00
vcoppe
553f73f992 change break point for centering 2026-03-29 15:14:21 +02:00
vcoppe
c8cedf2e2c simplify illustration 2026-03-29 14:06:59 +02:00
vcoppe
a751817847 max size for docs 2026-03-28 19:41:44 +01:00
vcoppe
d1ef12db8d work in progress 2026-03-28 19:31:52 +01:00
vcoppe
43d73edf29 small fix 2026-03-28 17:12:43 +01:00
vcoppe
5a0b8c376c small ui changes 2026-03-28 13:03:25 +01:00
vcoppe
9743fd460e update embedding instructions 2026-03-28 12:09:31 +01:00
vcoppe
f70f92a176 change note type 2026-03-28 11:42:11 +01:00
vcoppe
1a4175446c add missing instructions 2026-03-28 11:40:27 +01:00
vcoppe
ed6dfab4c1 fix embedding spacing 2026-03-28 11:32:25 +01:00
vcoppe
6a6e1105c0 update images 2026-03-28 11:32:05 +01:00
vcoppe
1677fe254b move theme button and search bar 2026-03-28 08:41:30 +01:00
vcoppe
02efe708c2 update maplibre 2026-03-27 21:47:17 +01:00
vcoppe
7dc834f506 small ui fixes 2026-03-27 21:32:33 +01:00
vcoppe
57c4958ff2 refresh routing controls on style load 2026-03-27 21:23:51 +01:00
vcoppe
03e59a8cce change default basemap 2026-03-27 19:43:01 +01:00
vcoppe
f3d18f09a0 refresh markers on style load 2026-03-27 19:21:25 +01:00
vcoppe
c1dbd984e6 fix validator 2026-03-27 19:07:48 +01:00
vcoppe
e4f227221d small detail 2026-03-27 18:49:32 +01:00
vcoppe
34139974aa change 3D shortcut 2026-03-27 18:49:20 +01:00
vcoppe
408b2422e6 add missing value 2026-03-27 18:35:25 +01:00
vcoppe
b59cb9e200 Merge branch 'maplibre' into dev 2026-03-27 18:31:23 +01:00
vcoppe
bd5cb65d0f switch ko-fi to open collective 2026-03-25 21:53:10 +01:00
vcoppe
4cfe487af0 fix typo 2026-03-18 18:35:33 +01:00
vcoppe
4da2e39e32 Merge branch 'graphhopper' into dev
migrate to graphhopper
2026-03-18 18:28:05 +01:00
vcoppe
5ff11a32c9 update readme 2026-03-15 17:00:03 +01:00
vcoppe
01a7ec916e remove console log 2026-03-07 15:59:08 +01:00
vcoppe
dd94a7d613 catch graphhopper exceptions 2026-03-07 15:57:58 +01:00
vcoppe
089b88c62d update graphhopper url 2026-03-07 15:30:22 +01:00
vcoppe
9c6e03f4a8 improve layer stacking 2026-01-30 21:30:37 +01:00
vcoppe
2a4dfe010e improve color management 2026-01-30 21:17:59 +01:00
vcoppe
f42a916c25 remove unused parameter 2026-01-30 21:17:11 +01:00
vcoppe
772b810fa8 simplify initialization 2026-01-30 21:16:56 +01:00
vcoppe
4d4d10d5c2 small UI tweaks 2026-01-30 21:16:32 +01:00
vcoppe
0e4c7dbe64 New translations en.json (Chinese Simplified) (#306) 2026-01-30 21:02:21 +01:00
vcoppe
a01ca79a82 finer-grained road access 2026-01-18 15:23:39 +01:00
vcoppe
c91baf7c83 switch gravel to graphhopper 2026-01-17 11:58:47 +01:00
vcoppe
5062de8ddf Merge branch 'dev' into graphhopper 2026-01-17 11:42:30 +01:00
vcoppe
9ca46b9d35 small fix 2025-12-24 17:21:26 +01:00
vcoppe
7c2e24bbc4 draft support for graphhopper 2025-12-23 16:49:47 +01:00
359 changed files with 2386 additions and 2527 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1 +1 @@
ko_fi: gpxstudio
open_collective: gpxstudio

View File

@@ -5,7 +5,7 @@
[**gpx.studio**](https://gpx.studio) is an online tool for creating and editing GPX files.
![gpx.studio screenshot](website/src/lib/assets/img/docs/getting-started/interface.png)
![gpx.studio screenshot](website/src/lib/assets/img/docs/getting-started/interface.webp)
This repository contains the source code of the website.
@@ -69,8 +69,8 @@ This project has been made possible thanks to the following open source projects
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) — fast GPX file parsing
- [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 maps
- [brouter](https://github.com/abrensch/brouter) — routing engine
- [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
- Search:
- [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation

View File

@@ -1398,10 +1398,7 @@ export class TrackPoint {
: undefined;
}
setExtensions(extensions: Record<string, string>) {
if (Object.keys(extensions).length === 0) {
return;
}
setExtension(key: string, value: string) {
if (!this.extensions) {
this.extensions = {};
}
@@ -1411,8 +1408,12 @@ export class TrackPoint {
if (!this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions']) {
this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions'] = {};
}
Object.entries(extensions).forEach(([key, value]) => {
this.extensions['gpxtpx:TrackPointExtension']['gpxtpx:Extensions'][key] = value;
}
setExtensions(extensions: Record<string, string>) {
Object.entries(extensions).forEach(([key, value]) => {
this.setExtension(key, value);
});
}

View File

@@ -22,7 +22,7 @@
"immer": "^10.1.1",
"jszip": "^3.10.1",
"mapillary-js": "^4.1.2",
"maplibre-gl": "^5.16.0",
"maplibre-gl": "^5.21.1",
"sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6",
"tailwind-merge": "^3.3.0"
@@ -1611,31 +1611,6 @@
"svelte": "^5"
}
},
"node_modules/@mapbox/geojson-rewind": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz",
"integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==",
"license": "ISC",
"dependencies": {
"get-stream": "^6.0.1",
"minimist": "^1.2.6"
},
"bin": {
"geojson-rewind": "geojson-rewind"
}
},
"node_modules/@mapbox/geojson-rewind/node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@mapbox/jsonlint-lines-primitives": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
@@ -1670,7 +1645,8 @@
"node_modules/@mapbox/unitbezier": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
"integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw=="
"integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==",
"license": "BSD-2-Clause"
},
"node_modules/@mapbox/vector-tile": {
"version": "2.0.4",
@@ -1704,10 +1680,13 @@
}
},
"node_modules/@maplibre/geojson-vt": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-5.0.4.tgz",
"integrity": "sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==",
"license": "ISC"
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.0.4.tgz",
"integrity": "sha512-HYv3POhMRCdhP3UPPATM/hfcy6/WuVIf5FKboH8u/ZuFMTnAIcSVlq5nfOqroLokd925w2QtE7YwquFOIacwVQ==",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
}
},
"node_modules/@maplibre/maplibre-gl-geocoder": {
"version": "1.9.4",
@@ -1729,9 +1708,9 @@
}
},
"node_modules/@maplibre/maplibre-gl-style-spec": {
"version": "24.4.1",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-24.4.1.tgz",
"integrity": "sha512-UKhA4qv1h30XT768ccSv5NjNCX+dgfoq2qlLVmKejspPcSQTYD4SrVucgqegmYcKcmwf06wcNAa/kRd0NHWbUg==",
"version": "24.7.0",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-24.7.0.tgz",
"integrity": "sha512-Ed7rcKYU5iELfablg9Mj+TVCsXsPBgdMyXPRAxb2v7oWg9YJnpQdZ5msDs1LESu/mtXy3Z48Vdppv2t/x5kAhw==",
"license": "ISC",
"dependencies": {
"@mapbox/jsonlint-lines-primitives": "~2.0.2",
@@ -1749,18 +1728,18 @@
}
},
"node_modules/@maplibre/mlt": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.2.tgz",
"integrity": "sha512-SQKdJ909VGROkA6ovJgtHNs9YXV4YXUPS+VaZ50I2Mt951SLlUm2Cv34x5Xwc1HiFlsd3h2Yrs5cn7xzqBmENw==",
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.8.tgz",
"integrity": "sha512-8vtfYGidr1rNkv5IwIoU2lfe3Oy+Wa8HluzQYcQi9cveU9K3pweAal/poQj4GJ0K/EW4bTQp2wVAs09g2yDRZg==",
"license": "(MIT OR Apache-2.0)",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0"
}
},
"node_modules/@maplibre/vt-pbf": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.2.1.tgz",
"integrity": "sha512-IxZBGq/+9cqf2qdWlFuQ+ZfoMhWpxDUGQZ/poPHOJBvwMUT1GuxLo6HgYTou+xxtsOsjfbcjI8PZaPCtmt97rA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.3.0.tgz",
"integrity": "sha512-jIvp8F5hQCcreqOOpEt42TJMUlsrEcpf/kI1T2v85YrQRV6PPXUcEXUg5karKtH6oh47XJZ4kHu56pUkOuqA7w==",
"license": "MIT",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0",
@@ -1772,6 +1751,12 @@
"supercluster": "^8.0.1"
}
},
"node_modules/@maplibre/vt-pbf/node_modules/@maplibre/geojson-vt": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-5.0.4.tgz",
"integrity": "sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==",
"license": "ISC"
},
"node_modules/@maplibre/vt-pbf/node_modules/pbf": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz",
@@ -2606,15 +2591,6 @@
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
"license": "MIT"
},
"node_modules/@types/geojson-vt": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz",
"integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==",
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/hammerjs": {
"version": "2.0.46",
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz",
@@ -2702,6 +2678,7 @@
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz",
"integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==",
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
@@ -4605,12 +4582,6 @@
"node": ">= 0.6.0"
}
},
"node_modules/geojson-vt": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz",
"integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==",
"license": "ISC"
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -5282,7 +5253,8 @@
"node_modules/kdbush": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
"integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==",
"license": "ISC"
},
"node_modules/keyv": {
"version": "4.5.4",
@@ -5683,33 +5655,29 @@
"integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
},
"node_modules/maplibre-gl": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.16.0.tgz",
"integrity": "sha512-/VDY89nr4jgLJyzmhy325cG6VUI02WkZ/UfVuDbG/piXzo6ODnM+omDFIwWY8tsEsBG26DNDmNMn3Y2ikHsBiA==",
"version": "5.21.1",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.21.1.tgz",
"integrity": "sha512-zto1RTnFkOpOO1bm93ElCXF1huey2N4LvXaGLMFcYAu9txh0OhGIdX1q3LZLkrMKgMxMeYduaQo+DVNzg098fg==",
"license": "BSD-3-Clause",
"dependencies": {
"@mapbox/geojson-rewind": "^0.5.2",
"@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/maplibre-gl-style-spec": "^24.4.1",
"@maplibre/mlt": "^1.1.2",
"@maplibre/vt-pbf": "^4.2.0",
"@maplibre/geojson-vt": "^6.0.4",
"@maplibre/maplibre-gl-style-spec": "^24.7.0",
"@maplibre/mlt": "^1.1.8",
"@maplibre/vt-pbf": "^4.3.0",
"@types/geojson": "^7946.0.16",
"@types/geojson-vt": "3.2.5",
"@types/supercluster": "^7.1.3",
"earcut": "^3.0.2",
"geojson-vt": "^4.0.2",
"gl-matrix": "^3.4.4",
"kdbush": "^4.0.2",
"murmurhash-js": "^1.0.0",
"pbf": "^4.0.1",
"potpack": "^2.1.0",
"quickselect": "^3.0.0",
"supercluster": "^8.0.1",
"tinyqueue": "^3.0.0"
},
"engines": {
@@ -6627,7 +6595,8 @@
"node_modules/quickselect": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g=="
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
"license": "ISC"
},
"node_modules/randombytes": {
"version": "2.1.0",
@@ -7356,6 +7325,7 @@
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
"integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
}
@@ -7814,7 +7784,8 @@
"node_modules/tinyqueue": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz",
"integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g=="
"integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==",
"license": "ISC"
},
"node_modules/to-regex-range": {
"version": "5.0.1",

View File

@@ -73,7 +73,7 @@
"immer": "^10.1.1",
"jszip": "^3.10.1",
"mapillary-js": "^4.1.2",
"maplibre-gl": "^5.16.0",
"maplibre-gl": "^5.21.1",
"sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6",
"tailwind-merge": "^3.3.0"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 KiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 KiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 KiB

After

Width:  |  Height:  |  Size: 348 KiB

View File

@@ -31,6 +31,7 @@ import bikerouterGravel from './custom/bikerouter-gravel.json';
export const maptilerKeyPlaceHolder = 'MAPTILER_KEY';
export const basemaps: { [key: string]: string | StyleSpecification } = {
maptilerStreets: `https://api.maptiler.com/maps/streets-v4/style.json?key=${maptilerKeyPlaceHolder}`,
maptilerTopo: `https://api.maptiler.com/maps/topo-v4/style.json?key=${maptilerKeyPlaceHolder}`,
maptilerOutdoors: `https://api.maptiler.com/maps/outdoor-v4/style.json?key=${maptilerKeyPlaceHolder}`,
maptilerSatellite: `https://api.maptiler.com/maps/hybrid-v4/style.json?key=${maptilerKeyPlaceHolder}`,
@@ -776,6 +777,7 @@ export type LayerTreeType = { [key: string]: LayerTreeType | boolean };
export const basemapTree: LayerTreeType = {
basemaps: {
world: {
maptilerStreets: true,
maptilerTopo: true,
maptilerOutdoors: true,
maptilerSatellite: true,
@@ -911,7 +913,7 @@ export const overpassTree: LayerTreeType = {
};
// Default basemap used
export const defaultBasemap = 'maptilerTopo';
export const defaultBasemap = 'maptilerStreets';
// Default overlays used (none)
export const defaultOverlays: LayerTreeType = {
@@ -1000,6 +1002,7 @@ export const defaultOverpassQueries: LayerTreeType = {
export const defaultBasemapTree: LayerTreeType = {
basemaps: {
world: {
maptilerStreets: true,
maptilerTopo: true,
maptilerOutdoors: true,
maptilerSatellite: true,

View File

@@ -64,3 +64,9 @@
</svelte:head>
<div id="docsearch" class={props.class ?? ''}></div>
<style>
#docsearch :global(button) {
margin-left: 0px;
}
</style>

View File

@@ -26,7 +26,7 @@
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button {...props} {variant} class={className} {onclick}>
<Button {...props} {variant} class="bg-inherit {className}" {onclick}>
{@render children()}
</Button>
{/snippet}

View File

@@ -1,15 +1,15 @@
<script lang="ts">
import { Button } from '$lib/components/ui/button';
import LanguageSelect from '$lib/components/LanguageSelect.svelte';
import ModeSwitch from '$lib/components/ModeSwitch.svelte';
import Logo from '$lib/components/Logo.svelte';
import { AtSign, BookOpenText, Heart, House, Map } from '@lucide/svelte';
import { i18n } from '$lib/i18n.svelte';
import { getURLForLanguage } from '$lib/utils';
</script>
<footer class="w-full">
<div class="mx-6 border-t">
<div class="mx-12 py-10 flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
<footer class="w-full px-12 py-10 border-t flex flex-col items-center">
<div class="w-full max-w-5xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
<div class="grow flex flex-col items-start">
<Logo class="h-8" width="153" />
<Button
@@ -20,7 +20,10 @@
>
MIT © 2026 gpx.studio
</Button>
<LanguageSelect class="w-40 mt-3" />
<div class="mt-3 flex flex-row gap-1.5">
<LanguageSelect />
<ModeSwitch />
</div>
</div>
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
<div class="flex flex-col items-start gap-1">
@@ -86,7 +89,7 @@
<Button
variant="link"
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
href="https://ko-fi.com/gpxstudio"
href="https://opencollective.com/gpxstudio"
target="_blank"
>
<Heart size="16" />
@@ -113,5 +116,4 @@
</div>
</div>
</div>
</div>
</footer>

View File

@@ -12,16 +12,17 @@
const { velocityUnits } = settings;
let panelHeight: number = $state(0);
let panelWidth: number = $state(0);
let {
gpxStatistics,
slicedGPXStatistics,
orientation,
panelSize,
}: {
gpxStatistics: Readable<GPXStatisticsGroup>;
slicedGPXStatistics: Readable<[GPXGlobalStatistics, number, number] | undefined>;
orientation: 'horizontal' | 'vertical';
panelSize: number;
} = $props();
let statistics = $derived(
@@ -32,12 +33,15 @@
<Card.Root
class="h-full {orientation === 'vertical'
? 'min-w-40 sm:min-w-44'
: 'w-full h-10'} border-none shadow-none p-0 text-sm sm:text-base"
: 'w-full h-fit my-1'} border-none shadow-none p-0 text-sm sm:text-base bg-transparent"
>
<Card.Content
class="h-full flex {orientation === 'vertical'
? 'flex-col justify-center'
: 'flex-row w-full justify-evenly'} gap-4 p-0"
<Card.Content class="h-full p-0">
<div
bind:clientHeight={panelHeight}
bind:clientWidth={panelWidth}
class="flex {orientation === 'vertical'
? 'flex-col h-full justify-center'
: 'flex-row w-full justify-evenly'} gap-4"
>
<Tooltip label={i18n._('quantities.distance')}>
<span class="flex flex-row items-center">
@@ -53,9 +57,8 @@
<WithUnits value={statistics.elevation.loss} type="elevation" />
</span>
</Tooltip>
{#if panelSize > 120 || orientation === 'horizontal'}
{#if panelHeight > 120 || (orientation === 'horizontal' && panelWidth > 450)}
<Tooltip
class={orientation === 'horizontal' ? 'hidden xs:block' : ''}
label="{$velocityUnits === 'speed'
? i18n._('quantities.speed')
: i18n._('quantities.pace')} ({i18n._('quantities.moving')} / {i18n._(
@@ -70,9 +73,8 @@
</span>
</Tooltip>
{/if}
{#if panelSize > 160 || orientation === 'horizontal'}
{#if panelHeight > 160 || (orientation === 'horizontal' && panelWidth > 620)}
<Tooltip
class={orientation === 'horizontal' ? 'hidden md:block' : ''}
label="{i18n._('quantities.time')} ({i18n._('quantities.moving')} / {i18n._(
'quantities.total'
)})"
@@ -85,5 +87,6 @@
</span>
</Tooltip>
{/if}
</div>
</Card.Content>
</Card.Root>

View File

@@ -5,16 +5,10 @@
import { getURLForLanguage } from '$lib/utils';
import { Languages } from '@lucide/svelte';
import { i18n } from '$lib/i18n.svelte';
let {
class: className = '',
}: {
class?: string;
} = $props();
</script>
<Select.Root type="single" value={i18n.lang}>
<Select.Trigger class="min-w-[180px] {className}" aria-label={i18n._('menu.language')}>
<Select.Trigger class="w-[180px] px-2" aria-label={i18n._('menu.language')}>
<Languages size="16" />
<span class="mr-auto">
{languages[i18n.lang]}

View File

@@ -375,7 +375,7 @@
<Menubar.Item inset onclick={() => map.toggle3D()}>
<Box size="16" />
{i18n._('menu.toggle_3d')}
<Shortcut key="{i18n._('menu.ctrl')} {i18n._('menu.drag')}" />
<Shortcut key={i18n._('menu.right_click_drag')} />
</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
@@ -515,7 +515,7 @@
</Button>
<Button
variant="ghost"
href="https://ko-fi.com/gpxstudio"
href="https://opencollective.com/gpxstudio"
target="_blank"
class="cursor-default h-fit rounded-sm font-bold text-support hover:text-support px-3 py-0.5"
aria-label={i18n._('menu.donate')}

View File

@@ -12,7 +12,7 @@
</script>
<Button
variant="ghost"
variant="outline"
size="icon"
class={className}
onclick={() => {

View File

@@ -1,22 +1,23 @@
<script lang="ts">
import Logo from '$lib/components/Logo.svelte';
import { Button } from '$lib/components/ui/button';
import AlgoliaDocSearch from '$lib/components/AlgoliaDocSearch.svelte';
import ModeSwitch from '$lib/components/ModeSwitch.svelte';
import { BookOpenText, House, Map } from '@lucide/svelte';
import { i18n } from '$lib/i18n.svelte';
import { getURLForLanguage } from '$lib/utils';
</script>
<nav class="w-full sticky top-0 bg-background z-50">
<div class="mx-6 py-2 flex flex-row items-center border-b gap-4 sm:gap-8">
<a href={getURLForLanguage(i18n.lang, '/')} class="shrink-0 translate-y-0.5">
<Logo class="h-8 sm:hidden" iconOnly={true} width="26" />
<Logo class="h-8 hidden sm:block" width="153" />
<nav class="sticky top-0 w-full px-12 py-2 bg-background z-50 flex flex-col items-center border-b">
<div class="w-full max-w-5xl flex flex-row items-center gap-4 sm:gap-8">
<a
href={getURLForLanguage(i18n.lang, '/')}
class="shrink-0 translate-y-0.25 justify-self-start"
>
<Logo class="h-8 xs:hidden" iconOnly={true} width="26" />
<Logo class="h-8 hidden xs:block" width="153" />
</a>
<Button
variant="link"
class="text-base px-0 has-[>svg]:px-0"
class="text-base px-0 has-[>svg]:px-0 ml-auto"
href={getURLForLanguage(i18n.lang, '/')}
>
<House size="18" />
@@ -39,7 +40,5 @@
<BookOpenText size="18" />
{i18n._('menu.help')}
</Button>
<AlgoliaDocSearch class="ml-auto" />
<ModeSwitch class="hidden xs:inline-flex" />
</div>
</nav>

View File

@@ -19,7 +19,7 @@
@apply text-foreground;
@apply text-3xl;
@apply font-semibold;
@apply mb-3 pt-6;
@apply mb-3;
}
:global(.markdown h2) {

View File

@@ -12,7 +12,7 @@
<div class="rounded-md overflow-hidden overflow-clip shadow-xl mx-auto">
{#if src === 'getting-started/interface'}
<enhanced:img
src="/src/lib/assets/img/docs/getting-started/interface.png"
src="/src/lib/assets/img/docs/getting-started/interface.webp"
{alt}
class="w-full max-w-3xl"
/>
@@ -20,13 +20,13 @@
<enhanced:img
src="/src/lib/assets/img/docs/tools/routing.png"
{alt}
class="w-full max-w-3xl"
class="w-full max-w-lg"
/>
{:else if src === 'tools/split'}
<enhanced:img
src="/src/lib/assets/img/docs/tools/split.png"
{alt}
class="w-full max-w-3xl"
class="w-full max-w-lg"
/>
{/if}
</div>

View File

@@ -68,14 +68,14 @@
<canvas bind:this={overlay} class="w-full h-full absolute pointer-events-none"></canvas>
<canvas bind:this={canvas} class="w-full h-full absolute"></canvas>
{#if showControls}
<div class="absolute bottom-10 right-1.5">
<div class="absolute bottom-9 right-2.5">
<Popover.Root>
<Popover.Trigger>
<ButtonWithTooltip
label={i18n._('chart.settings')}
variant="outline"
side="left"
class="w-7 h-7 p-0 flex justify-center opacity-70 hover:opacity-100 transition-opacity duration-300 hover:bg-background"
class="w-7 h-7 p-0 flex justify-center opacity-70 hover:opacity-100 transition-opacity duration-300 bg-background"
>
<ChartNoAxesColumn size="18" />
</ButtonWithTooltip>

View File

@@ -117,13 +117,12 @@
{/if}
</div>
<div
class="{options.elevation.show ? '' : 'h-10'} flex flex-row gap-2 px-2 sm:px-4"
class="{options.elevation.show ? '' : 'h-10'} flex flex-row gap-2 p-2 sm:px-4"
style={options.elevation.show ? `height: ${options.elevation.height}px` : ''}
>
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={options.elevation.height}
orientation={options.elevation.show ? 'vertical' : 'horizontal'}
/>
{#if options.elevation.show}

View File

@@ -29,7 +29,7 @@ export const defaultEmbeddingOptions = {
key: '',
files: [],
ids: [],
basemap: 'maptilerTopo',
basemap: 'maptilerStreets',
elevation: {
show: true,
height: 170,
@@ -90,6 +90,9 @@ export function getCleanedEmbeddingOptions(
delete cleanedOptions[key];
}
}
if (cleanedOptions['key'] && cleanedOptions['key'] === PUBLIC_MAPTILER_KEY) {
delete cleanedOptions['key'];
}
return cleanedOptions;
}

View File

@@ -100,7 +100,11 @@
</span>
</div>
<div class="w-full flex flex-row flex-wrap gap-2">
<Button class="bg-support grow" href="https://ko-fi.com/gpxstudio" target="_blank">
<Button
class="bg-support grow"
href="https://opencollective.com/gpxstudio"
target="_blank"
>
{i18n._('menu.support_button')}
<span>🙏</span>
</Button>

View File

@@ -5,7 +5,7 @@ import { get } from 'svelte/store';
import { map } from '$lib/components/map/map';
import { allHidden } from '$lib/logic/hidden';
import type { GeoJSONSource } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '../style';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
const { distanceMarkers, distanceUnits } = settings;

View File

@@ -28,7 +28,7 @@ import { fileActions } from '$lib/logic/file-actions';
import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import { gpxColors } from './gpx-layers';
import { gpxColors } from '$lib/components/map/gpx-layer/gpx-layers';
const colors = [
'#ff0000',
@@ -251,7 +251,7 @@ export class GPXLayer {
source: this.fileId,
layout: {
'text-field': '»',
'text-offset': [0, -0.1],
'text-offset': [0, -0.06],
'text-keep-upright': false,
'text-max-angle': 361,
'text-allow-overlap': true,
@@ -261,7 +261,6 @@ export class GPXLayer {
},
paint: {
'text-color': 'white',
'text-opacity': 0.7,
'text-halo-width': 0.2,
'text-halo-color': 'white',
},

View File

@@ -31,7 +31,7 @@ export class StartEndMarkers {
unsubscribes: (() => void)[] = [];
constructor() {
map.onLoad(() => this.update());
map.onLoad((map_) => map_.on('style.load', this.updateBinded));
this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded));
this.unsubscribes.push(slicedGPXStatistics.subscribe(this.updateBinded));
this.unsubscribes.push(hoveredPoint.subscribe(this.updateBinded));

View File

@@ -7,7 +7,7 @@ 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 { ANCHOR_LAYER_KEY } from '../style';
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';
@@ -24,7 +24,7 @@ liveQuery(() => db.overpassdata.toArray()).subscribe((pois) => {
});
export class OverpassLayer {
overpassUrl = 'https://maps.mail.ru/osm/tools/overpass/api/interpreter';
overpassUrl = 'https://overpass.private.coffee/api/interpreter';
minZoom = 12;
queryZoom = 12;
expirationTime = 7 * 24 * 3600 * 1000;

View File

@@ -1,5 +1,4 @@
import type { LayerTreeType } from '$lib/assets/layers';
import { writable } from 'svelte/store';
export function anySelectedLayer(node: LayerTreeType) {
return (

View File

@@ -54,7 +54,7 @@ export class MapLibreGLMap {
zoom: 0,
hash: hash,
boxZoom: false,
maxPitch: 85,
maxPitch: 90,
});
this.layerEventManager = new MapLayerEventManager(map);
map.addControl(

View File

@@ -2,7 +2,7 @@ import maplibregl, { type LayerSpecification, type VectorSourceSpecification } f
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
import 'mapillary-js/dist/mapillary.css';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '../style';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
const mapillarySource: VectorSourceSpecification = {

View File

@@ -85,9 +85,11 @@ export class StyleManager {
this.merge(style, basemapStyle);
if (this._maptilerKey !== '') {
const terrain = this.getCurrentTerrain();
style.sources[terrain.source] = terrainSources[terrain.source];
style.terrain = terrain.exaggeration > 0 ? terrain : undefined;
}
style.layers.push(...anchorLayers);
@@ -152,6 +154,7 @@ export class StyleManager {
}
updateTerrain() {
if (this._maptilerKey === '') return;
const map_ = get(this._map);
if (!map_) return;

View File

@@ -55,6 +55,7 @@ export class RoutingControls {
fileUnsubscribe: () => void = () => {};
unsubscribes: Function[] = [];
updateControlsBinded: () => void = this.updateControls.bind(this);
appendAnchorBinded: (e: MapMouseEvent) => void = this.appendAnchor.bind(this);
draggedAnchorIndex: number | null = null;
@@ -129,10 +130,11 @@ export class RoutingControls {
this.loadIcons();
map_.on('style.load', this.updateControlsBinded);
map_.on('click', this.appendAnchorBinded);
layerEventManager.on('mousemove', this.fileId, this.showTemporaryAnchorBinded);
this.fileUnsubscribe = this.file.subscribe(this.updateControls.bind(this));
this.fileUnsubscribe = this.file.subscribe(this.updateControlsBinded);
}
updateControls() {
@@ -232,6 +234,7 @@ export class RoutingControls {
this.active = false;
map_?.off('style.load', this.updateControlsBinded);
map_?.off('click', this.appendAnchorBinded);
layerEventManager?.off('mousemove', this.fileId, this.showTemporaryAnchorBinded);
map_?.off('mousemove', this.updateTemporaryAnchorBinded);
@@ -683,17 +686,7 @@ export class RoutingControls {
try {
response = await route(targetTrackPoints.map((trkpt) => trkpt.getCoordinates()));
} catch (e: any) {
if (e.message.includes('from-position not mapped in existing datafile')) {
toast.error(i18n._('toolbar.routing.error.from'));
} else if (e.message.includes('via1-position not mapped in existing datafile')) {
toast.error(i18n._('toolbar.routing.error.via'));
} else if (e.message.includes('to-position not mapped in existing datafile')) {
toast.error(i18n._('toolbar.routing.error.to'));
} else if (e.message.includes('Time-out')) {
toast.error(i18n._('toolbar.routing.error.timeout'));
} else {
toast.error(e.message);
}
toast.error(i18n._(e.message, e.message));
return false;
}

View File

@@ -6,37 +6,213 @@ import { get } from 'svelte/store';
const { routing, routingProfile, privateRoads } = settings;
export const routingProfiles: { [key: string]: string } = {
bike: 'Trekking-dry',
racing_bike: 'fastbike',
gravel_bike: 'gravel',
mountain_bike: 'MTB',
foot: 'Hiking-Alpine-SAC6',
motorcycle: 'Car-FastEco',
water: 'river',
railway: 'rail',
export type RoutingProfile = {
engine: 'graphhopper' | 'brouter';
profile: string;
};
export const routingProfiles: { [key: string]: RoutingProfile } = {
bike: { engine: 'graphhopper', profile: 'bike' },
racing_bike: { engine: 'graphhopper', profile: 'racingbike' },
gravel_bike: { engine: 'graphhopper', profile: 'gravelbike' },
mountain_bike: { engine: 'graphhopper', profile: 'mtb' },
foot: { engine: 'graphhopper', profile: 'foot' },
motorcycle: { engine: 'graphhopper', profile: 'motorcycle' },
water: { engine: 'brouter', profile: 'river' },
railway: { engine: 'brouter', profile: 'rail' },
};
export function route(points: Coordinates[]): Promise<TrackPoint[]> {
if (get(routing)) {
return getRoute(points, routingProfiles[get(routingProfile)], get(privateRoads));
const profile = routingProfiles[get(routingProfile)];
if (profile.engine === 'graphhopper') {
return getGraphHopperRoute(points, profile.profile, get(privateRoads));
} else {
return getBRouterRoute(points, profile.profile);
}
} else {
return getIntermediatePoints(points);
}
}
async function getRoute(
const graphhopperDetails = ['road_class', 'surface', 'hike_rating', 'mtb_rating'];
const hikeRatingToSACScale: { [key: string]: string } = {
'1': 'hiking',
'2': 'mountain_hiking',
'3': 'demanding_mountain_hiking',
'4': 'alpine_hiking',
'5': 'demanding_alpine_hiking',
'6': 'difficult_alpine_hiking',
};
const mtbRatingToScale: { [key: string]: string } = {
'1': '0',
'2': '1',
'3': '2',
'4': '3',
'5': '4',
'6': '5',
'7': '6',
};
const graphhopperBlockPrivateCustomModels: { [key: string]: any } = {
bike: {
priority: [
{
if: 'bike_road_access == PRIVATE',
multiply_by: '0.0',
},
],
},
racingbike: {
priority: [
{
if: 'bike_road_access == PRIVATE',
multiply_by: '0.0',
},
],
},
gravelbike: {
priority: [
{
if: 'bike_road_access == PRIVATE',
multiply_by: '0.0',
},
],
},
mtb: {
priority: [
{
if: 'bike_road_access == PRIVATE',
multiply_by: '0.0',
},
],
},
foot: {
priority: [
{
if: 'foot_road_access == PRIVATE',
multiply_by: '0.0',
},
],
},
motorcycle: {
priority: [
{
if: 'road_access == PRIVATE',
multiply_by: '0.0',
},
],
},
};
async function getGraphHopperRoute(
points: Coordinates[],
brouterProfile: string,
graphHopperProfile: string,
privateRoads: boolean
): Promise<TrackPoint[]> {
let url = `https://brouter.gpx.studio?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile + (privateRoads ? '-private' : '')}&format=geojson&alternativeidx=0`;
let response = await fetch('https://graphhopper.gpx.studio/route', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
points: points.map((point) => [point.lon, point.lat]),
profile: graphHopperProfile,
elevation: true,
points_encoded: false,
details: graphhopperDetails,
custom_model: privateRoads
? {}
: graphhopperBlockPrivateCustomModels[graphHopperProfile] || {},
}),
});
if (!response.ok) {
const error = await response.json();
if (error.message.includes('Cannot find point 0')) {
throw new Error('toolbar.routing.error.from');
} else if (error.message.includes('Cannot find point 1')) {
if (points.length == 3) {
throw new Error('toolbar.routing.error.via');
} else {
throw new Error('toolbar.routing.error.to');
}
} else if (error.hints[0].details.includes('PointDistanceExceededException')) {
throw new Error('toolbar.routing.error.distance');
} else if (error.hints[0].details.includes('ConnectionNotFoundException')) {
throw new Error('toolbar.routing.error.connection');
} else {
throw new Error(error.message);
}
}
let json = await response.json();
let route: TrackPoint[] = [];
let coordinates = json.paths[0].points.coordinates;
let details = json.paths[0].details;
for (let i = 0; i < coordinates.length; i++) {
route.push(
new TrackPoint({
attributes: {
lat: coordinates[i][1],
lon: coordinates[i][0],
},
ele: coordinates[i][2] ?? (i > 0 ? route[i - 1].ele : 0),
extensions: {},
})
);
}
for (let key of graphhopperDetails) {
let detail = details[key];
for (let i = 0; i < detail.length; i++) {
for (let j = detail[i][0]; j < detail[i][1] + (i == detail.length - 1); j++) {
if (detail[i][2] !== undefined && detail[i][2] !== 'missing') {
if (key === 'road_class') {
route[j].setExtension('highway', detail[i][2]);
} else if (key === 'hike_rating') {
const sacScale = hikeRatingToSACScale[detail[i][2]];
if (sacScale) {
route[j].setExtension('sac_scale', sacScale);
}
} else if (key === 'mtb_rating') {
const mtbScale = mtbRatingToScale[detail[i][2]];
if (mtbScale) {
route[j].setExtension('mtb_scale', mtbScale);
}
} else if (key === 'surface' && detail[i][2] !== 'other') {
route[j].setExtension('surface', detail[i][2]);
}
}
}
}
}
return route;
}
async function getBRouterRoute(
points: Coordinates[],
brouterProfile: string
): Promise<TrackPoint[]> {
let url = `https://brouter.de/brouter?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile}&format=geojson&alternativeidx=0`;
let response = await fetch(url);
// Check if the response is ok
if (!response.ok) {
throw new Error(`${await response.text()}`);
const error = await response.text();
if (error.includes('from-position not mapped in existing datafile')) {
throw new Error('toolbar.routing.error.from');
} else if (error.includes('via1-position not mapped in existing datafile')) {
throw new Error('toolbar.routing.error.via');
} else if (error.includes('to-position not mapped in existing datafile')) {
throw new Error('toolbar.routing.error.to');
} else if (error.includes('Time-out')) {
throw new Error('toolbar.routing.error.timeout');
} else {
throw new Error(error);
}
}
let geojson = await response.json();
@@ -52,14 +228,13 @@ async function getRoute(
let tags = messageIdx < messages.length ? getTags(messages[messageIdx][tagIdx]) : {};
for (let i = 0; i < coordinates.length; i++) {
let coord = coordinates[i];
route.push(
new TrackPoint({
attributes: {
lat: coord[1],
lon: coord[0],
lat: coordinates[i][1],
lon: coordinates[i][0],
},
ele: coord[2] ?? (i > 0 ? route[i - 1].ele : 0),
ele: coordinates[i][2] ?? (i > 0 ? route[i - 1].ele : 0),
})
);

View File

@@ -12,6 +12,7 @@ title: Files and statistics
let gpxStatistics = writable(exampleGPXFile.getStatistics());
let slicedGPXStatistics = writable(undefined);
let hoveredPoint = writable(null);
let additionalDatasets = writable(['speed', 'atemp']);
let elevationFill = writable(undefined);
</script>
@@ -84,19 +85,17 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
<ElevationProfile
{gpxStatistics}
{slicedGPXStatistics}
{hoveredPoint}
{additionalDatasets}
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Additional data

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Help keep the website free (and ad-free)
Each time you add or move GPS points, our servers calculate the best route on the road network.
We also use APIs from <a href="https://mapbox.com" target="_blank">Mapbox</a> to display beautiful maps, retrieve elevation data and allow you to search for places.
Unfortunately, this is expensive.
If you enjoy using this tool and find it valuable, please consider making a small donation to help keep the website free and ad-free.
Thank you very much for your support! ❤️

View File

@@ -1,5 +0,0 @@
Mapbox is the company that provides some of the beautiful maps on this website.
They also develop the <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">map engine</a> which powers **gpx.studio**.
We are incredibly fortunate and grateful to be part of their <a href="https://mapbox.com/community" target="_blank">Community</a> program, which supports nonprofits, educational institutions, and positive impact organizations.
This partnership allows **gpx.studio** to benefit from Mapbox tools at discounted prices, greatly contributing to the financial viability of the project and enabling us to offer the best possible user experience.

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Translation
The website is translated by volunteers using a collaborative translation platform.
You can contribute by adding or improving translations on our <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin project</a>.
If you would like to start translating into a new language, please <a href="#contact">get in touch</a>.
Any help is greatly appreciated!

View File

@@ -13,8 +13,8 @@ title: Інтэграцыя
Усё, што вам трэба, гэта:
1. <a href="https://account.mapbox.com/auth/signup" target="_blank">Ключ доступу Mapbox</a> для загрузкі карты і
2. Файлы GPX, размешчаныя на вашым серверы або на Google Drive, або даступныя праз публічны URL.
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.
Затым вы можаце пагуляць з канфігуратарам ніжэй, каб наладзіць сваю карту і стварыць адпаведны HTML-код.

View File

@@ -56,10 +56,12 @@ These controls allow you to navigate the map, zoom in and out, and switch betwee
- **Кропкі цікавасці** можна дадаць на карту, каб паказаць розныя катэгорыі месцаў, такіх як крамы, рэстараны або жыллё.
<div class="flex flex-col items-center">
<DocsLayers />
<span class="text-sm text-center mt-2">
Навядзіце курсор мышы на карту, каб паказаць накладанне <a href="https://hiking.waymarkedtrails.org" target="_blank">Пешаходных Сцежак</a> на базавай карце <a href="https://www.mapbox.com/maps/outdoors" target="_blank">Mapbox Outdoors</a>.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span>
</div>
Вялікая калекцыя глабальных і лакальных базавых карт і накладанняў даступная ў **gpx.studio**, а таксама выбар катэгорый кропак цікавасці.
@@ -67,4 +69,4 @@ These controls allow you to navigate the map, zoom in and out, and switch betwee
У гэтых наладах вы таксама можаце кіраваць непразрыстасцю накладанняў.
Для прасунутых карыстальнікаў можна дадаваць карыстальніцкія базавыя карты і накладкі, дадаўшы 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://docs.mapbox.com/help/glossary/style/" target="_blank">JSON у стылі Mapbox</a>.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.

View File

@@ -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://mapbox.com" target="_blank">Mapbox</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.mapbox.com/data/tilesets/reference/mapbox-terrain-dem-v1/#elevation-data" target="_blank">documentation</a>.
Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote>

View File

@@ -5,6 +5,7 @@ title: Merge
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ To use this tool, you need to [select](../files-and-stats) multiple files, [trac
- 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.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

View File

@@ -12,6 +12,7 @@ title: Fitxers i estadístiques
let gpxStatistics = writable(exampleGPXFile.getStatistics());
let slicedGPXStatistics = writable(undefined);
let hoveredPoint = writable(null);
let additionalDatasets = writable(['speed', 'atemp']);
let elevationFill = writable(undefined);
</script>
@@ -84,19 +85,17 @@ També pots utilitzar la rodeta del ratolí per apropar o allunyar el perfil d'e
<ElevationProfile
{gpxStatistics}
{slicedGPXStatistics}
{hoveredPoint}
{additionalDatasets}
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Dades addicionals

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Ajuda a mantenir aquesta pàgina web gratuïta (i sense anuncis)
Cada cop que afegeixes o mous un punt GPS, els nostres servidors calculen la millor ruta possible.
També utilitzen l'API de <a href="https://mapbox.com" target="_blank">Mapbox</a> per ensenyar mapes bonics, donar informació sobre l'altitud i permetre la cerca de llocs d'interès.
Desafortunadament, això és car.
Si gaudeixes aquesta eina i la trobes valuosa, si us plau, considera fer una petita donació per ajudar a mantenir la pàgina web gratuïta i sense anuncis.
Moltíssimes gràcies pel teu suport! ❤️

View File

@@ -1,5 +0,0 @@
Mapbox és l'empresa que ofereix alguns dels mapes d'aquest lloc web.
Ells també desenvolupen el <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">motor de mapes</a> el qual recolza **gpx.studio**.
Som increïblement afortunats i estem agraïts de formar part del seu programa <a href="https://mapbox.com/community" target="_blank">comunitari</a>, que dona suport a organitzacions sense ànim de lucre, institucions educatives i organitzacions d'impacte positiu.
Aquesta associació permet a **gpx.studio** beneficiar-se de les eines de Mapbox a preus amb descompte, contribuint en gran mesura a la viabilitat financera del projecte i permetent oferir la millor experiència d'usuari possible.

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Traducció
Aquesta pàgina web ha estat traduïda per voluntaris utilitzant una plataforma de traducció col·laborativa.
Tu també pots contribuir-hi afegint o millorant les traduccions al nostre <a href="https://crowdin.com/project/gpxstudio" target="_blank">projecte de Crowdin</a>.
Si vols començar a traduir ara mateix a una nova llengua, si us plau <a href="#contact">posa't en contacte amb nosaltres</a>.
Qualsevol ajuda és molt apreciada!

View File

@@ -13,8 +13,8 @@ Pots utilitzar **gpx.studio** per crear mapes que mostrin els teus arxius GPX i
Tot el que necessites és:
1. Un <a href="https://account.mapbox.com/auth/signup" target="_blank"> token d'accés a Mapbox</a> per carregar el mapa i
2. Arxius GPX allotjats en el teu servidor, a Google Drive o accessibles a través d'una URL pública.
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.
Aleshores pots jugar amb el configurador de sota per personalitzar el teu mapa i generar el corresponent codi HTML.

View File

@@ -55,8 +55,13 @@ El botó de capa de mapa permet canviar entre diferents mapes base i alternar ca
- Les **Capes sobreposades** són capes addicionals que es poden mostrar sobre el mapa base per proporcionar informació complementària.
- Els **Punts d'interès** es poden afegir al mapa per mostrar diferents categories de llocs, com botigues, restaurants o allotjaments.
<div class="flex flex-col items-center"><DocsLayers /><span class="text-sm text-center mt-2">Situa el cursor sobre el mapa per mostrar la capa <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> sobreposada sobre del <a href="https://www.mapbox.com/maps/outdoors" target="_blank">Mapbox Outdoors</a> mapa base.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span>
</div>
Una gran col·lecció de mapes i capes sobreposades globals i locals està disponible a **gpx.studio**, així com una selecció de categories de punts d'interès.
@@ -64,4 +69,4 @@ Poden activar-se en el [configuració de capes del mapa](./menu/settings).
En aquests ajustaments pots gestionar l'opacitat de les capes sobreposades.
Per a usuaris avançats és possible afegir mapes base i sobreposicions personalitzades proporcionant <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, o <a href="https://docs.mapbox.com/help/glossary/style/" target="_blank">JSON tipus Mapbox</a> URLs.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.

View File

@@ -29,13 +29,13 @@ Pots arrossegar y deixar arxius directament des del seu sistema d'arxius cap a l
Crear una còpia dels arxius seleccionats.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Esborra
Delete the currently selected files.
Esborra l'arxiu seleccinat.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete all
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Esborra-ho tot
Delete all files.
Esborra tots els fitxers.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar...

View File

@@ -18,7 +18,7 @@ Aquesta eina permet afegir dades d'elevació a traces i [punts d'interès](../gp
<DocsNote>
Dades d'elevació subministrades per <a href="https://mapbox.com" target="_blank">Mapbox</a>.
Pots aprendre més sobre els seus orígens i precisió en la <a href="https://docs.mapbox.com/data/tilesets/reference/mapbox-terrain-dem-v1/#elevation-data" target="_blank">documentació</a>.
Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote>

View File

@@ -5,6 +5,7 @@ title: Fusionar
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ Per utilitzar aquesta eina, s'ha de [seleccionar](../files-and-stats) múltiples
- La segona opció es pot utilitzar per a crear o gestionar arxius amb múltiples [tracs o segments](../gpx).
Fusionar arxius (o tracs) crearà un sol arxiu (o trac) que contindrà tots els tracs (o segments) seleccionats.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

View File

@@ -12,6 +12,7 @@ title: Soubory a statistiky
let gpxStatistics = writable(exampleGPXFile.getStatistics());
let slicedGPXStatistics = writable(undefined);
let hoveredPoint = writable(null);
let additionalDatasets = writable(['speed', 'atemp']);
let elevationFill = writable(undefined);
</script>
@@ -84,19 +85,17 @@ Pomocí kolečka myši můžete také výškový profil přiblížit a oddálit
<ElevationProfile
{gpxStatistics}
{slicedGPXStatistics}
{hoveredPoint}
{additionalDatasets}
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Doplňující údaje

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Pomozte udržet web zdarma (a bez reklam)
Vždy, když přidáte nebo přesunete GPS body, naše servery vypočítají nejlepší cestu po silniční síti.
Používáme také API z <a href="https://mapbox.com" target="_blank">Mapboxu</a> pro zobrazení krásných map, získání dat o nadmořské výšce a vyhledávání míst.
Bohužel, to vše je nákladné.
Pokud rádi používáte tento nástroj a zdá se vám hodnotný, zvažte prosím malý příspěvek k udržení webu zdarma a bez reklam.
Děkujeme za vaši podporu! ❤️

View File

@@ -1,5 +0,0 @@
Mapbox je společnost poskytující některé z krásných map na tomto webu.
Vyvíjí také <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">mapový engine</a> na jehož základě provozujeme **gpx.studio**.
Jsme velmi rádi a vděční za to, že můžeme být součástí jejich <a href="https://mapbox.com/community" target="_blank">komunitního</a> programu, který podporuje neziskové a vzdělávací organizace a organizace s pozitivním dopadem.
Toto partnerství umožňuje **gpx.studio** využívat nástroje Mapboxu se slevou a přináší projektu finanční udržitelnost. Díky tomu vám můžeme nabídnout tu nejlepší uživatelskou přívětivost.

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Překlad
Tento web je překládán dobrovolníky prostřednictvím kolaborativní překladatelské platformy.
Ke zlepšení překladů můžete přispět na našem <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin projektu</a>.
Pokud byste chtěli zahájit překlad do nového jazyka, <a href="#contact">ozvěte se nám</a>, prosím.
Jakákoliv pomoc je velmi ceněna!

View File

@@ -13,8 +13,8 @@ Pomocí **gpx.studio** můžete vytvářet mapy se zobrazením souborů GPX a vk
Vše, co potřebujete, je:
1. <a href="https://account.mapbox.com/auth/signup" target="_blank">Přístupový token Mapboxu</a> k načtení mapy,
2. Soubory GPX umístěné na vašem serveru nebo na Disku Google, nebo přístupné prostřednictvím veřejné adresy URL.
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.
V níže zobrazeném konfigurátoru si pak můžete mapu přizpůsobit a vygenerovat odpovídající kód HTML.

View File

@@ -56,10 +56,12 @@ Tlačítko mapové vrstvy umožňuje přepínat mezi různými podkladovými map
- **Body zájmu** lze přidat do mapy a zobrazit tak různé kategorie míst, jako jsou obchody, restaurace nebo ubytování.
<div class="flex flex-col items-center">
<DocsLayers />
<span class="text-sm text-center mt-2">
Po najetí myší nad mapu se zobrazí překryv<a href="https://hiking.waymarkedtrails.org" target="_blank">značených stezek pro pěší turistiku</a> na podkladové mapě <a href="https://www.mapbox.com/maps/outdoors" target="_blank">Mapbox Outdoors</a>.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span>
</div>
V **gpx.studio** je k dispozici rozsáhlá sbírka globálních a místních podkladových map a překryvů a také řada kategorií bodů zájmu.
@@ -67,4 +69,4 @@ Lze je povolit v nabídce [nastavení mapových vrstev](./menu/settings).
V tomto nastavení můžete také spravovat neprůhlednost překryvů.
Pokročilí uživatelé mohou přidávat vlastní podkladové mapy a překryvy pomocí <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> nebo URL <a href="https://docs.mapbox.com/help/glossary/style/" target="_blank">Mapbox stylu JSON</a>.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.

View File

@@ -18,7 +18,7 @@ Tento nástroj umožňuje přidat údaje o nadmořské výšce ke stopám a [bod
<DocsNote>
Údaje o nadmořské výšce poskytuje <a href="https://mapbox.com" target="_blank">Mapbox</a>.
Více informací o jejich původu a přesnosti najdete v <a href="https://docs.mapbox.com/data/tilesets/reference/mapbox-terrain-dem-v1/#elevation-data" target="_blank">dokumentaci</a>.
Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote>

View File

@@ -5,6 +5,7 @@ title: Sloučit
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ Chcete-li použít tento nástroj, musíte [vybrat](../files-and-stats) více so
- Druhá možnost může být použita k vytvoření nebo správě souborů s více [trasami nebo segmenty](../gpx).
Sloučením souborů (nebo tras) vznikne jeden soubor (nebo trasa) obsahující všechny trasy (nebo úseky) z výběru.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

View File

@@ -12,6 +12,7 @@ title: Files and statistics
let gpxStatistics = writable(exampleGPXFile.getStatistics());
let slicedGPXStatistics = writable(undefined);
let hoveredPoint = writable(null);
let additionalDatasets = writable(['speed', 'atemp']);
let elevationFill = writable(undefined);
</script>
@@ -84,19 +85,17 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
<ElevationProfile
{gpxStatistics}
{slicedGPXStatistics}
{hoveredPoint}
{additionalDatasets}
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Additional data

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Help keep the website free (and ad-free)
Each time you add or move GPS points, our servers calculate the best route on the road network.
We also use APIs from <a href="https://mapbox.com" target="_blank">Mapbox</a> to display beautiful maps, retrieve elevation data and allow you to search for places.
Unfortunately, this is expensive.
If you enjoy using this tool and find it valuable, please consider making a small donation to help keep the website free and ad-free.
Mange tak for din støtte! ❤️

View File

@@ -1,5 +0,0 @@
Mapbox is the company that provides some of the beautiful maps on this website.
They also develop the <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">map engine</a> which powers **gpx.studio**.
We are incredibly fortunate and grateful to be part of their <a href="https://mapbox.com/community" target="_blank">Community</a> program, which supports nonprofits, educational institutions, and positive impact organizations.
Dette partnerskab tillader **gpx. tudio-** at drage fordel af Mapbox værktøjer til nedsatte priser i høj grad bidrage til projektets finansielle levedygtighed og sætte os i stand til at tilbyde den bedst mulige brugeroplevelse.

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Translation
Hjemmesiden er oversat af frivillige ved hjælp af en kollaborativ oversættelsesplatform.
You can contribute by adding or improving translations on our <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin project</a>.
If you would like to start translating into a new language, please <a href="#contact">get in touch</a>.
Enhver hjælp er værdsat!

View File

@@ -13,8 +13,8 @@ You can use **gpx.studio** to create maps showing your GPX files and embed them
All you need is:
1. A <a href="https://account.mapbox.com/auth/signup" target="_blank">Mapbox access token</a> to load the map, and
2. GPX files hosted on your server or on Google Drive, or accessible via a public URL.
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.
You can then play with the configurator below to customize your map and generate the corresponding HTML code.

View File

@@ -56,10 +56,12 @@ The map layers button allows you to switch between different basemaps, and toggl
- **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 <a href="https://www.mapbox.com/maps/outdoors" target="_blank">Mapbox Outdoors</a> basemap.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</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.
@@ -67,4 +69,4 @@ They can be enabled in the [map layer settings dialog](./menu/settings).
In these settings, you can also manage the opacity of the overlays.
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://docs.mapbox.com/help/glossary/style/" target="_blank">Mapbox style JSON</a> URLs.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.

View File

@@ -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://mapbox.com" target="_blank">Mapbox</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.mapbox.com/data/tilesets/reference/mapbox-terrain-dem-v1/#elevation-data" target="_blank">documentation</a>.
Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote>

View File

@@ -5,6 +5,7 @@ title: Merge
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ To use this tool, you need to [select](../files-and-stats) multiple files, [trac
- 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.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

View File

@@ -12,6 +12,7 @@ title: Dateien und Statistiken
let gpxStatistics = writable(exampleGPXFile.getStatistics());
let slicedGPXStatistics = writable(undefined);
let hoveredPoint = writable(null);
let additionalDatasets = writable(['speed', 'atemp']);
let elevationFill = writable(undefined);
</script>
@@ -84,19 +85,17 @@ Sie können auch das Mausrad verwenden, um auf dem Höhenprofil heranzuzoomen un
<ElevationProfile
{gpxStatistics}
{slicedGPXStatistics}
{hoveredPoint}
{additionalDatasets}
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Zusätzliche Daten

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Helfen Sie, die Website kostenlos (und werbefrei) zu erhalten
Jedes Mal, wenn Sie GPS-Punkte hinzufügen oder verschieben, berechnen unsere Server die beste Route im Straßennetz.
Wir verwenden auch APIs von <a href="https://mapbox.com" target="_blank">Mapbox</a>, um schöne Karten anzuzeigen, Höhendaten abzurufen und Ihnen die Suche nach Orten zu ermöglichen.
Leider ist dies mit hohen Kosten verbunden.
Wenn Sie dieses Tool gerne verwenden und es wertvoll finden, erwägen Sie bitte eine kleine Spende, um die Website kostenlos und werbefrei zu halten.
Herzlichen Dank für Ihre Unterstützung! ❤️

View File

@@ -1,5 +0,0 @@
Mapbox ist das Unternehmen, das einige der schönen Karten auf dieser Website zur Verfügung stellt.
Sie entwickeln auch die <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">Karten-Engine</a> welche **gpx.studio** unterstützt.
Wir sind äußerst glücklich und dankbar, Teil ihres <a href="https://mapbox.com/community" target="_blank">Community</a> Programms zu sein, das gemeinnützige Organisationen, Bildungseinrichtungen und Organisationen mit positivem Einfluss unterstützt.
Diese Partnerschaft ermöglicht es **gpx.studio**, von den Mapbox-Tools zu ermäßigten Preisen zu profitieren, was erheblich zur finanziellen Tragfähigkeit des Projekts beiträgt und es uns ermöglicht, die bestmögliche Benutzererfahrung zu bieten.

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Übersetzung
Die Webseite wird von Freiwilligen mit einer gemeinsamen Übersetzungsplattform übersetzt.
Sie können dazu beitragen, indem Sie Übersetzungen in unserem <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin Projekt</a> hinzufügen oder verbessern.
Wenn Sie mit der Übersetzung in einer neuen Sprache beginnen möchten, kontaktieren Sie uns bitte <a href="#contact">Kontaktaufnahme</a>.
Jede Hilfe ist sehr willkommen!

View File

@@ -13,8 +13,8 @@ Du kannst **gpx.studio** verwenden, um Karten zu erstellen, die deine GPX-Dateie
Alles was Sie brauchen:
1. Eine <a href="https://account.mapbox.com/auth/signup" target="_blank">Mapbox Zugriffstoken</a> zum Laden der Karte, und
2. GPX-Dateien, die auf Ihrem Server oder Google Drive gehostet werden oder über eine öffentliche URL erreichbar sind.
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.
Sie können dann mit dem Konfigurator unten spielen, um Ihre Karte anzupassen und den entsprechenden HTML-Code zu generieren.

View File

@@ -56,10 +56,12 @@ Mit der Schaltfläche Karten-Ebenen können Sie zwischen verschiedenen Basemaps
- **Punkte von Interesse** können auf der Karte angezeigt werden, um verschiedene Kategorien von Orten wie Geschäfte, Restaurants oder Unterkünfte anzuzeigen.
<div class="flex flex-col items-center">
<DocsLayers />
<span class="text-sm text-center mt-2">
Fahren Sie über der Karte, um die <a href="https://hiking.waymarkedtrails.org" target="_blank">Wegmarkierte Wanderwege</a> Overlay oben auf die <a href="https://www.mapbox.com/maps/outdoors" target="_blank">Mapbox Outdoors</a> Basemap anzuzeigen.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span>
</div>
Eine große Sammlung globaler und lokaler Basemaps und Overlays ist im **gpx.studio** sowie eine Auswahl von Point-of-Interest Kategorien verfügbar.
@@ -67,4 +69,4 @@ Sie können im [Einstellungsdialog für die Kartenlayer Einstellungen](./menu/se
In diesen Einstellungen können Sie auch die Deckkraft der Overlays verwalten.
Für fortgeschrittene Benutzer ist es möglich, benutzerdefinierte Basemaps und Overlays durch die Bereitstellung von <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>hinzuzufügen, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>oder <a href="https://docs.mapbox.com/help/glossary/style/" target="_blank">Mapbox Stil JSON</a> URLs.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.

View File

@@ -33,7 +33,7 @@ Erstelle eine Kopie der aktuell ausgewählten Dateien.
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" /> Lösche alles
Delete all files.

View File

@@ -18,7 +18,7 @@ Mit diesem Tool kannst du Höhendaten zu Routen und [Points of Interest] (../gpx
<DocsNote>
Höhendaten werden von <a href="https://mapbox.com" target="_blank">Mapbox</a> bereitgestellt.
Du kannst mehr über den Ursprung und die Genauigkeit des Tools in der <a href="https://docs.mapbox.com/data/tilesets/reference/mapbox-terrain-dem-v1/#elevation-data" target="_blank">Dokumentation</a> erfahren.
Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote>

View File

@@ -5,6 +5,7 @@ title: Zusammenfügen
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ Um dieses Tool nutzen zu können, musst du [select](../files-and-stats) mehrere
- Die zweite Option kann verwendet werden, um Dateien mit mehreren [Tracks oder Segments](../gpx) zu erstellen oder zu verwalten.
Das Zusammenführen von Dateien (oder Tracks) führt zu einer einzigen Datei (oder Track), die alle Tracks (oder Segmente) aus der Auswahl enthält.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

View File

@@ -12,6 +12,7 @@ title: Files and statistics
let gpxStatistics = writable(exampleGPXFile.getStatistics());
let slicedGPXStatistics = writable(undefined);
let hoveredPoint = writable(null);
let additionalDatasets = writable(['speed', 'atemp']);
let elevationFill = writable(undefined);
</script>
@@ -84,19 +85,17 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
<ElevationProfile
{gpxStatistics}
{slicedGPXStatistics}
{hoveredPoint}
{additionalDatasets}
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Additional data

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Help keep the website free (and ad-free)
Each time you add or move GPS points, our servers calculate the best route on the road network.
We also use APIs from <a href="https://mapbox.com" target="_blank">Mapbox</a> to display beautiful maps, retrieve elevation data and allow you to search for places.
Unfortunately, this is expensive.
If you enjoy using this tool and find it valuable, please consider making a small donation to help keep the website free and ad-free.
Thank you very much for your support! ❤️

View File

@@ -1,5 +0,0 @@
Mapbox is the company that provides some of the beautiful maps on this website.
They also develop the <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">map engine</a> which powers **gpx.studio**.
We are incredibly fortunate and grateful to be part of their <a href="https://mapbox.com/community" target="_blank">Community</a> program, which supports nonprofits, educational institutions, and positive impact organizations.
This partnership allows **gpx.studio** to benefit from Mapbox tools at discounted prices, greatly contributing to the financial viability of the project and enabling us to offer the best possible user experience.

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Translation
The website is translated by volunteers using a collaborative translation platform.
You can contribute by adding or improving translations on our <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin project</a>.
If you would like to start translating into a new language, please <a href="#contact">get in touch</a>.
Any help is greatly appreciated!

View File

@@ -13,8 +13,8 @@ You can use **gpx.studio** to create maps showing your GPX files and embed them
All you need is:
1. A <a href="https://account.mapbox.com/auth/signup" target="_blank">Mapbox access token</a> to load the map, and
2. GPX files hosted on your server or on Google Drive, or accessible via a public URL.
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.
You can then play with the configurator below to customize your map and generate the corresponding HTML code.

View File

@@ -56,10 +56,12 @@ The map layers button allows you to switch between different basemaps, and toggl
- **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 <a href="https://www.mapbox.com/maps/outdoors" target="_blank">Mapbox Outdoors</a> basemap.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</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.
@@ -67,4 +69,4 @@ They can be enabled in the [map layer settings dialog](./menu/settings).
In these settings, you can also manage the opacity of the overlays.
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://docs.mapbox.com/help/glossary/style/" target="_blank">Mapbox style JSON</a> URLs.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.

View File

@@ -28,9 +28,9 @@ Change the language used in the interface.
<DocsNote>
You can contribute by adding or improving translations on our <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin project</a>.
If you would like to start translating into a new language, please <a href="#contact">get in touch</a>.
Any help is greatly appreciated!
Μπορείτε να συνεισφέρετε προσθέτοντας ή βελτιώνοντας μεταφράσεις στο <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin έργο</a>.
Αν θέλετε να ξεκινήσετε μετάφραση μιας νέας γλώσσας, παρακαλώ <a href="#contact">επικοινωνήστε μαζί μας</a>.
Οποιαδήποτε βοήθεια εκτιμάται ιδιαίτερα!
</DocsNote>

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" />

View File

@@ -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://mapbox.com" target="_blank">Mapbox</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.mapbox.com/data/tilesets/reference/mapbox-terrain-dem-v1/#elevation-data" target="_blank">documentation</a>.
Elevation data is provided by <a href="https://maptiler.com" target="_blank">MapTiler</a>.
You can learn more about its origin and accuracy in the <a href="https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/" target="_blank">documentation</a>.
</DocsNote>

View File

@@ -5,6 +5,7 @@ title: Merge
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ To use this tool, you need to [select](../files-and-stats) multiple files, [trac
- 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.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

View File

@@ -90,15 +90,12 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
{elevationFill}
/>
</div>
<div class="flex flex-col items-center -mt-6">
<div class="h-10 w-fit">
<div class="flex flex-col items-center w-full">
<GPXStatistics
{gpxStatistics}
{slicedGPXStatistics}
panelSize={120}
orientation={'horizontal'}
/>
</div>
</div>
### Additional data

View File

@@ -1,13 +0,0 @@
<script>
import { HeartHandshake } from '@lucide/svelte';
</script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Help keep the website free (and ad-free)
Each time you add or move GPS points, our servers calculate the best route on the road network.
We also use APIs from <a href="https://maptiler.com" target="_blank">MapTiler</a> to display beautiful maps, retrieve elevation data and allow you to search for places.
Unfortunately, this is expensive.
If you enjoy using this tool and find it valuable, please consider making a small donation to help keep the website free and ad-free.
Thank you very much for your support! ❤️

View File

@@ -1,12 +0,0 @@
<script>
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Translation
The website is translated by volunteers using a collaborative translation platform.
You can contribute by adding or improving translations on our <a href="https://crowdin.com/project/gpxstudio" target="_blank">Crowdin project</a>.
If you would like to start translating into a new language, please <a href="#contact">get in touch</a>.
Any help is greatly appreciated!

View File

@@ -12,8 +12,8 @@ title: Integration
You can use **gpx.studio** to create maps showing your GPX files and embed them in your website.
All you need is:
1. A <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">MapTiler key</a> to load the map, and
1. GPX files hosted on your server or on Google Drive, or accessible via a public URL.
1. GPX files hosted on your server or on Google Drive, or accessible via a public URL;
1. *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.
You can then play with the configurator below to customize your map and generate the corresponding HTML code.

View File

@@ -56,10 +56,12 @@ Only one basemap can be displayed at a time.
- **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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</span>
<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 <a href="https://www.maptiler.com/maps/outdoor-topo/" target="_blank">MapTiler Topo</a> basemap.
</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.

View File

@@ -5,6 +5,7 @@ title: Merge
<script>
import { Group } from '@lucide/svelte';
import Merge from '$lib/components/toolbar/tools/Merge.svelte';
import DocsNote from '$lib/components/docs/DocsNote.svelte';
</script>
# <Group size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
@@ -15,6 +16,13 @@ To use this tool, you need to [select](../files-and-stats) multiple files, [trac
- 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.
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
</DocsNote>
<div class="flex flex-row justify-center">
<Merge class="text-foreground p-3 border rounded-md shadow-lg" />
</div>

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