39 Commits
Author SHA1 Message Date
vcoppe 99890fe6da New translations file.mdx (Russian)
[ci skip]
2026-10-06 23:37:21 +02:00
vcoppe 8a4721f7fc New translations edit.mdx (Portuguese)
[ci skip]
2026-10-01 18:35:08 +02:00
vcoppe c29733091b New translations getting-started.mdx (Portuguese)
[ci skip]
2026-10-01 18:35:06 +02:00
vcoppe b06800e2fe New translations files-and-stats.mdx (Portuguese)
[ci skip]
2026-10-01 18:35:05 +02:00
vcoppe deaf5e0926 New translations en.json (Portuguese)
[ci skip]
2026-10-01 18:35:02 +02:00
vcoppe 8e5beaabe9 New translations en.json (Portuguese)
[ci skip]
2026-10-01 16:47:57 +02:00
vcoppe 8a38627467 New translations elevation.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:47 +02:00
vcoppe ceadc7d1b5 New translations faq.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:46 +02:00
vcoppe 383d21a4a1 New translations time.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:44 +02:00
vcoppe 153ecb9765 New translations scissors.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:42 +02:00
vcoppe d911761e17 New translations routing.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:40 +02:00
vcoppe 7540565d79 New translations poi.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:38 +02:00
vcoppe 01332e7a03 New translations minify.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:36 +02:00
vcoppe 1aabfb4584 New translations merge.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:33 +02:00
vcoppe 44d76966e2 New translations extract.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:32 +02:00
vcoppe 1722520d23 New translations clean.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:30 +02:00
vcoppe 8e99ed2689 New translations view.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:28 +02:00
vcoppe 4f88fe179a New translations file.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:26 +02:00
vcoppe b13602b33e New translations map-controls.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:24 +02:00
vcoppe 8138fe780b New translations integration.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:22 +02:00
vcoppe f4d6cd9cc3 New translations getting-started.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:20 +02:00
vcoppe 902107c36b New translations files-and-stats.mdx (Portuguese)
[ci skip]
2026-09-30 16:20:18 +02:00
vcoppe ea8e8bc1e3 New translations en.json (Portuguese)
[ci skip]
2026-09-30 14:33:57 +02:00
vcoppe c89a6148f2 New translations edit.mdx (Russian)
[ci skip]
2026-09-21 22:13:00 +02:00
vcoppe fa732b0343 New translations en.json (Portuguese)
[ci skip]
2026-09-02 03:11:59 +02:00
vcoppe 142ee61484 New translations en.json (Portuguese)
[ci skip]
2026-09-02 02:14:31 +02:00
vcoppe 873059cfcc New translations view.mdx (Chinese Traditional, Hong Kong)
[ci skip]
2026-08-14 12:27:32 +02:00
vcoppe 9e380e597e New translations settings.mdx (Chinese Traditional, Hong Kong)
[ci skip]
2026-08-14 12:27:30 +02:00
vcoppe f4dc516fe5 New translations files-and-stats.mdx (Chinese Traditional, Hong Kong)
[ci skip]
2026-08-14 10:41:57 +02:00
vcoppe bca6c32193 New translations routing.mdx (Russian)
[ci skip]
2026-08-11 14:53:35 +02:00
vcoppe 9f52d4d60d New translations elevation.mdx (Dutch)
[ci skip]
2026-08-10 14:56:55 +02:00
vcoppe a1475ab7ba New translations en.json (Dutch)
[ci skip]
2026-08-10 14:56:54 +02:00
vcoppe 0987c6a72e New translations elevation.mdx (Basque)
[ci skip]
2026-08-06 17:52:04 +02:00
vcoppe a02de61d0a New translations merge.mdx (Basque)
[ci skip]
2026-08-06 17:52:03 +02:00
vcoppe 75e477ba52 New translations view.mdx (Basque)
[ci skip]
2026-08-06 17:52:01 +02:00
vcoppe b72cebc186 New translations map-controls.mdx (Basque)
[ci skip]
2026-08-06 17:51:59 +02:00
vcoppe 5dd53cd9eb New translations integration.mdx (Basque)
[ci skip]
2026-08-06 17:51:58 +02:00
vcoppe 2c82444832 New translations elevation.mdx (German)
[ci skip]
2026-08-01 13:11:15 +02:00
vcoppe 93ac92969d New translations en.json (Spanish)
[ci skip]
2026-07-29 17:33:54 +02:00
58 changed files with 315 additions and 329 deletions

No files matched your search

+67 -70
View File
@@ -20,7 +20,7 @@
"immer": "^10.1.1",
"jszip": "^3.10.1",
"mapillary-js": "^4.1.2",
"maplibre-gl": "^6.0.0",
"maplibre-gl": "^5.21.1",
"sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6"
},
@@ -3236,18 +3236,13 @@
}
},
"node_modules/@mapbox/jsonlint-lines-primitives": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.3.tgz",
"integrity": "sha512-0SElaV0uMxEnxzBhhX9WTuPyUeMsAN/SS0i16tjuba4/mio63MG9khjC1a0JAiPGXAwvwm4UfHJURCN7nyudQg==",
"license": "MIT",
"version": "2.0.2",
"engines": {
"node": ">= 22"
"node": ">= 0.6"
}
},
"node_modules/@mapbox/point-geometry": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz",
"integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==",
"license": "ISC"
},
"node_modules/@mapbox/sphericalmercator": {
@@ -3258,32 +3253,24 @@
"license": "MIT"
},
"node_modules/@mapbox/tiny-sdf": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.2.0.tgz",
"integrity": "sha512-LVL4wgI9YAum5V+LNVQO6QgFBPw7/MIIY4XJPNsPDMrjEwcE+JfKk1LuIl8GnF197ejVdC9QdPaxrx5gfgdGXg==",
"version": "2.0.7",
"license": "BSD-2-Clause"
},
"node_modules/@mapbox/unitbezier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-1.0.0.tgz",
"integrity": "sha512-fqd515fjBmANKGGsQ286E2Wvj/XvDFpGzwJxq4CI6jMQue6Oy04uCKp+JWKF00xRTmk6cEu1jPJ9p3xqH8YWqQ==",
"version": "0.0.1",
"license": "BSD-2-Clause"
},
"node_modules/@mapbox/vector-tile": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-3.0.0.tgz",
"integrity": "sha512-Qf10S1uIHMk20ri/IVBnpS+esUEkVaR5Hftmz88jTInrpmWgPGJfPe3LVjjlE77trLx8tH6qjTG7uWH9hIq/0Q==",
"version": "2.0.4",
"license": "BSD-3-Clause",
"dependencies": {
"@mapbox/point-geometry": "~1.1.0",
"@types/geojson": "^7946.0.16",
"pbf": "^5.0.0"
"pbf": "^4.0.1"
}
},
"node_modules/@mapbox/vector-tile/node_modules/pbf": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"version": "4.0.1",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
@@ -3292,13 +3279,18 @@
"pbf": "bin/pbf"
}
},
"node_modules/@mapbox/whoots-js": {
"version": "3.1.0",
"license": "ISC",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@maplibre/geojson-vt": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.1.1.tgz",
"integrity": "sha512-FVMOcmSP/yqol45t7StApEyTL5/vmqBCuFhH9n+fFuINenhaX+YgHHIt1yJ86S8kln3uJLcMvmEU2cfn6E2eCQ==",
"version": "6.0.4",
"license": "ISC",
"dependencies": {
"kdbush": "^4.1.0"
"kdbush": "^4.0.2"
}
},
"node_modules/@maplibre/maplibre-gl-geocoder": {
@@ -3319,16 +3311,15 @@
}
},
"node_modules/@maplibre/maplibre-gl-style-spec": {
"version": "26.2.1",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-26.2.1.tgz",
"integrity": "sha512-QFKCXkOeSzOr8jF75jm6kySOg+dUvOehPhRi68gcOYPHb7U5JloUq0dJW0Y5/fZV8ygfT0Vp2RWodvq+fyxFWA==",
"version": "24.8.1",
"license": "ISC",
"dependencies": {
"@mapbox/jsonlint-lines-primitives": "^2.0.3",
"@mapbox/unitbezier": "^1.0.0",
"@mapbox/jsonlint-lines-primitives": "~2.0.2",
"@mapbox/unitbezier": "^0.0.1",
"json-stringify-pretty-compact": "^4.0.0",
"minimist": "^1.2.8",
"quickselect": "^3.0.0",
"rw": "^1.3.3",
"tinyqueue": "^3.0.0"
},
"bin": {
@@ -3338,29 +3329,31 @@
}
},
"node_modules/@maplibre/mlt": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.12.tgz",
"integrity": "sha512-ZeK5w2TTeHOajcLaEQs1KZXw2V9wIKo1PmThlxlsHoXsQsYlBqLJzPOd6tJHRtGTChUY3DPPmjXRArYVvAbmZw==",
"version": "1.1.8",
"license": "(MIT OR Apache-2.0)",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0"
}
},
"node_modules/@maplibre/vt-pbf": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.3.2.tgz",
"integrity": "sha512-j6p0AdjvAR19Z3XaCysle7A4ZSo08tYOzxD0Y9NQylwPAkwJJeYub5b2eVucdeDh7erhv69DahoLOevDRERRUw==",
"version": "4.3.0",
"license": "MIT",
"dependencies": {
"@mapbox/point-geometry": "^1.1.0",
"@mapbox/vector-tile": "^2.0.4",
"@maplibre/geojson-vt": "^5.0.4",
"@types/geojson": "^7946.0.16",
"pbf": "^5.1.0"
"@types/supercluster": "^7.1.3",
"pbf": "^4.0.1",
"supercluster": "^8.0.1"
}
},
"node_modules/@maplibre/vt-pbf/node_modules/@maplibre/geojson-vt": {
"version": "5.0.4",
"license": "ISC"
},
"node_modules/@maplibre/vt-pbf/node_modules/pbf": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"version": "4.0.1",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
@@ -4296,6 +4289,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/supercluster": {
"version": "7.1.3",
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/three": {
"version": "0.134.0",
"license": "MIT"
@@ -5720,8 +5720,6 @@
},
"node_modules/json-stringify-pretty-compact": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz",
"integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==",
"license": "MIT"
},
"node_modules/jszip": {
@@ -5735,9 +5733,7 @@
}
},
"node_modules/kdbush": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.1.0.tgz",
"integrity": "sha512-e9vurzrXJQrFX6ckpHP3bvj5l+9CnYzkxDNnNQ1h2QTqdWsUAJgXiKdGNcOa1EY85dU8KbQ+z/FdQdB7P+9yfQ==",
"version": "4.0.2",
"license": "ISC"
},
"node_modules/keyv": {
@@ -6158,25 +6154,25 @@
"license": "(MIT AND Zlib)"
},
"node_modules/maplibre-gl": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-6.0.0.tgz",
"integrity": "sha512-1wBgEhzTZfA+cDpFdt0fM1mJA5mJ90fifORJ7D8JcKLJCvPT/iTx9bNxkP7DqEYde65DJd7gE7h83khwNRqdyg==",
"version": "5.22.0",
"license": "BSD-3-Clause",
"dependencies": {
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
"@mapbox/point-geometry": "^1.1.0",
"@mapbox/tiny-sdf": "^2.2.0",
"@mapbox/unitbezier": "^1.0.0",
"@mapbox/vector-tile": "^3.0.0",
"@maplibre/geojson-vt": "^6.1.1",
"@maplibre/maplibre-gl-style-spec": "^26.1.0",
"@maplibre/mlt": "^1.1.12",
"@maplibre/vt-pbf": "^4.3.2",
"@mapbox/tiny-sdf": "^2.0.7",
"@mapbox/unitbezier": "^0.0.1",
"@mapbox/vector-tile": "^2.0.4",
"@mapbox/whoots-js": "^3.1.0",
"@maplibre/geojson-vt": "^6.0.4",
"@maplibre/maplibre-gl-style-spec": "^24.8.1",
"@maplibre/mlt": "^1.1.8",
"@maplibre/vt-pbf": "^4.3.0",
"@types/geojson": "^7946.0.16",
"earcut": "^3.2.3",
"earcut": "^3.0.2",
"gl-matrix": "^3.4.4",
"kdbush": "^4.1.0",
"kdbush": "^4.0.2",
"murmurhash-js": "^1.0.0",
"pbf": "^5.1.2",
"pbf": "^4.0.1",
"potpack": "^2.1.0",
"quickselect": "^3.0.0",
"tinyqueue": "^3.0.0"
@@ -6190,15 +6186,11 @@
}
},
"node_modules/maplibre-gl/node_modules/earcut": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.2.3.tgz",
"integrity": "sha512-vnS4AVwp1KHAF13i1vp1/2D5evWy3k5u/iW/B81QVsUZtV8cv2tU0b2VNFlqvh4kYwrFMDdjPCfAmfyJW9y14Q==",
"version": "3.0.2",
"license": "ISC"
},
"node_modules/maplibre-gl/node_modules/pbf": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-5.1.2.tgz",
"integrity": "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==",
"version": "4.0.1",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
@@ -6259,8 +6251,6 @@
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -6795,8 +6785,6 @@
},
"node_modules/quickselect": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
"license": "ISC"
},
"node_modules/rbush": {
@@ -6932,6 +6920,10 @@
}
}
},
"node_modules/rw": {
"version": "1.3.3",
"license": "BSD-3-Clause"
},
"node_modules/rxjs": {
"version": "7.8.2",
"license": "Apache-2.0",
@@ -7165,6 +7157,13 @@
"xtend": "^4.0.0"
}
},
"node_modules/supercluster": {
"version": "8.0.1",
"license": "ISC",
"dependencies": {
"kdbush": "^4.0.2"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7406,8 +7405,6 @@
},
"node_modules/tinyqueue": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz",
"integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==",
"license": "ISC"
},
"node_modules/totalist": {
+1 -1
View File
@@ -75,7 +75,7 @@
"immer": "^10.1.1",
"jszip": "^3.10.1",
"mapillary-js": "^4.1.2",
"maplibre-gl": "^6.0.0",
"maplibre-gl": "^5.21.1",
"sanitize-html": "^2.17.0",
"sortablejs": "^1.15.6"
}
+1 -1
View File
@@ -1168,7 +1168,7 @@ export type CustomLayer = {
maxZoom: number;
layerType: 'basemap' | 'overlay';
resourceType: 'raster' | 'vector';
value: string | StyleSpecification;
value: string | maplibregl.StyleSpecification;
};
type OverpassQueryData = {
@@ -2,7 +2,6 @@
import CustomControl from './custom-control';
import { map } from '$lib/components/map/map';
import { onMount, type Snippet } from 'svelte';
import type { Map } from 'maplibre-gl';
let {
position = 'top-right',
@@ -18,7 +17,7 @@
let control: CustomControl | null = null;
onMount(() => {
map.onLoad((map: Map) => {
map.onLoad((map: maplibregl.Map) => {
if (position.includes('right')) container.classList.add('float-right');
else container.classList.add('float-left');
container.classList.remove('hidden');
@@ -1,10 +1,9 @@
import { MapPopup } from '$lib/components/map/map-popup';
import type { Map } from 'maplibre-gl';
export let waypointPopup: MapPopup | null = null;
export let trackpointPopup: MapPopup | null = null;
export function createPopups(map: Map) {
export function createPopups(map: maplibregl.Map) {
removePopups();
waypointPopup = new MapPopup(map, {
closeButton: false,
@@ -1,10 +1,9 @@
import { get, type Readable } from 'svelte/store';
import {
import maplibregl, {
type GeoJSONSource,
type FilterSpecification,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
Point,
} from 'maplibre-gl';
import { map } from '$lib/components/map/map';
import { waypointPopup, trackpointPopup } from './gpx-layer-popup';
@@ -121,7 +120,7 @@ export class GPXLayer {
selected: boolean = false;
currentWaypointData: GeoJSON.FeatureCollection | null = null;
draggedWaypointIndex: number | null = null;
draggingStartingPosition: Point = new Point(0, 0);
draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
unsubscribe: Function[] = [];
updateBinded: () => void = this.update.bind(this);
@@ -7,7 +7,6 @@
import { Layers } from '@lucide/svelte';
import { settings } from '$lib/logic/settings';
import { map } from '$lib/components/map/map';
import type { Map } from 'maplibre-gl';
let container: HTMLDivElement;
let overpassLayer: OverpassLayer;
@@ -22,7 +21,7 @@
selectedOverpassTree,
} = settings;
map.onLoad((_map: Map) => {
map.onLoad((_map: maplibregl.Map) => {
if (overpassLayer) {
overpassLayer.remove();
}
@@ -15,9 +15,7 @@
poi: PopupItem<any>;
} = $props();
let tags: Record<string, string> = $derived(
poi ? (typeof poi.item.tags == 'object' ? poi.item.tags : JSON.parse(poi.item.tags)) : {}
);
let tags: Record<string, string> = $derived(poi ? JSON.parse(poi.item.tags) : {});
let name = $derived.by(() => {
if (poi) {
if (tags.name !== undefined && tags.name !== '') {
@@ -6,7 +6,7 @@ import { overpassQueryData } from '$lib/assets/layers';
import { MapPopup } from '$lib/components/map/map-popup';
import { settings } from '$lib/logic/settings';
import { db } from '$lib/db';
import type { Map as MapLibreMap, GeoJSONSource } from 'maplibre-gl';
import type { GeoJSONSource } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
import { loadSVGIcon } from '$lib/utils';
@@ -28,7 +28,7 @@ export class OverpassLayer {
minZoom = 12;
queryZoom = 12;
expirationTime = 7 * 24 * 3600 * 1000;
map: MapLibreMap;
map: maplibregl.Map;
layerEventManager: MapLayerEventManager;
popup: MapPopup;
@@ -40,7 +40,7 @@ export class OverpassLayer {
updateBinded = this.update.bind(this);
onHoverBinded = this.onHover.bind(this);
constructor(map: MapLibreMap, layerEventManager: MapLayerEventManager) {
constructor(map: maplibregl.Map, layerEventManager: MapLayerEventManager) {
this.map = map;
this.layerEventManager = layerEventManager;
this.popup = new MapPopup(map, {
@@ -1,19 +1,10 @@
import { fileStateCollection } from '$lib/logic/file-state';
import {
LngLatBounds,
MapMouseEvent,
MapTouchEvent,
Point,
type Map,
type MapGeoJSONFeature,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
} from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
type MapLayerMouseEventListener = (e: MapLayerMouseEvent) => void;
type MapLayerTouchEventListener = (e: MapLayerTouchEvent) => void;
type MapLayerMouseEventListener = (e: maplibregl.MapLayerMouseEvent) => void;
type MapLayerTouchEventListener = (e: maplibregl.MapLayerTouchEvent) => void;
type MapLayerListener = {
features: MapGeoJSONFeature[];
features: maplibregl.MapGeoJSONFeature[];
mousemoves: MapLayerMouseEventListener[];
mouseenters: MapLayerMouseEventListener[];
mouseleaves: MapLayerMouseEventListener[];
@@ -24,10 +15,10 @@ type MapLayerListener = {
};
export class MapLayerEventManager {
private _map: Map;
private _map: maplibregl.Map;
private _listeners: Record<string, MapLayerListener> = {};
constructor(map: Map) {
constructor(map: maplibregl.Map) {
this._map = map;
this._map.on('mousemove', this._handleMouseMove.bind(this));
this._map.on('click', this._handleMouseClick.bind(this, 'click'));
@@ -150,7 +141,7 @@ export class MapLayerEventManager {
}
}
private _handleMouseMove(e: MapMouseEvent) {
private _handleMouseMove(e: maplibregl.MapMouseEvent) {
if (e.originalEvent.buttons > 0) return;
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => {
@@ -159,20 +150,29 @@ export class MapLayerEventManager {
if ((features.length == 0) != (listener.features.length == 0)) {
if (features.length > 0) {
if (listener.mouseenters.length > 0) {
const event = new MapMouseEvent('mouseenter', e.target, e.originalEvent, {
features: featuresByLayer[layerId]!,
});
const event = new maplibregl.MapMouseEvent(
'mouseenter',
e.target,
e.originalEvent,
{
features: featuresByLayer[layerId]!,
}
);
listener.mouseenters.forEach((l) => l(event));
}
} else {
if (listener.mouseleaves.length > 0) {
const event = new MapMouseEvent('mouseleave', e.target, e.originalEvent);
const event = new maplibregl.MapMouseEvent(
'mouseleave',
e.target,
e.originalEvent
);
listener.mouseleaves.forEach((l) => l(event));
}
}
}
if (features.length > 0 && listener.mousemoves.length > 0) {
const event = new MapMouseEvent('mousemove', e.target, e.originalEvent, {
const event = new maplibregl.MapMouseEvent('mousemove', e.target, e.originalEvent, {
features: featuresByLayer[layerId]!,
});
listener.mousemoves.forEach((l) => l(event));
@@ -181,39 +181,49 @@ export class MapLayerEventManager {
});
}
private _handleMouseClick(type: string, e: MapMouseEvent) {
private _handleMouseClick(type: string, e: maplibregl.MapMouseEvent) {
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || [];
const listener = this._listeners[layerId];
if (features.length > 0) {
if (type === 'click' && listener.clicks.length > 0) {
const event = new MapMouseEvent('click', e.target, e.originalEvent, {
const event = new maplibregl.MapMouseEvent('click', e.target, e.originalEvent, {
features: features,
});
listener.clicks.forEach((l) => l(event));
} else if (type === 'contextmenu' && listener.contextmenus.length > 0) {
const event = new MapMouseEvent('contextmenu', e.target, e.originalEvent, {
features: features,
});
const event = new maplibregl.MapMouseEvent(
'contextmenu',
e.target,
e.originalEvent,
{
features: features,
}
);
listener.contextmenus.forEach((l) => l(event));
} else if (type === 'mousedown' && listener.mousedowns.length > 0) {
const event = new MapMouseEvent('mousedown', e.target, e.originalEvent, {
features: features,
});
const event = new maplibregl.MapMouseEvent(
'mousedown',
e.target,
e.originalEvent,
{
features: features,
}
);
listener.mousedowns.forEach((l) => l(event));
}
}
});
}
private _handleTouchStart(e: MapTouchEvent) {
private _handleTouchStart(e: maplibregl.MapTouchEvent) {
const featuresByLayer = this._getRenderedFeaturesByLayer(e);
Object.keys(this._listeners).forEach((layerId) => {
const features = featuresByLayer[layerId] || [];
const listener = this._listeners[layerId];
if (features.length > 0) {
const event: MapLayerTouchEvent = new MapTouchEvent(
const event: maplibregl.MapLayerTouchEvent = new maplibregl.MapTouchEvent(
'touchstart',
e.target,
e.originalEvent
@@ -224,15 +234,18 @@ export class MapLayerEventManager {
});
}
private _getBounds(point: Point) {
private _getBounds(point: maplibregl.Point) {
const delta = 30;
return new LngLatBounds(
return new maplibregl.LngLatBounds(
this._map.unproject([point.x - delta, point.y + delta]),
this._map.unproject([point.x + delta, point.y - delta])
);
}
private _filterLayersIntersectingBounds(layerIds: string[], bounds: LngLatBounds): string[] {
private _filterLayersIntersectingBounds(
layerIds: string[],
bounds: maplibregl.LngLatBounds
): string[] {
let result = layerIds.filter((layerId) => {
if (!this._map.getLayer(layerId)) return false;
const fileId = layerId.replace('-waypoints', '');
@@ -248,7 +261,7 @@ export class MapLayerEventManager {
return result;
}
private _getRenderedFeaturesByLayer(e: MapMouseEvent | MapTouchEvent) {
private _getRenderedFeaturesByLayer(e: maplibregl.MapMouseEvent | maplibregl.MapTouchEvent) {
const layerIds = this._filterLayersIntersectingBounds(
Object.keys(this._listeners),
this._getBounds(e.point)
@@ -257,7 +270,7 @@ export class MapLayerEventManager {
layerIds.length > 0
? this._map.queryRenderedFeatures(e.point, { layers: layerIds })
: [];
const featuresByLayer: Record<string, MapGeoJSONFeature[]> = {};
const featuresByLayer: Record<string, maplibregl.MapGeoJSONFeature[]> = {};
features.forEach((f) => {
if (!featuresByLayer[f.layer.id]) {
featuresByLayer[f.layer.id] = [];
+8 -8
View File
@@ -1,5 +1,5 @@
import { TrackPoint, Waypoint } from 'gpx';
import { LngLat, Map, MapMouseEvent, Popup, type PopupOptions } from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
import { mount, tick, unmount } from 'svelte';
import { get, writable, type Writable } from 'svelte/store';
import MapPopupComponent from '$lib/components/map/MapPopup.svelte';
@@ -11,15 +11,15 @@ export type PopupItem<T = Waypoint | TrackPoint | any> = {
};
export class MapPopup {
map: Map;
popup: Popup;
map: maplibregl.Map;
popup: maplibregl.Popup;
item: Writable<PopupItem | null> = writable(null);
component: ReturnType<typeof mount>;
maybeHideBinded = this.maybeHide.bind(this);
constructor(map: Map, options?: PopupOptions) {
constructor(map: maplibregl.Map, options?: maplibregl.PopupOptions) {
this.map = map;
this.popup = new Popup(options);
this.popup = new maplibregl.Popup(options);
this.component = mount(MapPopupComponent, {
target: document.body,
props: {
@@ -51,7 +51,7 @@ export class MapPopup {
this.map.on('mousemove', this.maybeHideBinded);
}
maybeHide(e: MapMouseEvent) {
maybeHide(e: maplibregl.MapMouseEvent) {
const item = get(this.item);
if (item === null) {
this.hide();
@@ -75,10 +75,10 @@ export class MapPopup {
getCoordinates() {
const item = get(this.item);
if (item === null) {
return new LngLat(0, 0);
return new maplibregl.LngLat(0, 0);
}
return item.item instanceof Waypoint || item.item instanceof TrackPoint
? item.item.getCoordinates()
: new LngLat(item.item.lon, item.item.lat);
: new maplibregl.LngLat(item.item.lon, item.item.lat);
}
}
+1 -3
View File
@@ -1,6 +1,5 @@
import * as maplibregl from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
import MaplibreGeocoder, {
type MaplibreGeocoderFeatureResults,
} from '@maplibre/maplibre-gl-geocoder';
@@ -40,7 +39,6 @@ export class MapLibreGLMap {
geocoder: boolean,
geolocate: boolean
) {
maplibregl.setWorkerUrl(workerUrl);
this._maptilerKey = maptilerKey;
this._styleManager = new StyleManager(this._mapStore, this._maptilerKey);
const map = new maplibregl.Map({
@@ -9,7 +9,6 @@
import { i18n } from '$lib/i18n.svelte';
import { onMount } from 'svelte';
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
import type { Map } from 'maplibre-gl';
const { streetViewSource } = settings;
@@ -21,7 +20,7 @@
let container: HTMLElement;
onMount(() => {
map.onLoad((map_: Map) => {
map.onLoad((map_: maplibregl.Map) => {
googleRedirect = new GoogleRedirect(map_);
mapillaryLayer = new MapillaryLayer(
map_,
@@ -1,11 +1,10 @@
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import type { Map, MapMouseEvent } from 'maplibre-gl';
export class GoogleRedirect {
map: Map;
map: maplibregl.Map;
enabled = false;
constructor(map: Map) {
constructor(map: maplibregl.Map) {
this.map = map;
}
@@ -25,7 +24,7 @@ export class GoogleRedirect {
this.map.off('click', this.openStreetView);
}
openStreetView(e: MapMouseEvent) {
openStreetView(e: maplibregl.MapMouseEvent) {
window.open(
`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${e.lngLat.lat},${e.lngLat.lng}`
);
@@ -1,10 +1,4 @@
import {
Map,
Marker,
type LayerSpecification,
type MapLayerMouseEvent,
type VectorSourceSpecification,
} from 'maplibre-gl';
import maplibregl, { type LayerSpecification, type VectorSourceSpecification } from 'maplibre-gl';
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
import 'mapillary-js/dist/mapillary.css';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
@@ -49,9 +43,9 @@ const mapillaryImageLayer: LayerSpecification = {
};
export class MapillaryLayer {
map: Map;
map: maplibregl.Map;
layerEventManager: MapLayerEventManager;
marker: Marker;
marker: maplibregl.Marker;
viewer: Viewer;
active = false;
@@ -62,7 +56,7 @@ export class MapillaryLayer {
onMouseLeaveBinded = this.onMouseLeave.bind(this);
constructor(
map: Map,
map: maplibregl.Map,
layerEventManager: MapLayerEventManager,
container: HTMLElement,
popupOpen: { value: boolean }
@@ -81,7 +75,7 @@ export class MapillaryLayer {
dot.className = 'maplibregl-user-location-dot';
element.appendChild(dot);
this.marker = new Marker({
this.marker = new maplibregl.Marker({
rotationAlignment: 'map',
element,
});
@@ -146,7 +140,7 @@ export class MapillaryLayer {
this.popupOpen.value = false;
}
onMouseEnter(e: MapLayerMouseEvent) {
onMouseEnter(e: maplibregl.MapLayerMouseEvent) {
if (
e.features &&
e.features.length > 0 &&
+11 -15
View File
@@ -9,17 +9,11 @@ import {
} from '$lib/assets/layers';
import { getLayers } from '$lib/components/map/layer-control/utils';
import { i18n } from '$lib/i18n.svelte';
import type {
Map,
GeoJSONSourceSpecification,
LayerSpecification,
StyleSpecification,
} from 'maplibre-gl';
const { currentBasemap, currentOverlays, customLayers, opacities, terrainSource, distanceUnits } =
settings;
const emptySource: GeoJSONSourceSpecification = {
const emptySource: maplibregl.GeoJSONSourceSpecification = {
type: 'geojson',
data: {
type: 'FeatureCollection',
@@ -38,18 +32,18 @@ export const ANCHOR_LAYER_KEY = {
waypoints: 'waypoints-end',
routingControls: 'routing-controls-end',
};
const anchorLayers: LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
const anchorLayers: maplibregl.LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
id: id,
type: 'symbol',
source: 'empty-source',
}));
export class StyleManager {
private _map: Writable<Map | null>;
private _map: Writable<maplibregl.Map | null>;
private _maptilerKey: string;
private _pastOverlays: Set<string> = new Set();
constructor(map: Writable<Map | null>, maptilerKey: string) {
constructor(map: Writable<maplibregl.Map | null>, maptilerKey: string) {
this._map = map;
this._maptilerKey = maptilerKey;
this._map.subscribe((map_) => {
@@ -82,10 +76,10 @@ export class StyleManager {
});
}
async buildStyle(basemap: string): Promise<StyleSpecification> {
async buildStyle(basemap: string): Promise<maplibregl.StyleSpecification> {
const custom = get(customLayers);
const style: StyleSpecification = {
const style: maplibregl.StyleSpecification = {
version: 8,
projection: {
type: 'globe',
@@ -98,7 +92,7 @@ export class StyleManager {
const basemapInfo = basemaps[basemap] ?? custom[basemap]?.value ?? basemaps[defaultBasemap];
let basemapStyle = basemaps.openStreetMap as StyleSpecification;
let basemapStyle = basemaps.openStreetMap as maplibregl.StyleSpecification;
try {
basemapStyle = await this.get(basemapInfo);
for (const source in basemapStyle.sources) {
@@ -209,7 +203,9 @@ export class StyleManager {
}
}
async get(styleInfo: StyleSpecification | string): Promise<StyleSpecification> {
async get(
styleInfo: maplibregl.StyleSpecification | string
): Promise<maplibregl.StyleSpecification> {
if (typeof styleInfo === 'string') {
let styleUrl = styleInfo as string;
const response = await fetch(styleUrl, { cache: 'force-cache' });
@@ -223,7 +219,7 @@ export class StyleManager {
}
}
merge(style: StyleSpecification, other: StyleSpecification) {
merge(style: maplibregl.StyleSpecification, other: maplibregl.StyleSpecification) {
style.sources = { ...style.sources, ...other.sources };
const units = get(distanceUnits);
for (let layer of other.layers ?? []) {
@@ -11,7 +11,7 @@
import Clean from '$lib/components/toolbar/tools/Clean.svelte';
import Reduce from '$lib/components/toolbar/tools/reduce/Reduce.svelte';
import RoutingControlPopup from '$lib/components/toolbar/tools/routing/RoutingControlPopup.svelte';
import { Popup } from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
import { settings } from '$lib/logic/settings';
let {
@@ -23,11 +23,11 @@
const { minimizeRoutingMenu } = settings;
let popupElement: HTMLDivElement | undefined = $state(undefined);
let popup: Popup | undefined = $derived.by(() => {
let popup: maplibregl.Popup | undefined = $derived.by(() => {
if (!popupElement) {
return undefined;
}
let popup = new Popup({
let popup = new maplibregl.Popup({
closeButton: false,
maxWidth: undefined,
});
@@ -16,7 +16,7 @@
import { getURLForLanguage } from '$lib/utils';
import { Trash2 } from '@lucide/svelte';
import { map } from '$lib/components/map/map';
import type { GeoJSONSource, LngLat } from 'maplibre-gl';
import type { GeoJSONSource } from 'maplibre-gl';
import { selection } from '$lib/logic/selection';
import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
@@ -29,7 +29,7 @@
let cleanType = $state(CleanType.INSIDE);
let deleteTrackpoints = $state(true);
let deleteWaypoints = $state(true);
let rectangleCoordinates: LngLat[] = $state([]);
let rectangleCoordinates: maplibregl.LngLat[] = $state([]);
$effect(() => {
if ($map) {
@@ -41,7 +41,6 @@
import { fileActions, getFileIds, newGPXFile } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { RoutingControls, routingControls } from './routing-controls';
import type { Popup } from 'maplibre-gl';
let {
minimized = $bindable(false),
@@ -52,7 +51,7 @@
}: {
minimized?: boolean;
minimizable?: boolean;
popup?: Popup;
popup?: maplibregl.Popup;
popupElement?: HTMLDivElement;
class?: string;
} = $props();
@@ -1,12 +1,10 @@
import { distance, type Coordinates, TrackPoint, TrackSegment, Track, projectedPoint } from 'gpx';
import { get, writable, type Readable } from 'svelte/store';
import {
import maplibregl, {
type MapMouseEvent,
type GeoJSONSource,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
Popup,
Point,
} from 'maplibre-gl';
import { route } from './routing';
import { toast } from 'svelte-sonner';
@@ -52,7 +50,7 @@ export class RoutingControls {
}
> = new Map();
anchors: GeoJSON.Feature<GeoJSON.Point, AnchorProperties>[] = [];
popup: Popup;
popup: maplibregl.Popup;
popupElement: HTMLElement;
fileUnsubscribe: () => void = () => {};
unsubscribes: Function[] = [];
@@ -63,7 +61,7 @@ export class RoutingControls {
draggedAnchorIndex: number | null = null;
lastDraggedAnchorEventTime: number = 0;
draggingStartingPosition: Point = new Point(0, 0);
draggingStartingPosition: maplibregl.Point = new maplibregl.Point(0, 0);
onMouseEnterBinded: () => void = this.onMouseEnter.bind(this);
onMouseLeaveBinded: () => void = this.onMouseLeave.bind(this);
onClickBinded: (e: MapLayerMouseEvent) => void = this.onClick.bind(this);
@@ -82,7 +80,7 @@ export class RoutingControls {
constructor(
fileId: string,
file: Readable<GPXFileWithStatistics | undefined>,
popup: Popup,
popup: maplibregl.Popup,
popupElement: HTMLElement
) {
this.fileId = fileId;
@@ -185,7 +183,7 @@ export class RoutingControls {
this.layers.forEach((layer, zoom) => {
try {
let source = map_.getSource(layer.id) as GeoJSONSource | undefined;
let source = map_.getSource(layer.id) as maplibregl.GeoJSONSource | undefined;
if (source) {
source.setData({
type: 'FeatureCollection',
@@ -522,7 +520,7 @@ export class RoutingControls {
});
}
async appendAnchor(e: MapMouseEvent) {
async appendAnchor(e: maplibregl.MapMouseEvent) {
// Add a new anchor to the end of the last segment
if (get(streetViewEnabled) && get(streetViewSource) === 'google') {
return;
@@ -611,7 +609,7 @@ export class RoutingControls {
await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchorPoint, newAnchorPoint]);
}
addIntermediateAnchor(e: MapMouseEvent) {
addIntermediateAnchor(e: maplibregl.MapMouseEvent) {
e.preventDefault();
if (this.temporaryAnchor !== null) {
@@ -8,13 +8,13 @@ import { get } from 'svelte/store';
import { fileStateCollection } from '$lib/logic/file-state';
import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import type { Map, GeoJSONSource, MapLayerMouseEvent } from 'maplibre-gl';
import type { GeoJSONSource } from 'maplibre-gl';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
import type { MapLayerEventManager } from '$lib/components/map/map-layer-event-manager';
import { loadSVGIcon } from '$lib/utils';
export class SplitControls {
map: Map;
map: maplibregl.Map;
layerEventManager: MapLayerEventManager;
unsubscribes: Function[] = [];
@@ -22,7 +22,7 @@ export class SplitControls {
layerOnMouseLeaveBinded: () => void = this.layerOnMouseLeave.bind(this);
layerOnClickBinded: (e: any) => void = this.layerOnClick.bind(this);
constructor(map: Map, layerEventManager: MapLayerEventManager) {
constructor(map: maplibregl.Map, layerEventManager: MapLayerEventManager) {
this.map = map;
this.layerEventManager = layerEventManager;
loadSVGIcon(
@@ -160,7 +160,7 @@ export class SplitControls {
mapCursor.notify(MapCursorState.SPLIT_CONTROL, false);
}
layerOnClick(e: MapLayerMouseEvent) {
layerOnClick(e: maplibregl.MapLayerMouseEvent) {
let coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates;
fileActions.split(
get(splitAs),
@@ -16,7 +16,7 @@
import { fileActions } from '$lib/logic/file-actions';
import { map } from '$lib/components/map/map';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { Marker } from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
import { getSvgForSymbol } from '$lib/components/map/gpx-layer/gpx-layer';
let props: {
@@ -41,7 +41,7 @@
})
);
let marker: Marker | null = null;
let marker: maplibregl.Marker | null = null;
function reset() {
if ($selectedWaypoint) {
@@ -125,7 +125,7 @@
let element = document.createElement('div');
element.classList.add('w-8', 'h-8');
element.innerHTML = getSvgForSymbol(symbolKey);
marker = new Marker({
marker = new maplibregl.Marker({
element,
anchor: 'bottom',
})
@@ -19,6 +19,6 @@ Mit diesem Tool kannst du Höhendaten zu Routen und [Points of Interest] (../gpx
<DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>.
Mehr über die Herkunft und Genauigkeit erfährst du in der <a href="https://mapterhorn.com/attribution/" target="_blank">Dokumentation</a>.
</DocsNote>
+2 -2
View File
@@ -13,8 +13,8 @@ title: Integrazioa
Behar duzun guztia hau da:
1. GPX files hosted on your server or on Google Drive, or accessible via a public URL;
2. _Optional:_ a <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">MapTiler key</a> to load MapTiler maps.
1. Zure zerbitzarian edo Google Drive-n ostatatutako GPX fitxategiak, edo URL publiko baten bidez eskura daitezke;
2. _Aukerakoa:_ <a href="https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/" target="_blank">MapTiler tekla</a> MapTiler mapak kargatzeko.
Ondoren, konfiguratzailearekin jolastu dezakezu zure mapa pertsonalizatzeko eta dagokion HTML kodea sortzeko.
+2 -2
View File
@@ -59,7 +59,7 @@ Maparen geruzen botoiak mapa-oinarri desberdinen artean aldatzeko aukera ematen
<DocsLayers />
<span class="text-sm text-center mt-2">
Hover over the map to show the <a href="https://hiking.waymarkedtrails.org" target="_blank">Waymarked Trails hiking</a> overlay on top of the topographic basemap.
Pasa ezazu maparen gainean <a href="https://hiking.waymarkedtrails.org" target="_blank">markatutako mendi-ibiliak</a> gainjartzeko oinarrizko mapa topografikoaren gainean.
</span>
</div>
@@ -69,4 +69,4 @@ Global eta tokiko mapa oinarri bilduma handia dago **gpx.studio**-n eskuragarri,
Ezarpen horietan, gainjartzeen opakutasuna ere kudeatu dezakezu.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.
Erabiltzaile aurreratuentzat, oinarrizko mapa pertsonalizatuak eta gainjartzeak gehi daitezke <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a> edo <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>https:///malibrea-spec.org/malibrea-spec. target="_blank">MapLibre estiloko JSON</a> URLak.
+2 -3
View File
@@ -48,7 +48,6 @@ Maparen orientazioa eta okertzea kontrolatzeko, mapa ere arrasta dezakezu <kbd>
</DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Pantaila osoa
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
Sartu edo irten pantaila osoko moduan.<kbd>F11</kbd> ere saka dezakezu txandakatzeko, edo <kbd>Ihes</kbd> irteteko.
@@ -18,7 +18,7 @@ Tresna honen bidez elebazio datuak gehitzen ahal dira ibilbidetan eta [interesgu
<DocsNote>
Elevation data is provided by <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>.
You can learn more about its origin and accuracy in the <a href="https://mapterhorn.com/attribution/" target="_blank">documentation</a>.
Altueraren datuak <a href="https://mapterhorn.com" target="_blank">Mapterhorn</a>k ematen ditu.
Haren jatorriari eta zehaztasunari buruz gehiago jakin dezakezu <a href="https://mapterhorn.com/attribution/" target="_blank">dokumentazioan</a>.
</DocsNote>
+2 -2
View File
@@ -18,8 +18,8 @@ Tresna hau erabiltzeko [hautatu](../files-and-stats) behar duzu hainbat fitxateg
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
Hautatutako elementuak fitxategien zerrendan agertzen diren ordenan batzen dira.
Berrantolatu elementuak arrastatu eta jareginez, behar izanez gero.
</DocsNote>
@@ -10,7 +10,7 @@ title: Stijging
# <MountainSnow size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
Met dit gereedschap kun je hoogtegegevens toevoegen aan sporen en [interessante punten](../gpx), of de bestaande gegevens vervangen.
Met deze tool kunt u hoogtegegevens toevoegen aan sporen en [punten van belang](../gpx) of de bestaande gegevens vervangen.
<div class="flex flex-row justify-center">
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
+1 -1
View File
@@ -30,6 +30,6 @@ Someone more experienced with OpenStreetMap will then review your note and make
<DocsNote>
More information on how to contribute to OpenStreetMap can be found <a href="https://wiki.openstreetmap.org/wiki/How_to_contribute" target="_blank">here</a>.
Mais informações sobre como contribuir para o OpenStreetMap podem ser encontradas <a href="https://wiki.openstreetmap.org/wiki/How_to_contribute" target="_blank">aqui</a>.
</DocsNote>
+3 -3
View File
@@ -1,5 +1,5 @@
---
title: Files and statistics
title: Ficheiros e estatísticas
---
<script lang="ts">
@@ -19,7 +19,7 @@ title: Files and statistics
# { title }
## File list
## Lista de ficheiros
Once you have [opened](./menu/file) files, they will be shown as tabs in the file list located at the bottom of the map.
You can reorder them by dragging and dropping the tabs.
@@ -103,7 +103,7 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
- **slope** information computed from the elevation data, or
- **surface** or **category** data coming from <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>'s <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> and <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">highway</a> tags.
- **superfície** ou **categoria** dados obtidos de <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> e <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">autoestrada</a> etiquetas.
This is only available for files created with **gpx.studio**.
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
+2 -2
View File
@@ -21,7 +21,7 @@ Before we dive into the details of each section, let's have a quick overview of
At the top of the interface, you will find the [main menu](./menu).
This is where you can access common actions such as opening, closing, and exporting files, undoing and redoing actions, and adjusting the application settings.
## Files and statistics
## Ficheiros e estatísticas
At the bottom of the interface, you will find the list of files currently open in the application.
You can click on a file to select it and display its statistics below the list.
@@ -34,4 +34,4 @@ On the left side of the interface, you will find the [toolbar](./toolbar), which
## Map controls
Finally, on the right side of the interface, you will find the [map controls](./map-controls).
These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
Estes controles permitem navegar pelo mapa, ampliar, reduzir e alternar entre diferentes estilos de mapa.
+1 -1
View File
@@ -20,7 +20,7 @@ You can then play with the configurator below to customize your map and generate
<DocsNote type="warning">
You will need to set up <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">Cross-Origin Resource Sharing (CORS)</a> headers on your server to allow <b>gpx.studio</b> to load your GPX files.
Precisará configurar <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">cabeçalhos de partilha de recursos entre origens (CORS)</a> no seu servidor para permitir que <b>gpx. tudio</b> para carregar os seus ficheiros GPX.
</DocsNote>
+2 -2
View File
@@ -11,7 +11,7 @@ title: Map controls
# { title }
The map controls are located on the right side of the interface.
These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
Estes controles permitem navegar pelo mapa, ampliar, reduzir e alternar entre diferentes estilos de mapa.
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
@@ -69,4 +69,4 @@ They can be enabled in the [map layer settings dialog](./menu/settings).
In these settings, you can also manage the opacity of the overlays.
For advanced users, it is possible to add custom basemaps and overlays by providing <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, or <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre style JSON</a> URLs.
Para utilizadores avançados, é possível adicionar maps de base e sobreposições personalizados, fornecendo <a href="https://en.wikipedia.org/wiki/Web_Map_Tile_Service" target="_blank">WMTS</a>, <a href="https://en.wikipedia.org/wiki/Web_Map_Service" target="_blank">WMS</a>, ou <a href="https://maplibre.org/maplibre-style-spec/" target="_blank">MapLibre com estrutura JSON</a> URLs.
+1 -1
View File
@@ -11,7 +11,7 @@ title: Edit actions
Unlike the file actions, the edit actions can potentially modify the content of the currently selected files.
Moreover, when the tree layout of the files list is enabled (see [Files and statistics](../files-and-stats)), they can also be applied to [tracks, segments, and points of interest](../gpx).
Therefore, we will refer to the elements that can be modified by these actions as _file items_.
Portanto, vamos referir-nos aos elementos que podem ser modificados por essas acções como _itens de ficheiro_.
Note that except for the undo and redo actions, the edit actions are also accessible through the context menu (right-click) of the file items.
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Undo and redo
+1 -1
View File
@@ -47,6 +47,6 @@ Open the export dialog to save all files to your computer.
<DocsNote type="warning">
If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
Se o seu download não começar depois de clicar no botão de descarregar, verifique as configurações do seu navegador para permitir descarregar do <b>gpx.studio</b>.
</DocsNote>
+1 -1
View File
@@ -51,4 +51,4 @@ To control the orientation and tilt of the map, you can also drag the map while
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
Também pode pressionar <kbd>F11</kbd> para alternar, ou <kbd>Escape</kbd> para sair.
+1 -1
View File
@@ -11,7 +11,7 @@ title: Clean
When the clean tool is selected, dragging the map will create a rectangular selection.
Depending on the options selected in the dialog shown below, clicking the delete button will remove GPS points and/or [points of interest](../gpx) located either inside or outside the selection.
Dependendo das opções selecionadas no diálogo mostrado abaixo, Clicar no botão apagar irá remover pontos de GPS e/ou [pontos de interesse](../gpx) localizados dentro ou fora da selecção.
<div class="flex flex-row justify-center">
<Clean class="text-foreground p-3 border rounded-md shadow-lg" />
@@ -10,7 +10,7 @@ title: Elevação
# <MountainSnow size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
This tool allows you to add elevation data to traces and [points of interest](../gpx), or to replace the existing data.
Esta ferramenta permite adicionar dados de elevação a rastros e [pontos de interesse](../gpx), ou substituir os dados existentes.
<div class="flex flex-row justify-center">
<Elevation class="text-foreground p-3 border rounded-md shadow-lg" />
+1 -1
View File
@@ -21,6 +21,6 @@ Similarly, applying the tool to a track containing multiple segments will create
<DocsNote>
When extracting the tracks from a file containing <a href="../gpx">points of interest</a>, the tool will automatically assign each point of interest to the track it is closest to.
Ao extrair as trilhas de um ficheiro que contém <a href="../gpx">pontos de interesse</a>, a ferramenta atribuirá automaticamente cada ponto de interesse para a faixa à qual está mais próximo.
</DocsNote>
+1 -1
View File
@@ -19,7 +19,7 @@ To use this tool, you need to [select](../files-and-stats) multiple files, [trac
<DocsNote>
Selected items are merged in the order they appear in the files list.
Reorder items by drag-and-drop if needed.
Reordenar itens por arrastar e soltar, se necessário.
</DocsNote>
+1 -1
View File
@@ -21,6 +21,6 @@ You can adjust the tolerance of the simplification algorithm using the slider, a
<DocsNote>
The tolerance value represents the maximum distance allowed between the original trace and the simplified trace.
You can read more about the algorithm used <a href="https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm" target="_blank">here</a>.
Pode ler mais sobre o algoritmo usado <a href="https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm" target="_blank">aqui</a>.
</DocsNote>
+2 -2
View File
@@ -1,5 +1,5 @@
---
title: Points of interest
title: Pontos de interesse
---
<script>
@@ -24,4 +24,4 @@ Validate the form when you are done.
### Editing a point of interest
The form above can also be used to edit an existing point of interest after selecting it on the map.
If you only need to move the point of interest, you can drag it to the desired location.
Se só precisar mover o ponto de interesse, pode arrastá-lo para o local desejado.
+1 -1
View File
@@ -81,4 +81,4 @@ Return to the starting point by the same route.
### <CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> Change the start of the loop
When the end point of the route is close enough to the start, you can change the start of the loop by clicking on any anchor point and selecting <button><CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> Start loop here</button> from the context menu.
Quando o ponto final da rota é suficientemente próximo do início, pode alterar o início do laço clicando em qualquer ponto de âncora e selecionando <button><CirclePlay size="16" class="inline-block" style="margin-bottom: 2px" /> início círculo aqui</button> no menu de contexto.
+1 -1
View File
@@ -29,4 +29,4 @@ Scissors will appear at the cursor position, showing that you can split the trac
You can choose to split the trace into two GPX files, or to keep the split parts in the same file as [tracks or segments](../gpx).
<DocsImage src="tools/split" alt="Hovering over the selected trace turns your cursor into scissors." />
<DocsImage src="tools/split" alt="Passar o rato sobre o rastro selecionado transforma o cursor numa tesoura." />
+1 -1
View File
@@ -18,7 +18,7 @@ You simply need to use the form shown below and validate it when you are done.
</div>
When you edit the speed, the moving time is adapted accordingly in the form, and vice versa.
Similarly, when you edit the start time, the end time is updated to keep the same total duration, and vice versa.
Da mesma forma, quando edita o tempo de partida o tempo de chegada é actualizado.
<DocsNote>
+36 -36
View File
@@ -9,88 +9,88 @@ title: Редактировать действия
# { title }
Unlike the file actions, the edit actions can potentially modify the content of the currently selected files.
Moreover, when the tree layout of the files list is enabled (see [Files and statistics](../files-and-stats)), they can also be applied to [tracks, segments, and points of interest](../gpx).
Therefore, we will refer to the elements that can be modified by these actions as _file items_.
Note that except for the undo and redo actions, the edit actions are also accessible through the context menu (right-click) of the file items.
В отличие от действий с файлами действия редактирования могут изменить содержимое выделенных файлов.
Более того, когда включено отображение списка файлов в виде дерева (см. [Файлы и статистика](../files-and-stats)), они также могут быть применены к [трекам, звеньям и интересным точкам](../gpx).
Таким образом, мы будем ссылаться на элементы, которые могут быть изменены этими действиями как _файловые единицы_.
Обратите внимание, что за исключением действий отмены и повтора, действия редактирования также доступны через контекстное меню (щелчок правой кнопкой мыши) файловых единиц.
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Undo and redo
### <Undo2 size="16" class="inline-block" style="margin-bottom: 2px" /><Redo2 size="16" class="inline-block" style="margin-bottom: 2px" /> Отменить и повторить
Using these buttons, you can undo or redo the last actions you performed.
This applies to all actions of the interface but not to view options, application settings, or map navigation.
С помощью этих кнопок можно отменить или повторить последние выполненные действия.
Это применимо ко всему поведению интерфейса кроме параметров просмотра, настроек приложения или перемещению по карте.
### <Info size="16" class="inline-block" style="margin-bottom: 2px" /> Info...
### <Info size="16" class="inline-block" style="margin-bottom: 2px" />Информация...
Open the information dialog of the currently selected file item, where you can see and edit its name and description.
Открывает информационный диалог выбранного в данный момент файла, где вы можете посмотреть и отредактировать его имя и описание.
### <PaintBucket size="16" class="inline-block" style="margin-bottom: 2px" /> Appearance...
### <PaintBucket size="16" class="inline-block" style="margin-bottom: 2px" />Внешнее представление...
Open the appearance dialog, where you can change the color, opacity, and width of the selected file items on the map.
Открывает диалог внешнего представления, где можно изменить цвет, прозрачность и ширину выделенных файловых элементов на карте.
### <EyeOff size="16" class="inline-block" style="margin-bottom: 2px" /> Hide/unhide
### <EyeOff size="16" class="inline-block" style="margin-bottom: 2px" /> Скрыть/показать
Toggle the visibility of the selected file items on the map.
Переключить видимость выбранных файлов на карте.
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New track
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" />Новый маршрут
Create a new track in the selected file.
Создать новый маршрут в выбранном файле.
<DocsNote>
This action is only available when the tree layout of the files list is enabled.
Additionally, the selection must be a single file.
Это действие доступно только при включенном отображении списка файлов в виде дерева.
Кроме того, должен быть выделен только один файл.
</DocsNote>
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New segment
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" />Новый отрезок
Create a new segment in the selected track.
Создать новый отрезок на выбранном маршруте.
<DocsNote>
This action is only available when the tree layout of the files list is enabled.
Additionally, the selection must be a single track.
Это действие доступно только при включенном отображении списка файлов в виде дерева.
Кроме того, должен быть выделен только один маршрут.
</DocsNote>
### <FileStack size="16" class="inline-block" style="margin-bottom: 2px" /> Select all
### <FileStack size="16" class="inline-block" style="margin-bottom: 2px" />Выбрать всё
Add all file items in the current hierarchy level to the selection.
Добавить все файлы текущего уровня иерархии к выделению.
### <Maximize size="16" class="inline-block" style="margin-bottom: 2px" /> Center
### <Maximize size="16" class="inline-block" style="margin-bottom: 2px" />По центру
Center the map on the selected file items.
Выровнять карту по центру на выбранных файловых единицах.
### <ClipboardCopy size="16" class="inline-block" style="margin-bottom: 2px" /> Copy
### <ClipboardCopy size="16" class="inline-block" style="margin-bottom: 2px" /> Копировать
Copy the selected file items to the clipboard.
Скопировать выбранные файловые единицы в буфер обмена.
<DocsNote>
This action is only available when the tree layout of the files list is enabled.
Это действие доступно только при включенном отображении списка файлов в виде дерева.
</DocsNote>
### <Scissors size="16" class="inline-block" style="margin-bottom: 2px" /> Cut
### <Scissors size="16" class="inline-block" style="margin-bottom: 2px" /> Вырезать
Cut the selected file items to the clipboard.
Вырезать выбранные файлы в буфер обмена.
<DocsNote>
This action is only available when the tree layout of the files list is enabled.
Это действие доступно только при включенном отображении списка файлов в виде дерева.
</DocsNote>
### <ClipboardPaste size="16" class="inline-block" style="margin-bottom: 2px" /> Paste
### <ClipboardPaste size="16" class="inline-block" style="margin-bottom: 2px" />Вставить
Paste the file items from the clipboard to the current hierarchy level if they are compatible with it.
Вставить файлы из буфера обмена на текущий уровень иерархии, если они совместимы с ним.
<DocsNote>
This action is only available when the tree layout of the files list is enabled.
Это действие доступно только при включенном отображении списка файлов в виде дерева.
</DocsNote>
### <Trash2 size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
### <Trash2 size="16" class="inline-block" style="margin-bottom: 2px" />Удалить
Delete the selected file items.
Удалить выбранные файловые единицы.
+18 -18
View File
@@ -1,5 +1,5 @@
---
title: File actions
title: Действия с файлами
---
<script lang="ts">
@@ -9,44 +9,44 @@ title: File actions
# { title }
The file actions menu contains a set of pretty self-explanatory file operations.
Меню действий с файлами включает в себя список вполне понятных операций с файлами.
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> Новый
Create a new empty file.
Создание нового пустого файла.
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Open...
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Открыть...
Open files from your computer.
Открыть файлы с вашего компьютера.
<DocsNote>
You can also drag and drop files directly from your file system into the window.
Также Вы можете перетаскивать файлы прямо из файловой системы в окно.
</DocsNote>
### <Copy size="16" class="inline-block" style="margin-bottom: 2px" /> Duplicate
### <Copy size="16" class="inline-block" style="margin-bottom: 2px" /> Создать копию
Create a copy of the currently selected files.
Создать копию выделенных файлов.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" />Удалить
Delete the currently selected files.
Удаление выбранных файлов.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete all
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" />Удалить всё
Delete all files.
Удаление всех файлов.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Export...
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Выгрузить...
Open the export dialog to save the currently selected files to your computer.
Открывает диалог для сохранения выделенных файлов на ваш компьютер.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Export all...
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Выгрузить все файлы...
Open the export dialog to save all files to your computer.
Открывает окно выгрузки в котором можно сохранить все файлы на ваш компьютер.
<DocsNote type="warning">
If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
Если загрузка не начинается после нажатия на кнопку загрузки, пожалуйста, проверьте настройки обозревателя и предоставьте необходимые разрешения на загрузку файлов с <b>gpx.studio</b>.
</DocsNote>
+1 -1
View File
@@ -71,7 +71,7 @@ title: Планирование и редактирование маршрута
Изменить направление маршрута на противоположное.
### <House size="16" class="inline-block" style="margin-bottom: 2px" /> Back to start
### <House size="16" class="inline-block" style="margin-bottom: 2px" /> Вернуться в начало
Подсоедините последнюю точку маршрута к начальной точке, используя выбранные параметры маршрутизации.
@@ -23,7 +23,7 @@ title: 檔案和統計
Once you have [opened](./menu/file) files, they will be shown as tabs in the file list located at the bottom of the map.
You can reorder them by dragging and dropping the tabs.
And when many files are open, you can scroll through the list of tabs to navigate between them.
當開啟的檔案較多時,也可以捲動分頁清單,在不同檔案之間切換。
<DocsNote>
+1 -1
View File
@@ -11,7 +11,7 @@ title: 設定
### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" /> 距離單位
Change the units used to display distances in the interface.
變更介面中顯示距離時所使用的單位。
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Velocity units
+21 -21
View File
@@ -1,5 +1,5 @@
---
title: View options
title: 檢視選項
---
<script lang="ts">
@@ -9,38 +9,38 @@ title: View options
# { title }
This menu provides options to rearrange the interface and the map view.
此選單提供重新排列介面與地圖檢視方式的選項。
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> Elevation profile
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> 高度剖面圖
Hide the elevation profile to make room for the map, or show it to inspect the current selection.
隱藏高度剖面圖以騰出更多地圖空間,或顯示高度剖面圖以查看目前的選取內容。
### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" /> File tree
### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" /> 檔案樹狀結構
Toggle the tree layout for the [file list](../files-and-stats).
切換[檔案清單](../files-and-stats)的樹狀版面配置。
This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map.
In addition, the file tree view enables you to inspect the [tracks, segments, and points of interest](../gpx) contained inside the files through collapsible sections.
此外,檔案樹狀檢視可讓你透過可收合的區段,查看檔案中包含的[軌跡、區段和興趣點](../gpx)。
### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> Switch to previous basemap
### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> 切換至上一個底圖
Change the basemap to the one previously selected through the [map layer control](../map-controls).
將底圖變更為先前透過[地圖圖層控制項](../map-controls)選取的底圖。
### <Layers2 size="16" class="inline-block" style="margin-bottom: 2px" /> Toggle overlays
### <Layers2 size="16" class="inline-block" style="margin-bottom: 2px" /> 切換疊加圖層
Toggle the visibility of the map overlays selected through the [map layer control](../map-controls).
切換透過[地圖圖層控制項](../map-controls)選取之地圖疊加圖層的顯示狀態。
### <Coins size="16" class="inline-block" style="margin-bottom: 2px" /> Distance markers
### <Coins size="16" class="inline-block" style="margin-bottom: 2px" /> 距離標記
Toggle the visibility of distance markers on the map.
They are displayed for the current selection, like the [elevation profile](../files-and-stats).
切換地圖上距離標記的顯示狀態。
距離標記會針對目前的選取內容顯示,就像[高度剖面圖](../files-and-stats)一樣。
### <Milestone size="16" class="inline-block" style="margin-bottom: 2px" /> Direction arrows
### <Milestone size="16" class="inline-block" style="margin-bottom: 2px" /> 方向箭頭
Toggle the visibility of direction arrows on the map.
切換地圖上方向箭頭的顯示狀態。
### <Box size="16" class="inline-block" style="margin-bottom: 2px" /> Toggle 3D
### <Box size="16" class="inline-block" style="margin-bottom: 2px" /> 切換 3D
Enter or exit the 3D map view.
進入或離開 3D 地圖檢視。
<DocsNote>
@@ -48,7 +48,7 @@ To control the orientation and tilt of the map, you can also drag the map while
</DocsNote>
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> Full screen
### <Maximize2 size="16" class="inline-block" style="margin-bottom: 2px" /> 全螢幕
Enter or exit full screen mode.
You can also press <kbd>F11</kbd> to toggle, or <kbd>Escape</kbd> to exit.
進入或離開全螢幕模式。
你也可以按下 <kbd>F11</kbd> 來切換,或按下 <kbd>Escape</kbd> 離開。
+4 -4
View File
@@ -1,6 +1,6 @@
import { get } from 'svelte/store';
import { selection } from '$lib/logic/selection';
import { LngLatBounds } from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
import { ListFileItem, ListWaypointItem } from '$lib/components/file-list/file-list';
import { fileStateCollection, GPXFileStateCollectionObserver } from '$lib/logic/file-state';
import { gpxStatistics } from '$lib/logic/statistics';
@@ -10,7 +10,7 @@ import type { Coordinates } from 'gpx';
import { page } from '$app/state';
export class BoundsManager {
private _bounds: LngLatBounds = new LngLatBounds();
private _bounds: maplibregl.LngLatBounds = new maplibregl.LngLatBounds();
private _files: Set<string> = new Set();
private _fileStateCollectionObserver: GPXFileStateCollectionObserver | null = null;
private _unsubscribes: (() => void)[] = [];
@@ -87,12 +87,12 @@ export class BoundsManager {
}
this._unsubscribes.forEach((unsubscribe) => unsubscribe());
this._unsubscribes = [];
this._bounds = new LngLatBounds([180, 90, -180, -90]);
this._bounds = new maplibregl.LngLatBounds([180, 90, -180, -90]);
}
centerMapOnSelection() {
let selected = get(selection).getSelected();
let bounds = new LngLatBounds();
let bounds = new maplibregl.LngLatBounds();
if (selected.find((item) => item instanceof ListWaypointItem)) {
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
+6 -6
View File
@@ -1,16 +1,16 @@
import { ListItem, ListLevel } from '$lib/components/file-list/file-list';
import { GPXFile, GPXStatistics, GPXStatisticsGroup, type Track } from 'gpx';
import { LngLatBounds } from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
export class GPXStatisticsTree {
level: ListLevel;
statistics: {
[key: string]: GPXStatisticsTree | GPXStatistics;
} = {};
wptBounds: LngLatBounds;
wptBounds: maplibregl.LngLatBounds;
constructor(element: GPXFile | Track) {
this.wptBounds = new LngLatBounds();
this.wptBounds = new maplibregl.LngLatBounds();
if (element instanceof GPXFile) {
this.level = ListLevel.FILE;
element.children.forEach((child, index) => {
@@ -49,11 +49,11 @@ export class GPXStatisticsTree {
return statistics;
}
intersectsBBox(bounds: LngLatBounds): boolean {
intersectsBBox(bounds: maplibregl.LngLatBounds): boolean {
for (let key in this.statistics) {
const stats = this.statistics[key];
if (stats instanceof GPXStatistics) {
const bbox = new LngLatBounds(
const bbox = new maplibregl.LngLatBounds(
stats.global.bounds.southWest,
stats.global.bounds.northEast
);
@@ -67,7 +67,7 @@ export class GPXStatisticsTree {
return false;
}
intersectsWaypointBBox(bounds: LngLatBounds): boolean {
intersectsWaypointBBox(bounds: maplibregl.LngLatBounds): boolean {
return !this.wptBounds.isEmpty() && this.wptBounds.intersects(bounds);
}
}
+4 -4
View File
@@ -3,7 +3,7 @@ import { twMerge } from 'tailwind-merge';
import { base } from '$app/paths';
import { languages } from '$lib/languages';
import { TrackPoint, Waypoint, type Coordinates, crossarcDistance, distance, GPXFile } from 'gpx';
import { Map as MapLibreMap, LngLatBounds } from 'maplibre-gl';
import maplibregl from 'maplibre-gl';
import { pointToTile, pointToTileFraction } from '@mapbox/tilebelt';
import type { GPXStatisticsTree } from '$lib/logic/statistics-tree';
import { ListTrackSegmentItem } from '$lib/components/file-list/file-list';
@@ -58,7 +58,7 @@ export function getClosestTrackSegments(
let segmentBounds = segmentStatistics.global.bounds;
let northEast = segmentBounds.northEast;
let southWest = segmentBounds.southWest;
let bounds = new LngLatBounds(southWest, northEast);
let bounds = new maplibregl.LngLatBounds(southWest, northEast);
if (bounds.contains(point)) {
segmentBoundsDistances.push([0, trackIndex, segmentIndex]);
} else {
@@ -106,7 +106,7 @@ export function getElevation(
let coordinates = points.map((point) =>
point instanceof TrackPoint || point instanceof Waypoint ? point.getCoordinates() : point
);
let bbox = new LngLatBounds();
let bbox = new maplibregl.LngLatBounds();
coordinates.forEach((coord) => bbox.extend(coord));
let tiles = coordinates.map((coord) => pointToTile(coord.lon, coord.lat, ELEVATION_ZOOM));
@@ -193,7 +193,7 @@ export function getElevation(
);
}
export function loadSVGIcon(map: MapLibreMap, id: string, svg: string, size: number = 100) {
export function loadSVGIcon(map: maplibregl.Map, id: string, svg: string, size: number = 100) {
if (!map.hasImage(id)) {
let icon = new Image(size, size);
icon.onload = () => {
+2 -2
View File
@@ -163,7 +163,7 @@
"path": "Sendero",
"pedestrian": "Peatonal",
"cycleway": "Ciclovía",
"steps": "Escalones",
"steps": "Pasos",
"road": "Carretera",
"bridleway": "Ruta ecuestre",
"platform": "Plataforma",
@@ -230,7 +230,7 @@
"extract": {
"tooltip": "Extraer contenidos en elementos separados",
"button": "Extraer",
"help": "Al extraer los contenidos de los elementos seleccionados creará un elemento separado para cada uno.",
"help": "La extracción del contenido de los elementos seleccionados creará un elemento separado para cada uno de sus contenidos.",
"help_invalid_selection": "Su selección debe contener elementos con múltiples trazas para extraerlos."
},
"elevation": {
+1 -1
View File
@@ -20,7 +20,7 @@
"export": "Exporteren...",
"export_all": "Alles exporteren...",
"export_options": "Exporteer instellingen",
"support_message": "Het gereedschap is gratis te gebruiken, maar is niet gratis om te onderhouden. Overweeg om de website te ondersteunen als je hem vaak gebruikt. Bedankt!",
"support_message": "De tool is gratis te gebruiken, maar is niet gratis om te onderhouden. Overweeg om de website te ondersteunen als je hem vaak gebruikt. Bedankt!",
"support_button": "Help de website gratis te houden",
"download_file": "Bestand downloaden",
"download_files": "Bestanden downloaden",
+9 -9
View File
@@ -64,7 +64,7 @@
"ctrl": "Ctrl",
"click": "Clique",
"drag": "Arrastar",
"right_click_drag": "Right-click drag",
"right_click_drag": "Clique direito arraste",
"metadata": {
"button": "Informações...",
"name": "Nome",
@@ -181,7 +181,7 @@
},
"sac_scale": {
"hiking": "Caminhada",
"mountain_hiking": "Mountain hiking",
"mountain_hiking": "",
"demanding_mountain_hiking": "Demanding mountain hiking",
"alpine_hiking": "Alpine hiking",
"demanding_alpine_hiking": "Demanding alpine hiking",
@@ -222,8 +222,8 @@
"remove_gaps": "Remove time gaps between traces",
"tooltip": "Merge items together",
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
"help_merge_contents": "Merging the contents of the selected items will group all the contents inside the first item.",
"help_cannot_merge_traces": "A sua seleção deve conter vários traços para conectá-los.",
"help_merge_contents": "Fundir o conteúdo dos itens selecionados agrupará todo o conteúdo no“item”.",
"help_cannot_merge_contents": "Your selection must contain several items to merge their contents.",
"selection_tip": "Tip: use {KEYBOARD_SHORTCUT} to add items to the selection."
},
@@ -239,14 +239,14 @@
"help_no_selection": "Select a file item to request elevation data."
},
"waypoint": {
"tooltip": "Create and edit points of interest",
"tooltip": "Criar ponto de interesse",
"icon": "Icon",
"link": "Link",
"link": "Ligação",
"longitude": "Longitude",
"latitude": "Latitude",
"create": "Criar ponto de interesse",
"add": "Adicionar ponto de interesse no ficheiro",
"help": "Fill in the form to create a new point of interest, or click on an existing one to edit it. Click on the map to fill the coordinates, or drag points of interest to move them.",
"help": "Preencha o formulário para criar um ponto de interesse, ou clique em um já existente para editá-lo. Clique no mapa para preencher as coordenadas ou arraste pontos de interesse para movê-las.",
"help_no_selection": "Select a file to create or edit points of interest."
},
"reduce": {
@@ -258,7 +258,7 @@
"help_no_selection": "Select a trace to reduce the number of its GPS points."
},
"clean": {
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
"tooltip": "Limpar pontos de GPS e pontos de interesse com uma seleção de retângulo",
"delete_trackpoints": "Excluir pontos GPS",
"delete_waypoints": "Excluir pontos de interesse",
"delete_inside": "Excluir na seleção",
@@ -552,7 +552,7 @@
"pitch": "Pitch",
"bearing": "Bearing",
"preview": "Prévia",
"code": "Integration code"
"code": "Código de integração"
},
"webgl2_required": "WebGL 2 é requerido para exibir o mapa.",
"enable_webgl2": "Aprender como ativar WebGL 2 no seu navegador",