21 Commits

Author SHA1 Message Date
vcoppe
9d5fc48286 New translations file.mdx (Ukrainian) 2026-03-11 19:04:38 +01:00
vcoppe
fa0339ed9f New translations translation.mdx (Ukrainian) 2026-03-11 17:56:19 +01:00
vcoppe
f6a89784b8 New translations funding.mdx (Ukrainian) 2026-03-11 17:56:18 +01:00
vcoppe
6301df55d5 New translations file.mdx (Catalan) 2026-03-10 09:10:17 +01:00
vcoppe
378f66de7a New translations en.json (Catalan) 2026-03-10 09:10:16 +01:00
vcoppe
0c48b52b5b New translations en.json (Dutch) 2026-03-05 14:53:55 +01:00
vcoppe
3a1e81467f New translations en.json (Basque) 2026-03-04 10:42:12 +01:00
vcoppe
40422b9059 New translations files-and-stats.mdx (Portuguese, Brazilian) 2026-03-01 17:36:41 +01:00
vcoppe
767fdbd773 New translations file.mdx (Portuguese, Brazilian) 2026-03-01 16:34:19 +01:00
vcoppe
1473886f54 New translations file.mdx (French) 2026-02-26 09:27:01 +01:00
vcoppe
daeb3d4f57 New translations en.json (Indonesian) 2026-02-19 06:29:33 +01:00
vcoppe
65bad83635 New translations en.json (Norwegian) 2026-02-12 21:05:16 +01:00
vcoppe
c2ac4fb7d9 New translations en.json (Hungarian) 2026-02-08 09:31:02 +01:00
vcoppe
c52fa0001a New translations mapbox.mdx (German) 2026-02-02 18:59:24 +01:00
vcoppe
dfad2ef3ef New translations en.json (German) 2026-02-02 18:59:22 +01:00
vcoppe
9c6e03f4a8 improve layer stacking 2026-01-30 21:30:37 +01:00
vcoppe
2a4dfe010e improve color management 2026-01-30 21:17:59 +01:00
vcoppe
f42a916c25 remove unused parameter 2026-01-30 21:17:11 +01:00
vcoppe
772b810fa8 simplify initialization 2026-01-30 21:16:56 +01:00
vcoppe
4d4d10d5c2 small UI tweaks 2026-01-30 21:16:32 +01:00
vcoppe
0e4c7dbe64 New translations en.json (Chinese Simplified) (#306) 2026-01-30 21:02:21 +01:00
32 changed files with 259 additions and 216 deletions

View File

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

View File

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

View File

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

View File

@@ -41,6 +41,7 @@
<Button
size="sm"
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)}`}
target="_blank"
>

View File

@@ -3,7 +3,7 @@ import { gpxStatistics } from '$lib/logic/statistics';
import { getConvertedDistanceToKilometers } from '$lib/units';
import type { GeoJSONSource } from 'mapbox-gl';
import { get } from 'svelte/store';
import { map } from '$lib/components/map/map';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map';
import { allHidden } from '$lib/logic/hidden';
const { distanceMarkers, distanceUnits } = settings;
@@ -44,7 +44,8 @@ export class DistanceMarkers {
});
}
if (!map_.getLayer('distance-markers')) {
map_.addLayer({
map_.addLayer(
{
id: 'distance-markers',
type: 'symbol',
source: 'distance-markers',
@@ -79,9 +80,9 @@ export class DistanceMarkers {
'text-halo-width': 2,
'text-halo-color': 'white',
},
});
} else {
map_.moveLayer('distance-markers');
},
ANCHOR_LAYER_KEY.distanceMarkers
);
}
} else {
if (map_.getLayer('distance-markers')) {

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,6 +20,28 @@ let fitBoundsOptions: mapboxgl.MapOptions['fitBoundsOptions'] = {
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 {
private _map: Writable<mapboxgl.Map | null> = writable(null);
private _onLoadCallbacks: ((map: mapboxgl.Map) => void)[] = [];
@@ -29,19 +51,15 @@ export class MapboxGLMap {
return this._map.subscribe(run, invalidate);
}
init(
accessToken: string,
language: string,
hash: boolean,
geocoder: boolean,
geolocate: boolean
) {
init(language: string, hash: boolean, geocoder: boolean, geolocate: boolean) {
const map = new mapboxgl.Map({
container: 'map',
style: {
version: 8,
sources: {},
layers: [],
sources: {
'empty-source': emptySource,
},
layers: anchorLayers,
imports: [
{
id: 'basemap',
@@ -50,11 +68,6 @@ export class MapboxGLMap {
{
id: 'overlays',
url: '',
data: {
version: 8,
sources: {},
layers: [],
},
},
],
},

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,6 +8,7 @@ import { get } from 'svelte/store';
import { fileStateCollection } from '$lib/logic/file-state';
import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
export class SplitControls {
map: mapboxgl.Map;
@@ -108,7 +109,8 @@ export class SplitControls {
}
if (!this.map.getLayer('split-controls')) {
this.map.addLayer({
this.map.addLayer(
{
id: 'split-controls',
type: 'symbol',
source: 'split-controls',
@@ -118,14 +120,14 @@ export class SplitControls {
'icon-padding': 0,
},
filter: ['<=', ['get', 'minZoom'], ['zoom']],
});
},
ANCHOR_LAYER_KEY.interactions
);
this.map.on('mouseenter', 'split-controls', this.layerOnMouseEnterBinded);
this.map.on('mouseleave', 'split-controls', this.layerOnMouseLeaveBinded);
this.map.on('click', 'split-controls', this.layerOnClickBinded);
}
this.map.moveLayer('split-controls');
} catch (e) {
// 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.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Esborra
Delete the currently selected files.
Esborra l'arxiu seleccinat.
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Delete all
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Esborra-ho tot
Delete all files.
Esborra tots els fitxers.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar...

View File

@@ -1,5 +1,5 @@
Mapbox ist das Unternehmen, das einige der schönen Karten auf dieser Website zur Verfügung stellt.
Sie entwickeln auch die <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">Karten-Engine</a> welche **gpx.studio** unterstützt.
Mapbox stellt einige der auf dieser Website verwendeten Karten bereit.
Sie entwickeln auch die <a href="https://github.com/mapbox/mapbox-gl-js" target="_blank">Karten-Engine</a>, die **gpx.studio** unterstützt.
Wir sind äußerst glücklich und dankbar, Teil ihres <a href="https://mapbox.com/community" target="_blank">Community</a> Programms zu sein, das gemeinnützige Organisationen, Bildungseinrichtungen und Organisationen mit positivem Einfluss unterstützt.
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.
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
Supprimer toutes les fichiers.
Supprimer tous les fichiers.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exporter...

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.
This layout is ideal for managing a large number of open files, as it organizes them into a vertical list on the right side of the map.
In addition, the file tree view enables you to inspect the [tracks, segments, and points of interest](./gpx) contained inside the files through collapsible sections.
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.
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.
@@ -105,6 +105,6 @@ Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-b
- **slope** information computed from the elevation data, or
- **surface** or **category** data coming from <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>'s <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> and <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">highway</a> tags.
This is only available for files created with **gpx.studio**.
Isso só está disponível para arquivos criados com **gpx.studio**.
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
Delete all files.
Apagar todos os arquivos.
### <Download size="16" class="inline-block" style="margin-bottom: 2px" /> Exportar...

View File

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

View File

@@ -2,7 +2,7 @@
import { Languages } from '@lucide/svelte';
</script>
## <Languages size="18" class="inline-block align-baseline" /> Translation
## <Languages size="18" class="inline-block align-baseline" /> Переклад
Сайт перекладається волонтерами з використанням платформи для спільного перекладу.
Ви можете зробити свій внесок, додаючи або покращуючи переклади в нашому <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">
If your download does not start after clicking the download button, please check your browser settings to allow downloads from <b>gpx.studio</b>.
Якщо завантаження не починається після натискання кнопки завантаження, будь ласка, перевірте налаштування браузера, щоб дозволити завантаження з <b>gpx.studio</b>.
</DocsNote>

View File

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

View File

@@ -28,7 +28,7 @@
"undo": "Desfer",
"redo": "Refer",
"delete": "Elimina el track",
"delete_all": "Delete all",
"delete_all": "Esborra-ho tot",
"select_all": "Seleccionar-ho tot",
"view": "Vista",
"elevation_profile": "Perfil delevacions",
@@ -80,7 +80,7 @@
"center": "Centrar",
"open_in": "Obrir amb",
"copy_coordinates": "Copiar coordenades",
"edit_osm": "Edit in OpenStreetMap"
"edit_osm": "Edita a OpenStreetMap"
},
"toolbar": {
"routing": {
@@ -282,7 +282,7 @@
"update": "Actualitza la capa"
},
"opacity": "Opacitat de la superposició",
"terrain": "Terrain source",
"terrain": "Terreny",
"label": {
"basemaps": "Mapes base",
"overlays": "Capes",
@@ -356,7 +356,7 @@
"water": "Aigua",
"shower": "Dutxa",
"shelter": "Refugi",
"cemetery": "Cemetery",
"cemetery": "Cementiri",
"motorized": "Cotxes i motos",
"fuel-station": "Gasolinera",
"parking": "Aparcament",

View File

@@ -21,14 +21,14 @@
"export_all": "Alle exportieren...",
"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_button": "Hilf dabei, die Webseite kostenlos zu belassen",
"support_button": "Hilf uns, die Website weiterhin kostenlos bereitzustellen",
"download_file": "Datei herunterladen",
"download_files": "Dateien herunterladen",
"edit": "Bearbeiten",
"undo": "Rückgängig",
"redo": "Wiederholen",
"delete": "Löschen",
"delete_all": "Delete all",
"delete_all": "Alle löschen",
"select_all": "Alle auswählen",
"view": "Ansicht",
"elevation_profile": "Höhenprofil",
@@ -80,7 +80,7 @@
"center": "Zentrieren",
"open_in": "Öffnen in",
"copy_coordinates": "Koordinaten kopieren",
"edit_osm": "Edit in OpenStreetMap"
"edit_osm": "In OpenStreetMap bearbeiten"
},
"toolbar": {
"routing": {
@@ -282,7 +282,7 @@
"update": "Layer aktualisieren"
},
"opacity": "Deckkraft der Überlagerung",
"terrain": "Terrain source",
"terrain": "Geländequelle",
"label": {
"basemaps": "Basiskarte",
"overlays": "Ebenen",
@@ -326,7 +326,7 @@
"usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "Mapterhorn Hillshade",
"mapterhornHillshade": "MapTiler Hillshade",
"openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "swisstopo Neigung",
"swisstopoHiking": "swisstopo Wandern",
@@ -356,7 +356,7 @@
"water": "Trinkwasser",
"shower": "Dusche",
"shelter": "Unterstand",
"cemetery": "Cemetery",
"cemetery": "Friedhof",
"motorized": "Autos und Motorräder",
"fuel-station": "Tankstelle",
"parking": "Parken",

View File

@@ -282,7 +282,7 @@
"update": "Eguneratu geruza"
},
"opacity": "Geruzaren opakutasuna",
"terrain": "Terrain source",
"terrain": "Lurrazala",
"label": {
"basemaps": "Oinarrizko mapak",
"overlays": "Geruzak",

View File

@@ -235,13 +235,13 @@
"help_no_selection": "Select a file item to request elevation data."
},
"waypoint": {
"tooltip": "Create and edit points of interest",
"icon": "Icon",
"tooltip": "PoI létrehozása és módosítása",
"icon": "Ikon",
"link": "Link",
"longitude": "Longitude",
"longitude": "Földrajzi hosszúság",
"latitude": "Szélesség",
"create": "POI fájlba mentése",
"add": "Add point of interest to file",
"add": "PoI fájlhoz adása",
"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."
},
@@ -249,8 +249,8 @@
"tooltip": "Reduce the number of GPS points",
"tolerance": "Tűréshatár",
"number_of_points": "GPS pontok száma",
"button": "Minify",
"help": "Use the slider to choose the number of GPS points to keep.",
"button": "Minimalizálás",
"help": "",
"help_no_selection": "Select a trace to reduce the number of its GPS points."
},
"clean": {

View File

@@ -491,7 +491,7 @@
"support_button": "Support gpx.studio on Ko-fi",
"route_planning": "Route planning",
"route_planning_description": "An intuitive interface to create itineraries tailored to each sport, based on OpenStreetMap data.",
"file_processing": "Advanced file processing",
"file_processing": "Pengolahan file lanjutan",
"file_processing_description": "A suite of tools for performing all common file processing tasks, and which can be applied to multiple files at once.",
"maps": "Global and local maps",
"maps_description": "A large collection of basemaps, overlays and points of interest to help you craft your next outdoor adventure, or visualize your latest achievement.",

View File

@@ -28,7 +28,7 @@
"undo": "Angre",
"redo": "Gjenta",
"delete": "Slett",
"delete_all": "Delete all",
"delete_all": "Slett alle",
"select_all": "Velg alle",
"view": "Visning",
"elevation_profile": "Høydeprofil",
@@ -80,7 +80,7 @@
"center": "Sentrer",
"open_in": "Åpne I",
"copy_coordinates": "Kopier koordinater",
"edit_osm": "Edit in OpenStreetMap"
"edit_osm": "Rediger i OpenStreetMap"
},
"toolbar": {
"routing": {
@@ -356,7 +356,7 @@
"water": "Vann",
"shower": "Dusj",
"shelter": "Ly",
"cemetery": "Cemetery",
"cemetery": "Gravplass",
"motorized": "Biler og motorsykler",
"fuel-station": "Bensinstasjon",
"parking": "Parkering",

View File

@@ -282,7 +282,7 @@
"update": "更新图层"
},
"opacity": "图层透明度",
"terrain": "Terrain source",
"terrain": "地形来源",
"label": {
"basemaps": "底图",
"overlays": "叠加层",
@@ -326,7 +326,7 @@
"usgs": "USGS",
"bikerouterGravel": "bikerouter.de Gravel",
"cyclOSMlite": "CyclOSM Lite",
"mapterhornHillshade": "Mapterhorn Hillshade",
"mapterhornHillshade": "山体阴影",
"openRailwayMap": "OpenRailwayMap",
"swisstopoSlope": "Swisstopo Slope",
"swisstopoHiking": "Swisstopo Hiking",