mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 15:43:25 +00:00
continue localization
This commit is contained in:
@@ -384,13 +384,13 @@ export const basemapTree: LayerTreeType = {
|
||||
bulgaria: ['bgMountains'],
|
||||
finland: ['finlandTopo'],
|
||||
france: ['ignPlanV2', 'ignFrScan25', 'ignSatellite'],
|
||||
newZealand: ['linz', 'linzTopo'],
|
||||
new_zealand: ['linz', 'linzTopo'],
|
||||
norway: ['norwayTopo'],
|
||||
spain: ['ignEs'],
|
||||
sweden: ['swedenTopo'],
|
||||
switzerland: ['swisstopo'],
|
||||
unitedKingdom: ['ordnanceSurvey'],
|
||||
unitedStates: ['usgs'],
|
||||
united_kingdom: ['ordnanceSurvey'],
|
||||
united_states: ['usgs'],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -399,7 +399,7 @@ export const overlayTree: LayerTreeType = {
|
||||
overlays: {
|
||||
world: {
|
||||
cyclOSM: ['cyclOSMlite'],
|
||||
waymarkedTrails: ['waymarkedTrailsHiking', 'waymarkedTrailsCycling', 'waymarkedTrailsMTB', 'waymarkedTrailsSkating', 'waymarkedTrailsHorseRiding', 'waymarkedTrailsWinter']
|
||||
waymarked_trails: ['waymarkedTrailsHiking', 'waymarkedTrailsCycling', 'waymarkedTrailsMTB', 'waymarkedTrailsSkating', 'waymarkedTrailsHorseRiding', 'waymarkedTrailsWinter']
|
||||
},
|
||||
countries: {
|
||||
france: ['ignFrCadastre', 'ignSlope'],
|
||||
|
@@ -8,6 +8,8 @@
|
||||
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
|
||||
|
||||
import { map, settings } from '$lib/stores';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
mapboxgl.accessToken =
|
||||
'pk.eyJ1IjoiZ3B4c3R1ZGlvIiwiYSI6ImNrdHVoM2pjNTBodmUycG1yZTNwcnJ3MzkifQ.YZnNs9s9oCQPzoXAWs_SLg';
|
||||
@@ -54,7 +56,7 @@
|
||||
style: { version: 8, sources: {}, layers: [] },
|
||||
projection: { name: 'mercator' },
|
||||
hash: true,
|
||||
language: 'auto',
|
||||
language: get(locale),
|
||||
attributionControl: false,
|
||||
logoPosition: 'bottom-right',
|
||||
boxZoom: false
|
||||
@@ -73,7 +75,8 @@
|
||||
accessToken: mapboxgl.accessToken,
|
||||
mapboxgl: mapboxgl,
|
||||
collapsed: true,
|
||||
flyTo: fitBoundsOptions
|
||||
flyTo: fitBoundsOptions,
|
||||
language: get(locale)
|
||||
})
|
||||
);
|
||||
|
||||
|
@@ -49,112 +49,112 @@
|
||||
</Menubar.Item>
|
||||
<Menubar.Separator />
|
||||
<Menubar.Item on:click={triggerFileInput}>
|
||||
<Upload size="16" class="mr-1" /> Load from desktop... <Menubar.Shortcut
|
||||
>⌘O</Menubar.Shortcut
|
||||
>
|
||||
<Upload size="16" class="mr-1" />
|
||||
{$_('menu.load_desktop')}
|
||||
<Menubar.Shortcut>⌘O</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
<Menubar.Item>
|
||||
<Cloud size="16" class="mr-1" />
|
||||
Load from Google Drive...</Menubar.Item
|
||||
{$_('menu.load_drive')}</Menubar.Item
|
||||
>
|
||||
<Menubar.Separator />
|
||||
<Menubar.Item on:click={duplicateSelectedFiles} disabled={$selectedFiles.size == 0}>
|
||||
<Copy size="16" class="mr-1" /> Duplicate <Menubar.Shortcut>⌘D</Menubar.Shortcut>
|
||||
<Copy size="16" class="mr-1" />
|
||||
{$_('menu.duplicate')}
|
||||
<Menubar.Shortcut>⌘D</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
<Menubar.Separator />
|
||||
<Menubar.Item on:click={exportSelectedFiles} disabled={$selectedFiles.size == 0}>
|
||||
<Download size="16" class="mr-1" /> Export... <Menubar.Shortcut>⌘S</Menubar.Shortcut>
|
||||
<Download size="16" class="mr-1" />
|
||||
{$_('menu.export')}
|
||||
<Menubar.Shortcut>⌘S</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
<Menubar.Item on:click={exportAllFiles} disabled={$fileCollection.files.length == 0}>
|
||||
<Download size="16" class="mr-1" /> Export all... <Menubar.Shortcut
|
||||
>⇧⌘S</Menubar.Shortcut
|
||||
>
|
||||
<Download size="16" class="mr-1" />
|
||||
{$_('menu.export_all')}
|
||||
<Menubar.Shortcut>⇧⌘S</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
</Menubar.Content>
|
||||
</Menubar.Menu>
|
||||
<Menubar.Menu>
|
||||
<Menubar.Trigger>Edit</Menubar.Trigger>
|
||||
<Menubar.Trigger>{$_('menu.edit')}</Menubar.Trigger>
|
||||
<Menubar.Content>
|
||||
<Menubar.Item>
|
||||
<Undo2 size="16" class="mr-1" /> Undo <Menubar.Shortcut>⌘Z</Menubar.Shortcut>
|
||||
<Undo2 size="16" class="mr-1" />
|
||||
{$_('menu.undo')}
|
||||
<Menubar.Shortcut>⌘Z</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
<Menubar.Item>
|
||||
<Redo2 size="16" class="mr-1" /> Redo <Menubar.Shortcut>⇧⌘Z</Menubar.Shortcut>
|
||||
<Redo2 size="16" class="mr-1" />
|
||||
{$_('menu.redo')}
|
||||
<Menubar.Shortcut>⇧⌘Z</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
<Menubar.Separator />
|
||||
<Menubar.Item on:click={removeSelectedFiles} disabled={$selectedFiles.size == 0}>
|
||||
<Trash2 size="16" class="mr-1" /> Delete <Menubar.Shortcut>⌘⌫</Menubar.Shortcut
|
||||
></Menubar.Item
|
||||
<Trash2 size="16" class="mr-1" />
|
||||
{$_('menu.delete')}
|
||||
<Menubar.Shortcut>⌘⌫</Menubar.Shortcut></Menubar.Item
|
||||
>
|
||||
<Menubar.Item
|
||||
class="text-destructive data-[highlighted]:text-destructive"
|
||||
on:click={removeAllFiles}
|
||||
disabled={$fileCollection.files.length == 0}
|
||||
>
|
||||
<Trash2 size="16" class="mr-1" /> Delete all<Menubar.Shortcut>⇧⌘⌫</Menubar.Shortcut
|
||||
></Menubar.Item
|
||||
<Trash2 size="16" class="mr-1" />
|
||||
{$_('menu.delete_all')}<Menubar.Shortcut>⇧⌘⌫</Menubar.Shortcut></Menubar.Item
|
||||
>
|
||||
</Menubar.Content>
|
||||
</Menubar.Menu>
|
||||
<Menubar.Menu>
|
||||
<Menubar.Trigger>Help</Menubar.Trigger>
|
||||
<Menubar.Content>
|
||||
<Menubar.Item>
|
||||
Quick help <Menubar.Shortcut>⌘H</Menubar.Shortcut>
|
||||
</Menubar.Item>
|
||||
<Menubar.Item>User guide</Menubar.Item>
|
||||
</Menubar.Content>
|
||||
</Menubar.Menu>
|
||||
<Menubar.Menu>
|
||||
<Menubar.Trigger>Settings</Menubar.Trigger>
|
||||
<Menubar.Trigger>{$_('menu.settings')}</Menubar.Trigger>
|
||||
<Menubar.Content
|
||||
><Menubar.Sub>
|
||||
<Menubar.SubTrigger inset>Distance units</Menubar.SubTrigger>
|
||||
<Menubar.SubTrigger inset>{$_('menu.distance_units')}</Menubar.SubTrigger>
|
||||
<Menubar.SubContent>
|
||||
<Menubar.RadioGroup bind:value={$settings.distanceUnits}>
|
||||
<Menubar.RadioItem value="metric">Metric</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="imperial">Imperial</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="metric">{$_('menu.metric')}</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="imperial">{$_('menu.imperial')}</Menubar.RadioItem>
|
||||
</Menubar.RadioGroup>
|
||||
</Menubar.SubContent>
|
||||
</Menubar.Sub>
|
||||
<Menubar.Sub>
|
||||
<Menubar.SubTrigger inset>Velocity units</Menubar.SubTrigger>
|
||||
<Menubar.SubTrigger inset>{$_('menu.velocity_units')}</Menubar.SubTrigger>
|
||||
<Menubar.SubContent>
|
||||
<Menubar.RadioGroup bind:value={$settings.velocityUnits}>
|
||||
<Menubar.RadioItem value="speed">Speed</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="pace">Pace</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="speed">{$_('quantities.speed')}</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="pace">{$_('quantities.pace')}</Menubar.RadioItem>
|
||||
</Menubar.RadioGroup>
|
||||
</Menubar.SubContent>
|
||||
</Menubar.Sub>
|
||||
<Menubar.Sub>
|
||||
<Menubar.SubTrigger inset>Temperature units</Menubar.SubTrigger>
|
||||
<Menubar.SubTrigger inset>{$_('menu.temperature_units')}</Menubar.SubTrigger>
|
||||
<Menubar.SubContent>
|
||||
<Menubar.RadioGroup bind:value={$settings.temperatureUnits}>
|
||||
<Menubar.RadioItem value="celsius">Celsius</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="fahrenheit">Fahrenheit</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="celsius">{$_('menu.celsius')}</Menubar.RadioItem>
|
||||
<Menubar.RadioItem value="fahrenheit">{$_('menu.fahrenheit')}</Menubar.RadioItem>
|
||||
</Menubar.RadioGroup>
|
||||
</Menubar.SubContent>
|
||||
</Menubar.Sub>
|
||||
<Menubar.Separator />
|
||||
<Menubar.CheckboxItem bind:checked={showDistanceMarkers}>
|
||||
Show distance markers
|
||||
{$_('menu.distance_markers')}
|
||||
</Menubar.CheckboxItem>
|
||||
<Menubar.CheckboxItem bind:checked={showDirectionMarkers}>
|
||||
Show direction markers
|
||||
{$_('menu.direction_markers')}
|
||||
</Menubar.CheckboxItem>
|
||||
</Menubar.Content>
|
||||
</Menubar.Menu>
|
||||
</Menubar.Root>
|
||||
<div class="h-fit flex flex-row items-center ml-1 gap-1">
|
||||
<Button variant="ghost" href="/about" target="_blank" class="cursor-default h-fit rounded-sm"
|
||||
>About</Button
|
||||
>{$_('menu.about')}</Button
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
href="https://ko-fi.com/gpxstudio"
|
||||
target="_blank"
|
||||
class="cursor-default h-fit rounded-sm"
|
||||
>Donate <HeartHandshake size="16" class="ml-1" /></Button
|
||||
>{$_('menu.donate')} <HeartHandshake size="16" class="ml-1" /></Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -17,25 +17,26 @@
|
||||
opacities,
|
||||
defaultBasemap
|
||||
} from '$lib/assets/layers';
|
||||
|
||||
import { _ } from 'svelte-i18n';
|
||||
</script>
|
||||
|
||||
<Sheet.Root>
|
||||
<Sheet.Trigger class="w-full">
|
||||
<Button variant="ghost" class="w-full px-1 py-1.5">
|
||||
<Settings size="18" class="mr-2" />
|
||||
Manage layers
|
||||
{$_('layers.manage')}
|
||||
</Button>
|
||||
</Sheet.Trigger>
|
||||
<Sheet.Content>
|
||||
<Sheet.Header class="h-full">
|
||||
<Sheet.Title>Layer settings</Sheet.Title>
|
||||
<Sheet.Title>{$_('layers.settings')}</Sheet.Title>
|
||||
<Sheet.Description>
|
||||
Select the map layers you want to show in the interface, add custom ones, and adjust their
|
||||
settings.
|
||||
{$_('layers.settings_help')}
|
||||
</Sheet.Description>
|
||||
<Accordion.Root class="flex flex-col overflow-hidden">
|
||||
<Accordion.Item value="item-1" class="flex flex-col overflow-hidden">
|
||||
<Accordion.Trigger>Layer selection</Accordion.Trigger>
|
||||
<Accordion.Trigger>{$_('layers.selection')}</Accordion.Trigger>
|
||||
<Accordion.Content class="grow flex flex-col border rounded">
|
||||
<ScrollArea class="py-2 pr-2">
|
||||
<LayerTree
|
||||
@@ -61,17 +62,17 @@
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item value="item-2">
|
||||
<Accordion.Trigger>Custom layers</Accordion.Trigger>
|
||||
<Accordion.Trigger>{$_('layers.custom_layers')}</Accordion.Trigger>
|
||||
<Accordion.Content>
|
||||
<ScrollArea>TODO custom layer list + new custom layer form</ScrollArea>
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item value="item-3">
|
||||
<Accordion.Trigger>Heatmap</Accordion.Trigger>
|
||||
<Accordion.Trigger>{$_('layers.heatmap')}</Accordion.Trigger>
|
||||
<Accordion.Content></Accordion.Content>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item value="item-4">
|
||||
<Accordion.Trigger>Points of interest</Accordion.Trigger>
|
||||
<Accordion.Trigger>{$_('layers.pois')}</Accordion.Trigger>
|
||||
<Accordion.Content></Accordion.Content>
|
||||
</Accordion.Item>
|
||||
</Accordion.Root>
|
||||
|
@@ -8,6 +8,8 @@
|
||||
|
||||
import { type CollapsedInfoTreeType, type LayerTreeType } from '$lib/assets/layers';
|
||||
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
export let name: string;
|
||||
export let node: LayerTreeType;
|
||||
export let multiple: boolean = false;
|
||||
@@ -60,7 +62,7 @@
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<Label for={id}>{id}</Label>
|
||||
<Label for={id}>{$_(`layers.label.${id}`)}</Label>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -73,7 +75,7 @@
|
||||
variant="ghost"
|
||||
class="w-full flex flex-row justify-between py-0 px-1 h-fit hover:bg-background"
|
||||
>
|
||||
<span class="mr-2">{id}</span>
|
||||
<span class="mr-2">{$_(`layers.label.${id}`)}</span>
|
||||
{#if open.children[id].self}
|
||||
<ChevronUp size="16" />
|
||||
{:else}
|
||||
|
@@ -15,6 +15,8 @@
|
||||
FolderTree
|
||||
} from 'lucide-svelte';
|
||||
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
let currentTool: string | null = null;
|
||||
|
||||
function getToggleTool(tool: string) {
|
||||
@@ -33,45 +35,43 @@
|
||||
>
|
||||
<ToolbarItem on:click={getToggleTool('routing')}>
|
||||
<Pencil slot="icon" size="18" />
|
||||
<span slot="tooltip">Edit the track points</span>
|
||||
<span slot="tooltip">{$_('toolbar.routing_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<CalendarClock slot="icon" size="18" />
|
||||
<span slot="tooltip">Change time and speed data</span>
|
||||
<span slot="tooltip">{$_('toolbar.time_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem on:click={reverseSelectedFiles}>
|
||||
<ArrowRightLeft slot="icon" size="18" />
|
||||
<span slot="tooltip">Reverse the file</span>
|
||||
<span slot="tooltip">{$_('toolbar.reverse_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Group slot="icon" size="18" />
|
||||
<span slot="tooltip">Merge with another file</span>
|
||||
<span slot="tooltip">{$_('toolbar.merge_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Ungroup slot="icon" size="18" />
|
||||
<span slot="tooltip">Extract the tracks or track segments to new files</span>
|
||||
<span slot="tooltip">{$_('toolbar.extract_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<MapPin slot="icon" size="18" />
|
||||
<span slot="tooltip">Create a new point of interest</span>
|
||||
<span slot="tooltip">{$_('toolbar.waypoint_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Shrink slot="icon" size="18" />
|
||||
<span slot="tooltip">Reduce the number of track points</span>
|
||||
<span slot="tooltip">{$_('toolbar.reduce_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<SquareDashedMousePointer slot="icon" size="18" />
|
||||
<span slot="tooltip"
|
||||
>Clean track points and points of interest with a rectangle selection</span
|
||||
>
|
||||
<span slot="tooltip">{$_('toolbar.clean_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Palette slot="icon" size="18" />
|
||||
<span slot="tooltip">Change the styling of the trace</span>
|
||||
<span slot="tooltip">{$_('toolbar.style_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<FolderTree slot="icon" size="18" />
|
||||
<span slot="tooltip">Manage the file structure</span>
|
||||
<span slot="tooltip">{$_('toolbar.structure_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
</div>
|
||||
{#if currentTool == 'routing'}
|
||||
|
@@ -1,7 +1,98 @@
|
||||
{
|
||||
"menu": {
|
||||
"file": "File",
|
||||
"new": "New"
|
||||
"new": "New",
|
||||
"load_desktop": "Load from desktop...",
|
||||
"load_drive": "Load from Google Drive...",
|
||||
"duplicate": "Duplicate",
|
||||
"export": "Export...",
|
||||
"export_all": "Export all...",
|
||||
"edit": "Edit",
|
||||
"undo": "Undo",
|
||||
"redo": "Redo",
|
||||
"delete": "Delete",
|
||||
"delete_all": "Delete all",
|
||||
"settings": "Settings",
|
||||
"distance_units": "Distance units",
|
||||
"metric": "Metric",
|
||||
"imperial": "Imperial",
|
||||
"velocity_units": "Velocity units",
|
||||
"temperature_units": "Temperature units",
|
||||
"celsius": "Celsius",
|
||||
"fahrenheit": "Fahrenheit",
|
||||
"distance_markers": "Show distance markers",
|
||||
"direction_markers": "Show direction markers",
|
||||
"about": "About",
|
||||
"donate": "Donate"
|
||||
},
|
||||
"toolbar": {
|
||||
"routing_tooltip": "Edit the route",
|
||||
"time_tooltip": "Change the time and speed data",
|
||||
"reverse_tooltip": "Reverse the direction",
|
||||
"merge_tooltip": "Merge files together",
|
||||
"extract_tooltip": "Extract inner tracks or segments",
|
||||
"waypoint_tooltip": "Create a new point of interest",
|
||||
"reduce_tooltip": "Reduce the number of points",
|
||||
"clean_tooltip": "Clean track points and points of interest with a rectangle selection",
|
||||
"style_tooltip": "Change the style of the route",
|
||||
"structure_tooltip": "Manage the file structure"
|
||||
},
|
||||
"layers": {
|
||||
"manage": "Manage layers",
|
||||
"settings": "Layer settings",
|
||||
"settings_help": "Select the map layers you want to show in the interface, add custom ones, and adjust their settings.",
|
||||
"selection": "Layer selection",
|
||||
"custom_layers": "Custom layers",
|
||||
"heatmap": "Heatmap",
|
||||
"pois": "Points of interest",
|
||||
"label": {
|
||||
"basemaps": "Basemaps",
|
||||
"overlays": "Overlays",
|
||||
"world": "World",
|
||||
"countries": "Countries",
|
||||
"bulgaria": "Bulgaria",
|
||||
"finland": "Finland",
|
||||
"france": "France",
|
||||
"new_zealand": "New Zealand",
|
||||
"norway": "Norway",
|
||||
"spain": "Spain",
|
||||
"sweden": "Sweden",
|
||||
"switzerland": "Switzerland",
|
||||
"united_kingdom": "United Kingdom",
|
||||
"united_states": "United States",
|
||||
"mapboxOutdoors": "Mapbox Outdoors",
|
||||
"mapboxSatellite": "Mapbox Satellite",
|
||||
"openStreetMap": "OpenStreetMap",
|
||||
"openTopoMap": "OpenTopoMap",
|
||||
"openHikingMap": "OpenHikingMap",
|
||||
"cyclOSM": "CyclOSM",
|
||||
"linz": "LINZ Topo",
|
||||
"linzTopo": "LINZ Topo50",
|
||||
"swisstopo": "swisstopo",
|
||||
"ignPlanV2": "IGN Plan",
|
||||
"ignFrScan25": "IGN SCAN25",
|
||||
"ignSatellite": "IGN Satellite",
|
||||
"ignEs": "IGN",
|
||||
"ordnanceSurvey": "Ordnance Survey",
|
||||
"norwayTopo": "Topografisk Norgeskart 4",
|
||||
"swedenTopo": "Lantmäteriet Topo",
|
||||
"finlandTopo": "Lantmäteriverket Terrängkarta",
|
||||
"bgMountains": "BGMountains",
|
||||
"usgs": "USGS",
|
||||
"cyclOSMlite": "CyclOSM Lite",
|
||||
"swisstopoSlope": "swisstopo Slope",
|
||||
"swisstopoCycling": "swisstopo Cycling",
|
||||
"swisstopoMountainBike": "swisstopo MTB",
|
||||
"ignFrCadastre": "IGN Cadastre",
|
||||
"ignSlope": "IGN Slope",
|
||||
"waymarked_trails": "Waymarked Trails",
|
||||
"waymarkedTrailsHiking": "Hiking",
|
||||
"waymarkedTrailsCycling": "Cycling",
|
||||
"waymarkedTrailsMTB": "MTB",
|
||||
"waymarkedTrailsSkating": "Skating",
|
||||
"waymarkedTrailsHorseRiding": "Horse Riding",
|
||||
"waymarkedTrailsWinter": "Winter"
|
||||
}
|
||||
},
|
||||
"quantities": {
|
||||
"distance": "Distance",
|
||||
|
Reference in New Issue
Block a user