9 Commits

Author SHA1 Message Date
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
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
75 changed files with 515 additions and 458 deletions

View File

@@ -27,8 +27,8 @@ Any help is greatly appreciated!
The code is split into two parts: The code is split into two parts:
- `gpx`: a Typescript library for parsing and manipulating GPX files, - `gpx`: a Typescript library for parsing and manipulating GPX files,
- `website`: the website itself, which is a [SvelteKit](https://kit.svelte.dev/) application. - `website`: the website itself, which is a [SvelteKit](https://kit.svelte.dev/) application.
You will need [Node.js](https://nodejs.org/) to build and run these two parts. You will need [Node.js](https://nodejs.org/) to build and run these two parts.
@@ -55,25 +55,25 @@ npm run dev
This project has been made possible thanks to the following open source projects: This project has been made possible thanks to the following open source projects:
- Development: - Development:
- [Svelte](https://github.com/sveltejs/svelte) and [SvelteKit](https://github.com/sveltejs/kit) — seamless development experience - [Svelte](https://github.com/sveltejs/svelte) and [SvelteKit](https://github.com/sveltejs/kit) — seamless development experience
- [MDsveX](https://github.com/pngwn/MDsveX) — allowing a Markdown-based documentation - [MDsveX](https://github.com/pngwn/MDsveX) — allowing a Markdown-based documentation
- Design: - Design:
- [shadcn-svelte](https://github.com/huntabyte/shadcn-svelte) — beautiful components - [shadcn-svelte](https://github.com/huntabyte/shadcn-svelte) — beautiful components
- [@lucide/svelte](https://github.com/lucide-icons/lucide/tree/main/packages/svelte) — beautiful icons - [@lucide/svelte](https://github.com/lucide-icons/lucide/tree/main/packages/svelte) — beautiful icons
- [tailwindcss](https://github.com/tailwindlabs/tailwindcss) — easy styling - [tailwindcss](https://github.com/tailwindlabs/tailwindcss) — easy styling
- [Chart.js](https://github.com/chartjs/Chart.js) — beautiful and fast charts - [Chart.js](https://github.com/chartjs/Chart.js) — beautiful and fast charts
- Logic: - Logic:
- [immer](https://github.com/immerjs/immer) — complex state management - [immer](https://github.com/immerjs/immer) — complex state management
- [Dexie.js](https://github.com/dexie/Dexie.js) — IndexedDB wrapper - [Dexie.js](https://github.com/dexie/Dexie.js) — IndexedDB wrapper
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) — fast GPX file parsing - [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 - [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree
- Mapping: - Mapping:
- [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) — beautiful and fast interactive maps - [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) — beautiful and fast interactive maps
- [brouter](https://github.com/abrensch/brouter) — routing engine - [GraphHopper](https://github.com/graphhopper/graphhopper) — routing engine
- [OpenStreetMap](https://www.openstreetmap.org) — map data used by Mapbox and brouter - [OpenStreetMap](https://www.openstreetmap.org) — map data used by Mapbox and GraphHopper
- Search: - Search:
- [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation - [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation
## License ## License

View File

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

View File

@@ -17,6 +17,7 @@
} }
}, },
"sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite", "sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite",
"glyphs": "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key={key}",
"layers": [ "layers": [
{ {
"id": "background", "id": "background",

View File

@@ -34,10 +34,11 @@
import { editStyle } from '$lib/components/file-list/style/utils.svelte'; import { editStyle } from '$lib/components/file-list/style/utils.svelte';
import { getSymbolKey, symbols } from '$lib/assets/symbols'; import { getSymbolKey, symbols } from '$lib/assets/symbols';
import { selection, copied, cut } from '$lib/logic/selection'; import { selection, copied, cut } from '$lib/logic/selection';
import { map } from '$lib/components/map/map';
import { fileActions, pasteSelection } from '$lib/logic/file-actions'; import { fileActions, pasteSelection } from '$lib/logic/file-actions';
import { allHidden } from '$lib/logic/hidden'; import { allHidden } from '$lib/logic/hidden';
import { boundsManager } from '$lib/logic/bounds'; import { boundsManager } from '$lib/logic/bounds';
import { gpxColors, gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers'; import { gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers';
import { fileStateCollection } from '$lib/logic/file-state'; import { fileStateCollection } from '$lib/logic/file-state';
import { waypointPopup } from '$lib/components/map/gpx-layer/gpx-layer-popup'; import { waypointPopup } from '$lib/components/map/gpx-layer/gpx-layer-popup';
import { allowedPastes } from './sortable-file-list'; import { allowedPastes } from './sortable-file-list';
@@ -57,11 +58,19 @@
let singleSelection = $derived($selection.size === 1); let singleSelection = $derived($selection.size === 1);
let nodeColors: string[] = $derived.by(() => { let nodeColors: string[] = $state([]);
$effect.pre(() => {
let colors: string[] = []; let colors: string[] = [];
if (node) { if (node && $map) {
if (node instanceof GPXFile) { if (node instanceof GPXFile) {
let defaultColor = $gpxColors.get(item.getFileId()); let defaultColor = undefined;
let layer = gpxLayers.getLayer(item.getFileId());
if (layer) {
defaultColor = layer.layerColor;
}
let style = node.getStyle(defaultColor); let style = node.getStyle(defaultColor);
colors = style.color; colors = style.color;
} else if (node instanceof Track) { } else if (node instanceof Track) {
@@ -74,14 +83,14 @@
colors.push(style['gpx_style:color']); colors.push(style['gpx_style:color']);
} }
if (colors.length === 0) { if (colors.length === 0) {
let defaultColor = $gpxColors.get(item.getFileId()); let layer = gpxLayers.getLayer(item.getFileId());
if (defaultColor) { if (layer) {
colors.push(defaultColor); colors.push(layer.layerColor);
} }
} }
} }
} }
return colors; nodeColors = colors;
}); });
let symbolKey = $derived(node instanceof Waypoint ? getSymbolKey(node.sym) : undefined); let symbolKey = $derived(node instanceof Waypoint ? getSymbolKey(node.sym) : undefined);

View File

@@ -48,7 +48,7 @@
language = 'en'; language = 'en';
} }
map.init(language, hash, geocoder, geolocate); map.init(PUBLIC_MAPBOX_TOKEN, language, hash, geocoder, geolocate);
}); });
onDestroy(() => { onDestroy(() => {

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { onDestroy } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import { gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers'; import { gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers';
import { DistanceMarkers } from '$lib/components/map/gpx-layer/distance-markers'; import { DistanceMarkers } from '$lib/components/map/gpx-layer/distance-markers';
import { StartEndMarkers } from '$lib/components/map/gpx-layer/start-end-markers'; import { StartEndMarkers } from '$lib/components/map/gpx-layer/start-end-markers';
@@ -9,10 +9,13 @@
let distanceMarkers: DistanceMarkers; let distanceMarkers: DistanceMarkers;
let startEndMarkers: StartEndMarkers; let startEndMarkers: StartEndMarkers;
map.onLoad((map_) => { onMount(() => {
gpxLayers.init(); gpxLayers.init();
startEndMarkers = new StartEndMarkers(); startEndMarkers = new StartEndMarkers();
distanceMarkers = new DistanceMarkers(); distanceMarkers = new DistanceMarkers();
});
map.onLoad((map_) => {
createPopups(map_); createPopups(map_);
}); });

View File

@@ -41,7 +41,6 @@
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
class="justify-start"
href={`https://www.openstreetmap.org/edit?#map=${(($map?.getZoom() ?? 17) + 1).toFixed(0)}/${trackpoint.item.getLatitude().toFixed(5)}/${trackpoint.item.getLongitude().toFixed(5)}`} href={`https://www.openstreetmap.org/edit?#map=${(($map?.getZoom() ?? 17) + 1).toFixed(0)}/${trackpoint.item.getLatitude().toFixed(5)}/${trackpoint.item.getLongitude().toFixed(5)}`}
target="_blank" target="_blank"
> >

View File

@@ -3,7 +3,7 @@ import { gpxStatistics } from '$lib/logic/statistics';
import { getConvertedDistanceToKilometers } from '$lib/units'; import { getConvertedDistanceToKilometers } from '$lib/units';
import type { GeoJSONSource } from 'mapbox-gl'; import type { GeoJSONSource } from 'mapbox-gl';
import { get } from 'svelte/store'; import { get } from 'svelte/store';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { allHidden } from '$lib/logic/hidden'; import { allHidden } from '$lib/logic/hidden';
const { distanceMarkers, distanceUnits } = settings; const { distanceMarkers, distanceUnits } = settings;
@@ -44,45 +44,44 @@ export class DistanceMarkers {
}); });
} }
if (!map_.getLayer('distance-markers')) { if (!map_.getLayer('distance-markers')) {
map_.addLayer( map_.addLayer({
{ id: 'distance-markers',
id: 'distance-markers', type: 'symbol',
type: 'symbol', source: 'distance-markers',
source: 'distance-markers', filter: [
filter: [ 'match',
'match', ['get', 'level'],
['get', 'level'], 100,
100, ['>=', ['zoom'], 0],
['>=', ['zoom'], 0], 50,
50, ['>=', ['zoom'], 7],
['>=', ['zoom'], 7], 25,
25, [
[ 'any',
'any', ['all', ['>=', ['zoom'], 8], ['<=', ['zoom'], 9]],
['all', ['>=', ['zoom'], 8], ['<=', ['zoom'], 9]],
['>=', ['zoom'], 11],
],
10,
['>=', ['zoom'], 10],
5,
['>=', ['zoom'], 11], ['>=', ['zoom'], 11],
1,
['>=', ['zoom'], 13],
false,
], ],
layout: { 10,
'text-field': ['get', 'distance'], ['>=', ['zoom'], 10],
'text-size': 14, 5,
'text-font': ['Open Sans Bold'], ['>=', ['zoom'], 11],
}, 1,
paint: { ['>=', ['zoom'], 13],
'text-color': 'black', false,
'text-halo-width': 2, ],
'text-halo-color': 'white', layout: {
}, 'text-field': ['get', 'distance'],
'text-size': 14,
'text-font': ['Open Sans Bold'],
}, },
ANCHOR_LAYER_KEY.distanceMarkers paint: {
); 'text-color': 'black',
'text-halo-width': 2,
'text-halo-color': 'white',
},
});
} else {
map_.moveLayer('distance-markers');
} }
} else { } else {
if (map_.getLayer('distance-markers')) { if (map_.getLayer('distance-markers')) {

View File

@@ -1,6 +1,6 @@
import { get, type Readable } from 'svelte/store'; import { get, type Readable } from 'svelte/store';
import mapboxgl, { type FilterSpecification } from 'mapbox-gl'; import mapboxgl, { type FilterSpecification } from 'mapbox-gl';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { waypointPopup, trackpointPopup } from './gpx-layer-popup'; import { waypointPopup, trackpointPopup } from './gpx-layer-popup';
import { import {
ListTrackSegmentItem, ListTrackSegmentItem,
@@ -22,7 +22,6 @@ import { fileActionManager } from '$lib/logic/file-action-manager';
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors'; import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { gpxColors } from '$lib/components/map/gpx-layer/gpx-layers';
const colors = [ const colors = [
'#ff0000', '#ff0000',
@@ -44,35 +43,16 @@ for (let color of colors) {
} }
// Get the color with the least amount of uses // Get the color with the least amount of uses
function getColor(fileId: string) { function getColor() {
let color = colors.reduce((a, b) => (colorCount[a] <= colorCount[b] ? a : b)); let color = colors.reduce((a, b) => (colorCount[a] <= colorCount[b] ? a : b));
colorCount[color]++; colorCount[color]++;
gpxColors.update((colors) => {
colors.set(fileId, color);
return colors;
});
return color; return color;
} }
function replaceColor(fileId: string, oldColor: string, newColor: string) { function decrementColor(color: string) {
if (colorCount.hasOwnProperty(oldColor)) {
colorCount[oldColor]--;
}
colorCount[newColor]++;
gpxColors.update((colors) => {
colors.set(fileId, newColor);
return colors;
});
}
function removeColor(fileId: string, color: string) {
if (colorCount.hasOwnProperty(color)) { if (colorCount.hasOwnProperty(color)) {
colorCount[color]--; colorCount[color]--;
} }
gpxColors.update((colors) => {
colors.delete(fileId);
return colors;
});
} }
export function getSvgForSymbol(symbol?: string | undefined, layerColor?: string | undefined) { export function getSvgForSymbol(symbol?: string | undefined, layerColor?: string | undefined) {
@@ -141,7 +121,7 @@ export class GPXLayer {
constructor(fileId: string, file: Readable<GPXFileWithStatistics | undefined>) { constructor(fileId: string, file: Readable<GPXFileWithStatistics | undefined>) {
this.fileId = fileId; this.fileId = fileId;
this.file = file; this.file = file;
this.layerColor = getColor(fileId); this.layerColor = getColor();
this.unsubscribe.push( this.unsubscribe.push(
map.subscribe(($map) => { map.subscribe(($map) => {
if ($map) { if ($map) {
@@ -178,7 +158,7 @@ export class GPXLayer {
file._data.style.color && file._data.style.color &&
this.layerColor !== `#${file._data.style.color}` this.layerColor !== `#${file._data.style.color}`
) { ) {
replaceColor(this.fileId, this.layerColor, `#${file._data.style.color}`); decrementColor(this.layerColor);
this.layerColor = `#${file._data.style.color}`; this.layerColor = `#${file._data.style.color}`;
} }
@@ -196,23 +176,20 @@ export class GPXLayer {
} }
if (!_map.getLayer(this.fileId)) { if (!_map.getLayer(this.fileId)) {
_map.addLayer( _map.addLayer({
{ id: this.fileId,
id: this.fileId, type: 'line',
type: 'line', source: this.fileId,
source: this.fileId, layout: {
layout: { 'line-join': 'round',
'line-join': 'round', 'line-cap': 'round',
'line-cap': 'round',
},
paint: {
'line-color': ['get', 'color'],
'line-width': ['get', 'width'],
'line-opacity': ['get', 'opacity'],
},
}, },
ANCHOR_LAYER_KEY.tracks paint: {
); 'line-color': ['get', 'color'],
'line-width': ['get', 'width'],
'line-opacity': ['get', 'opacity'],
},
});
_map.on('click', this.fileId, this.layerOnClickBinded); _map.on('click', this.fileId, this.layerOnClickBinded);
_map.on('contextmenu', this.fileId, this.layerOnContextMenuBinded); _map.on('contextmenu', this.fileId, this.layerOnContextMenuBinded);
@@ -235,21 +212,18 @@ export class GPXLayer {
} }
if (!_map.getLayer(this.fileId + '-waypoints')) { if (!_map.getLayer(this.fileId + '-waypoints')) {
_map.addLayer( _map.addLayer({
{ id: this.fileId + '-waypoints',
id: this.fileId + '-waypoints', type: 'symbol',
type: 'symbol', source: this.fileId + '-waypoints',
source: this.fileId + '-waypoints', layout: {
layout: { 'icon-image': ['get', 'icon'],
'icon-image': ['get', 'icon'], 'icon-size': 0.3,
'icon-size': 0.3, 'icon-anchor': 'bottom',
'icon-anchor': 'bottom', 'icon-padding': 0,
'icon-padding': 0, 'icon-allow-overlap': true,
'icon-allow-overlap': true,
},
}, },
ANCHOR_LAYER_KEY.waypoints });
);
_map.on( _map.on(
'mouseenter', 'mouseenter',
@@ -298,7 +272,7 @@ export class GPXLayer {
'text-halo-color': 'white', 'text-halo-color': 'white',
}, },
}, },
ANCHOR_LAYER_KEY.directionMarkers _map.getLayer('distance-markers') ? 'distance-markers' : undefined
); );
} }
} else { } else {
@@ -390,7 +364,7 @@ export class GPXLayer {
this.unsubscribe.forEach((unsubscribe) => unsubscribe()); this.unsubscribe.forEach((unsubscribe) => unsubscribe());
removeColor(this.fileId, this.layerColor); decrementColor(this.layerColor);
} }
moveToFront() { moveToFront() {
@@ -399,13 +373,13 @@ export class GPXLayer {
return; return;
} }
if (_map.getLayer(this.fileId)) { if (_map.getLayer(this.fileId)) {
_map.moveLayer(this.fileId, ANCHOR_LAYER_KEY.tracks); _map.moveLayer(this.fileId);
} }
if (_map.getLayer(this.fileId + '-waypoints')) { if (_map.getLayer(this.fileId + '-waypoints')) {
_map.moveLayer(this.fileId + '-waypoints', ANCHOR_LAYER_KEY.waypoints); _map.moveLayer(this.fileId + '-waypoints');
} }
if (_map.getLayer(this.fileId + '-direction')) { if (_map.getLayer(this.fileId + '-direction')) {
_map.moveLayer(this.fileId + '-direction', ANCHOR_LAYER_KEY.directionMarkers); _map.moveLayer(this.fileId + '-direction');
} }
} }

View File

@@ -1,5 +1,4 @@
import { GPXFileStateCollectionObserver } from '$lib/logic/file-state'; import { GPXFileStateCollectionObserver } from '$lib/logic/file-state';
import { writable } from 'svelte/store';
import { GPXLayer } from './gpx-layer'; import { GPXLayer } from './gpx-layer';
export class GPXLayerCollection { export class GPXLayerCollection {
@@ -43,4 +42,3 @@ export class GPXLayerCollection {
} }
export const gpxLayers = new GPXLayerCollection(); export const gpxLayers = new GPXLayerCollection();
export const gpxColors = writable(new Map<string, string>());

View File

@@ -54,27 +54,28 @@
<Card.Root class="border-none shadow-md text-base p-2 max-w-[50dvw] gap-0"> <Card.Root class="border-none shadow-md text-base p-2 max-w-[50dvw] gap-0">
<Card.Header class="p-0 gap-0"> <Card.Header class="p-0 gap-0">
<Card.Title class="text-md flex flex-row"> <Card.Title class="text-md">
<div class="flex flex-col"> <div class="flex flex-row gap-3">
<p>{name}</p> <div class="flex flex-col">
<div class="text-muted-foreground text-xs font-normal"> {name}
{poi.item.lat.toFixed(6)}&deg; {poi.item.lon.toFixed(6)}&deg; <div class="text-muted-foreground text-xs font-normal">
{poi.item.lat.toFixed(6)}&deg; {poi.item.lon.toFixed(6)}&deg;
</div>
</div> </div>
<Button
class="ml-auto"
variant="outline"
size="icon"
href="https://www.openstreetmap.org/edit?editor=id&{poi.item.type ??
'node'}={poi.item.id}"
target="_blank"
>
<PencilLine size="16" />
</Button>
</div> </div>
<Button
class="ml-auto"
variant="outline"
size="icon-sm"
href="https://www.openstreetmap.org/edit?editor=id&{poi.item.type ?? 'node'}={poi
.item.id}"
target="_blank"
>
<PencilLine size="16" />
</Button>
</Card.Title> </Card.Title>
</Card.Header> </Card.Header>
<Card.Content class="flex flex-col gap-1 p-0 text-sm whitespace-normal break-all"> <Card.Content class="flex flex-col p-0 text-sm mt-1 whitespace-normal break-all">
<ScrollArea class="flex flex-col max-h-[30dvh]"> <ScrollArea class="flex flex-col max-h-[30dvh]">
{#if tags.image || tags['image:0']} {#if tags.image || tags['image:0']}
<div class="w-full rounded-md overflow-clip my-2 max-w-96 mx-auto"> <div class="w-full rounded-md overflow-clip my-2 max-w-96 mx-auto">
@@ -99,14 +100,8 @@
{/each} {/each}
</div> </div>
</ScrollArea> </ScrollArea>
<Button <Button class="mt-2" variant="outline" disabled={$selection.size === 0} onclick={addToFile}>
size="sm" <MapPin size="16" />
class="mt-1 justify-start"
variant="outline"
disabled={$selection.size === 0}
onclick={addToFile}
>
<MapPin size="14" />
{i18n._('toolbar.waypoint.add')} {i18n._('toolbar.waypoint.add')}
</Button> </Button>
</Card.Content> </Card.Content>

View File

@@ -6,7 +6,6 @@ import { overpassQueryData } from '$lib/assets/layers';
import { MapPopup } from '$lib/components/map/map-popup'; import { MapPopup } from '$lib/components/map/map-popup';
import { settings } from '$lib/logic/settings'; import { settings } from '$lib/logic/settings';
import { db } from '$lib/db'; import { db } from '$lib/db';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
const { currentOverpassQueries } = settings; const { currentOverpassQueries } = settings;
@@ -86,20 +85,17 @@ export class OverpassLayer {
} }
if (!this.map.getLayer('overpass')) { if (!this.map.getLayer('overpass')) {
this.map.addLayer( this.map.addLayer({
{ id: 'overpass',
id: 'overpass', type: 'symbol',
type: 'symbol', source: 'overpass',
source: 'overpass', layout: {
layout: { 'icon-image': ['get', 'icon'],
'icon-image': ['get', 'icon'], 'icon-size': 0.25,
'icon-size': 0.25, 'icon-padding': 0,
'icon-padding': 0, 'icon-allow-overlap': ['step', ['zoom'], false, 14, true],
'icon-allow-overlap': ['step', ['zoom'], false, 14, true],
},
}, },
ANCHOR_LAYER_KEY.overpass });
);
this.map.on('mouseenter', 'overpass', this.onHoverBinded); this.map.on('mouseenter', 'overpass', this.onHoverBinded);
this.map.on('click', 'overpass', this.onHoverBinded); this.map.on('click', 'overpass', this.onHoverBinded);

View File

@@ -20,28 +20,6 @@ let fitBoundsOptions: mapboxgl.MapOptions['fitBoundsOptions'] = {
easing: () => 1, easing: () => 1,
}; };
const emptySource: mapboxgl.GeoJSONSourceSpecification = {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [],
},
};
export const ANCHOR_LAYER_KEY = {
mapillary: 'mapillary-end',
tracks: 'tracks-end',
directionMarkers: 'direction-markers-end',
distanceMarkers: 'distance-markers-end',
interactions: 'interactions-end',
overpass: 'overpass-end',
waypoints: 'waypoints-end',
};
const anchorLayers: mapboxgl.LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
id: id,
type: 'symbol',
source: 'empty-source',
}));
export class MapboxGLMap { export class MapboxGLMap {
private _map: Writable<mapboxgl.Map | null> = writable(null); private _map: Writable<mapboxgl.Map | null> = writable(null);
private _onLoadCallbacks: ((map: mapboxgl.Map) => void)[] = []; private _onLoadCallbacks: ((map: mapboxgl.Map) => void)[] = [];
@@ -51,15 +29,19 @@ export class MapboxGLMap {
return this._map.subscribe(run, invalidate); return this._map.subscribe(run, invalidate);
} }
init(language: string, hash: boolean, geocoder: boolean, geolocate: boolean) { init(
accessToken: string,
language: string,
hash: boolean,
geocoder: boolean,
geolocate: boolean
) {
const map = new mapboxgl.Map({ const map = new mapboxgl.Map({
container: 'map', container: 'map',
style: { style: {
version: 8, version: 8,
sources: { sources: {},
'empty-source': emptySource, layers: [],
},
layers: anchorLayers,
imports: [ imports: [
{ {
id: 'basemap', id: 'basemap',
@@ -68,6 +50,11 @@ export class MapboxGLMap {
{ {
id: 'overlays', id: 'overlays',
url: '', url: '',
data: {
version: 8,
sources: {},
layers: [],
},
}, },
], ],
}, },
@@ -225,21 +212,16 @@ export class MapboxGLMap {
const map = get(this._map); const map = get(this._map);
if (map) { if (map) {
const source = get(terrainSource); const source = get(terrainSource);
try { if (!map.getSource(source)) {
if (!map.getSource(source)) { map.addSource(source, terrainSources[source]);
map.addSource(source, terrainSources[source]); }
} if (map.getPitch() > 0) {
if (map.getPitch() > 0) { map.setTerrain({
map.setTerrain({ source: source,
source: source, exaggeration: 1,
exaggeration: 1, });
}); } else {
} else { map.setTerrain(null);
map.setTerrain(null);
}
} catch (e) {
// No reliable way to check if the map is ready to add sources and layers
return;
} }
} }
} }

View File

@@ -2,7 +2,6 @@ import mapboxgl, { type LayerSpecification, type VectorSourceSpecification } fro
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module'; import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
import 'mapillary-js/dist/mapillary.css'; import 'mapillary-js/dist/mapillary.css';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
const mapillarySource: VectorSourceSpecification = { const mapillarySource: VectorSourceSpecification = {
type: 'vector', type: 'vector',
@@ -100,10 +99,10 @@ export class MapillaryLayer {
this.map.addSource('mapillary', mapillarySource); this.map.addSource('mapillary', mapillarySource);
} }
if (!this.map.getLayer('mapillary-sequence')) { if (!this.map.getLayer('mapillary-sequence')) {
this.map.addLayer(mapillarySequenceLayer, ANCHOR_LAYER_KEY.mapillary); this.map.addLayer(mapillarySequenceLayer);
} }
if (!this.map.getLayer('mapillary-image')) { if (!this.map.getLayer('mapillary-image')) {
this.map.addLayer(mapillaryImageLayer, ANCHOR_LAYER_KEY.mapillary); this.map.addLayer(mapillaryImageLayer);
} }
this.map.on('style.load', this.addBinded); this.map.on('style.load', this.addBinded);
this.map.on('mouseenter', 'mapillary-image', this.onMouseEnterBinded); this.map.on('mouseenter', 'mapillary-image', this.onMouseEnterBinded);

View File

@@ -15,7 +15,7 @@
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import { getURLForLanguage } from '$lib/utils'; import { getURLForLanguage } from '$lib/utils';
import { Trash2 } from '@lucide/svelte'; import { Trash2 } from '@lucide/svelte';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import type { GeoJSONSource } from 'mapbox-gl'; import type { GeoJSONSource } from 'mapbox-gl';
import { selection } from '$lib/logic/selection'; import { selection } from '$lib/logic/selection';
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
@@ -63,18 +63,15 @@
}); });
} }
if (!$map.getLayer('rectangle')) { if (!$map.getLayer('rectangle')) {
$map.addLayer( $map.addLayer({
{ id: 'rectangle',
id: 'rectangle', type: 'fill',
type: 'fill', source: 'rectangle',
source: 'rectangle', paint: {
paint: { 'fill-color': 'SteelBlue',
'fill-color': 'SteelBlue', 'fill-opacity': 0.5,
'fill-opacity': 0.5,
},
}, },
ANCHOR_LAYER_KEY.interactions });
);
} }
} }
} }

View File

@@ -2,6 +2,7 @@
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import Help from '$lib/components/Help.svelte'; import Help from '$lib/components/Help.svelte';
import { MountainSnow } from '@lucide/svelte'; import { MountainSnow } from '@lucide/svelte';
import { map } from '$lib/components/map/map';
import { i18n } from '$lib/i18n.svelte'; import { i18n } from '$lib/i18n.svelte';
import { getURLForLanguage } from '$lib/utils'; import { getURLForLanguage } from '$lib/utils';
import { selection } from '$lib/logic/selection'; import { selection } from '$lib/logic/selection';
@@ -19,7 +20,11 @@
variant="outline" variant="outline"
class="whitespace-normal h-fit" class="whitespace-normal h-fit"
disabled={!validSelection} disabled={!validSelection}
onclick={() => fileActions.addElevationToSelection()} onclick={() => {
if ($map) {
fileActions.addElevationToSelection($map);
}
}}
> >
<MountainSnow size="16" class="shrink-0" /> <MountainSnow size="16" class="shrink-0" />
{i18n._('toolbar.elevation.button')} {i18n._('toolbar.elevation.button')}

View File

@@ -1,5 +1,5 @@
import { ListItem, ListTrackSegmentItem } from '$lib/components/file-list/file-list'; import { ListItem, ListTrackSegmentItem } from '$lib/components/file-list/file-list';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
import { GPXFileStateCollectionObserver, type GPXFileState } from '$lib/logic/file-state'; import { GPXFileStateCollectionObserver, type GPXFileState } from '$lib/logic/file-state';
import { selection } from '$lib/logic/selection'; import { selection } from '$lib/logic/selection';
@@ -144,18 +144,17 @@ export class ReducedGPXLayerCollection {
}); });
} }
if (!map_.getLayer('simplified')) { if (!map_.getLayer('simplified')) {
map_.addLayer( map_.addLayer({
{ id: 'simplified',
id: 'simplified', type: 'line',
type: 'line', source: 'simplified',
source: 'simplified', paint: {
paint: { 'line-color': 'white',
'line-color': 'white', 'line-width': 3,
'line-width': 3,
},
}, },
ANCHOR_LAYER_KEY.interactions });
); } else {
map_.moveLayer('simplified');
} }
} }

View File

@@ -21,7 +21,7 @@
SquareArrowUpLeft, SquareArrowUpLeft,
SquareArrowOutDownRight, SquareArrowOutDownRight,
} from '@lucide/svelte'; } from '@lucide/svelte';
import { brouterProfiles } from '$lib/components/toolbar/tools/routing/routing'; import { routingProfiles } from '$lib/components/toolbar/tools/routing/routing';
import { i18n } from '$lib/i18n.svelte'; import { i18n } from '$lib/i18n.svelte';
import { slide } from 'svelte/transition'; import { slide } from 'svelte/transition';
import { import {
@@ -167,7 +167,7 @@
{i18n._(`toolbar.routing.activities.${$routingProfile}`)} {i18n._(`toolbar.routing.activities.${$routingProfile}`)}
</Select.Trigger> </Select.Trigger>
<Select.Content> <Select.Content>
{#each Object.keys(brouterProfiles) as profile} {#each Object.keys(routingProfiles) as profile}
<Select.Item value={profile} <Select.Item value={profile}
>{i18n._( >{i18n._(
`toolbar.routing.activities.${profile}` `toolbar.routing.activities.${profile}`

View File

@@ -731,17 +731,7 @@ export class RoutingControls {
try { try {
response = await route(targetCoordinates); response = await route(targetCoordinates);
} catch (e: any) { } catch (e: any) {
if (e.message.includes('from-position not mapped in existing datafile')) { toast.error(i18n._(e.message, e.message));
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);
}
return false; return false;
} }

View File

@@ -6,37 +6,213 @@ import { get } from 'svelte/store';
const { routing, routingProfile, privateRoads } = settings; const { routing, routingProfile, privateRoads } = settings;
export const brouterProfiles: { [key: string]: string } = { export type RoutingProfile = {
bike: 'Trekking-dry', engine: 'graphhopper' | 'brouter';
racing_bike: 'fastbike', profile: string;
gravel_bike: 'gravel', };
mountain_bike: 'MTB',
foot: 'Hiking-Alpine-SAC6', export const routingProfiles: { [key: string]: RoutingProfile } = {
motorcycle: 'Car-FastEco', bike: { engine: 'graphhopper', profile: 'bike' },
water: 'river', racing_bike: { engine: 'graphhopper', profile: 'racingbike' },
railway: 'rail', 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[]> { export function route(points: Coordinates[]): Promise<TrackPoint[]> {
if (get(routing)) { if (get(routing)) {
return getRoute(points, brouterProfiles[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 { } else {
return getIntermediatePoints(points); 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[], points: Coordinates[],
brouterProfile: string, graphHopperProfile: string,
privateRoads: boolean privateRoads: boolean
): Promise<TrackPoint[]> { ): 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); let response = await fetch(url);
// Check if the response is ok
if (!response.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(); let geojson = await response.json();
@@ -52,14 +228,13 @@ async function getRoute(
let tags = messageIdx < messages.length ? getTags(messages[messageIdx][tagIdx]) : {}; let tags = messageIdx < messages.length ? getTags(messages[messageIdx][tagIdx]) : {};
for (let i = 0; i < coordinates.length; i++) { for (let i = 0; i < coordinates.length; i++) {
let coord = coordinates[i];
route.push( route.push(
new TrackPoint({ new TrackPoint({
attributes: { attributes: {
lat: coord[1], lat: coordinates[i][1],
lon: coord[0], 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

@@ -8,7 +8,6 @@ import { get } from 'svelte/store';
import { fileStateCollection } from '$lib/logic/file-state'; import { fileStateCollection } from '$lib/logic/file-state';
import { fileActions } from '$lib/logic/file-actions'; import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
export class SplitControls { export class SplitControls {
map: mapboxgl.Map; map: mapboxgl.Map;
@@ -109,25 +108,24 @@ export class SplitControls {
} }
if (!this.map.getLayer('split-controls')) { if (!this.map.getLayer('split-controls')) {
this.map.addLayer( this.map.addLayer({
{ id: 'split-controls',
id: 'split-controls', type: 'symbol',
type: 'symbol', source: 'split-controls',
source: 'split-controls', layout: {
layout: { 'icon-image': 'split-control',
'icon-image': 'split-control', 'icon-size': 0.25,
'icon-size': 0.25, 'icon-padding': 0,
'icon-padding': 0,
},
filter: ['<=', ['get', 'minZoom'], ['zoom']],
}, },
ANCHOR_LAYER_KEY.interactions filter: ['<=', ['get', 'minZoom'], ['zoom']],
); });
this.map.on('mouseenter', 'split-controls', this.layerOnMouseEnterBinded); this.map.on('mouseenter', 'split-controls', this.layerOnMouseEnterBinded);
this.map.on('mouseleave', 'split-controls', this.layerOnMouseLeaveBinded); this.map.on('mouseleave', 'split-controls', this.layerOnMouseLeaveBinded);
this.map.on('click', 'split-controls', this.layerOnClickBinded); this.map.on('click', 'split-controls', this.layerOnClickBinded);
} }
this.map.moveLayer('split-controls');
} catch (e) { } catch (e) {
// No reliable way to check if the map is ready to add sources and layers // No reliable way to check if the map is ready to add sources and layers
} }

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. Crear una còpia dels arxius seleccionats.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Esborra ### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
Esborra l'arxiu seleccinat. Delete the currently selected files.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Esborra-ho tot ### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete all
Esborra tots els fitxers. Delete all files.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar... ### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar...

View File

@@ -1,5 +1,5 @@
Mapbox stellt einige der auf dieser Website verwendeten Karten bereit. 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>, die **gpx.studio** unterstützt. 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 froh und dankbar, Teil ihres <a href="https://mapbox.com/community" target="_blank">Community</a> Programms zu sein, das gemeinnützige Organisationen, Bildungseinrichtungen und Organisationen 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. 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

@@ -35,7 +35,7 @@ Supprimer les fichiers sélectionnés.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Supprimer tout ### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Supprimer tout
Supprimer tous les fichiers. Supprimer toutes les fichiers.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exporter... ### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exporter...

View File

@@ -8,11 +8,11 @@ title: FAQ
# { title } # { title }
### Czy muszę przekazać darowiznę za korzystanie ze strony internetowej? ### Do I need to donate to use the website?
Nie. Nie.
Strona internetowa jest darmowa i zawsze będzie (o ile będzie się zgadzał rachunek). The website is free to use and always will be (as long as it is financially sustainable).
Darowizny są jednak doceniane i pomagają utrzymać funkcjonowanie strony. However, donations are appreciated and help keep the website running.
### Why is this route chosen over that one? _Or_ how can I add something to the map? ### Why is this route chosen over that one? _Or_ how can I add something to the map?

View File

@@ -8,12 +8,12 @@ title: Wprowadzenie
# { title } # { title }
Witamy w oficjalnym przewodniku dla **gpx.studio**! Welcome to the official guide for **gpx.studio**!
Ten przewodnik przeprowadzi Cię przez wszystkie komponenty i narzędzia interfejsu, co pomoże stać się wydajnym użytkownikiem aplikacji. This guide will walk you through all the components and tools of the interface, helping you become a proficient user of the application.
<DocsImage src="getting-started/interface" alt="The gpx.studio interface." /> <DocsImage src="getting-started/interface" alt="The gpx.studio interface." />
Jak pokazano na zrzucie ekranu powyżej, interfejs jest podzielony na cztery główne sekcje zorganizowane wokół mapy. As shown in the screenshot above, the interface is divided into four main sections organized around the map.
Before we dive into the details of each section, let's have a quick overview of the interface. Before we dive into the details of each section, let's have a quick overview of the interface.
## Menu główne ## Menu główne
@@ -31,7 +31,7 @@ In the [dedicated section](./files-and-stats), we will explain how to select mul
On the left side of the interface, you will find the [toolbar](./toolbar), which contains all the tools you can use to edit your files. On the left side of the interface, you will find the [toolbar](./toolbar), which contains all the tools you can use to edit your files.
## Sterowanie mapą ## Map controls
Na koniec, po prawej stronie interfejsu znajdziesz [sterowanie mapą] (./map-controls). Finally, on the right side of the interface, you will find the [map controls](./map-controls).
Za pomocą tych elementów sterujących można poruszać się po mapie, powiększać i pomniejszać widok oraz przełączać się między różnymi stylami mapy. These controls allow you to navigate the map, zoom in and out, and switch between different map styles.

View File

@@ -2,7 +2,7 @@
import { HeartHandshake } from '@lucide/svelte'; import { HeartHandshake } from '@lucide/svelte';
</script> </script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> Pomóż nam utrzymać tę stronę jako bezpłatną (i wolną od reklam) ## <HeartHandshake size="18" class="inline-block align-baseline" /> Help keep the website free (and ad-free)
Za każdym razem, gdy dodasz lub przenosisz punkty GPS, nasze serwery obliczają najlepszą trasę w sieci drogowej. Za każdym razem, gdy dodasz lub przenosisz punkty GPS, nasze serwery obliczają najlepszą trasę w sieci drogowej.
Używamy również API z <a href="https://mapbox.com" target="_blank">Mapbox</a> do wyświetlania pięknych map, pobierania danych wysokości i wyszukiwania miejsc. Używamy również API z <a href="https://mapbox.com" target="_blank">Mapbox</a> do wyświetlania pięknych map, pobierania danych wysokości i wyszukiwania miejsc.

View File

@@ -2,11 +2,11 @@
import { Languages } from '@lucide/svelte'; import { Languages } from '@lucide/svelte';
</script> </script>
## <Languages size="18" class="inline-block align-baseline" /> Tłumaczenie ## <Languages size="18" class="inline-block align-baseline" /> Translation
Strona internetowa jest tłumaczona przez wolontariuszy na platformie do współpracy w tłumaczeniu. Strona internetowa jest tłumaczona przez wolontariuszy na platformie do współpracy w tłumaczeniu.
Możesz przyczynić się do rozwoju naszego projektu, dodając lub ulepszając tłumaczenia w ramach <a href="https://crowdin.com/project/gpxstudio" target="_blank">projektu Crowdin</a>. Możesz pomóc dodając i sprawdzając istniejące tłumaczenie w <a href="https://crowdin.com/project/gpxstudio" target="_blank">projekcie Crowdin</a>.
Jeśli chciałbyś dodać język, którego nie ma na liście <a href="#contact">skontaktuj się z nami</a>. Jeśli chciałbyś dodać język, którego nie ma na liście <a href="#contact">skontaktuj się</a>.
Każda pomoc jest bardzo mile widziana! Każda pomoc jest bardzo mile widziana!

View File

@@ -1,5 +1,5 @@
--- ---
title: Sterowanie mapą title: Map controls
--- ---
<script> <script>
@@ -10,10 +10,10 @@ title: Sterowanie mapą
# { title } # { title }
Elementy sterujące mapą znajdują się po prawej stronie interfejsu. The map controls are located on the right side of the interface.
Za pomocą tych elementów sterujących można poruszać się po mapie, powiększać i pomniejszać widok oraz przełączać się między różnymi stylami mapy. These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Nawigacja mapą ### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
The controls at the top allow you to zoom in <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> and out <Minus size="16" class="inline-block" style="margin-bottom: 2px" />, and to change the orientation and tilt of the map <Compass size="16" class="inline-block" style="margin-bottom: 2px" />. The controls at the top allow you to zoom in <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> and out <Minus size="16" class="inline-block" style="margin-bottom: 2px" />, and to change the orientation and tilt of the map <Compass size="16" class="inline-block" style="margin-bottom: 2px" />.
@@ -39,7 +39,7 @@ This only works if you have allowed your browser and <b>gpx.studio</b> to access
### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Street view ### <PersonStanding size="16" class="inline-block" style="margin-bottom: 2px" /> Street view
Ten przycisk może być użyty do włączenia trybu street view na mapie. This button can be used to enable street view mode on the map.
Depending on the street view source chosen in the [settings](./menu/settings), street view imagery can be accessed differently. Depending on the street view source chosen in the [settings](./menu/settings), street view imagery can be accessed differently.
- <a href="https://www.mapillary.com/" target="_blank">Mapillary</a>: the street view coverage will appear as green lines on the map. When zoomed in enough, green dots will show the exact locations where street view imagery is available. Hovering over a green dot will show the street view image at that location. - <a href="https://www.mapillary.com/" target="_blank">Mapillary</a>: the street view coverage will appear as green lines on the map. When zoomed in enough, green dots will show the exact locations where street view imagery is available. Hovering over a green dot will show the street view image at that location.

View File

@@ -9,44 +9,44 @@ title: Akcje menu Plik
# { title } # { title }
Menu operacji na plikach zawiera zestaw funkcji, których przeznaczenie jest dość oczywiste. The file actions menu contains a set of pretty self-explanatory file operations.
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> Nowy ### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New
Tworzy nowy pusty plik. Tworzy nowy pusty plik.
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Otwórz... ### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Open...
Otwórz pliki z komputera. Open files from your computer.
<DocsNote> <DocsNote>
Można również przeciągać i upuszczać pliki bezpośrednio z systemu plików do okna. You can also drag and drop files directly from your file system into the window.
</DocsNote> </DocsNote>
### <Copy size="16" class="inline-block" style="margin-bottom: 2px" /> Duplikuj ### <Copy size="16" class="inline-block" style="margin-bottom: 2px" /> Duplicate
Utwórz kopię aktualnie zaznaczonych plików. Create a copy of the currently selected files.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Usuń ### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
Usuń aktualnie zaznaczone pliki. Delete the currently selected files.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Usuń wszystko ### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete all
Usuń wszystkie pliki. Delete all files.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Eksport... ### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Export...
Otwórz okno dialogowe eksportu, aby zapisać aktualnie wybrane pliki na komputerze. Open the export dialog to save the currently selected files to your computer.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Eksportuj wszystko... ### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Export all...
Otwórz okno dialogowe eksportu, aby zapisać wszystkie pliki na komputerze. Open the export dialog to save all files to your computer.
<DocsNote type="warning"> <DocsNote type="warning">
Jeśli po kliknięciu przycisku pobierania plik nie zacznie się pobierać, sprawdź ustawienia przeglądarki i upewnij się, że zezwalają one na pobieranie plików z witryny <b>gpx.studio</b>. If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
</DocsNote> </DocsNote>

View File

@@ -11,11 +11,11 @@ title: Settings
### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" /> Distance units ### <Ruler size="16" class="inline-block" style="margin-bottom: 2px" /> Distance units
Zmień jednostki stosowane do wyświetlania odległości w interfejsie. Change the units used to display distances in the interface.
### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Velocity units ### <Zap size="16" class="inline-block" style="margin-bottom: 2px" /> Velocity units
Zmień jednostki używane do wyświetlania prędkości w interfejsie. Change the units used to display velocities in the interface.
You can choose between distance per hour or minutes per distance, which can be more suitable for running activities. You can choose between distance per hour or minutes per distance, which can be more suitable for running activities.
### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> Temperature units ### <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> Temperature units
@@ -28,8 +28,8 @@ Change the language used in the interface.
<DocsNote> <DocsNote>
Możesz przyczynić się do rozwoju naszego projektu, dodając lub ulepszając tłumaczenia w ramach <a href="https://crowdin.com/project/gpxstudio" target="_blank">projektu Crowdin</a>. Możesz pomóc dodając i sprawdzając istniejące tłumaczenie w <a href="https://crowdin.com/project/gpxstudio" target="_blank">projekcie Crowdin</a>.
Jeśli chciałbyś dodać język, którego nie ma na liście <a href="#contact">skontaktuj się z nami</a>. Jeśli chciałbyś dodać język, którego nie ma na liście <a href="#contact">skontaktuj się</a>.
Każda pomoc jest bardzo mile widziana! Każda pomoc jest bardzo mile widziana!
</DocsNote> </DocsNote>

View File

@@ -9,21 +9,21 @@ title: Akcje menu Widok
# { title } # { title }
To menu zawiera opcje zmiany kolejności interfejsu i widoku mapy. This menu provides options to rearrange the interface and the map view.
### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> Profil wysokościowy ### <ChartArea size="16" class="inline-block" style="margin-bottom: 2px" /> Elevation profile
Ukryj profil ukształtowania terenu, aby zrobić miejsce na mapie lub pokaż go, aby sprawdzić bieżący wybór. 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" /> Drzewo plików ### <ListTree size="16" class="inline-block" style="margin-bottom: 2px" /> File tree
Przełącz układ drzewa na [listy plików](../files-and-stats). Toggle the tree layout for the [file list](../files-and-stats).
This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map. This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map.
Dodatkowo, widok drzewa plików umożliwia sprawdzenie [tras, segmentów, oraz punktów zainteresowania](../gpx) zawarte w plikach poprzez zwijalne sekcje. 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.
### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> Przełącz na poprzednią mapę ### <Map size="16" class="inline-block" style="margin-bottom: 2px" /> Switch to previous basemap
Zmień mapę na mapę wybraną poprzednio przez [sterowanie warstwą map](../map-controls). Change the basemap to the one previously selected through the [map layer control](../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 overlays

View File

@@ -1,5 +1,5 @@
--- ---
title: Planowanie i edycja trasy title: Route planning and editing
--- ---
<script> <script>
@@ -11,11 +11,11 @@ title: Planowanie i edycja trasy
# <Pencil size="24" class="inline-block" style="margin-bottom: 5px" /> { title } # <Pencil size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
Narzędzie do planowania i edycji trasy pozwala na tworzenie i edytowanie tras poprzez umieszczanie lub przesuwanie punktów kotwiczenia na mapie. The route planning and editing tool allows you to create and edit routes by placing or moving anchor points on the map.
## Settings ## Settings
Jak pokazano poniżej, okno dialogowe narzędzia zawiera kilka ustawień do kontrolowania zachowania rutingu. As shown below, the tool dialog contains a few settings to control the routing behavior.
You can minimize the dialog to save space by clicking on <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>. You can minimize the dialog to save space by clicking on <button><SquareArrowUpLeft size="16" class="inline-block" style="margin-bottom: 2px" /></button>.
<div class="flex flex-row justify-center"> <div class="flex flex-row justify-center">

View File

@@ -24,7 +24,7 @@ Validate the selection when you are satisfied with the result.
## Podziel ## Podziel
To split the selected trace into two parts, click on one of the split markers displayed along the trace. To split the selected trace into two parts, click on one of the split markers displayed along the trace.
Aby podzielić w wybranym przez Ciebie punkcie, zaznacz punkt na śladzie trasy. To split at a specific point of your choice, hover over the trace on the map.
Scissors will appear at the cursor position, showing that you can split the trace at that point. Scissors will appear at the cursor position, showing that you can split the trace at that point.
You can choose to split the trace into two GPX files, or to keep the split parts in the same file as [tracks or segments](../gpx). 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).

View File

@@ -10,18 +10,18 @@ title: Czas
# <CalendarClock size="24" class="inline-block" style="margin-bottom: 5px" /> { title } # <CalendarClock size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
To narzędzie pozwala na zmianę lub dodanie znaczników czasu do śladu. This tool allows you to change or add timestamps to a trace.
Musisz po prostu użyć poniższego formularza i potwierdzić go po zakończeniu. You simply need to use the form shown below and validate it when you are done.
<div class="flex flex-row justify-center"> <div class="flex flex-row justify-center">
<Time class="text-foreground p-3 border rounded-md shadow-lg" /> <Time class="text-foreground p-3 border rounded-md shadow-lg" />
</div> </div>
Podczas edycji prędkości, czas poruszania się jest odpowiednio dostosowywany w formularzu i odwrotnie. When you edit the speed, the moving time is adapted accordingly in the form, and vice versa.
Podobnie, kiedy edytujesz czas rozpoczęcia, czas zakończenia jest aktualizowany, aby zachować ten sam czas trwania i odwrotnie. Similarly, when you edit the start time, the end time is updated to keep the same total duration, and vice versa.
<DocsNote> <DocsNote>
Gdy używasz to narzędzie z istniejącymi znacznikami czasu, zmiana czasu lub prędkości po prostu się zmieni, rozciągnij lub kompresuj je. When using this tool with existing timestamps, changing the time or speed will simply shift, stretch, or compress them accordingly.
</DocsNote> </DocsNote>

View File

@@ -50,7 +50,7 @@ Clicando com o botão direito em uma aba arquivo, você pode acessar as mesmas a
As mentioned in the [view options section](./menu/view), you can switch to a tree layout for the files list. As mentioned in the [view options section](./menu/view), you can switch to a tree layout for the files list.
This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map. This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map.
Além disso, a exibição de árvore de arquivos permite que você inspecione as [faixas, segmentos, e pontos de interesse](./gpx) contidos dentro dos arquivos através de seções recolhidas. 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.
Você também pode aplicar as [ações de edição](./menu/edit) e [ferramentas](./toolbar) para itens de arquivos internos. Você também pode aplicar as [ações de edição](./menu/edit) e [ferramentas](./toolbar) para itens de arquivos internos.
Além disso, você pode arrastar e soltar os itens internos para reordená-los, ou movê-los na hierarquia ou até mesmo para outro arquivo. Além disso, você pode arrastar e soltar os itens internos para reordená-los, ou movê-los na hierarquia ou até mesmo para outro arquivo.
@@ -105,6 +105,6 @@ Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-b
- **slope** information computed from the elevation data, or - **slope** information computed from the elevation data, or
- **surface** or **category** data coming from <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>'s <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> and <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">highway</a> tags. - **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.
Isso só está disponível para arquivos criados com **gpx.studio**. This is only available for files created with **gpx.studio**.
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile. If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.

View File

@@ -35,7 +35,7 @@ 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
Apagar todos os arquivos. Delete all files.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar... ### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar...

View File

@@ -2,8 +2,7 @@
import { HeartHandshake } from '@lucide/svelte'; import { HeartHandshake } from '@lucide/svelte';
</script> </script>
## <HeartHandshake size="18" class="inline-block align-baseline" /> ## <HeartHandshake size="18" class="inline-block align-baseline" /> Help keep the website free (and ad-free)
Допоможіть нам залишати цей сайт безкоштовним (та без реклами)
Кожного разу, коли ви додаєте або переміщуєте GPS точки, наші сервери обчислюють найкращий маршрут на мережі доріг. Кожного разу, коли ви додаєте або переміщуєте GPS точки, наші сервери обчислюють найкращий маршрут на мережі доріг.
Ми також використовуємо API від <a href="https://mapbox.com" target="_blank">Mapbox</a> для зображення красивих карт, отримання даних висот та можливості пошуку місць. Ми також використовуємо API від <a href="https://mapbox.com" target="_blank">Mapbox</a> для зображення красивих карт, отримання даних висот та можливості пошуку місць.

View File

@@ -2,7 +2,7 @@
import { Languages } from '@lucide/svelte'; import { Languages } from '@lucide/svelte';
</script> </script>
## <Languages size="18" class="inline-block align-baseline" /> Переклад ## <Languages size="18" class="inline-block align-baseline" /> Translation
Сайт перекладається волонтерами з використанням платформи для спільного перекладу. Сайт перекладається волонтерами з використанням платформи для спільного перекладу.
Ви можете зробити свій внесок, додаючи або покращуючи переклади в нашому <a href="https://crowdin.com/project/gpxstudio" target="_blank">проєкті Crowdin</a>. Ви можете зробити свій внесок, додаючи або покращуючи переклади в нашому <a href="https://crowdin.com/project/gpxstudio" target="_blank">проєкті Crowdin</a>.

View File

@@ -47,6 +47,6 @@ Open the export dialog to save all files to your computer.
<DocsNote type="warning"> <DocsNote type="warning">
Якщо завантаження не починається після натискання кнопки завантаження, будь ласка, перевірте налаштування браузера, щоб дозволити завантаження з <b>gpx.studio</b>. If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
</DocsNote> </DocsNote>

View File

@@ -31,7 +31,7 @@ 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
. 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

View File

@@ -807,7 +807,7 @@ export const fileActions = {
}); });
}); });
}, },
addElevationToSelection: async () => { addElevationToSelection: async (map: mapboxgl.Map) => {
if (get(selection).size === 0) { if (get(selection).size === 0) {
return; return;
} }

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -28,7 +28,7 @@
"undo": "Desfer", "undo": "Desfer",
"redo": "Refer", "redo": "Refer",
"delete": "Elimina el track", "delete": "Elimina el track",
"delete_all": "Esborra-ho tot", "delete_all": "Delete all",
"select_all": "Seleccionar-ho tot", "select_all": "Seleccionar-ho tot",
"view": "Vista", "view": "Vista",
"elevation_profile": "Perfil delevacions", "elevation_profile": "Perfil delevacions",
@@ -80,7 +80,7 @@
"center": "Centrar", "center": "Centrar",
"open_in": "Obrir amb", "open_in": "Obrir amb",
"copy_coordinates": "Copiar coordenades", "copy_coordinates": "Copiar coordenades",
"edit_osm": "Edita a OpenStreetMap" "edit_osm": "Edit in OpenStreetMap"
}, },
"toolbar": { "toolbar": {
"routing": { "routing": {
@@ -190,8 +190,6 @@
"from": "El punt d'inici és massa lluny de la via més propera", "from": "El punt d'inici és massa lluny de la via més propera",
"via": "El punt és massa lluny de la via més propera", "via": "El punt és massa lluny de la via més propera",
"to": "El punt final és massa lluny de la via més propera", "to": "El punt final és massa lluny de la via més propera",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "El càlcul de la ruta tarda més del compte, prova d'afegir punts més propers entre si" "timeout": "El càlcul de la ruta tarda més del compte, prova d'afegir punts més propers entre si"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Actualitza la capa" "update": "Actualitza la capa"
}, },
"opacity": "Opacitat de la superposició", "opacity": "Opacitat de la superposició",
"terrain": "Terreny", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Mapes base", "basemaps": "Mapes base",
"overlays": "Capes", "overlays": "Capes",
@@ -358,7 +356,7 @@
"water": "Aigua", "water": "Aigua",
"shower": "Dutxa", "shower": "Dutxa",
"shelter": "Refugi", "shelter": "Refugi",
"cemetery": "Cementiri", "cemetery": "Cemetery",
"motorized": "Cotxes i motos", "motorized": "Cotxes i motos",
"fuel-station": "Gasolinera", "fuel-station": "Gasolinera",
"parking": "Aparcament", "parking": "Aparcament",

View File

@@ -190,8 +190,6 @@
"from": "Počáteční bod je příliš daleko od nejbližší cesty", "from": "Počáteční bod je příliš daleko od nejbližší cesty",
"via": "Průchozí bod je příliš daleko od nejbližší cesty", "via": "Průchozí bod je příliš daleko od nejbližší cesty",
"to": "Koncový bod je příliš daleko od nejbližší cesty", "to": "Koncový bod je příliš daleko od nejbližší cesty",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Výpočet trasy trval příliš dlouho, zkuste přidat body blíže k sobě" "timeout": "Výpočet trasy trval příliš dlouho, zkuste přidat body blíže k sobě"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Aktualizovat vrstvu" "update": "Aktualizovat vrstvu"
}, },
"opacity": "Průhlednost překryvu", "opacity": "Průhlednost překryvu",
"terrain": "Zdroj terénu", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Základní mapy", "basemaps": "Základní mapy",
"overlays": "Překrytí", "overlays": "Překrytí",

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -21,14 +21,14 @@
"export_all": "Alle exportieren...", "export_all": "Alle exportieren...",
"export_options": "Export-Einstellungen", "export_options": "Export-Einstellungen",
"support_message": "Das Tool darf frei benutzt werden, aber es darf nicht woanders aufgesetzt werden. Bitte unterstützen Sie die Website, wenn Sie sie häufig benutzen. Vielen Dank!", "support_message": "Das Tool darf frei benutzt werden, aber es darf nicht woanders aufgesetzt werden. Bitte unterstützen Sie die Website, wenn Sie sie häufig benutzen. Vielen Dank!",
"support_button": "Hilf uns, die Website weiterhin kostenlos bereitzustellen", "support_button": "Hilf dabei, die Webseite kostenlos zu belassen",
"download_file": "Datei herunterladen", "download_file": "Datei herunterladen",
"download_files": "Dateien herunterladen", "download_files": "Dateien herunterladen",
"edit": "Bearbeiten", "edit": "Bearbeiten",
"undo": "Rückgängig", "undo": "Rückgängig",
"redo": "Wiederholen", "redo": "Wiederholen",
"delete": "Löschen", "delete": "Löschen",
"delete_all": "Alle löschen", "delete_all": "Delete all",
"select_all": "Alle auswählen", "select_all": "Alle auswählen",
"view": "Ansicht", "view": "Ansicht",
"elevation_profile": "Höhenprofil", "elevation_profile": "Höhenprofil",
@@ -80,7 +80,7 @@
"center": "Zentrieren", "center": "Zentrieren",
"open_in": "Öffnen in", "open_in": "Öffnen in",
"copy_coordinates": "Koordinaten kopieren", "copy_coordinates": "Koordinaten kopieren",
"edit_osm": "In OpenStreetMap bearbeiten" "edit_osm": "Edit in OpenStreetMap"
}, },
"toolbar": { "toolbar": {
"routing": { "routing": {
@@ -190,8 +190,6 @@
"from": "Der Startpunkt ist zu weit von der nächsten Straße entfernt", "from": "Der Startpunkt ist zu weit von der nächsten Straße entfernt",
"via": "Der Via-Punkt ist zu weit entfernt von der nächsten Straße", "via": "Der Via-Punkt ist zu weit entfernt von der nächsten Straße",
"to": "Der Endpunkt ist zu weit von der nächsten Straße entfernt", "to": "Der Endpunkt ist zu weit von der nächsten Straße entfernt",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route-Berechnung benötigte zu viel Zeit; versuche, die Punkte näher aneinander zu setzen" "timeout": "Route-Berechnung benötigte zu viel Zeit; versuche, die Punkte näher aneinander zu setzen"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Layer aktualisieren" "update": "Layer aktualisieren"
}, },
"opacity": "Deckkraft der Überlagerung", "opacity": "Deckkraft der Überlagerung",
"terrain": "Geländequelle", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Basiskarte", "basemaps": "Basiskarte",
"overlays": "Ebenen", "overlays": "Ebenen",
@@ -328,7 +326,7 @@
"usgs": "USGS", "usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel", "bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite", "cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "MapTiler Hillshade", "mapterhornHillshade": "Mapterhorn Hillshade",
"openRailwayMap": "OpenRailwayMap", "openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "swisstopo Neigung", "swisstopoSlope": "swisstopo Neigung",
"swisstopoHiking": "swisstopo Wandern", "swisstopoHiking": "swisstopo Wandern",
@@ -358,7 +356,7 @@
"water": "Trinkwasser", "water": "Trinkwasser",
"shower": "Dusche", "shower": "Dusche",
"shelter": "Unterstand", "shelter": "Unterstand",
"cemetery": "Friedhof", "cemetery": "Cemetery",
"motorized": "Autos und Motorräder", "motorized": "Autos und Motorräder",
"fuel-station": "Tankstelle", "fuel-station": "Tankstelle",
"parking": "Parken", "parking": "Parken",

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,6 +190,8 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is to far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "El punto de inicio está demasiado lejos de la carretera más cercana", "from": "El punto de inicio está demasiado lejos de la carretera más cercana",
"via": "El punto de paso está demasiado lejos de la carretera más cercana", "via": "El punto de paso está demasiado lejos de la carretera más cercana",
"to": "El punto final está demasiado lejos de la carretera más cercana", "to": "El punto final está demasiado lejos de la carretera más cercana",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Calcular la ruta llevó demasiado tiempo, intente añadir puntos más cercanos entre ellos" "timeout": "Calcular la ruta llevó demasiado tiempo, intente añadir puntos más cercanos entre ellos"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Actualizar capa" "update": "Actualizar capa"
}, },
"opacity": "Opacidad de la capa superpuesta", "opacity": "Opacidad de la capa superpuesta",
"terrain": "Origen del terreno", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Mapas base", "basemaps": "Mapas base",
"overlays": "Capas", "overlays": "Capas",

View File

@@ -190,8 +190,6 @@
"from": "Hasiera puntua errepide hurbilenetik oso hurrun dago", "from": "Hasiera puntua errepide hurbilenetik oso hurrun dago",
"via": "Puntua errepide hurbilenetik oso hurrun dago", "via": "Puntua errepide hurbilenetik oso hurrun dago",
"to": "Bukaera puntua errepide hurbilenetik oso hurrun dago", "to": "Bukaera puntua errepide hurbilenetik oso hurrun dago",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Ibilbidea kalkulatzea luzeegi joan da, saiatu hurbilago dauden puntuak gehitzen" "timeout": "Ibilbidea kalkulatzea luzeegi joan da, saiatu hurbilago dauden puntuak gehitzen"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Eguneratu geruza" "update": "Eguneratu geruza"
}, },
"opacity": "Geruzaren opakutasuna", "opacity": "Geruzaren opakutasuna",
"terrain": "Lurrazala", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Oinarrizko mapak", "basemaps": "Oinarrizko mapak",
"overlays": "Geruzak", "overlays": "Geruzak",

View File

@@ -190,8 +190,6 @@
"from": "Aloituspiste on liian kaukana lähimmästä tiestä", "from": "Aloituspiste on liian kaukana lähimmästä tiestä",
"via": "Reittipiste on liian kaukana lähimmästä tiestä", "via": "Reittipiste on liian kaukana lähimmästä tiestä",
"to": "Päätepiste on liian kaukana lähimmästä tiestä", "to": "Päätepiste on liian kaukana lähimmästä tiestä",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Reitin laskenta kesti liian kauan. Tihennä reittipisteitä" "timeout": "Reitin laskenta kesti liian kauan. Tihennä reittipisteitä"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Le point de départ est trop éloigné de la route la plus proche", "from": "Le point de départ est trop éloigné de la route la plus proche",
"via": "Le point de passage est trop éloigné de la route la plus proche", "via": "Le point de passage est trop éloigné de la route la plus proche",
"to": "Le point d'arrivée est trop éloigné de la route la plus proche", "to": "Le point d'arrivée est trop éloigné de la route la plus proche",
"distance": "Le point d'arrivée est trop loin du point de départ",
"connection": "Aucune connexion trouvée entre les points",
"timeout": "Le calcul de l'itinéraire a pris trop de temps, essayez d'ajouter des points plus rapprochés" "timeout": "Le calcul de l'itinéraire a pris trop de temps, essayez d'ajouter des points plus rapprochés"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "נקודת ההתחלה רחוקה מדיי מהכביש הקרוב ביותר", "from": "נקודת ההתחלה רחוקה מדיי מהכביש הקרוב ביותר",
"via": "נקודת המעבר רחוקה מדיי מהכביש הקרוב ביותר", "via": "נקודת המעבר רחוקה מדיי מהכביש הקרוב ביותר",
"to": "נקודת הסיום רחוקה מדיי מהכביש הקרוב ביותר", "to": "נקודת הסיום רחוקה מדיי מהכביש הקרוב ביותר",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "A kiindulási pont túl messze van a legközelebbi úttól", "from": "A kiindulási pont túl messze van a legközelebbi úttól",
"via": "A köztes pont túl messze van a legközelebbi úttól", "via": "A köztes pont túl messze van a legközelebbi úttól",
"to": "A végpont túl messze van a legközelebbi úttól", "to": "A végpont túl messze van a legközelebbi úttól",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Az útvonal kiszámítása túl sokáig tartott. Próbáljon meg közelebbi pontokat adni egymáshoz" "timeout": "Az útvonal kiszámítása túl sokáig tartott. Próbáljon meg közelebbi pontokat adni egymáshoz"
} }
}, },
@@ -237,13 +235,13 @@
"help_no_selection": "Select a file item to request elevation data." "help_no_selection": "Select a file item to request elevation data."
}, },
"waypoint": { "waypoint": {
"tooltip": "PoI létrehozása és módosítása", "tooltip": "Create and edit points of interest",
"icon": "Ikon", "icon": "Icon",
"link": "Link", "link": "Link",
"longitude": "Földrajzi hosszúság", "longitude": "Longitude",
"latitude": "Szélesség", "latitude": "Szélesség",
"create": "POI fájlba mentése", "create": "POI fájlba mentése",
"add": "PoI fájlhoz adása", "add": "Add point of interest to file",
"help": "Töltsd ki az űrlapot egy új POI létrehozásához, vagy kattints egy meglévőre a szerkesztéshez. Kattints a térképre a koordináták megadásához, vagy áthelyezéshez egérrel húzd el a POI-kat.", "help": "Töltsd ki az űrlapot egy új POI létrehozásához, vagy kattints egy meglévőre a szerkesztéshez. Kattints a térképre a koordináták megadásához, vagy áthelyezéshez egérrel húzd el a POI-kat.",
"help_no_selection": "Select a file to create or edit points of interest." "help_no_selection": "Select a file to create or edit points of interest."
}, },
@@ -251,8 +249,8 @@
"tooltip": "Reduce the number of GPS points", "tooltip": "Reduce the number of GPS points",
"tolerance": "Tűréshatár", "tolerance": "Tűréshatár",
"number_of_points": "GPS pontok száma", "number_of_points": "GPS pontok száma",
"button": "Minimalizálás", "button": "Minify",
"help": "", "help": "Use the slider to choose the number of GPS points to keep.",
"help_no_selection": "Select a trace to reduce the number of its GPS points." "help_no_selection": "Select a trace to reduce the number of its GPS points."
}, },
"clean": { "clean": {

View File

@@ -190,8 +190,6 @@
"from": "Titik awal terlalu jauh dari jalan terdekat", "from": "Titik awal terlalu jauh dari jalan terdekat",
"via": "Titik via terlalu jauh dari jalan terdekat", "via": "Titik via terlalu jauh dari jalan terdekat",
"to": "Titik akhir terlalu jauh dari jalan terdekat", "to": "Titik akhir terlalu jauh dari jalan terdekat",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Perhitungan rute memakan waktu terlalu lama, coba tambahkan titik-titik yang lebih dekat satu sama lain" "timeout": "Perhitungan rute memakan waktu terlalu lama, coba tambahkan titik-titik yang lebih dekat satu sama lain"
} }
}, },
@@ -493,7 +491,7 @@
"support_button": "Support gpx.studio on Ko-fi", "support_button": "Support gpx.studio on Ko-fi",
"route_planning": "Route planning", "route_planning": "Route planning",
"route_planning_description": "An intuitive interface to create itineraries tailored to each sport, based on OpenStreetMap data.", "route_planning_description": "An intuitive interface to create itineraries tailored to each sport, based on OpenStreetMap data.",
"file_processing": "Pengolahan file lanjutan", "file_processing": "Advanced file processing",
"file_processing_description": "A suite of tools for performing all common file processing tasks, and which can be applied to multiple files at once.", "file_processing_description": "A suite of tools for performing all common file processing tasks, and which can be applied to multiple files at once.",
"maps": "Global and local maps", "maps": "Global and local maps",
"maps_description": "A large collection of basemaps, overlays and points of interest to help you craft your next outdoor adventure, or visualize your latest achievement.", "maps_description": "A large collection of basemaps, overlays and points of interest to help you craft your next outdoor adventure, or visualize your latest achievement.",

View File

@@ -190,8 +190,6 @@
"from": "Il punto di partenza è troppo lontano dalla strada più vicina", "from": "Il punto di partenza è troppo lontano dalla strada più vicina",
"via": "Il punto di arrivo è troppo lontano dalla strada più vicina", "via": "Il punto di arrivo è troppo lontano dalla strada più vicina",
"to": "Il punto di arrivo è troppo lontano dalla strada più vicina", "to": "Il punto di arrivo è troppo lontano dalla strada più vicina",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Il calcolo del percorso ha richiesto troppo tempo, prova ad aggiungere punti più vicini" "timeout": "Il calcolo del percorso ha richiesto troppo tempo, prova ad aggiungere punti più vicini"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Pradžios taškas yra per toli nuo artimiausio kelio", "from": "Pradžios taškas yra per toli nuo artimiausio kelio",
"via": "Tarpinis taškas yra per toli nuo artimiausio kelio", "via": "Tarpinis taškas yra per toli nuo artimiausio kelio",
"to": "Pabaigos taškas yra per toli nuo artimiausio kelio", "to": "Pabaigos taškas yra per toli nuo artimiausio kelio",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Maršruto skaičiavimas užtruko per ilgai, pabandykite pridėti taškus arčiau vienas kito" "timeout": "Maršruto skaičiavimas užtruko per ilgai, pabandykite pridėti taškus arčiau vienas kito"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -54,7 +54,7 @@
"mapillary": "Mapillary", "mapillary": "Mapillary",
"google": "Google", "google": "Google",
"toggle_street_view": "Street view", "toggle_street_view": "Street view",
"layers": "Kaartlagen...", "layers": "Kaart lagen...",
"distance_markers": "Afstandsmarkeringen", "distance_markers": "Afstandsmarkeringen",
"direction_markers": "Richtingspijlen", "direction_markers": "Richtingspijlen",
"help": "Help", "help": "Help",
@@ -190,8 +190,6 @@
"from": "Het startpunt ligt te ver van de dichtstbijzijnde weg", "from": "Het startpunt ligt te ver van de dichtstbijzijnde weg",
"via": "Het via punt ligt te ver van de dichtstbijzijnde weg", "via": "Het via punt ligt te ver van de dichtstbijzijnde weg",
"to": "Het eindpunt is te ver van de dichtstbijzijnde weg", "to": "Het eindpunt is te ver van de dichtstbijzijnde weg",
"distance": "Het eindpunt is te ver vanaf het startpunt",
"connection": "Geen verbinding gevonden tussen de punten",
"timeout": "Routeberekening heeft te lang geduurd, probeer punten dichter bij elkaar toe te voegen" "timeout": "Routeberekening heeft te lang geduurd, probeer punten dichter bij elkaar toe te voegen"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Update laag" "update": "Update laag"
}, },
"opacity": "Laag Transparantie", "opacity": "Laag Transparantie",
"terrain": "Terrein bron", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Basis kaarten", "basemaps": "Basis kaarten",
"overlays": "Lagen", "overlays": "Lagen",

View File

@@ -28,7 +28,7 @@
"undo": "Angre", "undo": "Angre",
"redo": "Gjenta", "redo": "Gjenta",
"delete": "Slett", "delete": "Slett",
"delete_all": "Slett alle", "delete_all": "Delete all",
"select_all": "Velg alle", "select_all": "Velg alle",
"view": "Visning", "view": "Visning",
"elevation_profile": "Høydeprofil", "elevation_profile": "Høydeprofil",
@@ -80,7 +80,7 @@
"center": "Sentrer", "center": "Sentrer",
"open_in": "Åpne I", "open_in": "Åpne I",
"copy_coordinates": "Kopier koordinater", "copy_coordinates": "Kopier koordinater",
"edit_osm": "Rediger i OpenStreetMap" "edit_osm": "Edit in OpenStreetMap"
}, },
"toolbar": { "toolbar": {
"routing": { "routing": {
@@ -190,8 +190,6 @@
"from": "Startpunktet er for langt unna nærmeste vei", "from": "Startpunktet er for langt unna nærmeste vei",
"via": "Via-punktet er for langt fra nærmeste vei", "via": "Via-punktet er for langt fra nærmeste vei",
"to": "Sluttpunktet er for langt unna nærmeste vei", "to": "Sluttpunktet er for langt unna nærmeste vei",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Ruteberegning tok for lang tid, prøv å legge til flere punkter" "timeout": "Ruteberegning tok for lang tid, prøv å legge til flere punkter"
} }
}, },
@@ -358,7 +356,7 @@
"water": "Vann", "water": "Vann",
"shower": "Dusj", "shower": "Dusj",
"shelter": "Ly", "shelter": "Ly",
"cemetery": "Gravplass", "cemetery": "Cemetery",
"motorized": "Biler og motorsykler", "motorized": "Biler og motorsykler",
"fuel-station": "Bensinstasjon", "fuel-station": "Bensinstasjon",
"parking": "Parkering", "parking": "Parkering",

View File

@@ -4,7 +4,7 @@
"app_title": "Aplikacja", "app_title": "Aplikacja",
"embed_title": "Edytor plików GPX online", "embed_title": "Edytor plików GPX online",
"help_title": "pomoc", "help_title": "pomoc",
"404_title": "Strona nie odnaleziona", "404_title": "nie odnaleziono strony",
"description": "Przeglądaj, edytuj i twórz pliki GPX online z zaawansowanymi możliwościami planowania trasy i narzędziami do przetwarzania plików, pięknymi mapami i szczegółowymi wizualizacjami danych." "description": "Przeglądaj, edytuj i twórz pliki GPX online z zaawansowanymi możliwościami planowania trasy i narzędziami do przetwarzania plików, pięknymi mapami i szczegółowymi wizualizacjami danych."
}, },
"menu": { "menu": {
@@ -190,8 +190,6 @@
"from": "Punkt początkowy jest zbyt daleko od najbliższej drogi", "from": "Punkt początkowy jest zbyt daleko od najbliższej drogi",
"via": "Punkt przelotowy jest zbyt daleko od najbliższej drogi", "via": "Punkt przelotowy jest zbyt daleko od najbliższej drogi",
"to": "Punkt końcowy jest zbyt daleko od najbliższej drogi", "to": "Punkt końcowy jest zbyt daleko od najbliższej drogi",
"distance": "Punkt końcowy jest zbyt daleko od punktu początkowego",
"connection": "Nie znaleziono połączenia między punktami",
"timeout": "Obliczanie trasy trwało zbyt długo, spróbuj dodać punkty bliżej siebie" "timeout": "Obliczanie trasy trwało zbyt długo, spróbuj dodać punkty bliżej siebie"
} }
}, },
@@ -284,7 +282,7 @@
"update": "Zaktualizuj warstwę" "update": "Zaktualizuj warstwę"
}, },
"opacity": "Przezroczystość nakładki", "opacity": "Przezroczystość nakładki",
"terrain": "Źródło danych terenowych", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "Mapy bazowe", "basemaps": "Mapy bazowe",
"overlays": "Nakładki", "overlays": "Nakładki",
@@ -328,7 +326,7 @@
"usgs": "USGS", "usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel", "bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite", "cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "Cieniowanie terenu Mapterhorn", "mapterhornHillshade": "Mapterhorn Hillshade",
"openRailwayMap": "OpenRailwayMap", "openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "swisstopo Stoki", "swisstopoSlope": "swisstopo Stoki",
"swisstopoHiking": "swisstopo Szlaki Turystyczne", "swisstopoHiking": "swisstopo Szlaki Turystyczne",

View File

@@ -190,8 +190,6 @@
"from": "O ponto de partida está muito longe da estrada mais próxima", "from": "O ponto de partida está muito longe da estrada mais próxima",
"via": "O ponto intermediário está muito longe da estrada mais próxima", "via": "O ponto intermediário está muito longe da estrada mais próxima",
"to": "O ponto de chegada está muito longe da estrada mais próxima", "to": "O ponto de chegada está muito longe da estrada mais próxima",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "O cálculo da rota demorou muito tempo, tente adicionar pontos mais próximos" "timeout": "O cálculo da rota demorou muito tempo, tente adicionar pontos mais próximos"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "O ponto de partida está muito longe da estrada mais próxima", "from": "O ponto de partida está muito longe da estrada mais próxima",
"via": "O ponto de partida está muito longe da estrada mais próxima", "via": "O ponto de partida está muito longe da estrada mais próxima",
"to": "O ponto final está muito longe do ponto de chegada", "to": "O ponto final está muito longe do ponto de chegada",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "O recalculo da demorou muito tempo, tente adicionar ponto mais próximos" "timeout": "O recalculo da demorou muito tempo, tente adicionar ponto mais próximos"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Начальная точка слишком далеко от ближайшей дороги", "from": "Начальная точка слишком далеко от ближайшей дороги",
"via": "Точка маршрута слишком далеко от ближайшей дороги", "via": "Точка маршрута слишком далеко от ближайшей дороги",
"to": "Конечная точка слишком далеко от ближайшей дороги", "to": "Конечная точка слишком далеко от ближайшей дороги",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Расчет маршрута занял слишком много времени, попробуйте добавить точки ближе" "timeout": "Расчет маршрута занял слишком много времени, попробуйте добавить точки ближе"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Početna tačka je predaleko od najbližeg puta", "from": "Početna tačka je predaleko od najbližeg puta",
"via": "Putna tačka je predaleko od najbližeg puta", "via": "Putna tačka je predaleko od najbližeg puta",
"to": "Krajnja tačka je predaleko od najbližeg puta", "to": "Krajnja tačka je predaleko od najbližeg puta",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Računanje rute je trajalo predugo, pokušajte da dodate putne tačke bliže jednu drugoj" "timeout": "Računanje rute je trajalo predugo, pokušajte da dodate putne tačke bliže jednu drugoj"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Startpunkten är för långt bort från närmaste väg", "from": "Startpunkten är för långt bort från närmaste väg",
"via": "Ruttpunkten är för långt bort från närmaste väg", "via": "Ruttpunkten är för långt bort från närmaste väg",
"to": "Slutpunkten är för långt bort från närmaste väg", "to": "Slutpunkten är för långt bort från närmaste väg",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Ruttberäkningen tog för lång tid, försök att lägga punkterna närmare varandra" "timeout": "Ruttberäkningen tog för lång tid, försök att lägga punkterna närmare varandra"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Başlangıç noktası en yakın yoldan çok uzak", "from": "Başlangıç noktası en yakın yoldan çok uzak",
"via": "Geçiş noktası en yakın yoldan çok uzak", "via": "Geçiş noktası en yakın yoldan çok uzak",
"to": "Bitiş noktası en yakın yoldan çok uzak", "to": "Bitiş noktası en yakın yoldan çok uzak",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Rota hesaplaması uzun sürdü, daha yakın noktalar eklemeyi deneyin" "timeout": "Rota hesaplaması uzun sürdü, daha yakın noktalar eklemeyi deneyin"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "Початкова точка знаходиться занадто далеко від найближчої дороги", "from": "Початкова точка знаходиться занадто далеко від найближчої дороги",
"via": "Проміжна точка знаходиться занадто далеко від найближчої дороги", "via": "Проміжна точка знаходиться занадто далеко від найближчої дороги",
"to": "Кінцева точка знаходиться занадто далеко від найближчої дороги", "to": "Кінцева точка знаходиться занадто далеко від найближчої дороги",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Розрахунок маршруту є занадто довгий, спробуйте додати ближчі точки" "timeout": "Розрахунок маршруту є занадто довгий, спробуйте додати ближчі точки"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "The start point is too far from the nearest road", "from": "The start point is too far from the nearest road",
"via": "The via point is too far from the nearest road", "via": "The via point is too far from the nearest road",
"to": "The end point is too far from the nearest road", "to": "The end point is too far from the nearest road",
"distance": "The end point is too far from the start point",
"connection": "No connection found between the points",
"timeout": "Route calculation took too long, try adding points closer together" "timeout": "Route calculation took too long, try adding points closer together"
} }
}, },

View File

@@ -190,8 +190,6 @@
"from": "起点离最近的道路太远", "from": "起点离最近的道路太远",
"via": "途径点离最近的道路太远", "via": "途径点离最近的道路太远",
"to": "终点离最近的道路太远", "to": "终点离最近的道路太远",
"distance": "起点到终点的距离太远",
"connection": "找不到经过途径点的路线",
"timeout": "轨迹计算耗时太长,请尝试添加更靠近路网的点" "timeout": "轨迹计算耗时太长,请尝试添加更靠近路网的点"
} }
}, },
@@ -284,7 +282,7 @@
"update": "更新图层" "update": "更新图层"
}, },
"opacity": "图层透明度", "opacity": "图层透明度",
"terrain": "地形来源", "terrain": "Terrain source",
"label": { "label": {
"basemaps": "底图", "basemaps": "底图",
"overlays": "叠加层", "overlays": "叠加层",
@@ -328,7 +326,7 @@
"usgs": "USGS", "usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel", "bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite", "cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "山体阴影", "mapterhornHillshade": "Mapterhorn Hillshade",
"openRailwayMap": "OpenRailwayMap", "openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "Swisstopo Slope", "swisstopoSlope": "Swisstopo Slope",
"swisstopoHiking": "Swisstopo Hiking", "swisstopoHiking": "Swisstopo Hiking",