mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-10-15 20:08:19 +00:00
Compare commits
34 Commits
drop-to-de
...
preserve-t
Author | SHA1 | Date | |
---|---|---|---|
![]() |
15f7aea300 | ||
![]() |
4ada271ad3 | ||
![]() |
1bda957778 | ||
![]() |
95328db1ee | ||
![]() |
65cbf5e751 | ||
![]() |
60f24f8757 | ||
![]() |
d1e4588813 | ||
![]() |
711825f5a3 | ||
![]() |
d823f44558 | ||
![]() |
193c77e51a | ||
![]() |
45f6c405c0 | ||
![]() |
78e1ea1e59 | ||
![]() |
ca51e1d788 | ||
![]() |
72b0b5a706 | ||
![]() |
4d1de97ba5 | ||
![]() |
04769002d0 | ||
![]() |
8190284148 | ||
![]() |
a668b4be62 | ||
![]() |
87534468d2 | ||
![]() |
d7a02f714a | ||
![]() |
0c16ddd534 | ||
![]() |
a96f989199 | ||
![]() |
35c7c9d965 | ||
![]() |
efa05b93ce | ||
![]() |
0e298cd0e4 | ||
![]() |
3ef98b2110 | ||
![]() |
fbf93ed6f9 | ||
![]() |
1bd56b6505 | ||
![]() |
acf0750ccb | ||
![]() |
48eaa344e4 | ||
![]() |
3262dec7d3 | ||
![]() |
572d206c2c | ||
![]() |
11934e5825 | ||
![]() |
5cca106d18 |
105
gpx/src/gpx.ts
105
gpx/src/gpx.ts
@@ -133,22 +133,21 @@ export class GPXFile extends GPXTreeNode<Track> {
|
|||||||
}
|
}
|
||||||
if (gpx.hasOwnProperty('_data')) {
|
if (gpx.hasOwnProperty('_data')) {
|
||||||
this._data = gpx._data;
|
this._data = gpx._data;
|
||||||
|
}
|
||||||
if (!this._data.hasOwnProperty('style')) {
|
if (!this._data.hasOwnProperty('style')) {
|
||||||
let style = this.getStyle();
|
let style = this.getStyle();
|
||||||
let fileStyle = {};
|
let fileStyle = {};
|
||||||
if (style.color.length === 1) {
|
if (style.color.length === 1) {
|
||||||
fileStyle['color'] = style.color[0];
|
fileStyle['color'] = style.color[0];
|
||||||
}
|
}
|
||||||
if (style.weight.length === 1) {
|
if (style.weight.length === 1) {
|
||||||
fileStyle['weight'] = style.weight[0];
|
fileStyle['weight'] = style.weight[0];
|
||||||
}
|
}
|
||||||
if (style.opacity.length === 1) {
|
if (style.opacity.length === 1) {
|
||||||
fileStyle['opacity'] = style.opacity[0];
|
fileStyle['opacity'] = style.opacity[0];
|
||||||
}
|
}
|
||||||
if (Object.keys(fileStyle).length > 0) {
|
if (Object.keys(fileStyle).length > 0) {
|
||||||
this.setStyle(fileStyle);
|
this.setStyle(fileStyle);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -775,12 +774,16 @@ export class TrackSegment extends GPXTreeLeaf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0 && points[i - 1].extensions && points[i - 1].extensions["gpxtpx:TrackPointExtension"] && points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] && points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface) {
|
if (i > 0 && points[i - 1].extensions && points[i - 1].extensions["gpxtpx:TrackPointExtension"] && points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"]) {
|
||||||
let surface = points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface;
|
Object.entries(points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"]).forEach(([key, value]) => {
|
||||||
if (statistics.global.surface[surface] === undefined) {
|
if (statistics.global.extensions[key] === undefined) {
|
||||||
statistics.global.surface[surface] = 0;
|
statistics.global.extensions[key] = {};
|
||||||
}
|
}
|
||||||
statistics.global.surface[surface] += dist;
|
if (statistics.global.extensions[key][value] === undefined) {
|
||||||
|
statistics.global.extensions[key][value] = 0;
|
||||||
|
}
|
||||||
|
statistics.global.extensions[key][value] += dist;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,7 +893,7 @@ export class TrackSegment extends GPXTreeLeaf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Producers
|
// Producers
|
||||||
replaceTrackPoints(start: number, end: number, points: TrackPoint[], speed?: number, startTime?: Date) {
|
replaceTrackPoints(start: number, end: number, points: TrackPoint[], speed?: number, startTime?: Date, removeGaps?: boolean) {
|
||||||
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
|
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
|
||||||
let trkpt = og.trkpt.slice();
|
let trkpt = og.trkpt.slice();
|
||||||
|
|
||||||
@@ -909,6 +912,21 @@ export class TrackSegment extends GPXTreeLeaf {
|
|||||||
} else if (last !== undefined && points[0].time < last.time) {
|
} else if (last !== undefined && points[0].time < last.time) {
|
||||||
// Adapt timestamps of the new points because they are too early
|
// Adapt timestamps of the new points because they are too early
|
||||||
points = withShiftedAndCompressedTimestamps(points, speed, 1, last);
|
points = withShiftedAndCompressedTimestamps(points, speed, 1, last);
|
||||||
|
} else if (last !== undefined && removeGaps) {
|
||||||
|
// Remove gaps between the new points and the previous point
|
||||||
|
if (last.getLatitude() === points[0].getLatitude() && last.getLongitude() === points[0].getLongitude()) {
|
||||||
|
// Same point, make the new points start at its timestamp and remove the first point
|
||||||
|
if (points[0].time > last.time) {
|
||||||
|
points = withShiftedAndCompressedTimestamps(points, speed, 1, last).slice(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Different points, make the new points start one second after the previous point
|
||||||
|
if (points[0].time.getTime() - last.time.getTime() > 1000) {
|
||||||
|
let artificialLast = points[0].clone();
|
||||||
|
artificialLast.time = new Date(last.time.getTime() + 1000);
|
||||||
|
points = withShiftedAndCompressedTimestamps(points, speed, 1, artificialLast);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (end < trkpt.length - 1) {
|
if (end < trkpt.length - 1) {
|
||||||
@@ -1060,11 +1078,10 @@ export class TrackPoint {
|
|||||||
return this.extensions && this.extensions["gpxpx:PowerExtension"] && this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] ? this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] : undefined;
|
return this.extensions && this.extensions["gpxpx:PowerExtension"] && this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] ? this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSurface(): string {
|
setExtensions(extensions: Record<string, string>) {
|
||||||
return this.extensions && this.extensions["gpxtpx:TrackPointExtension"] && this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] && this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface ? this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface : undefined;
|
if (Object.keys(extensions).length === 0) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
setSurface(surface: string): void {
|
|
||||||
if (!this.extensions) {
|
if (!this.extensions) {
|
||||||
this.extensions = {};
|
this.extensions = {};
|
||||||
}
|
}
|
||||||
@@ -1074,7 +1091,13 @@ 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"]["surface"] = surface;
|
Object.entries(extensions).forEach(([key, value]) => {
|
||||||
|
this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"][key] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getExtensions(): Record<string, string> {
|
||||||
|
return this.extensions && this.extensions["gpxtpx:TrackPointExtension"] && this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] ? this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] : {};
|
||||||
}
|
}
|
||||||
|
|
||||||
toTrackPointType(exclude: string[] = []): TrackPointType {
|
toTrackPointType(exclude: string[] = []): TrackPointType {
|
||||||
@@ -1104,8 +1127,11 @@ export class TrackPoint {
|
|||||||
if (this.extensions["gpxpx:PowerExtension"] && this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] && !exclude.includes('power')) {
|
if (this.extensions["gpxpx:PowerExtension"] && this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] && !exclude.includes('power')) {
|
||||||
trkpt.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] = this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"];
|
trkpt.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"] = this.extensions["gpxpx:PowerExtension"]["gpxpx:PowerInWatts"];
|
||||||
}
|
}
|
||||||
if (this.extensions["gpxtpx:TrackPointExtension"] && this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] && this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface && !exclude.includes('surface')) {
|
if (this.extensions["gpxtpx:TrackPointExtension"] && this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] && !exclude.includes('extensions')) {
|
||||||
trkpt.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] = { surface: this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface };
|
trkpt.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] = {};
|
||||||
|
Object.entries(this.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"]).forEach(([key, value]) => {
|
||||||
|
trkpt.extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"][key] = value;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return trkpt;
|
return trkpt;
|
||||||
@@ -1255,7 +1281,7 @@ export class GPXStatistics {
|
|||||||
avg: number,
|
avg: number,
|
||||||
count: number,
|
count: number,
|
||||||
},
|
},
|
||||||
surface: Record<string, number>,
|
extensions: Record<string, Record<string, number>>,
|
||||||
};
|
};
|
||||||
local: {
|
local: {
|
||||||
points: TrackPoint[],
|
points: TrackPoint[],
|
||||||
@@ -1326,7 +1352,7 @@ export class GPXStatistics {
|
|||||||
avg: 0,
|
avg: 0,
|
||||||
count: 0,
|
count: 0,
|
||||||
},
|
},
|
||||||
surface: {},
|
extensions: {},
|
||||||
};
|
};
|
||||||
this.local = {
|
this.local = {
|
||||||
points: [],
|
points: [],
|
||||||
@@ -1396,11 +1422,16 @@ export class GPXStatistics {
|
|||||||
this.global.cad.count += other.global.cad.count;
|
this.global.cad.count += other.global.cad.count;
|
||||||
this.global.power.avg = (this.global.power.count * this.global.power.avg + other.global.power.count * other.global.power.avg) / Math.max(1, this.global.power.count + other.global.power.count);
|
this.global.power.avg = (this.global.power.count * this.global.power.avg + other.global.power.count * other.global.power.avg) / Math.max(1, this.global.power.count + other.global.power.count);
|
||||||
this.global.power.count += other.global.power.count;
|
this.global.power.count += other.global.power.count;
|
||||||
Object.keys(other.global.surface).forEach((surface) => {
|
Object.keys(other.global.extensions).forEach((extension) => {
|
||||||
if (this.global.surface[surface] === undefined) {
|
if (this.global.extensions[extension] === undefined) {
|
||||||
this.global.surface[surface] = 0;
|
this.global.extensions[extension] = {};
|
||||||
}
|
}
|
||||||
this.global.surface[surface] += other.global.surface[surface];
|
Object.keys(other.global.extensions[extension]).forEach((value) => {
|
||||||
|
if (this.global.extensions[extension][value] === undefined) {
|
||||||
|
this.global.extensions[extension][value] = 0;
|
||||||
|
}
|
||||||
|
this.global.extensions[extension][value] += other.global.extensions[extension][value];
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -92,9 +92,7 @@ export type TrackPointExtension = {
|
|||||||
'gpxtpx:atemp'?: number;
|
'gpxtpx:atemp'?: number;
|
||||||
'gpxtpx:hr'?: number;
|
'gpxtpx:hr'?: number;
|
||||||
'gpxtpx:cad'?: number;
|
'gpxtpx:cad'?: number;
|
||||||
'gpxtpx:Extensions'?: {
|
'gpxtpx:Extensions'?: Record<string, string>;
|
||||||
surface?: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PowerExtension = {
|
export type PowerExtension = {
|
||||||
|
@@ -45,24 +45,9 @@ export async function handle({ event, resolve }) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stringsHTML = page === 'app' ? stringsToHTML(strings) : '';
|
|
||||||
|
|
||||||
const response = await resolve(event, {
|
const response = await resolve(event, {
|
||||||
transformPageChunk: ({ html }) => html.replace('<html>', htmlTag).replace('<head>', headTag).replace('</body>', `<div class="fixed -z-10 text-transparent">${stringsHTML}</div></body>`)
|
transformPageChunk: ({ html }) => html.replace('<html>', htmlTag).replace('<head>', headTag),
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
|
||||||
|
|
||||||
function stringsToHTML(dictionary, strings = new Set(), root = true) {
|
|
||||||
Object.values(dictionary).forEach((value) => {
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
stringsToHTML(value, strings, false);
|
|
||||||
} else {
|
|
||||||
strings.add(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (root) {
|
|
||||||
return Array.from(strings).map((string) => `<p>${string}</p>`).join('');
|
|
||||||
}
|
|
||||||
}
|
}
|
161
website/src/lib/assets/colors.ts
Normal file
161
website/src/lib/assets/colors.ts
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
export const surfaceColors: { [key: string]: string } = {
|
||||||
|
"missing": "#d1d1d1",
|
||||||
|
"paved": "#8c8c8c",
|
||||||
|
"unpaved": "#6b443a",
|
||||||
|
"asphalt": "#8c8c8c",
|
||||||
|
"concrete": "#8c8c8c",
|
||||||
|
"cobblestone": "#ffd991",
|
||||||
|
"paving_stones": "#8c8c8c",
|
||||||
|
"sett": "#ffd991",
|
||||||
|
"metal": "#8c8c8c",
|
||||||
|
"wood": "#6b443a",
|
||||||
|
"compacted": "#ffffa8",
|
||||||
|
"fine_gravel": "#ffffa8",
|
||||||
|
"gravel": "#ffffa8",
|
||||||
|
"pebblestone": "#ffffa8",
|
||||||
|
"rock": "#ffd991",
|
||||||
|
"dirt": "#ffffa8",
|
||||||
|
"ground": "#6b443a",
|
||||||
|
"earth": "#6b443a",
|
||||||
|
"mud": "#6b443a",
|
||||||
|
"sand": "#ffffc4",
|
||||||
|
"grass": "#61b55c",
|
||||||
|
"grass_paver": "#61b55c",
|
||||||
|
"clay": "#6b443a",
|
||||||
|
"stone": "#ffd991",
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getSurfaceColor(surface: string): string {
|
||||||
|
return surfaceColors[surface] ? surfaceColors[surface] : surfaceColors.missing;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const highwayColors: { [key: string]: string } = {
|
||||||
|
"missing": "#d1d1d1",
|
||||||
|
"motorway": "#ff4d33",
|
||||||
|
"motorway_link": "#ff4d33",
|
||||||
|
"trunk": "#ff5e4d",
|
||||||
|
"trunk_link": "#ff947f",
|
||||||
|
"primary": "#ff6e5c",
|
||||||
|
"primary_link": "#ff6e5c",
|
||||||
|
"secondary": "#ff8d7b",
|
||||||
|
"secondary_link": "#ff8d7b",
|
||||||
|
"tertiary": "#ffd75f",
|
||||||
|
"tertiary_link": "#ffd75f",
|
||||||
|
"unclassified": "#f1f2a5",
|
||||||
|
"road": "#f1f2a5",
|
||||||
|
"residential": "#73b2ff",
|
||||||
|
"living_street": "#73b2ff",
|
||||||
|
"service": "#9c9cd9",
|
||||||
|
"track": "#a8e381",
|
||||||
|
"footway": "#a8e381",
|
||||||
|
"path": "#a8e381",
|
||||||
|
"pedestrian": "#a8e381",
|
||||||
|
"cycleway": "#9de2ff",
|
||||||
|
"construction": "#e09a4a",
|
||||||
|
"bridleway": "#946f43",
|
||||||
|
"raceway": "#ff0000",
|
||||||
|
"rest_area": "#9c9cd9",
|
||||||
|
"services": "#9c9cd9",
|
||||||
|
"corridor": "#474747",
|
||||||
|
"elevator": "#474747",
|
||||||
|
"steps": "#474747",
|
||||||
|
"bus_stop": "#8545a3",
|
||||||
|
"busway": "#8545a3",
|
||||||
|
"via_ferrata": "#474747"
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sacScaleColors: { [key: string]: string } = {
|
||||||
|
"hiking": "#007700",
|
||||||
|
"mountain_hiking": "#1843ad",
|
||||||
|
"demanding_mountain_hiking": "#ffff00",
|
||||||
|
"alpine_hiking": "#ff9233",
|
||||||
|
"demanding_alpine_hiking": "#ff0000",
|
||||||
|
"difficult_alpine_hiking": "#000000",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mtbScaleColors: { [key: string]: string } = {
|
||||||
|
"0-": "#007700",
|
||||||
|
"0": "#007700",
|
||||||
|
"0+": "#007700",
|
||||||
|
"1-": "#1843ad",
|
||||||
|
"1": "#1843ad",
|
||||||
|
"1+": "#1843ad",
|
||||||
|
"2-": "#ffff00",
|
||||||
|
"2": "#ffff00",
|
||||||
|
"2+": "#ffff00",
|
||||||
|
"3": "#ff0000",
|
||||||
|
"4": "#00ff00",
|
||||||
|
"5": "#000000",
|
||||||
|
"6": "#b105eb",
|
||||||
|
};
|
||||||
|
|
||||||
|
function createPattern(backgroundColor: string, sacScaleColor: string | undefined, mtbScaleColor: string | undefined, size: number = 16, lineWidth: number = 4) {
|
||||||
|
let canvas = document.createElement('canvas');
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
if (ctx) {
|
||||||
|
ctx.fillStyle = backgroundColor;
|
||||||
|
ctx.fillRect(0, 0, size, size);
|
||||||
|
ctx.lineWidth = lineWidth;
|
||||||
|
|
||||||
|
const halfSize = size / 2;
|
||||||
|
const halfLineWidth = lineWidth / 2;
|
||||||
|
if (sacScaleColor) {
|
||||||
|
ctx.strokeStyle = sacScaleColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(halfSize - halfLineWidth, - halfLineWidth);
|
||||||
|
ctx.lineTo(size + halfLineWidth, halfSize + halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(- halfLineWidth, halfSize - halfLineWidth);
|
||||||
|
ctx.lineTo(halfSize + halfLineWidth, size + halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
if (mtbScaleColor) {
|
||||||
|
ctx.strokeStyle = mtbScaleColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(halfSize - halfLineWidth, size + halfLineWidth);
|
||||||
|
ctx.lineTo(size + halfLineWidth, halfSize - halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(- halfLineWidth, halfSize + halfLineWidth);
|
||||||
|
ctx.lineTo(halfSize + halfLineWidth, - halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx?.createPattern(canvas, 'repeat') || backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const patterns: Record<string, string | CanvasPattern> = {};
|
||||||
|
export function getHighwayColor(highway: string, sacScale: string | undefined, mtbScale: string | undefined) {
|
||||||
|
let backgroundColor = highwayColors[highway] ? highwayColors[highway] : highwayColors.missing;
|
||||||
|
let sacScaleColor = sacScale ? sacScaleColors[sacScale] : undefined;
|
||||||
|
let mtbScaleColor = mtbScale ? mtbScaleColors[mtbScale] : undefined;
|
||||||
|
if (sacScale || mtbScale) {
|
||||||
|
let patternId = `${backgroundColor}-${[sacScale, mtbScale].filter(x => x).join('-')}`;
|
||||||
|
if (!patterns[patternId]) {
|
||||||
|
patterns[patternId] = createPattern(backgroundColor, sacScaleColor, mtbScaleColor);
|
||||||
|
}
|
||||||
|
return patterns[patternId];
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxSlope = 20;
|
||||||
|
export function getSlopeColor(slope: number): string {
|
||||||
|
if (slope > maxSlope) {
|
||||||
|
slope = maxSlope;
|
||||||
|
} else if (slope < -maxSlope) {
|
||||||
|
slope = -maxSlope;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = slope / maxSlope;
|
||||||
|
v = 1 / (1 + Math.exp(-6 * v));
|
||||||
|
v = v - 0.5;
|
||||||
|
|
||||||
|
let hue = ((0.5 - v) * 120).toString(10);
|
||||||
|
let lightness = 90 - Math.abs(v) * 70;
|
||||||
|
|
||||||
|
return `hsl(${hue},70%,${lightness}%)`;
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.0 MiB |
@@ -1,11 +1,11 @@
|
|||||||
import { TramFront, Utensils, ShoppingBasket, Droplet, ShowerHead, Fuel, CircleParking, Fence, FerrisWheel, Bed, Mountain, Pickaxe, Store, TrainFront, Bus, Ship, Croissant, House, Tent, Wrench, Binoculars } from 'lucide-static';
|
import { TramFront, Utensils, ShoppingBasket, Droplet, ShowerHead, Fuel, CircleParking, Fence, FerrisWheel, Bed, Mountain, Pickaxe, Store, TrainFront, Bus, Ship, Croissant, House, Tent, Wrench, Binoculars } from 'lucide-static';
|
||||||
import { type Style } from 'mapbox-gl';
|
import { type StyleSpecification } from 'mapbox-gl';
|
||||||
import ignFrTopo from './custom/ign-fr-topo.json';
|
import ignFrTopo from './custom/ign-fr-topo.json';
|
||||||
import ignFrPlan from './custom/ign-fr-plan.json';
|
import ignFrPlan from './custom/ign-fr-plan.json';
|
||||||
import ignFrSatellite from './custom/ign-fr-satellite.json';
|
import ignFrSatellite from './custom/ign-fr-satellite.json';
|
||||||
import bikerouterGravel from './custom/bikerouter-gravel.json';
|
import bikerouterGravel from './custom/bikerouter-gravel.json';
|
||||||
|
|
||||||
export const basemaps: { [key: string]: string | Style; } = {
|
export const basemaps: { [key: string]: string | StyleSpecification; } = {
|
||||||
mapboxOutdoors: 'mapbox://styles/mapbox/outdoors-v12',
|
mapboxOutdoors: 'mapbox://styles/mapbox/outdoors-v12',
|
||||||
mapboxSatellite: 'mapbox://styles/mapbox/satellite-streets-v12',
|
mapboxSatellite: 'mapbox://styles/mapbox/satellite-streets-v12',
|
||||||
openStreetMap: {
|
openStreetMap: {
|
||||||
@@ -158,7 +158,7 @@ export const basemaps: { [key: string]: string | Style; } = {
|
|||||||
tiles: ['https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix={z}&TileCol={x}&TileRow={y}'],
|
tiles: ['https://www.ign.es/wmts/mapa-raster?layer=MTN&style=default&tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix={z}&TileCol={x}&TileRow={y}'],
|
||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
maxzoom: 20,
|
maxzoom: 20,
|
||||||
attribution: 'IGN-F/Géoportail'
|
attribution: '© <a href="https://www.ign.es" target="_blank">IGN</a>'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
layers: [{
|
layers: [{
|
||||||
@@ -167,6 +167,23 @@ export const basemaps: { [key: string]: string | Style; } = {
|
|||||||
source: 'ignEs',
|
source: 'ignEs',
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
ignEsSatellite: {
|
||||||
|
version: 8,
|
||||||
|
sources: {
|
||||||
|
ignEsSatellite: {
|
||||||
|
type: 'raster',
|
||||||
|
tiles: ['https://www.ign.es/wmts/pnoa-ma?layer=OI.OrthoimageCoverage&style=default&tilematrixset=GoogleMapsCompatible&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix={z}&TileCol={x}&TileRow={y}'],
|
||||||
|
tileSize: 256,
|
||||||
|
maxzoom: 20,
|
||||||
|
attribution: '© <a href="https://www.ign.es" target="_blank">IGN</a>'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layers: [{
|
||||||
|
id: 'ignEsSatellite',
|
||||||
|
type: 'raster',
|
||||||
|
source: 'ignEsSatellite',
|
||||||
|
}],
|
||||||
|
},
|
||||||
ordnanceSurvey: "https://api.os.uk/maps/vector/v1/vts/resources/styles?srs=3857&key=piCT8WysfuC3xLSUW7sGLfrAAJoYDvQz",
|
ordnanceSurvey: "https://api.os.uk/maps/vector/v1/vts/resources/styles?srs=3857&key=piCT8WysfuC3xLSUW7sGLfrAAJoYDvQz",
|
||||||
norwayTopo: {
|
norwayTopo: {
|
||||||
version: 8,
|
version: 8,
|
||||||
@@ -286,7 +303,7 @@ export const basemaps: { [key: string]: string | Style; } = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const overlays: { [key: string]: string | Style; } = {
|
export const overlays: { [key: string]: string | StyleSpecification; } = {
|
||||||
cyclOSMlite: {
|
cyclOSMlite: {
|
||||||
version: 8,
|
version: 8,
|
||||||
sources: {
|
sources: {
|
||||||
@@ -636,6 +653,7 @@ export const basemapTree: LayerTreeType = {
|
|||||||
},
|
},
|
||||||
spain: {
|
spain: {
|
||||||
ignEs: true,
|
ignEs: true,
|
||||||
|
ignEsSatellite: true,
|
||||||
},
|
},
|
||||||
sweden: {
|
sweden: {
|
||||||
swedenTopo: true,
|
swedenTopo: true,
|
||||||
@@ -740,7 +758,7 @@ export const overpassTree: LayerTreeType = {
|
|||||||
export const defaultBasemap = 'mapboxOutdoors';
|
export const defaultBasemap = 'mapboxOutdoors';
|
||||||
|
|
||||||
// Default overlays used (none)
|
// Default overlays used (none)
|
||||||
export const defaultOverlays = {
|
export const defaultOverlays: LayerTreeType = {
|
||||||
overlays: {
|
overlays: {
|
||||||
world: {
|
world: {
|
||||||
waymarked_trails: {
|
waymarked_trails: {
|
||||||
@@ -855,6 +873,7 @@ export const defaultBasemapTree: LayerTreeType = {
|
|||||||
},
|
},
|
||||||
spain: {
|
spain: {
|
||||||
ignEs: false,
|
ignEs: false,
|
||||||
|
ignEsSatellite: false,
|
||||||
},
|
},
|
||||||
sweden: {
|
sweden: {
|
||||||
swedenTopo: false,
|
swedenTopo: false,
|
||||||
|
@@ -1,31 +0,0 @@
|
|||||||
export const surfaceColors: { [key: string]: string } = {
|
|
||||||
'missing': '#d1d1d1',
|
|
||||||
'paved': '#8c8c8c',
|
|
||||||
'unpaved': '#6b443a',
|
|
||||||
'asphalt': '#8c8c8c',
|
|
||||||
'concrete': '#8c8c8c',
|
|
||||||
'chipseal': '#8c8c8c',
|
|
||||||
'cobblestone': '#ffd991',
|
|
||||||
'unhewn_cobblestone': '#ffd991',
|
|
||||||
'paving_stones': '#8c8c8c',
|
|
||||||
'stepping_stones': '#c7b2db',
|
|
||||||
'sett': '#ffd991',
|
|
||||||
'metal': '#8c8c8c',
|
|
||||||
'wood': '#6b443a',
|
|
||||||
'compacted': '#ffffa8',
|
|
||||||
'fine_gravel': '#ffffa8',
|
|
||||||
'gravel': '#ffffa8',
|
|
||||||
'pebblestone': '#ffffa8',
|
|
||||||
'rock': '#ffd991',
|
|
||||||
'dirt': '#ffffa8',
|
|
||||||
'ground': '#6b443a',
|
|
||||||
'earth': '#6b443a',
|
|
||||||
'snow': '#bdfffc',
|
|
||||||
'ice': '#bdfffc',
|
|
||||||
'salt': '#b6c0f2',
|
|
||||||
'mud': '#6b443a',
|
|
||||||
'sand': '#ffffc4',
|
|
||||||
'woodchips': '#6b443a',
|
|
||||||
'grass': '#61b55c',
|
|
||||||
'grass_paver': '#61b55c'
|
|
||||||
}
|
|
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from '$lib/components/ui/button/index.js';
|
import { Button } from '$lib/components/ui/button/index.js';
|
||||||
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
||||||
|
import type { Builder } from 'bits-ui';
|
||||||
|
|
||||||
export let variant:
|
export let variant:
|
||||||
| 'default'
|
| 'default'
|
||||||
@@ -12,11 +13,12 @@
|
|||||||
| undefined = 'default';
|
| undefined = 'default';
|
||||||
export let label: string;
|
export let label: string;
|
||||||
export let side: 'top' | 'right' | 'bottom' | 'left' = 'top';
|
export let side: 'top' | 'right' | 'bottom' | 'left' = 'top';
|
||||||
|
export let builders: Builder[] = [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Tooltip.Root>
|
<Tooltip.Root>
|
||||||
<Tooltip.Trigger asChild let:builder>
|
<Tooltip.Trigger asChild let:builder>
|
||||||
<Button builders={[builder]} {variant} {...$$restProps}>
|
<Button builders={[...builders, builder]} {variant} {...$$restProps} on:click>
|
||||||
<slot />
|
<slot />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip.Trigger>
|
</Tooltip.Trigger>
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
|
||||||
|
import * as Popover from '$lib/components/ui/popover';
|
||||||
import * as ToggleGroup from '$lib/components/ui/toggle-group';
|
import * as ToggleGroup from '$lib/components/ui/toggle-group';
|
||||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
|
||||||
import Chart from 'chart.js/auto';
|
import Chart from 'chart.js/auto';
|
||||||
import mapboxgl from 'mapbox-gl';
|
import mapboxgl from 'mapbox-gl';
|
||||||
import { map } from '$lib/stores';
|
import { map } from '$lib/stores';
|
||||||
@@ -12,12 +13,15 @@
|
|||||||
Orbit,
|
Orbit,
|
||||||
SquareActivity,
|
SquareActivity,
|
||||||
Thermometer,
|
Thermometer,
|
||||||
Zap
|
Zap,
|
||||||
|
Circle,
|
||||||
|
Check,
|
||||||
|
ChartNoAxesColumn,
|
||||||
|
Construction
|
||||||
} from 'lucide-svelte';
|
} from 'lucide-svelte';
|
||||||
import { surfaceColors } from '$lib/assets/surfaces';
|
import { getSlopeColor, getSurfaceColor, getHighwayColor } from '$lib/assets/colors';
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import {
|
import {
|
||||||
getCadenceUnits,
|
|
||||||
getCadenceWithUnits,
|
getCadenceWithUnits,
|
||||||
getConvertedDistance,
|
getConvertedDistance,
|
||||||
getConvertedElevation,
|
getConvertedElevation,
|
||||||
@@ -26,45 +30,26 @@
|
|||||||
getDistanceUnits,
|
getDistanceUnits,
|
||||||
getDistanceWithUnits,
|
getDistanceWithUnits,
|
||||||
getElevationWithUnits,
|
getElevationWithUnits,
|
||||||
getHeartRateUnits,
|
|
||||||
getHeartRateWithUnits,
|
getHeartRateWithUnits,
|
||||||
getPowerUnits,
|
|
||||||
getPowerWithUnits,
|
getPowerWithUnits,
|
||||||
getTemperatureUnits,
|
|
||||||
getTemperatureWithUnits,
|
getTemperatureWithUnits,
|
||||||
getVelocityUnits,
|
getVelocityWithUnits
|
||||||
getVelocityWithUnits,
|
|
||||||
secondsToHHMMSS
|
|
||||||
} from '$lib/units';
|
} from '$lib/units';
|
||||||
import type { Writable } from 'svelte/store';
|
import type { Writable } from 'svelte/store';
|
||||||
import { DateFormatter } from '@internationalized/date';
|
|
||||||
import type { GPXStatistics } from 'gpx';
|
import type { GPXStatistics } from 'gpx';
|
||||||
import { settings } from '$lib/db';
|
import { settings } from '$lib/db';
|
||||||
import { mode } from 'mode-watcher';
|
import { mode } from 'mode-watcher';
|
||||||
|
import { df } from '$lib/utils';
|
||||||
|
|
||||||
export let gpxStatistics: Writable<GPXStatistics>;
|
export let gpxStatistics: Writable<GPXStatistics>;
|
||||||
export let slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined>;
|
export let slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined>;
|
||||||
export let panelSize: number;
|
|
||||||
export let additionalDatasets: string[];
|
export let additionalDatasets: string[];
|
||||||
export let elevationFill: 'slope' | 'surface' | undefined;
|
export let elevationFill: 'slope' | 'surface' | 'highway' | undefined;
|
||||||
export let showControls: boolean = true;
|
export let showControls: boolean = true;
|
||||||
|
|
||||||
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
|
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
|
||||||
|
|
||||||
let df: DateFormatter;
|
|
||||||
|
|
||||||
$: if ($locale) {
|
|
||||||
df = new DateFormatter($locale, {
|
|
||||||
dateStyle: 'medium',
|
|
||||||
timeStyle: 'medium'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let canvas: HTMLCanvasElement;
|
let canvas: HTMLCanvasElement;
|
||||||
let showAdditionalScales = true;
|
|
||||||
let updateShowAdditionalScales = () => {
|
|
||||||
showAdditionalScales = canvas.width / window.devicePixelRatio >= 600;
|
|
||||||
};
|
|
||||||
let overlay: HTMLCanvasElement;
|
let overlay: HTMLCanvasElement;
|
||||||
let chart: Chart;
|
let chart: Chart;
|
||||||
|
|
||||||
@@ -83,12 +68,11 @@
|
|||||||
x: {
|
x: {
|
||||||
type: 'linear',
|
type: 'linear',
|
||||||
ticks: {
|
ticks: {
|
||||||
callback: function (value: number, index: number, ticks: { value: number }[]) {
|
callback: function (value: number) {
|
||||||
if (index === ticks.length - 1) {
|
|
||||||
return `${value.toFixed(1).replace(/\.0+$/, '')}`;
|
|
||||||
}
|
|
||||||
return `${value.toFixed(1).replace(/\.0+$/, '')} ${getDistanceUnits()}`;
|
return `${value.toFixed(1).replace(/\.0+$/, '')} ${getDistanceUnits()}`;
|
||||||
}
|
},
|
||||||
|
align: 'inner',
|
||||||
|
maxRotation: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
y: {
|
y: {
|
||||||
@@ -159,7 +143,10 @@
|
|||||||
segment: point.slope.segment.toFixed(1),
|
segment: point.slope.segment.toFixed(1),
|
||||||
length: getDistanceWithUnits(point.slope.length)
|
length: getDistanceWithUnits(point.slope.length)
|
||||||
};
|
};
|
||||||
let surface = point.surface ? point.surface : 'unknown';
|
let surface = point.extensions.surface ? point.extensions.surface : 'unknown';
|
||||||
|
let highway = point.extensions.highway ? point.extensions.highway : 'unknown';
|
||||||
|
let sacScale = point.extensions.sac_scale;
|
||||||
|
let mtbScale = point.extensions.mtb_scale;
|
||||||
|
|
||||||
let labels = [
|
let labels = [
|
||||||
` ${$_('quantities.distance')}: ${getDistanceWithUnits(point.x, false)}`,
|
` ${$_('quantities.distance')}: ${getDistanceWithUnits(point.x, false)}`,
|
||||||
@@ -172,6 +159,17 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elevationFill === 'highway') {
|
||||||
|
labels.push(
|
||||||
|
` ${$_('quantities.highway')}: ${$_(`toolbar.routing.highway.${highway}`)}${
|
||||||
|
sacScale ? ` (${$_(`toolbar.routing.sac_scale.${sacScale}`)})` : ''
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
if (mtbScale) {
|
||||||
|
labels.push(` ${$_('toolbar.routing.mtb_scale')}: ${mtbScale}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (point.time) {
|
if (point.time) {
|
||||||
labels.push(` ${$_('quantities.time')}: ${df.format(point.time)}`);
|
labels.push(` ${$_('quantities.time')}: ${df.format(point.time)}`);
|
||||||
}
|
}
|
||||||
@@ -226,72 +224,21 @@
|
|||||||
stacked: false,
|
stacked: false,
|
||||||
onResize: function () {
|
onResize: function () {
|
||||||
updateOverlay();
|
updateOverlay();
|
||||||
updateShowAdditionalScales();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let datasets: {
|
let datasets: string[] = ['speed', 'hr', 'cad', 'atemp', 'power'];
|
||||||
[key: string]: {
|
datasets.forEach((id) => {
|
||||||
id: string;
|
|
||||||
getLabel: () => string;
|
|
||||||
getUnits: () => string;
|
|
||||||
};
|
|
||||||
} = {
|
|
||||||
speed: {
|
|
||||||
id: 'speed',
|
|
||||||
getLabel: () => ($velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')),
|
|
||||||
getUnits: () => getVelocityUnits()
|
|
||||||
},
|
|
||||||
hr: {
|
|
||||||
id: 'hr',
|
|
||||||
getLabel: () => $_('quantities.heartrate'),
|
|
||||||
getUnits: () => getHeartRateUnits()
|
|
||||||
},
|
|
||||||
cad: {
|
|
||||||
id: 'cad',
|
|
||||||
getLabel: () => $_('quantities.cadence'),
|
|
||||||
getUnits: () => getCadenceUnits()
|
|
||||||
},
|
|
||||||
atemp: {
|
|
||||||
id: 'atemp',
|
|
||||||
getLabel: () => $_('quantities.temperature'),
|
|
||||||
getUnits: () => getTemperatureUnits()
|
|
||||||
},
|
|
||||||
power: {
|
|
||||||
id: 'power',
|
|
||||||
getLabel: () => $_('quantities.power'),
|
|
||||||
getUnits: () => getPowerUnits()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let [id, dataset] of Object.entries(datasets)) {
|
|
||||||
options.scales[`y${id}`] = {
|
options.scales[`y${id}`] = {
|
||||||
type: 'linear',
|
type: 'linear',
|
||||||
position: 'right',
|
position: 'right',
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: dataset.getLabel() + ' (' + dataset.getUnits() + ')',
|
|
||||||
padding: {
|
|
||||||
top: 6,
|
|
||||||
bottom: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
grid: {
|
||||||
display: false
|
display: false
|
||||||
},
|
},
|
||||||
reverse: () => id === 'speed' && $velocityUnits === 'pace',
|
reverse: () => id === 'speed' && $velocityUnits === 'pace',
|
||||||
display: false
|
display: false
|
||||||
};
|
};
|
||||||
}
|
});
|
||||||
options.scales.yspeed['ticks'] = {
|
|
||||||
callback: function (value: number) {
|
|
||||||
if ($velocityUnits === 'speed') {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
return secondsToHHMMSS(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
Chart.register((await import('chartjs-plugin-zoom')).default); // dynamic import to avoid SSR and 'window is not defined' error
|
Chart.register((await import('chartjs-plugin-zoom')).default); // dynamic import to avoid SSR and 'window is not defined' error
|
||||||
@@ -324,8 +271,6 @@
|
|||||||
element
|
element
|
||||||
});
|
});
|
||||||
|
|
||||||
updateShowAdditionalScales();
|
|
||||||
|
|
||||||
let startIndex = 0;
|
let startIndex = 0;
|
||||||
let endIndex = 0;
|
let endIndex = 0;
|
||||||
function getIndex(evt) {
|
function getIndex(evt) {
|
||||||
@@ -414,7 +359,7 @@
|
|||||||
segment: data.local.slope.segment[index],
|
segment: data.local.slope.segment[index],
|
||||||
length: data.local.slope.length[index]
|
length: data.local.slope.length[index]
|
||||||
},
|
},
|
||||||
surface: point.getSurface(),
|
extensions: point.getExtensions(),
|
||||||
coordinates: point.getCoordinates(),
|
coordinates: point.getCoordinates(),
|
||||||
index: index
|
index: index
|
||||||
};
|
};
|
||||||
@@ -424,7 +369,6 @@
|
|||||||
order: 1
|
order: 1
|
||||||
};
|
};
|
||||||
chart.data.datasets[1] = {
|
chart.data.datasets[1] = {
|
||||||
label: datasets.speed.getLabel(),
|
|
||||||
data: data.local.points.map((point, index) => {
|
data: data.local.points.map((point, index) => {
|
||||||
return {
|
return {
|
||||||
x: getConvertedDistance(data.local.distance.total[index]),
|
x: getConvertedDistance(data.local.distance.total[index]),
|
||||||
@@ -433,11 +377,10 @@
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
normalized: true,
|
normalized: true,
|
||||||
yAxisID: `y${datasets.speed.id}`,
|
yAxisID: 'yspeed',
|
||||||
hidden: true
|
hidden: true
|
||||||
};
|
};
|
||||||
chart.data.datasets[2] = {
|
chart.data.datasets[2] = {
|
||||||
label: datasets.hr.getLabel(),
|
|
||||||
data: data.local.points.map((point, index) => {
|
data: data.local.points.map((point, index) => {
|
||||||
return {
|
return {
|
||||||
x: getConvertedDistance(data.local.distance.total[index]),
|
x: getConvertedDistance(data.local.distance.total[index]),
|
||||||
@@ -446,11 +389,10 @@
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
normalized: true,
|
normalized: true,
|
||||||
yAxisID: `y${datasets.hr.id}`,
|
yAxisID: 'yhr',
|
||||||
hidden: true
|
hidden: true
|
||||||
};
|
};
|
||||||
chart.data.datasets[3] = {
|
chart.data.datasets[3] = {
|
||||||
label: datasets.cad.getLabel(),
|
|
||||||
data: data.local.points.map((point, index) => {
|
data: data.local.points.map((point, index) => {
|
||||||
return {
|
return {
|
||||||
x: getConvertedDistance(data.local.distance.total[index]),
|
x: getConvertedDistance(data.local.distance.total[index]),
|
||||||
@@ -459,11 +401,10 @@
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
normalized: true,
|
normalized: true,
|
||||||
yAxisID: `y${datasets.cad.id}`,
|
yAxisID: 'ycad',
|
||||||
hidden: true
|
hidden: true
|
||||||
};
|
};
|
||||||
chart.data.datasets[4] = {
|
chart.data.datasets[4] = {
|
||||||
label: datasets.atemp.getLabel(),
|
|
||||||
data: data.local.points.map((point, index) => {
|
data: data.local.points.map((point, index) => {
|
||||||
return {
|
return {
|
||||||
x: getConvertedDistance(data.local.distance.total[index]),
|
x: getConvertedDistance(data.local.distance.total[index]),
|
||||||
@@ -472,11 +413,10 @@
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
normalized: true,
|
normalized: true,
|
||||||
yAxisID: `y${datasets.atemp.id}`,
|
yAxisID: 'yatemp',
|
||||||
hidden: true
|
hidden: true
|
||||||
};
|
};
|
||||||
chart.data.datasets[5] = {
|
chart.data.datasets[5] = {
|
||||||
label: datasets.power.getLabel(),
|
|
||||||
data: data.local.points.map((point, index) => {
|
data: data.local.points.map((point, index) => {
|
||||||
return {
|
return {
|
||||||
x: getConvertedDistance(data.local.distance.total[index]),
|
x: getConvertedDistance(data.local.distance.total[index]),
|
||||||
@@ -485,43 +425,29 @@
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
normalized: true,
|
normalized: true,
|
||||||
yAxisID: `y${datasets.power.id}`,
|
yAxisID: 'ypower',
|
||||||
hidden: true
|
hidden: true
|
||||||
};
|
};
|
||||||
chart.options.scales.x['min'] = 0;
|
chart.options.scales.x['min'] = 0;
|
||||||
chart.options.scales.x['max'] = getConvertedDistance(data.global.distance.total);
|
chart.options.scales.x['max'] = getConvertedDistance(data.global.distance.total);
|
||||||
|
|
||||||
// update units
|
|
||||||
for (let [id, dataset] of Object.entries(datasets)) {
|
|
||||||
chart.options.scales[`y${id}`].title.text =
|
|
||||||
dataset.getLabel() + ' (' + dataset.getUnits() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
chart.update();
|
chart.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxSlope = 20;
|
|
||||||
function slopeFillCallback(context) {
|
function slopeFillCallback(context) {
|
||||||
let slope = context.p0.raw.slope.segment;
|
return getSlopeColor(context.p0.raw.slope.segment);
|
||||||
if (slope > maxSlope) {
|
|
||||||
slope = maxSlope;
|
|
||||||
} else if (slope < -maxSlope) {
|
|
||||||
slope = -maxSlope;
|
|
||||||
}
|
|
||||||
|
|
||||||
let v = slope / maxSlope;
|
|
||||||
v = 1 / (1 + Math.exp(-6 * v));
|
|
||||||
v = v - 0.5;
|
|
||||||
|
|
||||||
let hue = ((0.5 - v) * 120).toString(10);
|
|
||||||
let lightness = 90 - Math.abs(v) * 70;
|
|
||||||
|
|
||||||
return ['hsl(', hue, ',70%,', lightness, '%)'].join('');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function surfaceFillCallback(context) {
|
function surfaceFillCallback(context) {
|
||||||
let surface = context.p0.raw.surface;
|
return getSurfaceColor(context.p0.raw.extensions.surface);
|
||||||
return surfaceColors[surface] ? surfaceColors[surface] : surfaceColors.missing;
|
}
|
||||||
|
|
||||||
|
function highwayFillCallback(context) {
|
||||||
|
return getHighwayColor(
|
||||||
|
context.p0.raw.extensions.highway,
|
||||||
|
context.p0.raw.extensions.sac_scale,
|
||||||
|
context.p0.raw.extensions.mtb_scale
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (chart) {
|
$: if (chart) {
|
||||||
@@ -533,6 +459,10 @@
|
|||||||
chart.data.datasets[0]['segment'] = {
|
chart.data.datasets[0]['segment'] = {
|
||||||
backgroundColor: surfaceFillCallback
|
backgroundColor: surfaceFillCallback
|
||||||
};
|
};
|
||||||
|
} else if (elevationFill === 'highway') {
|
||||||
|
chart.data.datasets[0]['segment'] = {
|
||||||
|
backgroundColor: highwayFillCallback
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
chart.data.datasets[0]['segment'] = {};
|
chart.data.datasets[0]['segment'] = {};
|
||||||
}
|
}
|
||||||
@@ -552,12 +482,6 @@
|
|||||||
chart.data.datasets[4].hidden = !includeTemperature;
|
chart.data.datasets[4].hidden = !includeTemperature;
|
||||||
chart.data.datasets[5].hidden = !includePower;
|
chart.data.datasets[5].hidden = !includePower;
|
||||||
}
|
}
|
||||||
chart.options.scales[`y${datasets.speed.id}`].display = includeSpeed && showAdditionalScales;
|
|
||||||
chart.options.scales[`y${datasets.hr.id}`].display = includeHeartRate && showAdditionalScales;
|
|
||||||
chart.options.scales[`y${datasets.cad.id}`].display = includeCadence && showAdditionalScales;
|
|
||||||
chart.options.scales[`y${datasets.atemp.id}`].display =
|
|
||||||
includeTemperature && showAdditionalScales;
|
|
||||||
chart.options.scales[`y${datasets.power.id}`].display = includePower && showAdditionalScales;
|
|
||||||
chart.update();
|
chart.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,6 +492,8 @@
|
|||||||
|
|
||||||
overlay.width = canvas.width / window.devicePixelRatio;
|
overlay.width = canvas.width / window.devicePixelRatio;
|
||||||
overlay.height = canvas.height / window.devicePixelRatio;
|
overlay.height = canvas.height / window.devicePixelRatio;
|
||||||
|
overlay.style.width = `${overlay.width}px`;
|
||||||
|
overlay.style.height = `${overlay.height}px`;
|
||||||
|
|
||||||
if ($slicedGPXStatistics) {
|
if ($slicedGPXStatistics) {
|
||||||
let startIndex = $slicedGPXStatistics[1];
|
let startIndex = $slicedGPXStatistics[1];
|
||||||
@@ -591,7 +517,7 @@
|
|||||||
startPixel,
|
startPixel,
|
||||||
chart.chartArea.top,
|
chart.chartArea.top,
|
||||||
endPixel - startPixel,
|
endPixel - startPixel,
|
||||||
chart.chartArea.bottom - chart.chartArea.top
|
chart.chartArea.height
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (overlay) {
|
} else if (overlay) {
|
||||||
@@ -611,75 +537,135 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="h-full grow min-w-0 flex flex-row gap-4 items-center {$$props.class ?? ''}">
|
<div class="h-full grow min-w-0 relative py-2">
|
||||||
<div class="grow h-full min-w-0 relative">
|
<canvas bind:this={overlay} class="w-full h-full absolute pointer-events-none"></canvas>
|
||||||
<canvas bind:this={overlay} class=" w-full h-full absolute pointer-events-none"></canvas>
|
<canvas bind:this={canvas} class="w-full h-full absolute"></canvas>
|
||||||
<canvas bind:this={canvas} class="w-full h-full"></canvas>
|
|
||||||
</div>
|
|
||||||
{#if showControls}
|
{#if showControls}
|
||||||
<div class="h-full flex flex-col justify-center" style="width: {panelSize > 158 ? 22 : 42}px">
|
<div class="absolute bottom-10 right-1.5">
|
||||||
<ToggleGroup.Root
|
<Popover.Root>
|
||||||
class="{panelSize > 158
|
<Popover.Trigger asChild let:builder>
|
||||||
? 'flex-col'
|
<ButtonWithTooltip
|
||||||
: 'flex-row'} flex-wrap gap-0 min-h-0 content-center border rounded-t-md"
|
label={$_('chart.settings')}
|
||||||
type="single"
|
builders={[builder]}
|
||||||
bind:value={elevationFill}
|
variant="outline"
|
||||||
>
|
class="w-7 h-7 p-0 flex justify-center opacity-70 hover:opacity-100 transition-opacity duration-300 hover:bg-background"
|
||||||
<ToggleGroup.Item class="p-0 w-5 h-5" value="slope" aria-label={$_('chart.show_slope')}>
|
|
||||||
<Tooltip side="left" label={$_('chart.show_slope')}>
|
|
||||||
<TriangleRight size="15" />
|
|
||||||
</Tooltip>
|
|
||||||
</ToggleGroup.Item>
|
|
||||||
<ToggleGroup.Item class="p-0 w-5 h-5" value="surface" aria-label={$_('chart.show_surface')}>
|
|
||||||
<Tooltip side="left" label={$_('chart.show_surface')}>
|
|
||||||
<BrickWall size="15" />
|
|
||||||
</Tooltip>
|
|
||||||
</ToggleGroup.Item>
|
|
||||||
</ToggleGroup.Root>
|
|
||||||
<ToggleGroup.Root
|
|
||||||
class="{panelSize > 158
|
|
||||||
? 'flex-col'
|
|
||||||
: 'flex-row'} flex-wrap gap-0 min-h-0 content-center border rounded-b-md -mt-[1px]"
|
|
||||||
type="multiple"
|
|
||||||
bind:value={additionalDatasets}
|
|
||||||
>
|
|
||||||
<ToggleGroup.Item
|
|
||||||
class="p-0 w-5 h-5"
|
|
||||||
value="speed"
|
|
||||||
aria-label={$velocityUnits === 'speed' ? $_('chart.show_speed') : $_('chart.show_pace')}
|
|
||||||
>
|
|
||||||
<Tooltip
|
|
||||||
side="left"
|
|
||||||
label={$velocityUnits === 'speed' ? $_('chart.show_speed') : $_('chart.show_pace')}
|
|
||||||
>
|
>
|
||||||
<Zap size="15" />
|
<ChartNoAxesColumn size="18" />
|
||||||
</Tooltip>
|
</ButtonWithTooltip>
|
||||||
</ToggleGroup.Item>
|
</Popover.Trigger>
|
||||||
<ToggleGroup.Item class="p-0 w-5 h-5" value="hr" aria-label={$_('chart.show_heartrate')}>
|
<Popover.Content class="w-fit p-0 flex flex-col divide-y" side="top" sideOffset={-32}>
|
||||||
<Tooltip side="left" label={$_('chart.show_heartrate')}>
|
<ToggleGroup.Root
|
||||||
<HeartPulse size="15" />
|
class="flex flex-col items-start gap-0 p-1"
|
||||||
</Tooltip>
|
type="single"
|
||||||
</ToggleGroup.Item>
|
bind:value={elevationFill}
|
||||||
<ToggleGroup.Item class="p-0 w-5 h-5" value="cad" aria-label={$_('chart.show_cadence')}>
|
>
|
||||||
<Tooltip side="left" label={$_('chart.show_cadence')}>
|
<ToggleGroup.Item
|
||||||
<Orbit size="15" />
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
</Tooltip>
|
value="slope"
|
||||||
</ToggleGroup.Item>
|
>
|
||||||
<ToggleGroup.Item
|
<div class="w-6 flex justify-center items-center">
|
||||||
class="p-0 w-5 h-5"
|
{#if elevationFill === 'slope'}
|
||||||
value="atemp"
|
<Circle class="h-1.5 w-1.5 fill-current text-current" />
|
||||||
aria-label={$_('chart.show_temperature')}
|
{/if}
|
||||||
>
|
</div>
|
||||||
<Tooltip side="left" label={$_('chart.show_temperature')}>
|
<TriangleRight size="15" class="mr-1" />
|
||||||
<Thermometer size="15" />
|
{$_('quantities.slope')}
|
||||||
</Tooltip>
|
</ToggleGroup.Item>
|
||||||
</ToggleGroup.Item>
|
<ToggleGroup.Item
|
||||||
<ToggleGroup.Item class="p-0 w-5 h-5" value="power" aria-label={$_('chart.show_power')}>
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
<Tooltip side="left" label={$_('chart.show_power')}>
|
value="surface"
|
||||||
<SquareActivity size="15" />
|
variant="outline"
|
||||||
</Tooltip>
|
>
|
||||||
</ToggleGroup.Item>
|
<div class="w-6 flex justify-center items-center">
|
||||||
</ToggleGroup.Root>
|
{#if elevationFill === 'surface'}
|
||||||
|
<Circle class="h-1.5 w-1.5 fill-current text-current" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<BrickWall size="15" class="mr-1" />
|
||||||
|
{$_('quantities.surface')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
<ToggleGroup.Item
|
||||||
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
|
value="highway"
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<div class="w-6 flex justify-center items-center">
|
||||||
|
{#if elevationFill === 'highway'}
|
||||||
|
<Circle class="h-1.5 w-1.5 fill-current text-current" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<Construction size="15" class="mr-1" />
|
||||||
|
{$_('quantities.highway')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
</ToggleGroup.Root>
|
||||||
|
<ToggleGroup.Root
|
||||||
|
class="flex flex-col items-start gap-0 p-1"
|
||||||
|
type="multiple"
|
||||||
|
bind:value={additionalDatasets}
|
||||||
|
>
|
||||||
|
<ToggleGroup.Item
|
||||||
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
|
value="speed"
|
||||||
|
>
|
||||||
|
<div class="w-6 flex justify-center items-center">
|
||||||
|
{#if additionalDatasets.includes('speed')}
|
||||||
|
<Check size="14" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<Zap size="15" class="mr-1" />
|
||||||
|
{$velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
<ToggleGroup.Item
|
||||||
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
|
value="hr"
|
||||||
|
>
|
||||||
|
<div class="w-6 flex justify-center items-center">
|
||||||
|
{#if additionalDatasets.includes('hr')}
|
||||||
|
<Check size="14" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<HeartPulse size="15" class="mr-1" />
|
||||||
|
{$_('quantities.heartrate')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
<ToggleGroup.Item
|
||||||
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
|
value="cad"
|
||||||
|
>
|
||||||
|
<div class="w-6 flex justify-center items-center">
|
||||||
|
{#if additionalDatasets.includes('cad')}
|
||||||
|
<Check size="14" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<Orbit size="15" class="mr-1" />
|
||||||
|
{$_('quantities.cadence')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
<ToggleGroup.Item
|
||||||
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
|
value="atemp"
|
||||||
|
>
|
||||||
|
<div class="w-6 flex justify-center items-center">
|
||||||
|
{#if additionalDatasets.includes('atemp')}
|
||||||
|
<Check size="14" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<Thermometer size="15" class="mr-1" />
|
||||||
|
{$_('quantities.temperature')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
<ToggleGroup.Item
|
||||||
|
class="p-0 pr-1.5 h-6 w-full rounded flex justify-start data-[state=on]:bg-background data-[state=on]:hover:bg-accent hover:bg-accent hover:text-foreground"
|
||||||
|
value="power"
|
||||||
|
>
|
||||||
|
<div class="w-6 flex justify-center items-center">
|
||||||
|
{#if additionalDatasets.includes('power')}
|
||||||
|
<Check size="14" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<SquareActivity size="15" class="mr-1" />
|
||||||
|
{$_('quantities.power')}
|
||||||
|
</ToggleGroup.Item>
|
||||||
|
</ToggleGroup.Root>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
import {
|
import {
|
||||||
Download,
|
Download,
|
||||||
Zap,
|
Zap,
|
||||||
BrickWall,
|
Earth,
|
||||||
HeartPulse,
|
HeartPulse,
|
||||||
Orbit,
|
Orbit,
|
||||||
Thermometer,
|
Thermometer,
|
||||||
@@ -31,19 +31,19 @@
|
|||||||
let open = false;
|
let open = false;
|
||||||
let exportOptions: Record<string, boolean> = {
|
let exportOptions: Record<string, boolean> = {
|
||||||
time: true,
|
time: true,
|
||||||
surface: true,
|
|
||||||
hr: true,
|
hr: true,
|
||||||
cad: true,
|
cad: true,
|
||||||
atemp: true,
|
atemp: true,
|
||||||
power: true
|
power: true,
|
||||||
|
extensions: true
|
||||||
};
|
};
|
||||||
let hide: Record<string, boolean> = {
|
let hide: Record<string, boolean> = {
|
||||||
time: false,
|
time: false,
|
||||||
surface: false,
|
|
||||||
hr: false,
|
hr: false,
|
||||||
cad: false,
|
cad: false,
|
||||||
atemp: false,
|
atemp: false,
|
||||||
power: false
|
power: false,
|
||||||
|
extensions: false
|
||||||
};
|
};
|
||||||
|
|
||||||
$: if ($exportState !== ExportState.NONE) {
|
$: if ($exportState !== ExportState.NONE) {
|
||||||
@@ -63,11 +63,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
hide.time = statistics.global.time.total === 0;
|
hide.time = statistics.global.time.total === 0;
|
||||||
hide.surface = !Object.keys(statistics.global.surface).some((key) => key !== 'unknown');
|
|
||||||
hide.hr = statistics.global.hr.count === 0;
|
hide.hr = statistics.global.hr.count === 0;
|
||||||
hide.cad = statistics.global.cad.count === 0;
|
hide.cad = statistics.global.cad.count === 0;
|
||||||
hide.atemp = statistics.global.atemp.count === 0;
|
hide.atemp = statistics.global.atemp.count === 0;
|
||||||
hide.power = statistics.global.power.count === 0;
|
hide.power = statistics.global.power.count === 0;
|
||||||
|
hide.extensions = Object.keys(statistics.global.extensions).length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$: exclude = Object.keys(exportOptions).filter((key) => !exportOptions[key]);
|
$: exclude = Object.keys(exportOptions).filter((key) => !exportOptions[key]);
|
||||||
@@ -144,11 +144,11 @@
|
|||||||
{$_('quantities.time')}
|
{$_('quantities.time')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-1.5 {hide.surface ? 'hidden' : ''}">
|
<div class="flex flex-row items-center gap-1.5 {hide.extensions ? 'hidden' : ''}">
|
||||||
<Checkbox id="export-surface" bind:checked={exportOptions.surface} />
|
<Checkbox id="export-extensions" bind:checked={exportOptions.extensions} />
|
||||||
<Label for="export-surface" class="flex flex-row items-center gap-1">
|
<Label for="export-extensions" class="flex flex-row items-center gap-1">
|
||||||
<BrickWall size="16" />
|
<Earth size="16" />
|
||||||
{$_('quantities.surface')}
|
{$_('quantities.osm_extensions')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-1.5 {hide.hr ? 'hidden' : ''}">
|
<div class="flex flex-row items-center gap-1.5 {hide.hr ? 'hidden' : ''}">
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<Card.Root
|
<Card.Root
|
||||||
class="h-full {orientation === 'vertical'
|
class="h-full {orientation === 'vertical'
|
||||||
? 'min-w-44 sm:min-w-52 text-sm sm:text-base'
|
? 'min-w-40 sm:min-w-44 text-sm sm:text-base'
|
||||||
: 'w-full'} border-none shadow-none"
|
: 'w-full'} border-none shadow-none"
|
||||||
>
|
>
|
||||||
<Card.Content
|
<Card.Content
|
||||||
@@ -38,15 +38,15 @@
|
|||||||
>
|
>
|
||||||
<Tooltip label={$_('quantities.distance')}>
|
<Tooltip label={$_('quantities.distance')}>
|
||||||
<span class="flex flex-row items-center">
|
<span class="flex flex-row items-center">
|
||||||
<Ruler size="18" class="mr-1" />
|
<Ruler size="16" class="mr-1" />
|
||||||
<WithUnits value={statistics.global.distance.total} type="distance" />
|
<WithUnits value={statistics.global.distance.total} type="distance" />
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label={$_('quantities.elevation_gain_loss')}>
|
<Tooltip label={$_('quantities.elevation_gain_loss')}>
|
||||||
<span class="flex flex-row items-center">
|
<span class="flex flex-row items-center">
|
||||||
<MoveUpRight size="18" class="mr-1" />
|
<MoveUpRight size="16" class="mr-1" />
|
||||||
<WithUnits value={statistics.global.elevation.gain} type="elevation" />
|
<WithUnits value={statistics.global.elevation.gain} type="elevation" />
|
||||||
<MoveDownRight size="18" class="mx-1" />
|
<MoveDownRight size="16" class="mx-1" />
|
||||||
<WithUnits value={statistics.global.elevation.loss} type="elevation" />
|
<WithUnits value={statistics.global.elevation.loss} type="elevation" />
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
)} / {$_('quantities.total')})"
|
)} / {$_('quantities.total')})"
|
||||||
>
|
>
|
||||||
<span class="flex flex-row items-center">
|
<span class="flex flex-row items-center">
|
||||||
<Zap size="18" class="mr-1" />
|
<Zap size="16" class="mr-1" />
|
||||||
<WithUnits value={statistics.global.speed.moving} type="speed" showUnits={false} />
|
<WithUnits value={statistics.global.speed.moving} type="speed" showUnits={false} />
|
||||||
<span class="mx-1">/</span>
|
<span class="mx-1">/</span>
|
||||||
<WithUnits value={statistics.global.speed.total} type="speed" />
|
<WithUnits value={statistics.global.speed.total} type="speed" />
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
label="{$_('quantities.time')} ({$_('quantities.moving')} / {$_('quantities.total')})"
|
label="{$_('quantities.time')} ({$_('quantities.moving')} / {$_('quantities.total')})"
|
||||||
>
|
>
|
||||||
<span class="flex flex-row items-center">
|
<span class="flex flex-row items-center">
|
||||||
<Timer size="18" class="mr-1" />
|
<Timer size="16" class="mr-1" />
|
||||||
<WithUnits value={statistics.global.time.moving} type="time" />
|
<WithUnits value={statistics.global.time.moving} type="time" />
|
||||||
<span class="mx-1">/</span>
|
<span class="mx-1">/</span>
|
||||||
<WithUnits value={statistics.global.time.total} type="time" />
|
<WithUnits value={statistics.global.time.total} type="time" />
|
||||||
|
@@ -50,6 +50,20 @@
|
|||||||
language = 'en';
|
language = 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadJson = mapboxgl.Style.prototype._load;
|
||||||
|
mapboxgl.Style.prototype._load = function (json, validate) {
|
||||||
|
if (
|
||||||
|
json['sources'] &&
|
||||||
|
json['sources']['mapbox-satellite'] &&
|
||||||
|
json['sources']['mapbox-satellite']['data'] &&
|
||||||
|
json['sources']['mapbox-satellite']['data']['data']
|
||||||
|
) {
|
||||||
|
// Temporary fix for https://github.com/gpxstudio/gpx.studio/issues/129
|
||||||
|
delete json['sources']['mapbox-satellite']['data']['data'];
|
||||||
|
}
|
||||||
|
loadJson.call(this, json, validate);
|
||||||
|
};
|
||||||
|
|
||||||
let newMap = new mapboxgl.Map({
|
let newMap = new mapboxgl.Map({
|
||||||
container: 'map',
|
container: 'map',
|
||||||
style: {
|
style: {
|
||||||
@@ -334,7 +348,7 @@
|
|||||||
|
|
||||||
div :global(.mapboxgl-popup) {
|
div :global(.mapboxgl-popup) {
|
||||||
@apply w-fit;
|
@apply w-fit;
|
||||||
@apply z-20;
|
@apply z-50;
|
||||||
}
|
}
|
||||||
|
|
||||||
div :global(.mapboxgl-popup-content) {
|
div :global(.mapboxgl-popup-content) {
|
||||||
|
25
website/src/lib/components/MapPopup.svelte
Normal file
25
website/src/lib/components/MapPopup.svelte
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svelte:options accessors />
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { TrackPoint, Waypoint } from 'gpx';
|
||||||
|
import type { Writable } from 'svelte/store';
|
||||||
|
import WaypointPopup from '$lib/components/gpx-layer/WaypointPopup.svelte';
|
||||||
|
import TrackpointPopup from '$lib/components/gpx-layer/TrackpointPopup.svelte';
|
||||||
|
import OverpassPopup from '$lib/components/layer-control/OverpassPopup.svelte';
|
||||||
|
import type { PopupItem } from './MapPopup';
|
||||||
|
|
||||||
|
export let item: Writable<PopupItem | null>;
|
||||||
|
export let container: HTMLDivElement | null = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={container}>
|
||||||
|
{#if $item}
|
||||||
|
{#if $item.item instanceof Waypoint}
|
||||||
|
<WaypointPopup waypoint={$item} />
|
||||||
|
{:else if $item.item instanceof TrackPoint}
|
||||||
|
<TrackpointPopup trackpoint={$item} />
|
||||||
|
{:else}
|
||||||
|
<OverpassPopup poi={$item} />
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</div>
|
78
website/src/lib/components/MapPopup.ts
Normal file
78
website/src/lib/components/MapPopup.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { TrackPoint, Waypoint } from "gpx";
|
||||||
|
import mapboxgl from "mapbox-gl";
|
||||||
|
import { tick } from "svelte";
|
||||||
|
import { get, writable, type Writable } from "svelte/store";
|
||||||
|
import MapPopupComponent from "./MapPopup.svelte";
|
||||||
|
|
||||||
|
export type PopupItem<T = Waypoint | TrackPoint | any> = {
|
||||||
|
item: T;
|
||||||
|
fileId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class MapPopup {
|
||||||
|
map: mapboxgl.Map;
|
||||||
|
popup: mapboxgl.Popup;
|
||||||
|
item: Writable<PopupItem | null> = writable(null);
|
||||||
|
maybeHideBinded = this.maybeHide.bind(this);
|
||||||
|
|
||||||
|
constructor(map: mapboxgl.Map, options?: mapboxgl.PopupOptions) {
|
||||||
|
this.map = map;
|
||||||
|
this.popup = new mapboxgl.Popup(options);
|
||||||
|
|
||||||
|
let component = new MapPopupComponent({
|
||||||
|
target: document.body,
|
||||||
|
props: {
|
||||||
|
item: this.item
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tick().then(() => this.popup.setDOMContent(component.container));
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(item: PopupItem | null) {
|
||||||
|
this.item.set(item);
|
||||||
|
if (item === null) {
|
||||||
|
this.hide();
|
||||||
|
} else {
|
||||||
|
tick().then(() => this.show());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
const i = get(this.item);
|
||||||
|
if (i === null) {
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.popup.setLngLat(this.getCoordinates()).addTo(this.map);
|
||||||
|
this.map.on('mousemove', this.maybeHideBinded);
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeHide(e: mapboxgl.MapMouseEvent) {
|
||||||
|
const i = get(this.item);
|
||||||
|
if (i === null) {
|
||||||
|
this.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.map.project(this.getCoordinates()).dist(this.map.project(e.lngLat)) > 60) {
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.popup.remove();
|
||||||
|
this.map.off('mousemove', this.maybeHideBinded);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
this.popup.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
getCoordinates() {
|
||||||
|
const i = get(this.item);
|
||||||
|
if (i === null) {
|
||||||
|
return new mapboxgl.LngLat(0, 0);
|
||||||
|
}
|
||||||
|
return (i.item instanceof Waypoint || i.item instanceof TrackPoint) ? i.item.getCoordinates() : new mapboxgl.LngLat(i.item.lon, i.item.lat);
|
||||||
|
}
|
||||||
|
}
|
@@ -260,9 +260,7 @@
|
|||||||
options.elevation.power ? 'power' : null
|
options.elevation.power ? 'power' : null
|
||||||
].filter((dataset) => dataset !== null)}
|
].filter((dataset) => dataset !== null)}
|
||||||
elevationFill={options.elevation.fill}
|
elevationFill={options.elevation.fill}
|
||||||
panelSize={options.elevation.height}
|
|
||||||
showControls={options.elevation.controls}
|
showControls={options.elevation.controls}
|
||||||
class="py-2"
|
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,7 +10,7 @@ export type EmbeddingOptions = {
|
|||||||
show: boolean;
|
show: boolean;
|
||||||
height: number;
|
height: number;
|
||||||
controls: boolean;
|
controls: boolean;
|
||||||
fill: 'slope' | 'surface' | undefined;
|
fill: 'slope' | 'surface' | 'highway' | undefined;
|
||||||
speed: boolean;
|
speed: boolean;
|
||||||
hr: boolean;
|
hr: boolean;
|
||||||
cad: boolean;
|
cad: boolean;
|
||||||
|
@@ -142,7 +142,7 @@
|
|||||||
let value = selected?.value;
|
let value = selected?.value;
|
||||||
if (value === 'none') {
|
if (value === 'none') {
|
||||||
options.elevation.fill = undefined;
|
options.elevation.fill = undefined;
|
||||||
} else if (value === 'slope' || value === 'surface') {
|
} else if (value === 'slope' || value === 'surface' || value === 'highway') {
|
||||||
options.elevation.fill = value;
|
options.elevation.fill = value;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@@ -153,6 +153,7 @@
|
|||||||
<Select.Content>
|
<Select.Content>
|
||||||
<Select.Item value="slope">{$_('quantities.slope')}</Select.Item>
|
<Select.Item value="slope">{$_('quantities.slope')}</Select.Item>
|
||||||
<Select.Item value="surface">{$_('quantities.surface')}</Select.Item>
|
<Select.Item value="surface">{$_('quantities.surface')}</Select.Item>
|
||||||
|
<Select.Item value="highway">{$_('quantities.highway')}</Select.Item>
|
||||||
<Select.Item value="none">{$_('embedding.none')}</Select.Item>
|
<Select.Item value="none">{$_('embedding.none')}</Select.Item>
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select.Root>
|
</Select.Root>
|
||||||
@@ -165,35 +166,35 @@
|
|||||||
<Checkbox id="show-speed" bind:checked={options.elevation.speed} />
|
<Checkbox id="show-speed" bind:checked={options.elevation.speed} />
|
||||||
<Label for="show-speed" class="flex flex-row items-center gap-1">
|
<Label for="show-speed" class="flex flex-row items-center gap-1">
|
||||||
<Zap size="16" />
|
<Zap size="16" />
|
||||||
{$_('chart.show_speed')}
|
{$_('quantities.speed')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-2">
|
<div class="flex flex-row items-center gap-2">
|
||||||
<Checkbox id="show-hr" bind:checked={options.elevation.hr} />
|
<Checkbox id="show-hr" bind:checked={options.elevation.hr} />
|
||||||
<Label for="show-hr" class="flex flex-row items-center gap-1">
|
<Label for="show-hr" class="flex flex-row items-center gap-1">
|
||||||
<HeartPulse size="16" />
|
<HeartPulse size="16" />
|
||||||
{$_('chart.show_heartrate')}
|
{$_('quantities.heartrate')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-2">
|
<div class="flex flex-row items-center gap-2">
|
||||||
<Checkbox id="show-cad" bind:checked={options.elevation.cad} />
|
<Checkbox id="show-cad" bind:checked={options.elevation.cad} />
|
||||||
<Label for="show-cad" class="flex flex-row items-center gap-1">
|
<Label for="show-cad" class="flex flex-row items-center gap-1">
|
||||||
<Orbit size="16" />
|
<Orbit size="16" />
|
||||||
{$_('chart.show_cadence')}
|
{$_('quantities.cadence')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-2">
|
<div class="flex flex-row items-center gap-2">
|
||||||
<Checkbox id="show-temp" bind:checked={options.elevation.temp} />
|
<Checkbox id="show-temp" bind:checked={options.elevation.temp} />
|
||||||
<Label for="show-temp" class="flex flex-row items-center gap-1">
|
<Label for="show-temp" class="flex flex-row items-center gap-1">
|
||||||
<Thermometer size="16" />
|
<Thermometer size="16" />
|
||||||
{$_('chart.show_temperature')}
|
{$_('quantities.temperature')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-2">
|
<div class="flex flex-row items-center gap-2">
|
||||||
<Checkbox id="show-power" bind:checked={options.elevation.power} />
|
<Checkbox id="show-power" bind:checked={options.elevation.power} />
|
||||||
<Label for="show-power" class="flex flex-row items-center gap-1">
|
<Label for="show-power" class="flex flex-row items-center gap-1">
|
||||||
<SquareActivity size="16" />
|
<SquareActivity size="16" />
|
||||||
{$_('chart.show_power')}
|
{$_('quantities.power')}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -49,17 +49,11 @@
|
|||||||
gpxLayers,
|
gpxLayers,
|
||||||
map
|
map
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import {
|
import { GPXTreeElement, Track, type AnyGPXTreeElement, Waypoint, GPXFile } from 'gpx';
|
||||||
GPXTreeElement,
|
|
||||||
Track,
|
|
||||||
TrackSegment,
|
|
||||||
type AnyGPXTreeElement,
|
|
||||||
Waypoint,
|
|
||||||
GPXFile
|
|
||||||
} from 'gpx';
|
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import MetadataDialog from './MetadataDialog.svelte';
|
import MetadataDialog from './MetadataDialog.svelte';
|
||||||
import StyleDialog from './StyleDialog.svelte';
|
import StyleDialog from './StyleDialog.svelte';
|
||||||
|
import { waypointPopup } from '$lib/components/gpx-layer/GPXLayerPopup';
|
||||||
|
|
||||||
export let node: GPXTreeElement<AnyGPXTreeElement> | Waypoint[] | Waypoint;
|
export let node: GPXTreeElement<AnyGPXTreeElement> | Waypoint[] | Waypoint;
|
||||||
export let item: ListItem;
|
export let item: ListItem;
|
||||||
@@ -179,7 +173,7 @@
|
|||||||
if (layer && file) {
|
if (layer && file) {
|
||||||
let waypoint = file.wpt[item.getWaypointIndex()];
|
let waypoint = file.wpt[item.getWaypointIndex()];
|
||||||
if (waypoint) {
|
if (waypoint) {
|
||||||
layer.showWaypointPopup(waypoint);
|
waypointPopup?.setItem({ item: waypoint, fileId: item.getFileId() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +182,7 @@
|
|||||||
if (item instanceof ListWaypointItem) {
|
if (item instanceof ListWaypointItem) {
|
||||||
let layer = gpxLayers.get(item.getFileId());
|
let layer = gpxLayers.get(item.getFileId());
|
||||||
if (layer) {
|
if (layer) {
|
||||||
layer.hideWaypointPopup();
|
waypointPopup?.setItem(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@@ -5,6 +5,8 @@ import { get } from "svelte/store";
|
|||||||
|
|
||||||
const { distanceMarkers, distanceUnits } = settings;
|
const { distanceMarkers, distanceUnits } = settings;
|
||||||
|
|
||||||
|
const stops = [[100, 0], [50, 7], [25, 8, 10], [10, 10], [5, 11], [1, 13]];
|
||||||
|
|
||||||
export class DistanceMarkers {
|
export class DistanceMarkers {
|
||||||
map: mapboxgl.Map;
|
map: mapboxgl.Map;
|
||||||
updateBinded: () => void = this.update.bind(this);
|
updateBinded: () => void = this.update.bind(this);
|
||||||
@@ -31,30 +33,36 @@ export class DistanceMarkers {
|
|||||||
data: this.getDistanceMarkersGeoJSON()
|
data: this.getDistanceMarkersGeoJSON()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!this.map.getLayer('distance-markers')) {
|
stops.forEach(([d, minzoom, maxzoom]) => {
|
||||||
this.map.addLayer({
|
if (!this.map.getLayer(`distance-markers-${d}`)) {
|
||||||
id: 'distance-markers',
|
this.map.addLayer({
|
||||||
type: 'symbol',
|
id: `distance-markers-${d}`,
|
||||||
source: 'distance-markers',
|
type: 'symbol',
|
||||||
layout: {
|
source: 'distance-markers',
|
||||||
'text-field': ['get', 'distance'],
|
filter: d === 5 ? ['any', ['==', ['get', 'level'], 5], ['==', ['get', 'level'], 25]] : ['==', ['get', 'level'], d],
|
||||||
'text-size': 14,
|
minzoom: minzoom,
|
||||||
'text-font': ['Open Sans Bold'],
|
maxzoom: maxzoom ?? 24,
|
||||||
'text-padding': 20,
|
layout: {
|
||||||
},
|
'text-field': ['get', 'distance'],
|
||||||
paint: {
|
'text-size': 14,
|
||||||
'text-color': 'black',
|
'text-font': ['Open Sans Bold'],
|
||||||
'text-halo-width': 2,
|
},
|
||||||
'text-halo-color': 'white',
|
paint: {
|
||||||
}
|
'text-color': 'black',
|
||||||
});
|
'text-halo-width': 2,
|
||||||
} else {
|
'text-halo-color': 'white',
|
||||||
this.map.moveLayer('distance-markers');
|
}
|
||||||
}
|
});
|
||||||
|
} else {
|
||||||
|
this.map.moveLayer(`distance-markers-${d}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.map.getLayer('distance-markers')) {
|
stops.forEach(([d]) => {
|
||||||
this.map.removeLayer('distance-markers');
|
if (this.map.getLayer(`distance-markers-${d}`)) {
|
||||||
}
|
this.map.removeLayer(`distance-markers-${d}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) { // No reliable way to check if the map is ready to add sources and layers
|
} catch (e) { // No reliable way to check if the map is ready to add sources and layers
|
||||||
return;
|
return;
|
||||||
@@ -73,6 +81,7 @@ export class DistanceMarkers {
|
|||||||
for (let i = 0; i < statistics.local.distance.total.length; i++) {
|
for (let i = 0; i < statistics.local.distance.total.length; i++) {
|
||||||
if (statistics.local.distance.total[i] >= currentTargetDistance * (get(distanceUnits) === 'metric' ? 1 : 1.60934)) {
|
if (statistics.local.distance.total[i] >= currentTargetDistance * (get(distanceUnits) === 'metric' ? 1 : 1.60934)) {
|
||||||
let distance = currentTargetDistance.toFixed(0);
|
let distance = currentTargetDistance.toFixed(0);
|
||||||
|
let [level, minzoom] = stops.find(([d]) => currentTargetDistance % d === 0) ?? [0, 0];
|
||||||
features.push({
|
features.push({
|
||||||
type: 'Feature',
|
type: 'Feature',
|
||||||
geometry: {
|
geometry: {
|
||||||
@@ -81,6 +90,8 @@ export class DistanceMarkers {
|
|||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
distance,
|
distance,
|
||||||
|
level,
|
||||||
|
minzoom,
|
||||||
}
|
}
|
||||||
} as GeoJSON.Feature);
|
} as GeoJSON.Feature);
|
||||||
currentTargetDistance += 1;
|
currentTargetDistance += 1;
|
||||||
|
@@ -2,11 +2,10 @@ import { currentTool, map, Tool } from "$lib/stores";
|
|||||||
import { settings, type GPXFileWithStatistics, dbUtils } from "$lib/db";
|
import { settings, type GPXFileWithStatistics, dbUtils } from "$lib/db";
|
||||||
import { get, type Readable } from "svelte/store";
|
import { get, type Readable } from "svelte/store";
|
||||||
import mapboxgl from "mapbox-gl";
|
import mapboxgl from "mapbox-gl";
|
||||||
import { currentPopupWaypoint, deleteWaypoint, waypointPopup } from "./WaypointPopup";
|
import { waypointPopup, deleteWaypoint, trackpointPopup } from "./GPXLayerPopup";
|
||||||
import { addSelectItem, selectItem, selection } from "$lib/components/file-list/Selection";
|
import { addSelectItem, selectItem, selection } from "$lib/components/file-list/Selection";
|
||||||
import { ListTrackSegmentItem, ListWaypointItem, ListWaypointsItem, ListTrackItem, ListFileItem, ListRootItem } from "$lib/components/file-list/FileList";
|
import { ListTrackSegmentItem, ListWaypointItem, ListWaypointsItem, ListTrackItem, ListFileItem, ListRootItem } from "$lib/components/file-list/FileList";
|
||||||
import type { Waypoint } from "gpx";
|
import { getClosestLinePoint, getElevation, resetCursor, setGrabbingCursor, setPointerCursor, setScissorsCursor } from "$lib/utils";
|
||||||
import { getElevation, resetCursor, setGrabbingCursor, setPointerCursor, setScissorsCursor } from "$lib/utils";
|
|
||||||
import { selectedWaypoint } from "$lib/components/toolbar/tools/Waypoint.svelte";
|
import { selectedWaypoint } from "$lib/components/toolbar/tools/Waypoint.svelte";
|
||||||
import { MapPin, Square } from "lucide-static";
|
import { MapPin, Square } from "lucide-static";
|
||||||
import { getSymbolKey, symbols } from "$lib/assets/symbols";
|
import { getSymbolKey, symbols } from "$lib/assets/symbols";
|
||||||
@@ -43,6 +42,31 @@ function decrementColor(color: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const inspectKey = 'Shift';
|
||||||
|
let inspectKeyDown: KeyDown | null = null;
|
||||||
|
class KeyDown {
|
||||||
|
key: string;
|
||||||
|
down: boolean = false;
|
||||||
|
constructor(key: string) {
|
||||||
|
this.key = key;
|
||||||
|
document.addEventListener('keydown', this.onKeyDown);
|
||||||
|
document.addEventListener('keyup', this.onKeyUp);
|
||||||
|
}
|
||||||
|
onKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === this.key) {
|
||||||
|
this.down = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onKeyUp = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === this.key) {
|
||||||
|
this.down = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isDown() {
|
||||||
|
return this.down;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getMarkerForSymbol(symbol: string | undefined, layerColor: string) {
|
function getMarkerForSymbol(symbol: string | undefined, layerColor: string) {
|
||||||
let symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
|
let symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
|
||||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
@@ -80,9 +104,9 @@ export class GPXLayer {
|
|||||||
updateBinded: () => void = this.update.bind(this);
|
updateBinded: () => void = this.update.bind(this);
|
||||||
layerOnMouseEnterBinded: (e: any) => void = this.layerOnMouseEnter.bind(this);
|
layerOnMouseEnterBinded: (e: any) => void = this.layerOnMouseEnter.bind(this);
|
||||||
layerOnMouseLeaveBinded: () => void = this.layerOnMouseLeave.bind(this);
|
layerOnMouseLeaveBinded: () => void = this.layerOnMouseLeave.bind(this);
|
||||||
|
layerOnMouseMoveBinded: (e: any) => void = this.layerOnMouseMove.bind(this);
|
||||||
layerOnClickBinded: (e: any) => void = this.layerOnClick.bind(this);
|
layerOnClickBinded: (e: any) => void = this.layerOnClick.bind(this);
|
||||||
layerOnContextMenuBinded: (e: any) => void = this.layerOnContextMenu.bind(this);
|
layerOnContextMenuBinded: (e: any) => void = this.layerOnContextMenu.bind(this);
|
||||||
maybeHideWaypointPopupBinded: (e: any) => void = this.maybeHideWaypointPopup.bind(this);
|
|
||||||
|
|
||||||
constructor(map: mapboxgl.Map, fileId: string, file: Readable<GPXFileWithStatistics | undefined>) {
|
constructor(map: mapboxgl.Map, fileId: string, file: Readable<GPXFileWithStatistics | undefined>) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
@@ -113,6 +137,10 @@ export class GPXLayer {
|
|||||||
this.draggable = get(currentTool) === Tool.WAYPOINT;
|
this.draggable = get(currentTool) === Tool.WAYPOINT;
|
||||||
|
|
||||||
this.map.on('style.import.load', this.updateBinded);
|
this.map.on('style.import.load', this.updateBinded);
|
||||||
|
|
||||||
|
if (inspectKeyDown === null) {
|
||||||
|
inspectKeyDown = new KeyDown(inspectKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
@@ -157,6 +185,7 @@ export class GPXLayer {
|
|||||||
this.map.on('contextmenu', this.fileId, this.layerOnContextMenuBinded);
|
this.map.on('contextmenu', this.fileId, this.layerOnContextMenuBinded);
|
||||||
this.map.on('mouseenter', this.fileId, this.layerOnMouseEnterBinded);
|
this.map.on('mouseenter', this.fileId, this.layerOnMouseEnterBinded);
|
||||||
this.map.on('mouseleave', this.fileId, this.layerOnMouseLeaveBinded);
|
this.map.on('mouseleave', this.fileId, this.layerOnMouseLeaveBinded);
|
||||||
|
this.map.on('mousemove', this.fileId, this.layerOnMouseMoveBinded);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get(directionMarkers)) {
|
if (get(directionMarkers)) {
|
||||||
@@ -224,11 +253,11 @@ export class GPXLayer {
|
|||||||
}).setLngLat(waypoint.getCoordinates());
|
}).setLngLat(waypoint.getCoordinates());
|
||||||
Object.defineProperty(marker, '_waypoint', { value: waypoint, writable: true });
|
Object.defineProperty(marker, '_waypoint', { value: waypoint, writable: true });
|
||||||
let dragEndTimestamp = 0;
|
let dragEndTimestamp = 0;
|
||||||
marker.getElement().addEventListener('mouseover', (e) => {
|
marker.getElement().addEventListener('mousemove', (e) => {
|
||||||
if (marker._isDragging) {
|
if (marker._isDragging) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.showWaypointPopup(marker._waypoint);
|
waypointPopup?.setItem({ item: marker._waypoint, fileId: this.fileId });
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
});
|
});
|
||||||
marker.getElement().addEventListener('click', (e) => {
|
marker.getElement().addEventListener('click', (e) => {
|
||||||
@@ -251,14 +280,14 @@ export class GPXLayer {
|
|||||||
} else if (get(currentTool) === Tool.WAYPOINT) {
|
} else if (get(currentTool) === Tool.WAYPOINT) {
|
||||||
selectedWaypoint.set([marker._waypoint, this.fileId]);
|
selectedWaypoint.set([marker._waypoint, this.fileId]);
|
||||||
} else {
|
} else {
|
||||||
this.showWaypointPopup(marker._waypoint);
|
waypointPopup?.setItem({ item: marker._waypoint, fileId: this.fileId });
|
||||||
}
|
}
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
});
|
});
|
||||||
marker.on('dragstart', () => {
|
marker.on('dragstart', () => {
|
||||||
setGrabbingCursor();
|
setGrabbingCursor();
|
||||||
marker.getElement().style.cursor = 'grabbing';
|
marker.getElement().style.cursor = 'grabbing';
|
||||||
this.hideWaypointPopup();
|
waypointPopup?.hide();
|
||||||
});
|
});
|
||||||
marker.on('dragend', (e) => {
|
marker.on('dragend', (e) => {
|
||||||
resetCursor();
|
resetCursor();
|
||||||
@@ -307,6 +336,7 @@ export class GPXLayer {
|
|||||||
this.map.off('contextmenu', this.fileId, this.layerOnContextMenuBinded);
|
this.map.off('contextmenu', this.fileId, this.layerOnContextMenuBinded);
|
||||||
this.map.off('mouseenter', this.fileId, this.layerOnMouseEnterBinded);
|
this.map.off('mouseenter', this.fileId, this.layerOnMouseEnterBinded);
|
||||||
this.map.off('mouseleave', this.fileId, this.layerOnMouseLeaveBinded);
|
this.map.off('mouseleave', this.fileId, this.layerOnMouseLeaveBinded);
|
||||||
|
this.map.off('mousemove', this.fileId, this.layerOnMouseMoveBinded);
|
||||||
this.map.off('style.import.load', this.updateBinded);
|
this.map.off('style.import.load', this.updateBinded);
|
||||||
|
|
||||||
if (this.map.getLayer(this.fileId + '-direction')) {
|
if (this.map.getLayer(this.fileId + '-direction')) {
|
||||||
@@ -353,6 +383,19 @@ export class GPXLayer {
|
|||||||
resetCursor();
|
resetCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layerOnMouseMove(e: any) {
|
||||||
|
if (inspectKeyDown?.isDown()) {
|
||||||
|
let trackIndex = e.features[0].properties.trackIndex;
|
||||||
|
let segmentIndex = e.features[0].properties.segmentIndex;
|
||||||
|
|
||||||
|
const file = get(this.file)?.file;
|
||||||
|
if (file) {
|
||||||
|
const closest = getClosestLinePoint(file.trk[trackIndex].trkseg[segmentIndex].trkpt, { lat: e.lngLat.lat, lon: e.lngLat.lng });
|
||||||
|
trackpointPopup?.setItem({ item: closest, fileId: this.fileId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
layerOnClick(e: any) {
|
layerOnClick(e: any) {
|
||||||
if (get(currentTool) === Tool.ROUTING && get(selection).hasAnyChildren(new ListRootItem(), true, ['waypoints'])) {
|
if (get(currentTool) === Tool.ROUTING && get(selection).hasAnyChildren(new ListRootItem(), true, ['waypoints'])) {
|
||||||
return;
|
return;
|
||||||
@@ -391,43 +434,6 @@ export class GPXLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showWaypointPopup(waypoint: Waypoint) {
|
|
||||||
if (get(currentPopupWaypoint) !== null) {
|
|
||||||
this.hideWaypointPopup();
|
|
||||||
}
|
|
||||||
let marker = this.markers[waypoint._data.index];
|
|
||||||
if (marker) {
|
|
||||||
currentPopupWaypoint.set([waypoint, this.fileId]);
|
|
||||||
marker.setPopup(waypointPopup);
|
|
||||||
marker.togglePopup();
|
|
||||||
this.map.on('mousemove', this.maybeHideWaypointPopupBinded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maybeHideWaypointPopup(e: any) {
|
|
||||||
let waypoint = get(currentPopupWaypoint)?.[0];
|
|
||||||
if (waypoint) {
|
|
||||||
let marker = this.markers[waypoint._data.index];
|
|
||||||
if (marker) {
|
|
||||||
if (this.map.project(marker.getLngLat()).dist(this.map.project(e.lngLat)) > 100) {
|
|
||||||
this.hideWaypointPopup();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.hideWaypointPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hideWaypointPopup() {
|
|
||||||
let waypoint = get(currentPopupWaypoint)?.[0];
|
|
||||||
if (waypoint) {
|
|
||||||
let marker = this.markers[waypoint._data.index];
|
|
||||||
marker?.getPopup()?.remove();
|
|
||||||
currentPopupWaypoint.set(null);
|
|
||||||
this.map.off('mousemove', this.maybeHideWaypointPopupBinded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getGeoJSON(): GeoJSON.FeatureCollection {
|
getGeoJSON(): GeoJSON.FeatureCollection {
|
||||||
let file = get(this.file)?.file;
|
let file = get(this.file)?.file;
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
44
website/src/lib/components/gpx-layer/GPXLayerPopup.ts
Normal file
44
website/src/lib/components/gpx-layer/GPXLayerPopup.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { dbUtils } from "$lib/db";
|
||||||
|
import { MapPopup } from "$lib/components/MapPopup";
|
||||||
|
|
||||||
|
export let waypointPopup: MapPopup | null = null;
|
||||||
|
export let trackpointPopup: MapPopup | null = null;
|
||||||
|
|
||||||
|
export function createPopups(map: mapboxgl.Map) {
|
||||||
|
removePopups();
|
||||||
|
waypointPopup = new MapPopup(map, {
|
||||||
|
closeButton: false,
|
||||||
|
focusAfterOpen: false,
|
||||||
|
maxWidth: undefined,
|
||||||
|
offset: {
|
||||||
|
'top': [0, 0],
|
||||||
|
'top-left': [0, 0],
|
||||||
|
'top-right': [0, 0],
|
||||||
|
'bottom': [0, -30],
|
||||||
|
'bottom-left': [0, -30],
|
||||||
|
'bottom-right': [0, -30],
|
||||||
|
'left': [10, -15],
|
||||||
|
'right': [-10, -15],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
trackpointPopup = new MapPopup(map, {
|
||||||
|
closeButton: false,
|
||||||
|
focusAfterOpen: false,
|
||||||
|
maxWidth: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removePopups() {
|
||||||
|
if (waypointPopup !== null) {
|
||||||
|
waypointPopup.remove();
|
||||||
|
waypointPopup = null;
|
||||||
|
}
|
||||||
|
if (trackpointPopup !== null) {
|
||||||
|
trackpointPopup.remove();
|
||||||
|
trackpointPopup = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteWaypoint(fileId: string, waypointIndex: number) {
|
||||||
|
dbUtils.applyToFile(fileId, (file) => file.replaceWaypoints(waypointIndex, waypointIndex, []));
|
||||||
|
}
|
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { map, gpxLayers } from '$lib/stores';
|
import { map, gpxLayers } from '$lib/stores';
|
||||||
import { GPXLayer } from './GPXLayer';
|
import { GPXLayer } from './GPXLayer';
|
||||||
import WaypointPopup from './WaypointPopup.svelte';
|
|
||||||
import { fileObservers } from '$lib/db';
|
import { fileObservers } from '$lib/db';
|
||||||
import { DistanceMarkers } from './DistanceMarkers';
|
import { DistanceMarkers } from './DistanceMarkers';
|
||||||
import { StartEndMarkers } from './StartEndMarkers';
|
import { StartEndMarkers } from './StartEndMarkers';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
|
import { createPopups, removePopups } from './GPXLayerPopup';
|
||||||
|
|
||||||
let distanceMarkers: DistanceMarkers | undefined = undefined;
|
let distanceMarkers: DistanceMarkers | undefined = undefined;
|
||||||
let startEndMarkers: StartEndMarkers | undefined = undefined;
|
let startEndMarkers: StartEndMarkers | undefined = undefined;
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
if (startEndMarkers) {
|
if (startEndMarkers) {
|
||||||
startEndMarkers.remove();
|
startEndMarkers.remove();
|
||||||
}
|
}
|
||||||
|
createPopups($map);
|
||||||
distanceMarkers = new DistanceMarkers($map);
|
distanceMarkers = new DistanceMarkers($map);
|
||||||
startEndMarkers = new StartEndMarkers($map);
|
startEndMarkers = new StartEndMarkers($map);
|
||||||
}
|
}
|
||||||
@@ -42,17 +43,14 @@
|
|||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
gpxLayers.forEach((layer) => layer.remove());
|
gpxLayers.forEach((layer) => layer.remove());
|
||||||
gpxLayers.clear();
|
gpxLayers.clear();
|
||||||
|
removePopups();
|
||||||
if (distanceMarkers) {
|
if (distanceMarkers) {
|
||||||
distanceMarkers.remove();
|
distanceMarkers.remove();
|
||||||
distanceMarkers = undefined;
|
distanceMarkers = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startEndMarkers) {
|
if (startEndMarkers) {
|
||||||
startEndMarkers.remove();
|
startEndMarkers.remove();
|
||||||
startEndMarkers = undefined;
|
startEndMarkers = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<WaypointPopup />
|
|
||||||
|
36
website/src/lib/components/gpx-layer/TrackpointPopup.svelte
Normal file
36
website/src/lib/components/gpx-layer/TrackpointPopup.svelte
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TrackPoint } from 'gpx';
|
||||||
|
import type { PopupItem } from '$lib/components/MapPopup';
|
||||||
|
import * as Card from '$lib/components/ui/card';
|
||||||
|
import WithUnits from '$lib/components/WithUnits.svelte';
|
||||||
|
import { Compass, Mountain, Timer } from 'lucide-svelte';
|
||||||
|
import { df } from '$lib/utils';
|
||||||
|
|
||||||
|
export let trackpoint: PopupItem<TrackPoint>;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Card.Root class="border-none shadow-md text-base p-2">
|
||||||
|
<Card.Header class="p-0">
|
||||||
|
<Card.Title class="text-md"></Card.Title>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Content class="flex flex-col p-0 text-xs gap-1">
|
||||||
|
<div class="flex flex-row items-center gap-1">
|
||||||
|
<Compass size="14" />
|
||||||
|
{trackpoint.item.getLatitude().toFixed(6)}° {trackpoint.item
|
||||||
|
.getLongitude()
|
||||||
|
.toFixed(6)}°
|
||||||
|
</div>
|
||||||
|
{#if trackpoint.item.ele !== undefined}
|
||||||
|
<div class="flex flex-row items-center gap-1">
|
||||||
|
<Mountain size="14" />
|
||||||
|
<WithUnits value={trackpoint.item.ele} type="elevation" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if trackpoint.item.time}
|
||||||
|
<div class="flex flex-row items-center gap-1">
|
||||||
|
<Timer size="14" />
|
||||||
|
{df.format(trackpoint.item.time)}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</Card.Content>
|
||||||
|
</Card.Root>
|
@@ -2,23 +2,20 @@
|
|||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import Shortcut from '$lib/components/Shortcut.svelte';
|
import Shortcut from '$lib/components/Shortcut.svelte';
|
||||||
import { waypointPopup, currentPopupWaypoint, deleteWaypoint } from './WaypointPopup';
|
import { deleteWaypoint } from './GPXLayerPopup';
|
||||||
import WithUnits from '$lib/components/WithUnits.svelte';
|
import WithUnits from '$lib/components/WithUnits.svelte';
|
||||||
import { Dot, ExternalLink, Trash2 } from 'lucide-svelte';
|
import { Dot, ExternalLink, Trash2 } from 'lucide-svelte';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { Tool, currentTool } from '$lib/stores';
|
import { Tool, currentTool } from '$lib/stores';
|
||||||
import { getSymbolKey, symbols } from '$lib/assets/symbols';
|
import { getSymbolKey, symbols } from '$lib/assets/symbols';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import sanitizeHtml from 'sanitize-html';
|
import sanitizeHtml from 'sanitize-html';
|
||||||
|
import type { Waypoint } from 'gpx';
|
||||||
|
import type { PopupItem } from '$lib/components/MapPopup';
|
||||||
|
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
|
||||||
|
|
||||||
let popupElement: HTMLDivElement;
|
export let waypoint: PopupItem<Waypoint>;
|
||||||
|
|
||||||
onMount(() => {
|
$: symbolKey = waypoint ? getSymbolKey(waypoint.item.sym) : undefined;
|
||||||
waypointPopup.setDOMContent(popupElement);
|
|
||||||
popupElement.classList.remove('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
$: symbolKey = $currentPopupWaypoint ? getSymbolKey($currentPopupWaypoint[0].sym) : undefined;
|
|
||||||
|
|
||||||
function sanitize(text: string | undefined): string {
|
function sanitize(text: string | undefined): string {
|
||||||
if (text === undefined) {
|
if (text === undefined) {
|
||||||
@@ -34,68 +31,63 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={popupElement} class="hidden">
|
<Card.Root class="border-none shadow-md text-base p-2 max-w-[50dvw]">
|
||||||
{#if $currentPopupWaypoint}
|
<Card.Header class="p-0">
|
||||||
<Card.Root class="border-none shadow-md text-base max-w-80 p-2">
|
<Card.Title class="text-md">
|
||||||
<Card.Header class="p-0">
|
{#if waypoint.item.link && waypoint.item.link.attributes && waypoint.item.link.attributes.href}
|
||||||
<Card.Title class="text-md">
|
<a href={waypoint.item.link.attributes.href} target="_blank">
|
||||||
{#if $currentPopupWaypoint[0].link && $currentPopupWaypoint[0].link.attributes && $currentPopupWaypoint[0].link.attributes.href}
|
{waypoint.item.name ?? waypoint.item.link.attributes.href}
|
||||||
<a href={$currentPopupWaypoint[0].link.attributes.href} target="_blank">
|
<ExternalLink size="12" class="inline-block mb-1.5" />
|
||||||
{$currentPopupWaypoint[0].name ?? $currentPopupWaypoint[0].link.attributes.href}
|
</a>
|
||||||
<ExternalLink size="12" class="inline-block mb-1.5" />
|
{:else}
|
||||||
</a>
|
{waypoint.item.name ?? $_('gpx.waypoint')}
|
||||||
|
{/if}
|
||||||
|
</Card.Title>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Content class="flex flex-col text-sm p-0">
|
||||||
|
<div class="flex flex-row items-center text-muted-foreground text-xs whitespace-nowrap">
|
||||||
|
{#if symbolKey}
|
||||||
|
<span>
|
||||||
|
{#if symbols[symbolKey].icon}
|
||||||
|
<svelte:component
|
||||||
|
this={symbols[symbolKey].icon}
|
||||||
|
size="12"
|
||||||
|
class="inline-block mb-0.5"
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
{$currentPopupWaypoint[0].name ?? $_('gpx.waypoint')}
|
<span class="w-4 inline-block" />
|
||||||
{/if}
|
{/if}
|
||||||
</Card.Title>
|
{$_(`gpx.symbol.${symbolKey}`)}
|
||||||
</Card.Header>
|
</span>
|
||||||
<Card.Content class="flex flex-col p-0 text-sm">
|
<Dot size="16" />
|
||||||
<div class="flex flex-row items-center text-muted-foreground text-xs whitespace-nowrap">
|
{/if}
|
||||||
{#if symbolKey}
|
{waypoint.item.getLatitude().toFixed(6)}° {waypoint.item.getLongitude().toFixed(6)}°
|
||||||
<span>
|
{#if waypoint.item.ele !== undefined}
|
||||||
{#if symbols[symbolKey].icon}
|
<Dot size="16" />
|
||||||
<svelte:component
|
<WithUnits value={waypoint.item.ele} type="elevation" />
|
||||||
this={symbols[symbolKey].icon}
|
{/if}
|
||||||
size="12"
|
</div>
|
||||||
class="inline-block mb-0.5"
|
<ScrollArea class="flex flex-col" viewportClasses="max-h-[30dvh]">
|
||||||
/>
|
{#if waypoint.item.desc}
|
||||||
{:else}
|
<span class="whitespace-pre-wrap">{@html sanitize(waypoint.item.desc)}</span>
|
||||||
<span class="w-4 inline-block" />
|
{/if}
|
||||||
{/if}
|
{#if waypoint.item.cmt && waypoint.item.cmt !== waypoint.item.desc}
|
||||||
{$_(`gpx.symbol.${symbolKey}`)}
|
<span class="whitespace-pre-wrap">{@html sanitize(waypoint.item.cmt)}</span>
|
||||||
</span>
|
{/if}
|
||||||
<Dot size="16" />
|
</ScrollArea>
|
||||||
{/if}
|
{#if $currentTool === Tool.WAYPOINT}
|
||||||
{$currentPopupWaypoint[0].getLatitude().toFixed(6)}° {$currentPopupWaypoint[0]
|
<Button
|
||||||
.getLongitude()
|
class="mt-2 w-full px-2 py-1 h-8 justify-start"
|
||||||
.toFixed(6)}°
|
variant="outline"
|
||||||
{#if $currentPopupWaypoint[0].ele !== undefined}
|
on:click={() => deleteWaypoint(waypoint.fileId, waypoint.item._data.index)}
|
||||||
<Dot size="16" />
|
>
|
||||||
<WithUnits value={$currentPopupWaypoint[0].ele} type="elevation" />
|
<Trash2 size="16" class="mr-1" />
|
||||||
{/if}
|
{$_('menu.delete')}
|
||||||
</div>
|
<Shortcut shift={true} click={true} />
|
||||||
{#if $currentPopupWaypoint[0].desc}
|
</Button>
|
||||||
<span class="whitespace-pre-wrap">{@html sanitize($currentPopupWaypoint[0].desc)}</span>
|
{/if}
|
||||||
{/if}
|
</Card.Content>
|
||||||
{#if $currentPopupWaypoint[0].cmt && $currentPopupWaypoint[0].cmt !== $currentPopupWaypoint[0].desc}
|
</Card.Root>
|
||||||
<span class="whitespace-pre-wrap">{@html sanitize($currentPopupWaypoint[0].cmt)}</span>
|
|
||||||
{/if}
|
|
||||||
{#if $currentTool === Tool.WAYPOINT}
|
|
||||||
<Button
|
|
||||||
class="mt-2 w-full px-2 py-1 h-8 justify-start"
|
|
||||||
variant="outline"
|
|
||||||
on:click={() =>
|
|
||||||
deleteWaypoint($currentPopupWaypoint[1], $currentPopupWaypoint[0]._data.index)}
|
|
||||||
>
|
|
||||||
<Trash2 size="16" class="mr-1" />
|
|
||||||
{$_('menu.delete')}
|
|
||||||
<Shortcut shift={true} click={true} />
|
|
||||||
</Button>
|
|
||||||
{/if}
|
|
||||||
</Card.Content>
|
|
||||||
</Card.Root>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
div :global(a) {
|
div :global(a) {
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
import { dbUtils } from "$lib/db";
|
|
||||||
import type { Waypoint } from "gpx";
|
|
||||||
import mapboxgl from "mapbox-gl";
|
|
||||||
import { writable } from "svelte/store";
|
|
||||||
|
|
||||||
export const currentPopupWaypoint = writable<[Waypoint, string] | null>(null);
|
|
||||||
|
|
||||||
export const waypointPopup = new mapboxgl.Popup({
|
|
||||||
closeButton: false,
|
|
||||||
maxWidth: undefined,
|
|
||||||
offset: {
|
|
||||||
'top': [0, 0],
|
|
||||||
'top-left': [0, 0],
|
|
||||||
'top-right': [0, 0],
|
|
||||||
'bottom': [0, -30],
|
|
||||||
'bottom-left': [0, -30],
|
|
||||||
'bottom-right': [0, -30],
|
|
||||||
'left': [0, 0],
|
|
||||||
'right': [0, 0]
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export function deleteWaypoint(fileId: string, waypointIndex: number) {
|
|
||||||
dbUtils.applyToFile(fileId, (file) => file.replaceWaypoints(waypointIndex, waypointIndex, []));
|
|
||||||
}
|
|
@@ -1,435 +1,422 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
import { Label } from '$lib/components/ui/label';
|
import { Label } from '$lib/components/ui/label';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { Separator } from '$lib/components/ui/separator';
|
import { Separator } from '$lib/components/ui/separator';
|
||||||
import * as RadioGroup from '$lib/components/ui/radio-group';
|
import * as RadioGroup from '$lib/components/ui/radio-group';
|
||||||
import {
|
import {
|
||||||
CirclePlus,
|
CirclePlus,
|
||||||
CircleX,
|
CircleX,
|
||||||
Minus,
|
Minus,
|
||||||
Pencil,
|
Pencil,
|
||||||
Plus,
|
Plus,
|
||||||
Save,
|
Save,
|
||||||
Trash2,
|
Trash2,
|
||||||
Move,
|
Move,
|
||||||
Map,
|
Map,
|
||||||
Layers2
|
Layers2
|
||||||
} from 'lucide-svelte';
|
} from 'lucide-svelte';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import { settings } from '$lib/db';
|
import { settings } from '$lib/db';
|
||||||
import { defaultBasemap, type CustomLayer } from '$lib/assets/layers';
|
import { defaultBasemap, type CustomLayer } from '$lib/assets/layers';
|
||||||
import { map } from '$lib/stores';
|
import { map } from '$lib/stores';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import Sortable from 'sortablejs/Sortable';
|
import Sortable from 'sortablejs/Sortable';
|
||||||
import { customBasemapUpdate } from './utils';
|
import { customBasemapUpdate } from './utils';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
customLayers,
|
customLayers,
|
||||||
selectedBasemapTree,
|
selectedBasemapTree,
|
||||||
selectedOverlayTree,
|
selectedOverlayTree,
|
||||||
currentBasemap,
|
currentBasemap,
|
||||||
previousBasemap,
|
previousBasemap,
|
||||||
currentOverlays,
|
currentOverlays,
|
||||||
previousOverlays,
|
previousOverlays,
|
||||||
customBasemapOrder,
|
customBasemapOrder,
|
||||||
customOverlayOrder
|
customOverlayOrder
|
||||||
} = settings;
|
} = settings;
|
||||||
|
|
||||||
let name: string = '';
|
let name: string = '';
|
||||||
let tileUrls: string[] = [''];
|
let tileUrls: string[] = [''];
|
||||||
let maxZoom: number = 20;
|
let maxZoom: number = 20;
|
||||||
let layerType: 'basemap' | 'overlay' = 'basemap';
|
let layerType: 'basemap' | 'overlay' = 'basemap';
|
||||||
let resourceType: 'raster' | 'vector' = 'raster';
|
let resourceType: 'raster' | 'vector' = 'raster';
|
||||||
|
|
||||||
let basemapContainer: HTMLElement;
|
let basemapContainer: HTMLElement;
|
||||||
let overlayContainer: HTMLElement;
|
let overlayContainer: HTMLElement;
|
||||||
|
|
||||||
let basemapSortable: Sortable;
|
let basemapSortable: Sortable;
|
||||||
let overlaySortable: Sortable;
|
let overlaySortable: Sortable;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if ($customBasemapOrder.length === 0) {
|
if ($customBasemapOrder.length === 0) {
|
||||||
$customBasemapOrder = Object.keys($customLayers).filter(
|
$customBasemapOrder = Object.keys($customLayers).filter(
|
||||||
(id) => $customLayers[id].layerType === 'basemap'
|
(id) => $customLayers[id].layerType === 'basemap'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($customOverlayOrder.length === 0) {
|
if ($customOverlayOrder.length === 0) {
|
||||||
$customOverlayOrder = Object.keys($customLayers).filter(
|
$customOverlayOrder = Object.keys($customLayers).filter(
|
||||||
(id) => $customLayers[id].layerType === 'overlay'
|
(id) => $customLayers[id].layerType === 'overlay'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
basemapSortable = Sortable.create(basemapContainer, {
|
basemapSortable = Sortable.create(basemapContainer, {
|
||||||
onSort: (e) => {
|
onSort: (e) => {
|
||||||
$customBasemapOrder = basemapSortable.toArray();
|
$customBasemapOrder = basemapSortable.toArray();
|
||||||
$selectedBasemapTree.basemaps['custom'] = $customBasemapOrder.reduce((acc, id) => {
|
$selectedBasemapTree.basemaps['custom'] = $customBasemapOrder.reduce((acc, id) => {
|
||||||
acc[id] = true;
|
acc[id] = true;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
overlaySortable = Sortable.create(overlayContainer, {
|
overlaySortable = Sortable.create(overlayContainer, {
|
||||||
onSort: (e) => {
|
onSort: (e) => {
|
||||||
$customOverlayOrder = overlaySortable.toArray();
|
$customOverlayOrder = overlaySortable.toArray();
|
||||||
$selectedOverlayTree.overlays['custom'] = $customOverlayOrder.reduce((acc, id) => {
|
$selectedOverlayTree.overlays['custom'] = $customOverlayOrder.reduce((acc, id) => {
|
||||||
acc[id] = true;
|
acc[id] = true;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
basemapSortable.sort($customBasemapOrder);
|
basemapSortable.sort($customBasemapOrder);
|
||||||
overlaySortable.sort($customOverlayOrder);
|
overlaySortable.sort($customOverlayOrder);
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
basemapSortable.destroy();
|
basemapSortable.destroy();
|
||||||
overlaySortable.destroy();
|
overlaySortable.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
$: if (tileUrls[0].length > 0) {
|
$: if (tileUrls[0].length > 0) {
|
||||||
if (
|
if (
|
||||||
tileUrls[0].includes('.json') ||
|
tileUrls[0].includes('.json') ||
|
||||||
(tileUrls[0].includes('api.mapbox.com/styles') && !tileUrls[0].includes('tiles'))
|
(tileUrls[0].includes('api.mapbox.com/styles') && !tileUrls[0].includes('tiles'))
|
||||||
) {
|
) {
|
||||||
resourceType = 'vector';
|
resourceType = 'vector';
|
||||||
} else {
|
} else {
|
||||||
resourceType = 'raster';
|
resourceType = 'raster';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLayer() {
|
function createLayer() {
|
||||||
if (selectedLayerId && $customLayers[selectedLayerId].layerType !== layerType) {
|
if (selectedLayerId && $customLayers[selectedLayerId].layerType !== layerType) {
|
||||||
deleteLayer(selectedLayerId);
|
deleteLayer(selectedLayerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof maxZoom === 'string') {
|
if (typeof maxZoom === 'string') {
|
||||||
maxZoom = parseInt(maxZoom);
|
maxZoom = parseInt(maxZoom);
|
||||||
}
|
}
|
||||||
|
let is512 = tileUrls.some((url) => url.includes('512'));
|
||||||
|
|
||||||
let layerId = selectedLayerId ?? getLayerId();
|
let layerId = selectedLayerId ?? getLayerId();
|
||||||
let layer: CustomLayer = {
|
let layer: CustomLayer = {
|
||||||
id: layerId,
|
id: layerId,
|
||||||
name: name,
|
name: name,
|
||||||
tileUrls: tileUrls.map((url) => decodeURI(url.trim())),
|
tileUrls: tileUrls.map((url) => decodeURI(url.trim())),
|
||||||
maxZoom: maxZoom,
|
maxZoom: maxZoom,
|
||||||
layerType: layerType,
|
layerType: layerType,
|
||||||
resourceType: resourceType,
|
resourceType: resourceType,
|
||||||
value: ''
|
value: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
if (resourceType === 'vector') {
|
if (resourceType === 'vector') {
|
||||||
layer.value = layer.tileUrls[0];
|
layer.value = layer.tileUrls[0];
|
||||||
} else {
|
} else {
|
||||||
layer.value = {
|
layer.value = {
|
||||||
version: 8,
|
version: 8,
|
||||||
sources: {
|
sources: {
|
||||||
[layerId]: {
|
[layerId]: {
|
||||||
type: 'raster',
|
type: 'raster',
|
||||||
tiles: layer.tileUrls,
|
tiles: layer.tileUrls,
|
||||||
tileSize: 256,
|
tileSize: is512 ? 512 : 256,
|
||||||
maxzoom: maxZoom
|
maxzoom: maxZoom
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
layers: [
|
layers: [
|
||||||
{
|
{
|
||||||
id: layerId,
|
id: layerId,
|
||||||
type: 'raster',
|
type: 'raster',
|
||||||
source: layerId
|
source: layerId
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
$customLayers[layerId] = layer;
|
$customLayers[layerId] = layer;
|
||||||
addLayer(layerId);
|
addLayer(layerId);
|
||||||
selectedLayerId = undefined;
|
selectedLayerId = undefined;
|
||||||
setDataFromSelectedLayer();
|
setDataFromSelectedLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLayerId() {
|
function getLayerId() {
|
||||||
for (let id = 0; ; id++) {
|
for (let id = 0; ; id++) {
|
||||||
if (!$customLayers.hasOwnProperty(`custom-${id}`)) {
|
if (!$customLayers.hasOwnProperty(`custom-${id}`)) {
|
||||||
return `custom-${id}`;
|
return `custom-${id}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLayer(layerId: string) {
|
function addLayer(layerId: string) {
|
||||||
if (layerType === 'basemap') {
|
if (layerType === 'basemap') {
|
||||||
selectedBasemapTree.update(($tree) => {
|
selectedBasemapTree.update(($tree) => {
|
||||||
if (!$tree.basemaps.hasOwnProperty('custom')) {
|
if (!$tree.basemaps.hasOwnProperty('custom')) {
|
||||||
$tree.basemaps['custom'] = {};
|
$tree.basemaps['custom'] = {};
|
||||||
}
|
}
|
||||||
$tree.basemaps['custom'][layerId] = true;
|
$tree.basemaps['custom'][layerId] = true;
|
||||||
return $tree;
|
return $tree;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($currentBasemap === layerId) {
|
if ($currentBasemap === layerId) {
|
||||||
$customBasemapUpdate++;
|
$customBasemapUpdate++;
|
||||||
} else {
|
} else {
|
||||||
$currentBasemap = layerId;
|
$currentBasemap = layerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$customBasemapOrder.includes(layerId)) {
|
if (!$customBasemapOrder.includes(layerId)) {
|
||||||
$customBasemapOrder = [...$customBasemapOrder, layerId];
|
$customBasemapOrder = [...$customBasemapOrder, layerId];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedOverlayTree.update(($tree) => {
|
selectedOverlayTree.update(($tree) => {
|
||||||
if (!$tree.overlays.hasOwnProperty('custom')) {
|
if (!$tree.overlays.hasOwnProperty('custom')) {
|
||||||
$tree.overlays['custom'] = {};
|
$tree.overlays['custom'] = {};
|
||||||
}
|
}
|
||||||
$tree.overlays['custom'][layerId] = true;
|
$tree.overlays['custom'][layerId] = true;
|
||||||
return $tree;
|
return $tree;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$currentOverlays.overlays['custom'] &&
|
$currentOverlays.overlays['custom'] &&
|
||||||
$currentOverlays.overlays['custom'][layerId] &&
|
$currentOverlays.overlays['custom'][layerId] &&
|
||||||
$map
|
$map
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
$map.removeImport(layerId);
|
$map.removeImport(layerId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// No reliable way to check if the map is ready to remove sources and layers
|
// No reliable way to check if the map is ready to remove sources and layers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$currentOverlays.overlays.hasOwnProperty('custom')) {
|
if (!$currentOverlays.overlays.hasOwnProperty('custom')) {
|
||||||
$currentOverlays.overlays['custom'] = {};
|
$currentOverlays.overlays['custom'] = {};
|
||||||
}
|
}
|
||||||
$currentOverlays.overlays['custom'][layerId] = true;
|
$currentOverlays.overlays['custom'][layerId] = true;
|
||||||
|
|
||||||
if (!$customOverlayOrder.includes(layerId)) {
|
if (!$customOverlayOrder.includes(layerId)) {
|
||||||
$customOverlayOrder = [...$customOverlayOrder, layerId];
|
$customOverlayOrder = [...$customOverlayOrder, layerId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryDeleteLayer(node: any, id: string): any {
|
function tryDeleteLayer(node: any, id: string): any {
|
||||||
if (node.hasOwnProperty(id)) {
|
if (node.hasOwnProperty(id)) {
|
||||||
delete node[id];
|
delete node[id];
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteLayer(layerId: string) {
|
function deleteLayer(layerId: string) {
|
||||||
let layer = $customLayers[layerId];
|
let layer = $customLayers[layerId];
|
||||||
if (layer.layerType === 'basemap') {
|
if (layer.layerType === 'basemap') {
|
||||||
if (layerId === $currentBasemap) {
|
if (layerId === $currentBasemap) {
|
||||||
$currentBasemap = defaultBasemap;
|
$currentBasemap = defaultBasemap;
|
||||||
}
|
}
|
||||||
if (layerId === $previousBasemap) {
|
if (layerId === $previousBasemap) {
|
||||||
$previousBasemap = defaultBasemap;
|
$previousBasemap = defaultBasemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
$selectedBasemapTree.basemaps['custom'] = tryDeleteLayer(
|
$selectedBasemapTree.basemaps['custom'] = tryDeleteLayer(
|
||||||
$selectedBasemapTree.basemaps['custom'],
|
$selectedBasemapTree.basemaps['custom'],
|
||||||
layerId
|
layerId
|
||||||
);
|
);
|
||||||
if (Object.keys($selectedBasemapTree.basemaps['custom']).length === 0) {
|
if (Object.keys($selectedBasemapTree.basemaps['custom']).length === 0) {
|
||||||
$selectedBasemapTree.basemaps = tryDeleteLayer(
|
$selectedBasemapTree.basemaps = tryDeleteLayer($selectedBasemapTree.basemaps, 'custom');
|
||||||
$selectedBasemapTree.basemaps,
|
}
|
||||||
'custom'
|
$customBasemapOrder = $customBasemapOrder.filter((id) => id !== layerId);
|
||||||
);
|
} else {
|
||||||
}
|
$currentOverlays.overlays['custom'][layerId] = false;
|
||||||
$customBasemapOrder = $customBasemapOrder.filter((id) => id !== layerId);
|
if ($previousOverlays.overlays['custom']) {
|
||||||
} else {
|
$previousOverlays.overlays['custom'] = tryDeleteLayer(
|
||||||
$currentOverlays.overlays['custom'][layerId] = false;
|
$previousOverlays.overlays['custom'],
|
||||||
if ($previousOverlays.overlays['custom']) {
|
layerId
|
||||||
$previousOverlays.overlays['custom'] = tryDeleteLayer(
|
);
|
||||||
$previousOverlays.overlays['custom'],
|
}
|
||||||
layerId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$selectedOverlayTree.overlays['custom'] = tryDeleteLayer(
|
$selectedOverlayTree.overlays['custom'] = tryDeleteLayer(
|
||||||
$selectedOverlayTree.overlays['custom'],
|
$selectedOverlayTree.overlays['custom'],
|
||||||
layerId
|
layerId
|
||||||
);
|
);
|
||||||
if (Object.keys($selectedOverlayTree.overlays['custom']).length === 0) {
|
if (Object.keys($selectedOverlayTree.overlays['custom']).length === 0) {
|
||||||
$selectedOverlayTree.overlays = tryDeleteLayer(
|
$selectedOverlayTree.overlays = tryDeleteLayer($selectedOverlayTree.overlays, 'custom');
|
||||||
$selectedOverlayTree.overlays,
|
}
|
||||||
'custom'
|
$customOverlayOrder = $customOverlayOrder.filter((id) => id !== layerId);
|
||||||
);
|
|
||||||
}
|
|
||||||
$customOverlayOrder = $customOverlayOrder.filter((id) => id !== layerId);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$currentOverlays.overlays['custom'] &&
|
$currentOverlays.overlays['custom'] &&
|
||||||
$currentOverlays.overlays['custom'][layerId] &&
|
$currentOverlays.overlays['custom'][layerId] &&
|
||||||
$map
|
$map
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
$map.removeImport(layerId);
|
$map.removeImport(layerId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// No reliable way to check if the map is ready to remove sources and layers
|
// No reliable way to check if the map is ready to remove sources and layers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$customLayers = tryDeleteLayer($customLayers, layerId);
|
$customLayers = tryDeleteLayer($customLayers, layerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
let selectedLayerId: string | undefined = undefined;
|
let selectedLayerId: string | undefined = undefined;
|
||||||
|
|
||||||
function setDataFromSelectedLayer() {
|
function setDataFromSelectedLayer() {
|
||||||
if (selectedLayerId) {
|
if (selectedLayerId) {
|
||||||
const layer = $customLayers[selectedLayerId];
|
const layer = $customLayers[selectedLayerId];
|
||||||
name = layer.name;
|
name = layer.name;
|
||||||
tileUrls = layer.tileUrls;
|
tileUrls = layer.tileUrls;
|
||||||
maxZoom = layer.maxZoom;
|
maxZoom = layer.maxZoom;
|
||||||
layerType = layer.layerType;
|
layerType = layer.layerType;
|
||||||
resourceType = layer.resourceType;
|
resourceType = layer.resourceType;
|
||||||
} else {
|
} else {
|
||||||
name = '';
|
name = '';
|
||||||
tileUrls = [''];
|
tileUrls = [''];
|
||||||
maxZoom = 20;
|
maxZoom = 20;
|
||||||
layerType = 'basemap';
|
layerType = 'basemap';
|
||||||
resourceType = 'raster';
|
resourceType = 'raster';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: selectedLayerId, setDataFromSelectedLayer();
|
$: selectedLayerId, setDataFromSelectedLayer();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
{#if $customBasemapOrder.length > 0}
|
{#if $customBasemapOrder.length > 0}
|
||||||
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
||||||
<Map size="16" />
|
<Map size="16" />
|
||||||
{$_('layers.label.basemaps')}
|
{$_('layers.label.basemaps')}
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<Separator />
|
<Separator />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div
|
<div
|
||||||
bind:this={basemapContainer}
|
bind:this={basemapContainer}
|
||||||
class="ml-1.5 flex flex-col gap-1 {$customBasemapOrder.length > 0 ? 'mb-2' : ''}"
|
class="ml-1.5 flex flex-col gap-1 {$customBasemapOrder.length > 0 ? 'mb-2' : ''}"
|
||||||
>
|
>
|
||||||
{#each $customBasemapOrder as id (id)}
|
{#each $customBasemapOrder as id (id)}
|
||||||
<div class="flex flex-row items-center gap-2" data-id={id}>
|
<div class="flex flex-row items-center gap-2" data-id={id}>
|
||||||
<Move size="12" />
|
<Move size="12" />
|
||||||
<span class="grow">{$customLayers[id].name}</span>
|
<span class="grow">{$customLayers[id].name}</span>
|
||||||
<Button variant="outline" on:click={() => (selectedLayerId = id)} class="p-1 h-7">
|
<Button variant="outline" on:click={() => (selectedLayerId = id)} class="p-1 h-7">
|
||||||
<Pencil size="16" />
|
<Pencil size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" on:click={() => deleteLayer(id)} class="p-1 h-7">
|
<Button variant="outline" on:click={() => deleteLayer(id)} class="p-1 h-7">
|
||||||
<Trash2 size="16" />
|
<Trash2 size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{#if $customOverlayOrder.length > 0}
|
{#if $customOverlayOrder.length > 0}
|
||||||
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
<div class="flex flex-row items-center gap-1 font-semibold mb-2">
|
||||||
<Layers2 size="16" />
|
<Layers2 size="16" />
|
||||||
{$_('layers.label.overlays')}
|
{$_('layers.label.overlays')}
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<Separator />
|
<Separator />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div
|
<div
|
||||||
bind:this={overlayContainer}
|
bind:this={overlayContainer}
|
||||||
class="ml-1.5 flex flex-col gap-1 {$customOverlayOrder.length > 0 ? 'mb-2' : ''}"
|
class="ml-1.5 flex flex-col gap-1 {$customOverlayOrder.length > 0 ? 'mb-2' : ''}"
|
||||||
>
|
>
|
||||||
{#each $customOverlayOrder as id (id)}
|
{#each $customOverlayOrder as id (id)}
|
||||||
<div class="flex flex-row items-center gap-2" data-id={id}>
|
<div class="flex flex-row items-center gap-2" data-id={id}>
|
||||||
<Move size="12" />
|
<Move size="12" />
|
||||||
<span class="grow">{$customLayers[id].name}</span>
|
<span class="grow">{$customLayers[id].name}</span>
|
||||||
<Button variant="outline" on:click={() => (selectedLayerId = id)} class="p-1 h-7">
|
<Button variant="outline" on:click={() => (selectedLayerId = id)} class="p-1 h-7">
|
||||||
<Pencil size="16" />
|
<Pencil size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" on:click={() => deleteLayer(id)} class="p-1 h-7">
|
<Button variant="outline" on:click={() => deleteLayer(id)} class="p-1 h-7">
|
||||||
<Trash2 size="16" />
|
<Trash2 size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card.Root>
|
<Card.Root>
|
||||||
<Card.Header class="p-3">
|
<Card.Header class="p-3">
|
||||||
<Card.Title class="text-base">
|
<Card.Title class="text-base">
|
||||||
{#if selectedLayerId}
|
{#if selectedLayerId}
|
||||||
{$_('layers.custom_layers.edit')}
|
{$_('layers.custom_layers.edit')}
|
||||||
{:else}
|
{:else}
|
||||||
{$_('layers.custom_layers.new')}
|
{$_('layers.custom_layers.new')}
|
||||||
{/if}
|
{/if}
|
||||||
</Card.Title>
|
</Card.Title>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content class="p-3 pt-0">
|
<Card.Content class="p-3 pt-0">
|
||||||
<fieldset class="flex flex-col gap-2">
|
<fieldset class="flex flex-col gap-2">
|
||||||
<Label for="name">{$_('menu.metadata.name')}</Label>
|
<Label for="name">{$_('menu.metadata.name')}</Label>
|
||||||
<Input bind:value={name} id="name" class="h-8" />
|
<Input bind:value={name} id="name" class="h-8" />
|
||||||
<Label for="url">{$_('layers.custom_layers.urls')}</Label>
|
<Label for="url">{$_('layers.custom_layers.urls')}</Label>
|
||||||
{#each tileUrls as url, i}
|
{#each tileUrls as url, i}
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
<Input
|
<Input
|
||||||
bind:value={tileUrls[i]}
|
bind:value={tileUrls[i]}
|
||||||
id="url"
|
id="url"
|
||||||
class="h-8"
|
class="h-8"
|
||||||
placeholder={$_('layers.custom_layers.url_placeholder')}
|
placeholder={$_('layers.custom_layers.url_placeholder')}
|
||||||
/>
|
/>
|
||||||
{#if tileUrls.length > 1}
|
{#if tileUrls.length > 1}
|
||||||
<Button
|
<Button
|
||||||
on:click={() =>
|
on:click={() => (tileUrls = tileUrls.filter((_, index) => index !== i))}
|
||||||
(tileUrls = tileUrls.filter((_, index) => index !== i))}
|
variant="outline"
|
||||||
variant="outline"
|
class="p-1 h-8"
|
||||||
class="p-1 h-8"
|
>
|
||||||
>
|
<Minus size="16" />
|
||||||
<Minus size="16" />
|
</Button>
|
||||||
</Button>
|
{/if}
|
||||||
{/if}
|
{#if i === tileUrls.length - 1}
|
||||||
{#if i === tileUrls.length - 1}
|
<Button
|
||||||
<Button
|
on:click={() => (tileUrls = [...tileUrls, ''])}
|
||||||
on:click={() => (tileUrls = [...tileUrls, ''])}
|
variant="outline"
|
||||||
variant="outline"
|
class="p-1 h-8"
|
||||||
class="p-1 h-8"
|
>
|
||||||
>
|
<Plus size="16" />
|
||||||
<Plus size="16" />
|
</Button>
|
||||||
</Button>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
</div>
|
{/each}
|
||||||
{/each}
|
{#if resourceType === 'raster'}
|
||||||
{#if resourceType === 'raster'}
|
<Label for="maxZoom">{$_('layers.custom_layers.max_zoom')}</Label>
|
||||||
<Label for="maxZoom">{$_('layers.custom_layers.max_zoom')}</Label>
|
<Input type="number" bind:value={maxZoom} id="maxZoom" min={0} max={22} class="h-8" />
|
||||||
<Input
|
{/if}
|
||||||
type="number"
|
<Label>{$_('layers.custom_layers.layer_type')}</Label>
|
||||||
bind:value={maxZoom}
|
<RadioGroup.Root bind:value={layerType} class="flex flex-row">
|
||||||
id="maxZoom"
|
<div class="flex items-center space-x-2">
|
||||||
min={0}
|
<RadioGroup.Item value="basemap" id="basemap" />
|
||||||
max={22}
|
<Label for="basemap">{$_('layers.custom_layers.basemap')}</Label>
|
||||||
class="h-8"
|
</div>
|
||||||
/>
|
<div class="flex items-center space-x-2">
|
||||||
{/if}
|
<RadioGroup.Item value="overlay" id="overlay" />
|
||||||
<Label>{$_('layers.custom_layers.layer_type')}</Label>
|
<Label for="overlay">{$_('layers.custom_layers.overlay')}</Label>
|
||||||
<RadioGroup.Root bind:value={layerType} class="flex flex-row">
|
</div>
|
||||||
<div class="flex items-center space-x-2">
|
</RadioGroup.Root>
|
||||||
<RadioGroup.Item value="basemap" id="basemap" />
|
{#if selectedLayerId}
|
||||||
<Label for="basemap">{$_('layers.custom_layers.basemap')}</Label>
|
<div class="mt-2 flex flex-row gap-2">
|
||||||
</div>
|
<Button variant="outline" on:click={createLayer} class="grow">
|
||||||
<div class="flex items-center space-x-2">
|
<Save size="16" class="mr-1" />
|
||||||
<RadioGroup.Item value="overlay" id="overlay" />
|
{$_('layers.custom_layers.update')}
|
||||||
<Label for="overlay">{$_('layers.custom_layers.overlay')}</Label>
|
</Button>
|
||||||
</div>
|
<Button variant="outline" on:click={() => (selectedLayerId = undefined)}>
|
||||||
</RadioGroup.Root>
|
<CircleX size="16" />
|
||||||
{#if selectedLayerId}
|
</Button>
|
||||||
<div class="mt-2 flex flex-row gap-2">
|
</div>
|
||||||
<Button variant="outline" on:click={createLayer} class="grow">
|
{:else}
|
||||||
<Save size="16" class="mr-1" />
|
<Button variant="outline" class="mt-2" on:click={createLayer}>
|
||||||
{$_('layers.custom_layers.update')}
|
<CirclePlus size="16" class="mr-1" />
|
||||||
</Button>
|
{$_('layers.custom_layers.create')}
|
||||||
<Button variant="outline" on:click={() => (selectedLayerId = undefined)}>
|
</Button>
|
||||||
<CircleX size="16" />
|
{/if}
|
||||||
</Button>
|
</fieldset>
|
||||||
</div>
|
</Card.Content>
|
||||||
{:else}
|
</Card.Root>
|
||||||
<Button variant="outline" class="mt-2" on:click={createLayer}>
|
|
||||||
<CirclePlus size="16" class="mr-1" />
|
|
||||||
{$_('layers.custom_layers.create')}
|
|
||||||
</Button>
|
|
||||||
{/if}
|
|
||||||
</fieldset>
|
|
||||||
</Card.Content>
|
|
||||||
</Card.Root>
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
import { get, writable } from 'svelte/store';
|
import { get, writable } from 'svelte/store';
|
||||||
import { customBasemapUpdate, getLayers } from './utils';
|
import { customBasemapUpdate, getLayers } from './utils';
|
||||||
import { OverpassLayer } from './OverpassLayer';
|
import { OverpassLayer } from './OverpassLayer';
|
||||||
import OverpassPopup from './OverpassPopup.svelte';
|
|
||||||
|
|
||||||
let container: HTMLDivElement;
|
let container: HTMLDivElement;
|
||||||
let overpassLayer: OverpassLayer;
|
let overpassLayer: OverpassLayer;
|
||||||
@@ -34,7 +33,7 @@
|
|||||||
if ($map) {
|
if ($map) {
|
||||||
let basemap = basemaps.hasOwnProperty($currentBasemap)
|
let basemap = basemaps.hasOwnProperty($currentBasemap)
|
||||||
? basemaps[$currentBasemap]
|
? basemaps[$currentBasemap]
|
||||||
: $customLayers[$currentBasemap]?.value ?? basemaps[defaultBasemap];
|
: ($customLayers[$currentBasemap]?.value ?? basemaps[defaultBasemap]);
|
||||||
$map.removeImport('basemap');
|
$map.removeImport('basemap');
|
||||||
if (typeof basemap === 'string') {
|
if (typeof basemap === 'string') {
|
||||||
$map.addImport({ id: 'basemap', url: basemap }, 'overlays');
|
$map.addImport({ id: 'basemap', url: basemap }, 'overlays');
|
||||||
@@ -85,18 +84,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateOverlays() {
|
function updateOverlays() {
|
||||||
if ($map && $currentOverlays) {
|
if ($map && $currentOverlays && $opacities) {
|
||||||
let overlayLayers = getLayers($currentOverlays);
|
let overlayLayers = getLayers($currentOverlays);
|
||||||
try {
|
try {
|
||||||
let activeOverlays = $map
|
let activeOverlays = $map.getStyle().imports.reduce((acc, i) => {
|
||||||
.getStyle()
|
if (!['basemap', 'overlays', 'glyphs-and-sprite'].includes(i.id)) {
|
||||||
.imports.filter((i) => i.id !== 'basemap' && i.id !== 'overlays');
|
acc[i.id] = i;
|
||||||
let toRemove = activeOverlays.filter((i) => !overlayLayers[i.id]);
|
}
|
||||||
toRemove.forEach((i) => {
|
return acc;
|
||||||
$map.removeImport(i.id);
|
}, {});
|
||||||
|
let toRemove = Object.keys(activeOverlays).filter((id) => !overlayLayers[id]);
|
||||||
|
toRemove.forEach((id) => {
|
||||||
|
$map.removeImport(id);
|
||||||
});
|
});
|
||||||
let toAdd = Object.entries(overlayLayers)
|
let toAdd = Object.entries(overlayLayers)
|
||||||
.filter(([id, selected]) => selected && !activeOverlays.some((j) => j.id === id))
|
.filter(([id, selected]) => selected && !activeOverlays.hasOwnProperty(id))
|
||||||
.map(([id]) => id);
|
.map(([id]) => id);
|
||||||
toAdd.forEach((id) => {
|
toAdd.forEach((id) => {
|
||||||
addOverlay(id);
|
addOverlay(id);
|
||||||
@@ -107,7 +109,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if ($map && $currentOverlays) {
|
$: if ($map && $currentOverlays && $opacities) {
|
||||||
updateOverlays();
|
updateOverlays();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +132,9 @@
|
|||||||
});
|
});
|
||||||
currentBasemap.subscribe((value) => {
|
currentBasemap.subscribe((value) => {
|
||||||
// Updates coming from the database, or from the user swapping basemaps
|
// Updates coming from the database, or from the user swapping basemaps
|
||||||
selectedBasemap.set(value);
|
if (value !== get(selectedBasemap)) {
|
||||||
|
selectedBasemap.set(value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let open = false;
|
let open = false;
|
||||||
@@ -209,8 +213,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</CustomControl>
|
</CustomControl>
|
||||||
|
|
||||||
<OverpassPopup />
|
|
||||||
|
|
||||||
<svelte:window
|
<svelte:window
|
||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
if (open && !cancelEvents && !container.contains(e.target)) {
|
if (open && !cancelEvents && !container.contains(e.target)) {
|
||||||
|
@@ -157,15 +157,16 @@
|
|||||||
max={1}
|
max={1}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
disabled={$selectedOverlay === undefined}
|
disabled={$selectedOverlay === undefined}
|
||||||
onValueChange={() => {
|
onValueChange={(value) => {
|
||||||
if ($selectedOverlay) {
|
if ($selectedOverlay) {
|
||||||
$opacities[$selectedOverlay.value] = $overlayOpacity[0];
|
if ($map && isSelected($currentOverlays, $selectedOverlay.value)) {
|
||||||
if ($map) {
|
try {
|
||||||
if ($map.getLayer($selectedOverlay.value)) {
|
$map.removeImport($selectedOverlay.value);
|
||||||
$map.removeLayer($selectedOverlay.value);
|
} catch (e) {
|
||||||
$currentOverlays = $currentOverlays;
|
// No reliable way to check if the map is ready to remove sources and layers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$opacities[$selectedOverlay.value] = value[0];
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import SphericalMercator from "@mapbox/sphericalmercator";
|
import SphericalMercator from "@mapbox/sphericalmercator";
|
||||||
import { getLayers } from "./utils";
|
import { getLayers } from "./utils";
|
||||||
import mapboxgl from "mapbox-gl";
|
|
||||||
import { get, writable } from "svelte/store";
|
import { get, writable } from "svelte/store";
|
||||||
import { liveQuery } from "dexie";
|
import { liveQuery } from "dexie";
|
||||||
import { db, settings } from "$lib/db";
|
import { db, settings } from "$lib/db";
|
||||||
import { overpassQueryData } from "$lib/assets/layers";
|
import { overpassQueryData } from "$lib/assets/layers";
|
||||||
|
import { MapPopup } from "$lib/components/MapPopup";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
currentOverpassQueries
|
currentOverpassQueries
|
||||||
@@ -14,14 +14,6 @@ const mercator = new SphericalMercator({
|
|||||||
size: 256,
|
size: 256,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const overpassPopupPOI = writable<Record<string, any> | null>(null);
|
|
||||||
|
|
||||||
export const overpassPopup = new mapboxgl.Popup({
|
|
||||||
closeButton: false,
|
|
||||||
maxWidth: undefined,
|
|
||||||
offset: 15,
|
|
||||||
});
|
|
||||||
|
|
||||||
let data = writable<GeoJSON.FeatureCollection>({ type: 'FeatureCollection', features: [] });
|
let data = writable<GeoJSON.FeatureCollection>({ type: 'FeatureCollection', features: [] });
|
||||||
|
|
||||||
liveQuery(() => db.overpassdata.toArray()).subscribe((pois) => {
|
liveQuery(() => db.overpassdata.toArray()).subscribe((pois) => {
|
||||||
@@ -34,6 +26,7 @@ export class OverpassLayer {
|
|||||||
queryZoom = 12;
|
queryZoom = 12;
|
||||||
expirationTime = 7 * 24 * 3600 * 1000;
|
expirationTime = 7 * 24 * 3600 * 1000;
|
||||||
map: mapboxgl.Map;
|
map: mapboxgl.Map;
|
||||||
|
popup: MapPopup;
|
||||||
|
|
||||||
currentQueries: Set<string> = new Set();
|
currentQueries: Set<string> = new Set();
|
||||||
nextQueries: Map<string, { x: number, y: number, queries: string[] }> = new Map();
|
nextQueries: Map<string, { x: number, y: number, queries: string[] }> = new Map();
|
||||||
@@ -42,10 +35,15 @@ export class OverpassLayer {
|
|||||||
queryIfNeededBinded = this.queryIfNeeded.bind(this);
|
queryIfNeededBinded = this.queryIfNeeded.bind(this);
|
||||||
updateBinded = this.update.bind(this);
|
updateBinded = this.update.bind(this);
|
||||||
onHoverBinded = this.onHover.bind(this);
|
onHoverBinded = this.onHover.bind(this);
|
||||||
maybeHidePopupBinded = this.maybeHidePopup.bind(this);
|
|
||||||
|
|
||||||
constructor(map: mapboxgl.Map) {
|
constructor(map: mapboxgl.Map) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
|
this.popup = new MapPopup(map, {
|
||||||
|
closeButton: false,
|
||||||
|
focusAfterOpen: false,
|
||||||
|
maxWidth: undefined,
|
||||||
|
offset: 15,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
@@ -125,27 +123,12 @@ export class OverpassLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHover(e: any) {
|
onHover(e: any) {
|
||||||
overpassPopupPOI.set({
|
this.popup.setItem({
|
||||||
...e.features[0].properties,
|
item: {
|
||||||
sym: overpassQueryData[e.features[0].properties.query].symbol ?? ''
|
...e.features[0].properties,
|
||||||
|
sym: overpassQueryData[e.features[0].properties.query].symbol ?? ''
|
||||||
|
}
|
||||||
});
|
});
|
||||||
overpassPopup.setLngLat(e.features[0].geometry.coordinates);
|
|
||||||
overpassPopup.addTo(this.map);
|
|
||||||
this.map.on('mousemove', this.maybeHidePopupBinded);
|
|
||||||
}
|
|
||||||
|
|
||||||
maybeHidePopup(e: any) {
|
|
||||||
let poi = get(overpassPopupPOI);
|
|
||||||
if (poi && this.map.project([poi.lon, poi.lat]).dist(this.map.project(e.lngLat)) > 100) {
|
|
||||||
this.hideWaypointPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hideWaypointPopup() {
|
|
||||||
overpassPopupPOI.set(null);
|
|
||||||
overpassPopup.remove();
|
|
||||||
|
|
||||||
this.map.off('mousemove', this.maybeHidePopupBinded);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query(bbox: [number, number, number, number]) {
|
query(bbox: [number, number, number, number]) {
|
||||||
|
@@ -1,102 +1,95 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { overpassPopup, overpassPopupPOI } from './OverpassLayer';
|
|
||||||
import { selection } from '$lib/components/file-list/Selection';
|
import { selection } from '$lib/components/file-list/Selection';
|
||||||
import { PencilLine, MapPin } from 'lucide-svelte';
|
import { PencilLine, MapPin } from 'lucide-svelte';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
import { dbUtils } from '$lib/db';
|
import { dbUtils } from '$lib/db';
|
||||||
|
import type { PopupItem } from '$lib/components/MapPopup';
|
||||||
|
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
|
||||||
|
|
||||||
let popupElement: HTMLDivElement;
|
export let poi: PopupItem<any>;
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
overpassPopup.setDOMContent(popupElement);
|
|
||||||
popupElement.classList.remove('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
let tags = {};
|
let tags = {};
|
||||||
let name = '';
|
let name = '';
|
||||||
$: if ($overpassPopupPOI) {
|
$: if (poi) {
|
||||||
tags = JSON.parse($overpassPopupPOI.tags);
|
tags = JSON.parse(poi.item.tags);
|
||||||
if (tags.name !== undefined && tags.name !== '') {
|
if (tags.name !== undefined && tags.name !== '') {
|
||||||
name = tags.name;
|
name = tags.name;
|
||||||
} else {
|
} else {
|
||||||
name = $_(`layers.label.${$overpassPopupPOI.query}`);
|
name = $_(`layers.label.${poi.item.query}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={popupElement} class="hidden">
|
<Card.Root class="border-none shadow-md text-base p-2 max-w-[50dvw]">
|
||||||
{#if $overpassPopupPOI}
|
<Card.Header class="p-0">
|
||||||
<Card.Root class="border-none shadow-md text-base p-2 max-w-[50dvw]">
|
<Card.Title class="text-md">
|
||||||
<Card.Header class="p-0">
|
<div class="flex flex-row gap-3">
|
||||||
<Card.Title class="text-md">
|
<div class="flex flex-col">
|
||||||
<div class="flex flex-row gap-3">
|
{name}
|
||||||
<div class="flex flex-col">
|
<div class="text-muted-foreground text-sm font-normal">
|
||||||
{name}
|
{poi.item.lat.toFixed(6)}° {poi.item.lon.toFixed(6)}°
|
||||||
<div class="text-muted-foreground text-sm font-normal">
|
|
||||||
{$overpassPopupPOI.lat.toFixed(6)}° {$overpassPopupPOI.lon.toFixed(6)}°
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
class="ml-auto p-1.5 h-8"
|
|
||||||
variant="outline"
|
|
||||||
href="https://www.openstreetmap.org/edit?editor=id&node={$overpassPopupPOI.id}"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<PencilLine size="16" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Card.Title>
|
</div>
|
||||||
</Card.Header>
|
<Button
|
||||||
|
class="ml-auto p-1.5 h-8"
|
||||||
|
variant="outline"
|
||||||
|
href="https://www.openstreetmap.org/edit?editor=id&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">
|
||||||
|
<ScrollArea class="flex flex-col" viewportClasses="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">
|
||||||
<!-- svelte-ignore a11y-missing-attribute -->
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
<img src={tags.image ?? tags['image:0']} />
|
<img src={tags.image ?? tags['image:0']} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Card.Content class="flex flex-col p-0 text-sm mt-1 whitespace-normal break-all">
|
<div class="grid grid-cols-[auto_auto] gap-x-3">
|
||||||
<div class="grid grid-cols-[auto_auto] gap-x-3">
|
{#each Object.entries(tags) as [key, value]}
|
||||||
{#each Object.entries(tags) as [key, value]}
|
{#if key !== 'name' && !key.includes('image')}
|
||||||
{#if key !== 'name' && !key.includes('image')}
|
<span class="font-mono">{key}</span>
|
||||||
<span class="font-mono">{key}</span>
|
{#if key === 'website' || key.startsWith('website:') || key === 'contact:website' || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'}
|
||||||
{#if key === 'website' || key === 'contact:website' || key === 'contact:facebook' || key === 'contact:instagram' || key === 'contact:twitter'}
|
<a href={value} target="_blank" class="text-link underline">{value}</a>
|
||||||
<a href={value} target="_blank" class="text-link underline">{value}</a>
|
{:else if key === 'phone' || key === 'contact:phone'}
|
||||||
{:else if key === 'phone' || key === 'contact:phone'}
|
<a href={'tel:' + value} class="text-link underline">{value}</a>
|
||||||
<a href={'tel:' + value} class="text-link underline">{value}</a>
|
{:else if key === 'email' || key === 'contact:email'}
|
||||||
{:else if key === 'email' || key === 'contact:email'}
|
<a href={'mailto:' + value} class="text-link underline">{value}</a>
|
||||||
<a href={'mailto:' + value} class="text-link underline">{value}</a>
|
{:else}
|
||||||
{:else}
|
<span>{value}</span>
|
||||||
<span>{value}</span>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/if}
|
||||||
</div>
|
{/each}
|
||||||
<Button
|
</div>
|
||||||
class="mt-2"
|
</ScrollArea>
|
||||||
variant="outline"
|
<Button
|
||||||
disabled={$selection.size === 0}
|
class="mt-2"
|
||||||
on:click={() => {
|
variant="outline"
|
||||||
let desc = Object.entries(tags)
|
disabled={$selection.size === 0}
|
||||||
.map(([key, value]) => `${key}: ${value}`)
|
on:click={() => {
|
||||||
.join('\n');
|
let desc = Object.entries(tags)
|
||||||
dbUtils.addOrUpdateWaypoint({
|
.map(([key, value]) => `${key}: ${value}`)
|
||||||
attributes: {
|
.join('\n');
|
||||||
lat: $overpassPopupPOI.lat,
|
dbUtils.addOrUpdateWaypoint({
|
||||||
lon: $overpassPopupPOI.lon
|
attributes: {
|
||||||
},
|
lat: poi.item.lat,
|
||||||
name: name,
|
lon: poi.item.lon
|
||||||
desc: desc,
|
},
|
||||||
cmt: desc,
|
name: name,
|
||||||
sym: $overpassPopupPOI.sym
|
desc: desc,
|
||||||
});
|
cmt: desc,
|
||||||
}}
|
sym: poi.item.sym
|
||||||
>
|
});
|
||||||
<MapPin size="16" class="mr-1" />
|
}}
|
||||||
{$_('toolbar.waypoint.add')}
|
>
|
||||||
</Button>
|
<MapPin size="16" class="mr-1" />
|
||||||
</Card.Content>
|
{$_('toolbar.waypoint.add')}
|
||||||
</Card.Root>
|
</Button>
|
||||||
{/if}
|
</Card.Content>
|
||||||
</div>
|
</Card.Root>
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
import mapboxgl from "mapbox-gl";
|
import mapboxgl, { type LayerSpecification, type VectorSourceSpecification } from "mapbox-gl";
|
||||||
import { Viewer } 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 { resetCursor, setPointerCursor } from "$lib/utils";
|
import { resetCursor, setPointerCursor } from "$lib/utils";
|
||||||
|
import type { Writable } from "svelte/store";
|
||||||
|
|
||||||
const mapillarySource = {
|
const mapillarySource: VectorSourceSpecification = {
|
||||||
type: 'vector',
|
type: 'vector',
|
||||||
tiles: ['https://tiles.mapillary.com/maps/vtp/mly1_computed_public/2/{z}/{x}/{y}?access_token=MLY|4381405525255083|3204871ec181638c3c31320490f03011'],
|
tiles: ['https://tiles.mapillary.com/maps/vtp/mly1_computed_public/2/{z}/{x}/{y}?access_token=MLY|4381405525255083|3204871ec181638c3c31320490f03011'],
|
||||||
minzoom: 6,
|
minzoom: 6,
|
||||||
maxzoom: 14,
|
maxzoom: 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapillarySequenceLayer = {
|
const mapillarySequenceLayer: LayerSpecification = {
|
||||||
id: 'mapillary-sequence',
|
id: 'mapillary-sequence',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
source: 'mapillary',
|
source: 'mapillary',
|
||||||
@@ -26,7 +27,7 @@ const mapillarySequenceLayer = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapillaryImageLayer = {
|
const mapillaryImageLayer: LayerSpecification = {
|
||||||
id: 'mapillary-image',
|
id: 'mapillary-image',
|
||||||
type: 'circle',
|
type: 'circle',
|
||||||
source: 'mapillary',
|
source: 'mapillary',
|
||||||
@@ -40,35 +41,56 @@ const mapillaryImageLayer = {
|
|||||||
|
|
||||||
export class MapillaryLayer {
|
export class MapillaryLayer {
|
||||||
map: mapboxgl.Map;
|
map: mapboxgl.Map;
|
||||||
popup: mapboxgl.Popup;
|
marker: mapboxgl.Marker;
|
||||||
viewer: Viewer;
|
viewer: Viewer;
|
||||||
|
|
||||||
|
active = false;
|
||||||
|
popupOpen: Writable<boolean>;
|
||||||
|
|
||||||
addBinded = this.add.bind(this);
|
addBinded = this.add.bind(this);
|
||||||
onMouseEnterBinded = this.onMouseEnter.bind(this);
|
onMouseEnterBinded = this.onMouseEnter.bind(this);
|
||||||
onMouseLeaveBinded = this.onMouseLeave.bind(this);
|
onMouseLeaveBinded = this.onMouseLeave.bind(this);
|
||||||
|
|
||||||
constructor(map: mapboxgl.Map, container: HTMLElement) {
|
constructor(map: mapboxgl.Map, container: HTMLElement, popupOpen: Writable<boolean>) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
|
|
||||||
this.viewer = new Viewer({
|
this.viewer = new Viewer({
|
||||||
accessToken: 'MLY|4381405525255083|3204871ec181638c3c31320490f03011',
|
accessToken: 'MLY|4381405525255083|3204871ec181638c3c31320490f03011',
|
||||||
container,
|
container,
|
||||||
});
|
});
|
||||||
container.classList.remove('hidden');
|
|
||||||
|
|
||||||
this.popup = new mapboxgl.Popup({
|
const element = document.createElement('div');
|
||||||
closeButton: false,
|
element.className = 'mapboxgl-user-location mapboxgl-user-location-show-heading';
|
||||||
maxWidth: container.style.width,
|
const dot = document.createElement('div');
|
||||||
}).setDOMContent(container);
|
dot.className = 'mapboxgl-user-location-dot';
|
||||||
|
const heading = document.createElement('div');
|
||||||
|
heading.className = 'mapboxgl-user-location-heading';
|
||||||
|
element.appendChild(dot);
|
||||||
|
element.appendChild(heading);
|
||||||
|
|
||||||
|
this.marker = new mapboxgl.Marker({
|
||||||
|
rotationAlignment: 'map',
|
||||||
|
element
|
||||||
|
});
|
||||||
|
|
||||||
this.viewer.on('position', async () => {
|
this.viewer.on('position', async () => {
|
||||||
if (this.popup.isOpen()) {
|
if (this.active) {
|
||||||
|
popupOpen.set(true);
|
||||||
let latLng = await this.viewer.getPosition();
|
let latLng = await this.viewer.getPosition();
|
||||||
this.popup.setLngLat(latLng);
|
this.marker.setLngLat(latLng).addTo(this.map);
|
||||||
if (!this.map.getBounds().contains(latLng)) {
|
if (!this.map.getBounds()?.contains(latLng)) {
|
||||||
this.map.panTo(latLng);
|
this.map.panTo(latLng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.viewer.on('bearing', (e: ViewerBearingEvent) => {
|
||||||
|
if (this.active) {
|
||||||
|
this.marker.setRotation(e.bearing);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.popupOpen = popupOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
@@ -101,15 +123,19 @@ export class MapillaryLayer {
|
|||||||
this.map.removeSource('mapillary');
|
this.map.removeSource('mapillary');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.popup.remove();
|
this.marker.remove();
|
||||||
|
this.popupOpen.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
closePopup() {
|
closePopup() {
|
||||||
this.popup.remove();
|
this.active = false;
|
||||||
|
this.marker.remove();
|
||||||
|
this.popupOpen.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseEnter(e: mapboxgl.MapLayerMouseEvent) {
|
onMouseEnter(e: mapboxgl.MapMouseEvent) {
|
||||||
this.popup.addTo(this.map).setLngLat(e.lngLat);
|
this.active = true;
|
||||||
|
|
||||||
this.viewer.resize();
|
this.viewer.resize();
|
||||||
this.viewer.moveTo(e.features[0].properties.id);
|
this.viewer.moveTo(e.features[0].properties.id);
|
||||||
|
|
||||||
|
@@ -8,16 +8,18 @@
|
|||||||
import { map, streetViewEnabled } from '$lib/stores';
|
import { map, streetViewEnabled } from '$lib/stores';
|
||||||
import { settings } from '$lib/db';
|
import { settings } from '$lib/db';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
const { streetViewSource } = settings;
|
const { streetViewSource } = settings;
|
||||||
|
|
||||||
let googleRedirect: GoogleRedirect;
|
let googleRedirect: GoogleRedirect;
|
||||||
let mapillaryLayer: MapillaryLayer;
|
let mapillaryLayer: MapillaryLayer;
|
||||||
|
let mapillaryOpen = writable(false);
|
||||||
let container: HTMLElement;
|
let container: HTMLElement;
|
||||||
|
|
||||||
$: if ($map) {
|
$: if ($map) {
|
||||||
googleRedirect = new GoogleRedirect($map);
|
googleRedirect = new GoogleRedirect($map);
|
||||||
mapillaryLayer = new MapillaryLayer($map, container);
|
mapillaryLayer = new MapillaryLayer($map, container, mapillaryOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (mapillaryLayer) {
|
$: if (mapillaryLayer) {
|
||||||
@@ -53,7 +55,9 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={container}
|
bind:this={container}
|
||||||
class="hidden relative w-[50vw] h-[40vh] rounded-md border-background border-2"
|
class="{$mapillaryOpen
|
||||||
|
? ''
|
||||||
|
: 'hidden'} !absolute bottom-[44px] right-2.5 z-10 w-[40%] h-[40%] bg-background rounded-md overflow-hidden border-background border-2"
|
||||||
>
|
>
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
|
@@ -11,15 +11,18 @@
|
|||||||
import { selection } from '$lib/components/file-list/Selection';
|
import { selection } from '$lib/components/file-list/Selection';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { Label } from '$lib/components/ui/label/index.js';
|
import { Label } from '$lib/components/ui/label/index.js';
|
||||||
|
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||||
import * as RadioGroup from '$lib/components/ui/radio-group';
|
import * as RadioGroup from '$lib/components/ui/radio-group';
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _, locale } from 'svelte-i18n';
|
||||||
import { dbUtils, getFile } from '$lib/db';
|
import { dbUtils, getFile } from '$lib/db';
|
||||||
import { Group } from 'lucide-svelte';
|
import { Group } from 'lucide-svelte';
|
||||||
import { getURLForLanguage } from '$lib/utils';
|
import { getURLForLanguage } from '$lib/utils';
|
||||||
import Shortcut from '$lib/components/Shortcut.svelte';
|
import Shortcut from '$lib/components/Shortcut.svelte';
|
||||||
|
import { gpxStatistics } from '$lib/stores';
|
||||||
|
|
||||||
let canMergeTraces = false;
|
let canMergeTraces = false;
|
||||||
let canMergeContents = false;
|
let canMergeContents = false;
|
||||||
|
let removeGaps = false;
|
||||||
|
|
||||||
$: if ($selection.size > 1) {
|
$: if ($selection.size > 1) {
|
||||||
canMergeTraces = true;
|
canMergeTraces = true;
|
||||||
@@ -56,22 +59,31 @@
|
|||||||
|
|
||||||
<div class="flex flex-col gap-3 w-full max-w-80 {$$props.class ?? ''}">
|
<div class="flex flex-col gap-3 w-full max-w-80 {$$props.class ?? ''}">
|
||||||
<RadioGroup.Root bind:value={mergeType}>
|
<RadioGroup.Root bind:value={mergeType}>
|
||||||
<Label class="flex flex-row items-center gap-2 leading-5">
|
<Label class="flex flex-row items-center gap-1.5 leading-5">
|
||||||
<RadioGroup.Item value={MergeType.TRACES} />
|
<RadioGroup.Item value={MergeType.TRACES} />
|
||||||
{$_('toolbar.merge.merge_traces')}
|
{$_('toolbar.merge.merge_traces')}
|
||||||
</Label>
|
</Label>
|
||||||
<Label class="flex flex-row items-center gap-2 leading-5">
|
<Label class="flex flex-row items-center gap-1.5 leading-5">
|
||||||
<RadioGroup.Item value={MergeType.CONTENTS} />
|
<RadioGroup.Item value={MergeType.CONTENTS} />
|
||||||
{$_('toolbar.merge.merge_contents')}
|
{$_('toolbar.merge.merge_contents')}
|
||||||
</Label>
|
</Label>
|
||||||
</RadioGroup.Root>
|
</RadioGroup.Root>
|
||||||
|
{#if mergeType === MergeType.TRACES && $gpxStatistics.global.time.total > 0}
|
||||||
|
<div class="flex flex-row items-center gap-1.5">
|
||||||
|
<Checkbox id="remove-gaps" bind:checked={removeGaps} />
|
||||||
|
<Label for="remove-gaps">{$_('toolbar.merge.remove_gaps')}</Label>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="whitespace-normal h-fit"
|
class="whitespace-normal h-fit"
|
||||||
disabled={(mergeType === MergeType.TRACES && !canMergeTraces) ||
|
disabled={(mergeType === MergeType.TRACES && !canMergeTraces) ||
|
||||||
(mergeType === MergeType.CONTENTS && !canMergeContents)}
|
(mergeType === MergeType.CONTENTS && !canMergeContents)}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
dbUtils.mergeSelection(mergeType === MergeType.TRACES);
|
dbUtils.mergeSelection(
|
||||||
|
mergeType === MergeType.TRACES,
|
||||||
|
mergeType === MergeType.TRACES && $gpxStatistics.global.time.total > 0 && removeGaps
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Group size="16" class="mr-1 shrink-0" />
|
<Group size="16" class="mr-1 shrink-0" />
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
import { Switch } from '$lib/components/ui/switch';
|
import { Switch } from '$lib/components/ui/switch';
|
||||||
import { Label } from '$lib/components/ui/label/index.js';
|
import { Label } from '$lib/components/ui/label/index.js';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import * as RadioGroup from '$lib/components/ui/radio-group';
|
||||||
import Help from '$lib/components/Help.svelte';
|
import Help from '$lib/components/Help.svelte';
|
||||||
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
|
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
|
||||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||||
@@ -19,16 +20,22 @@
|
|||||||
RouteOff,
|
RouteOff,
|
||||||
Repeat,
|
Repeat,
|
||||||
SquareArrowUpLeft,
|
SquareArrowUpLeft,
|
||||||
SquareArrowOutDownRight
|
SquareArrowOutDownRight,
|
||||||
|
Timer
|
||||||
} from 'lucide-svelte';
|
} from 'lucide-svelte';
|
||||||
|
|
||||||
import { map, newGPXFile, routingControls, selectFileWhenLoaded } from '$lib/stores';
|
import {
|
||||||
|
gpxStatistics,
|
||||||
|
map,
|
||||||
|
newGPXFile,
|
||||||
|
routingControls,
|
||||||
|
selectFileWhenLoaded
|
||||||
|
} from '$lib/stores';
|
||||||
import { dbUtils, getFile, getFileIds, settings } from '$lib/db';
|
import { dbUtils, getFile, getFileIds, settings } from '$lib/db';
|
||||||
import { brouterProfiles, routingProfileSelectItem } from './Routing';
|
import { brouterProfiles, routingProfileSelectItem } from './Routing';
|
||||||
|
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _, locale } from 'svelte-i18n';
|
||||||
import { RoutingControls } from './RoutingControls';
|
import { RoutingControls } from './RoutingControls';
|
||||||
import mapboxgl from 'mapbox-gl';
|
|
||||||
import { fileObservers } from '$lib/db';
|
import { fileObservers } from '$lib/db';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { getOrderedSelection, selection } from '$lib/components/file-list/Selection';
|
import { getOrderedSelection, selection } from '$lib/components/file-list/Selection';
|
||||||
@@ -40,6 +47,7 @@
|
|||||||
type ListItem
|
type ListItem
|
||||||
} from '$lib/components/file-list/FileList';
|
} from '$lib/components/file-list/FileList';
|
||||||
import { flyAndScale, getURLForLanguage, resetCursor, setCrosshairCursor } from '$lib/utils';
|
import { flyAndScale, getURLForLanguage, resetCursor, setCrosshairCursor } from '$lib/utils';
|
||||||
|
import { TimestampsMode } from '$lib/types';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import { TrackPoint } from 'gpx';
|
import { TrackPoint } from 'gpx';
|
||||||
|
|
||||||
@@ -49,7 +57,7 @@
|
|||||||
export let popupElement: HTMLElement | undefined = undefined;
|
export let popupElement: HTMLElement | undefined = undefined;
|
||||||
let selectedItem: ListItem | null = null;
|
let selectedItem: ListItem | null = null;
|
||||||
|
|
||||||
const { privateRoads, routing } = settings;
|
const { privateRoads, routing, timestampsMode } = settings;
|
||||||
|
|
||||||
$: if ($map && popup && popupElement) {
|
$: if ($map && popup && popupElement) {
|
||||||
// remove controls for deleted files
|
// remove controls for deleted files
|
||||||
@@ -161,7 +169,7 @@
|
|||||||
</Select.Root>
|
</Select.Root>
|
||||||
</Label>
|
</Label>
|
||||||
<Label class="flex flex-row justify-between items-center gap-2">
|
<Label class="flex flex-row justify-between items-center gap-2">
|
||||||
<span class="flex flex-row gap-1">
|
<span class="flex flex-row items-center gap-1">
|
||||||
<TriangleAlert size="16" />
|
<TriangleAlert size="16" />
|
||||||
{$_('toolbar.routing.allow_private')}
|
{$_('toolbar.routing.allow_private')}
|
||||||
</span>
|
</span>
|
||||||
@@ -169,6 +177,28 @@
|
|||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $gpxStatistics.global.time.total > 0}
|
||||||
|
<RadioGroup.Root bind:value={$timestampsMode}>
|
||||||
|
<div class="flex flex-row items-center gap-2">
|
||||||
|
<RadioGroup.Item
|
||||||
|
value={TimestampsMode.PRESERVE_AVERAGE_SPEED}
|
||||||
|
id={TimestampsMode.PRESERVE_AVERAGE_SPEED}
|
||||||
|
/>
|
||||||
|
<Label for={TimestampsMode.PRESERVE_AVERAGE_SPEED}>
|
||||||
|
{$_('toolbar.routing.preserve_average_speed')}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row items-center gap-2">
|
||||||
|
<RadioGroup.Item
|
||||||
|
value={TimestampsMode.PRESERVE_TIMESTAMPS}
|
||||||
|
id={TimestampsMode.PRESERVE_TIMESTAMPS}
|
||||||
|
/>
|
||||||
|
<Label for={TimestampsMode.PRESERVE_TIMESTAMPS}>
|
||||||
|
{$_('toolbar.routing.preserve_timestamps')}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
</RadioGroup.Root>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row flex-wrap justify-center gap-1">
|
<div class="flex flex-row flex-wrap justify-center gap-1">
|
||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
|
@@ -3,7 +3,6 @@ import { TrackPoint, distance } from "gpx";
|
|||||||
import { derived, get, writable } from "svelte/store";
|
import { derived, get, writable } from "svelte/store";
|
||||||
import { settings } from "$lib/db";
|
import { settings } from "$lib/db";
|
||||||
import { _, isLoading, locale } from "svelte-i18n";
|
import { _, isLoading, locale } from "svelte-i18n";
|
||||||
import { map } from "$lib/stores";
|
|
||||||
import { getElevation } from "$lib/utils";
|
import { getElevation } from "$lib/utils";
|
||||||
|
|
||||||
const { routing, routingProfile, privateRoads } = settings;
|
const { routing, routingProfile, privateRoads } = settings;
|
||||||
@@ -66,7 +65,7 @@ async function getRoute(points: Coordinates[], brouterProfile: string, privateRo
|
|||||||
const latIdx = messages[0].indexOf("Latitude");
|
const latIdx = messages[0].indexOf("Latitude");
|
||||||
const tagIdx = messages[0].indexOf("WayTags");
|
const tagIdx = messages[0].indexOf("WayTags");
|
||||||
let messageIdx = 1;
|
let messageIdx = 1;
|
||||||
let surface = messageIdx < messages.length ? getSurface(messages[messageIdx][tagIdx]) : undefined;
|
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];
|
let coord = coordinates[i];
|
||||||
@@ -83,25 +82,26 @@ async function getRoute(points: Coordinates[], brouterProfile: string, privateRo
|
|||||||
coordinates[i][1] == Number(messages[messageIdx][latIdx]) / 1000000) {
|
coordinates[i][1] == Number(messages[messageIdx][latIdx]) / 1000000) {
|
||||||
messageIdx++;
|
messageIdx++;
|
||||||
|
|
||||||
if (messageIdx == messages.length) surface = undefined;
|
if (messageIdx == messages.length) tags = {};
|
||||||
else surface = getSurface(messages[messageIdx][tagIdx]);
|
else tags = getTags(messages[messageIdx][tagIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface) {
|
route[route.length - 1].setExtensions(tags);
|
||||||
route[route.length - 1].setSurface(surface);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSurface(message: string): string | undefined {
|
function getTags(message: string): { [key: string]: string } {
|
||||||
const fields = message.split(" ");
|
const fields = message.split(" ");
|
||||||
for (let i = 0; i < fields.length; i++) if (fields[i].startsWith("surface=")) {
|
let tags: { [key: string]: string } = {};
|
||||||
return fields[i].substring(8);
|
for (let i = 0; i < fields.length; i++) {
|
||||||
|
let [key, value] = fields[i].split("=");
|
||||||
|
key = key.replace(/:/g, '_');
|
||||||
|
tags[key] = value;
|
||||||
}
|
}
|
||||||
return undefined;
|
return tags;
|
||||||
};
|
}
|
||||||
|
|
||||||
function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> {
|
function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> {
|
||||||
let route: TrackPoint[] = [];
|
let route: TrackPoint[] = [];
|
||||||
|
@@ -2,15 +2,16 @@ import { distance, type Coordinates, TrackPoint, TrackSegment, Track, projectedP
|
|||||||
import { get, writable, type Readable } from "svelte/store";
|
import { get, writable, type Readable } from "svelte/store";
|
||||||
import mapboxgl from "mapbox-gl";
|
import mapboxgl from "mapbox-gl";
|
||||||
import { route } from "./Routing";
|
import { route } from "./Routing";
|
||||||
|
|
||||||
import { toast } from "svelte-sonner";
|
import { toast } from "svelte-sonner";
|
||||||
|
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { dbUtils, type GPXFileWithStatistics } from "$lib/db";
|
import { dbUtils, settings, type GPXFileWithStatistics } from "$lib/db";
|
||||||
import { getOrderedSelection, selection } from "$lib/components/file-list/Selection";
|
import { getOrderedSelection, selection } from "$lib/components/file-list/Selection";
|
||||||
import { ListFileItem, ListTrackItem, ListTrackSegmentItem } from "$lib/components/file-list/FileList";
|
import { ListFileItem, ListTrackItem, ListTrackSegmentItem } from "$lib/components/file-list/FileList";
|
||||||
import { currentTool, streetViewEnabled, Tool } from "$lib/stores";
|
import { currentTool, streetViewEnabled, Tool } from "$lib/stores";
|
||||||
import { getClosestLinePoint, resetCursor, setGrabbingCursor } from "$lib/utils";
|
import { getClosestLinePoint, resetCursor, setGrabbingCursor } from "$lib/utils";
|
||||||
|
import { TimestampsMode } from "$lib/types";
|
||||||
|
|
||||||
|
const { streetViewSource, timestampsMode } = settings;
|
||||||
|
|
||||||
export const canChangeStart = writable(false);
|
export const canChangeStart = writable(false);
|
||||||
|
|
||||||
@@ -458,7 +459,7 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async appendAnchor(e: mapboxgl.MapMouseEvent) { // Add a new anchor to the end of the last segment
|
async appendAnchor(e: mapboxgl.MapMouseEvent) { // Add a new anchor to the end of the last segment
|
||||||
if (get(streetViewEnabled)) {
|
if (get(streetViewEnabled) && get(streetViewSource) === 'google') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,9 +575,11 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (anchors[0].point._data.index === 0) { // First anchor is the first point of the segment
|
if (anchors[0].point._data.index === 0) { // First anchor is the first point of the segment
|
||||||
|
response[0].time = anchors[0].point.time;
|
||||||
anchors[0].point = response[0]; // replace the first anchor
|
anchors[0].point = response[0]; // replace the first anchor
|
||||||
anchors[0].point._data.index = 0;
|
anchors[0].point._data.index = 0;
|
||||||
} else if (anchors[0].point._data.index === segment.trkpt.length - 1 && distance(anchors[0].point.getCoordinates(), response[0].getCoordinates()) < 1) { // First anchor is the last point of the segment, and the new point is close enough
|
} else if (anchors[0].point._data.index === segment.trkpt.length - 1 && distance(anchors[0].point.getCoordinates(), response[0].getCoordinates()) < 1) { // First anchor is the last point of the segment, and the new point is close enough
|
||||||
|
response[0].time = anchors[0].point.time;
|
||||||
anchors[0].point = response[0]; // replace the first anchor
|
anchors[0].point = response[0]; // replace the first anchor
|
||||||
anchors[0].point._data.index = segment.trkpt.length - 1;
|
anchors[0].point._data.index = segment.trkpt.length - 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -585,6 +588,7 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (anchors[anchors.length - 1].point._data.index === segment.trkpt.length - 1) { // Last anchor is the last point of the segment
|
if (anchors[anchors.length - 1].point._data.index === segment.trkpt.length - 1) { // Last anchor is the last point of the segment
|
||||||
|
response[response.length - 1].time = anchors[anchors.length - 1].point.time;
|
||||||
anchors[anchors.length - 1].point = response[response.length - 1]; // replace the last anchor
|
anchors[anchors.length - 1].point = response[response.length - 1]; // replace the last anchor
|
||||||
anchors[anchors.length - 1].point._data.index = segment.trkpt.length - 1;
|
anchors[anchors.length - 1].point._data.index = segment.trkpt.length - 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -608,20 +612,40 @@ export class RoutingControls {
|
|||||||
let startTime = anchors[0].point.time;
|
let startTime = anchors[0].point.time;
|
||||||
|
|
||||||
if (stats.global.speed.moving > 0) {
|
if (stats.global.speed.moving > 0) {
|
||||||
|
let replacingTime = 0;
|
||||||
|
|
||||||
|
if (get(timestampsMode) === TimestampsMode.PRESERVE_TIMESTAMPS) {
|
||||||
|
this.extendResponseToContiguousAdaptedTimePoints(segment, anchors, response);
|
||||||
|
|
||||||
|
response.forEach((point) => point.time = undefined);
|
||||||
|
startTime = anchors[0].point.time;
|
||||||
|
|
||||||
|
replacingTime = stats.local.time.total[anchors[anchors.length - 1].point._data.index] - stats.local.time.total[anchors[0].point._data.index];
|
||||||
|
|
||||||
|
if (replacingTime > 0) {
|
||||||
|
for (let i = 1; i < anchors.length - 1; i++) {
|
||||||
|
anchors[i].point._data['adapted_time'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let replacingDistance = 0;
|
let replacingDistance = 0;
|
||||||
for (let i = 1; i < response.length; i++) {
|
for (let i = 1; i < response.length; i++) {
|
||||||
replacingDistance += distance(response[i - 1].getCoordinates(), response[i].getCoordinates()) / 1000;
|
replacingDistance += distance(response[i - 1].getCoordinates(), response[i].getCoordinates()) / 1000;
|
||||||
}
|
}
|
||||||
let replacedDistance = stats.local.distance.moving[anchors[anchors.length - 1].point._data.index] - stats.local.distance.moving[anchors[0].point._data.index];
|
|
||||||
|
|
||||||
let newDistance = stats.global.distance.moving + replacingDistance - replacedDistance;
|
if (get(timestampsMode) === TimestampsMode.PRESERVE_AVERAGE_SPEED || replacingTime === 0) {
|
||||||
let newTime = newDistance / stats.global.speed.moving * 3600;
|
let replacedDistance = stats.local.distance.moving[anchors[anchors.length - 1].point._data.index] - stats.local.distance.moving[anchors[0].point._data.index];
|
||||||
|
|
||||||
let remainingTime = stats.global.time.moving - (stats.local.time.moving[anchors[anchors.length - 1].point._data.index] - stats.local.time.moving[anchors[0].point._data.index]);
|
let newDistance = stats.global.distance.moving + replacingDistance - replacedDistance;
|
||||||
let replacingTime = newTime - remainingTime;
|
let newTime = newDistance / stats.global.speed.moving * 3600;
|
||||||
|
|
||||||
if (replacingTime <= 0) { // Fallback to simple time difference
|
let remainingTime = stats.global.time.moving - (stats.local.time.moving[anchors[anchors.length - 1].point._data.index] - stats.local.time.moving[anchors[0].point._data.index]);
|
||||||
replacingTime = stats.local.time.total[anchors[anchors.length - 1].point._data.index] - stats.local.time.total[anchors[0].point._data.index];
|
replacingTime = newTime - remainingTime;
|
||||||
|
|
||||||
|
if (replacingTime <= 0) { // Fallback to simple time difference
|
||||||
|
replacingTime = stats.local.time.total[anchors[anchors.length - 1].point._data.index] - stats.local.time.total[anchors[0].point._data.index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
speed = replacingDistance / replacingTime * 3600;
|
speed = replacingDistance / replacingTime * 3600;
|
||||||
@@ -637,6 +661,41 @@ export class RoutingControls {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extendResponseToContiguousAdaptedTimePoints(segment: TrackSegment, anchors: Anchor[], response: TrackPoint[]) {
|
||||||
|
while (anchors[0].point._data.adapted_time) {
|
||||||
|
let previousAnchor = null;
|
||||||
|
for (let i = 0; i < this.anchors.length; i++) {
|
||||||
|
if (this.anchors[i].point._data.index < anchors[0].point._data.index) {
|
||||||
|
previousAnchor = this.anchors[i];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (previousAnchor === null) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
response.splice(0, 0, ...segment.trkpt.slice(previousAnchor.point._data.index, anchors[0].point._data.index).map((point) => point.clone()));
|
||||||
|
anchors.splice(0, 0, previousAnchor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (anchors[anchors.length - 1].point._data.adapted_time) {
|
||||||
|
let nextAnchor = null;
|
||||||
|
for (let i = this.anchors.length - 1; i >= 0; i--) {
|
||||||
|
if (this.anchors[i].point._data.index > anchors[anchors.length - 1].point._data.index) {
|
||||||
|
nextAnchor = this.anchors[i];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextAnchor === null) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
response.push(...segment.trkpt.slice(anchors[anchors.length - 1].point._data.index + 1, nextAnchor.point._data.index + 1).map((point) => point.clone()));
|
||||||
|
anchors.push(nextAnchor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.remove();
|
this.remove();
|
||||||
this.unsubscribes.forEach((unsubscribe) => unsubscribe());
|
this.unsubscribes.forEach((unsubscribe) => unsubscribe());
|
||||||
|
@@ -1,31 +1,33 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ScrollArea as ScrollAreaPrimitive } from "bits-ui";
|
import { ScrollArea as ScrollAreaPrimitive } from 'bits-ui';
|
||||||
import { Scrollbar } from "./index.js";
|
import { Scrollbar } from './index.js';
|
||||||
import { cn } from "$lib/utils.js";
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
type $$Props = ScrollAreaPrimitive.Props & {
|
type $$Props = ScrollAreaPrimitive.Props & {
|
||||||
orientation?: "vertical" | "horizontal" | "both";
|
orientation?: 'vertical' | 'horizontal' | 'both';
|
||||||
scrollbarXClasses?: string;
|
scrollbarXClasses?: string;
|
||||||
scrollbarYClasses?: string;
|
scrollbarYClasses?: string;
|
||||||
|
viewportClasses?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
let className: $$Props["class"] = undefined;
|
let className: $$Props['class'] = undefined;
|
||||||
export { className as class };
|
export { className as class };
|
||||||
export let orientation = "vertical";
|
export let orientation = 'vertical';
|
||||||
export let scrollbarXClasses: string = "";
|
export let scrollbarXClasses: string = '';
|
||||||
export let scrollbarYClasses: string = "";
|
export let scrollbarYClasses: string = '';
|
||||||
|
export let viewportClasses: string = '';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ScrollAreaPrimitive.Root {...$$restProps} class={cn("relative overflow-hidden", className)}>
|
<ScrollAreaPrimitive.Root {...$$restProps} class={cn('relative overflow-hidden', className)}>
|
||||||
<ScrollAreaPrimitive.Viewport class="h-full w-full rounded-[inherit]">
|
<ScrollAreaPrimitive.Viewport class={cn('h-full w-full rounded-[inherit]', viewportClasses)}>
|
||||||
<ScrollAreaPrimitive.Content>
|
<ScrollAreaPrimitive.Content>
|
||||||
<slot />
|
<slot />
|
||||||
</ScrollAreaPrimitive.Content>
|
</ScrollAreaPrimitive.Content>
|
||||||
</ScrollAreaPrimitive.Viewport>
|
</ScrollAreaPrimitive.Viewport>
|
||||||
{#if orientation === "vertical" || orientation === "both"}
|
{#if orientation === 'vertical' || orientation === 'both'}
|
||||||
<Scrollbar orientation="vertical" class={scrollbarYClasses} />
|
<Scrollbar orientation="vertical" class={scrollbarYClasses} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if orientation === "horizontal" || orientation === "both"}
|
{#if orientation === 'horizontal' || orientation === 'both'}
|
||||||
<Scrollbar orientation="horizontal" class={scrollbarXClasses} />
|
<Scrollbar orientation="horizontal" class={scrollbarXClasses} />
|
||||||
{/if}
|
{/if}
|
||||||
<ScrollAreaPrimitive.Corner />
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
@@ -9,8 +9,8 @@ import { ListFileItem, ListItem, ListTrackItem, ListLevel, ListTrackSegmentItem,
|
|||||||
import { updateAnchorPoints } from '$lib/components/toolbar/tools/routing/Simplify';
|
import { updateAnchorPoints } from '$lib/components/toolbar/tools/routing/Simplify';
|
||||||
import { SplitType } from '$lib/components/toolbar/tools/scissors/Scissors.svelte';
|
import { SplitType } from '$lib/components/toolbar/tools/scissors/Scissors.svelte';
|
||||||
import { getClosestLinePoint, getElevation } from '$lib/utils';
|
import { getClosestLinePoint, getElevation } from '$lib/utils';
|
||||||
|
import { TimestampsMode } from '$lib/types';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import type mapboxgl from 'mapbox-gl';
|
|
||||||
|
|
||||||
enableMapSet();
|
enableMapSet();
|
||||||
enablePatches();
|
enablePatches();
|
||||||
@@ -91,6 +91,7 @@ export const settings = {
|
|||||||
routing: dexieSettingStore('routing', true),
|
routing: dexieSettingStore('routing', true),
|
||||||
routingProfile: dexieSettingStore('routingProfile', 'bike'),
|
routingProfile: dexieSettingStore('routingProfile', 'bike'),
|
||||||
privateRoads: dexieSettingStore('privateRoads', false),
|
privateRoads: dexieSettingStore('privateRoads', false),
|
||||||
|
timestampsMode: dexieSettingStore('timestampsMode', TimestampsMode.PRESERVE_AVERAGE_SPEED),
|
||||||
currentBasemap: dexieSettingStore('currentBasemap', defaultBasemap),
|
currentBasemap: dexieSettingStore('currentBasemap', defaultBasemap),
|
||||||
previousBasemap: dexieSettingStore('previousBasemap', defaultBasemap),
|
previousBasemap: dexieSettingStore('previousBasemap', defaultBasemap),
|
||||||
selectedBasemapTree: dexieSettingStore('selectedBasemapTree', defaultBasemapTree),
|
selectedBasemapTree: dexieSettingStore('selectedBasemapTree', defaultBasemapTree),
|
||||||
@@ -574,7 +575,7 @@ export const dbUtils = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
mergeSelection: (mergeTraces: boolean) => {
|
mergeSelection: (mergeTraces: boolean, removeGaps: boolean) => {
|
||||||
applyGlobal((draft) => {
|
applyGlobal((draft) => {
|
||||||
let first = true;
|
let first = true;
|
||||||
let target: ListItem = new ListRootItem();
|
let target: ListItem = new ListRootItem();
|
||||||
@@ -649,7 +650,7 @@ export const dbUtils = {
|
|||||||
let s = new TrackSegment();
|
let s = new TrackSegment();
|
||||||
toMerge.trk.map((track) => {
|
toMerge.trk.map((track) => {
|
||||||
track.trkseg.forEach((segment) => {
|
track.trkseg.forEach((segment) => {
|
||||||
s.replaceTrackPoints(s.trkpt.length, s.trkpt.length, segment.trkpt.slice(), speed, startTime);
|
s.replaceTrackPoints(s.trkpt.length, s.trkpt.length, segment.trkpt.slice(), speed, startTime, removeGaps);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
toMerge.trk = [toMerge.trk[0]];
|
toMerge.trk = [toMerge.trk[0]];
|
||||||
@@ -658,7 +659,7 @@ export const dbUtils = {
|
|||||||
if (toMerge.trkseg.length > 0) {
|
if (toMerge.trkseg.length > 0) {
|
||||||
let s = new TrackSegment();
|
let s = new TrackSegment();
|
||||||
toMerge.trkseg.forEach((segment) => {
|
toMerge.trkseg.forEach((segment) => {
|
||||||
s.replaceTrackPoints(s.trkpt.length, s.trkpt.length, segment.trkpt.slice(), speed, startTime);
|
s.replaceTrackPoints(s.trkpt.length, s.trkpt.length, segment.trkpt.slice(), speed, startTime, removeGaps);
|
||||||
});
|
});
|
||||||
toMerge.trkseg = [s];
|
toMerge.trkseg = [s];
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Soubory a statistiky
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Pomocí tlačítek vpravo od výškového profilu můžete volitelně obarvit výškový profil podle:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -9,29 +9,29 @@ title: Erste Schritte
|
|||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
Willkommen bei der offiziellen Anleitung für **gpx.studio**!
|
Willkommen bei der offiziellen Anleitung für **gpx.studio**!
|
||||||
This guide will walk you through all the components and tools of the interface, helping you become a proficient user of the application.
|
Diese Anleitung führt Sie durch alle Komponenten und Werkzeuge der Benutzeroberfläche und hilft Ihnen dabei ein erfahrener Anwender zu werden.
|
||||||
|
|
||||||
<DocsImage src="getting-started/interface" alt="Die gpx.studio Oberfläche." />
|
<DocsImage src="getting-started/interface" alt="Die gpx.studio Oberfläche." />
|
||||||
|
|
||||||
Wie im obigen Screenshot dargestellt, ist die Oberfläche in vier Bereiche um die Karte herum aufgeteilt.
|
Wie im obigen Screenshot dargestellt, ist die Benutzeroberfläche in vier Bereiche um die Karte herum aufgeteilt.
|
||||||
Bevor wir in die Details der einzelnen Bereiche einsteigen, lassen Sie uns einen Überblick der Oberfläche verschaffen.
|
Bevor wir in die Details der einzelnen Bereiche einsteigen, lassen Sie uns einen Überblick der Benutzeroberfläche verschaffen.
|
||||||
|
|
||||||
## Menü
|
## Menü
|
||||||
|
|
||||||
At the top of the interface, you will find the [main menu](./menu).
|
Am oberen Rand der Benutzeroberfläche findest du das [Hauptmenü](./menu).
|
||||||
This is where you can access common actions such as opening, closing, and exporting files, undoing and redoing actions, and adjusting the application settings.
|
Hier können Sie auf allgemeine Aktionen zugreifen, wie zum Beispiel das Öffnen, Schließen und Exportieren von Dateien, Rückgängig machen und Wiederholen sowie Anpassen der Einstellungen der Anwendung.
|
||||||
|
|
||||||
## Files and statistics
|
## Files and statistics
|
||||||
|
|
||||||
At the bottom of the interface, you will find the list of files currently open in the application.
|
Am unteren Rand der Benutzeroberfläche finden Sie die Liste der aktuell geöffneten Dateien der Anwendung.
|
||||||
You can click on a file to select it and display its statistics below the list.
|
Sie können auf eine Datei klicken, um sie auszuwählen und ihre Statistiken unter der Liste anzuzeigen.
|
||||||
In the [dedicated section](./files-and-stats), we will explain how to select multiple files and switch to a vertical layout for advanced file management.
|
Im [zugehörigen Abschnitt](./files-and-stats) werden wir erklären, wie wir mehrere Dateien auswählen und zu einem vertikalen Layout für eine erweiterte Dateiverwaltung wechseln.
|
||||||
|
|
||||||
## Werkzeugleiste
|
## Werkzeugleiste
|
||||||
|
|
||||||
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.
|
Am linken Rand der Benutzeroberfläche finden Sie die [Werkzeugleiste](./toolbar), die alle Werkzeuge enthält, mit denen Sie Ihre Dateien bearbeiten können.
|
||||||
|
|
||||||
## Kartensteuerungen
|
## Kartensteuerungen
|
||||||
|
|
||||||
Finally, on the right side of the interface, you will find the [map controls](./map-controls).
|
Schließlich findest du am rechten Rand der Benutzeroberfläche die [Kartensteuerungen](./map-controls).
|
||||||
These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
|
Mit diesen Steuerelementen können Sie auf der Karte navigieren, vergrößern und zwischen verschiedenen Kartenstilen wechseln.
|
||||||
|
@@ -11,7 +11,7 @@ title: Kartensteuerungen
|
|||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
The map controls are located on the right side of the interface.
|
The map controls are located on the right side of the interface.
|
||||||
These controls allow you to navigate the map, zoom in and out, and switch between different map styles.
|
Mit diesen Steuerelementen können Sie auf der Karte navigieren, vergrößern und zwischen verschiedenen Kartenstilen wechseln.
|
||||||
|
|
||||||
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
|
### <Diff size="16" class="inline-block" style="margin-bottom: 2px" /> Map navigation
|
||||||
|
|
||||||
|
@@ -8,10 +8,10 @@ title: Menü
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
The main menu, located at the top of the interface, provides access to actions, options, and settings divided into several categories, explained separately in the following sections.
|
Das Hauptmenü, welches sich oben in der Benutzeroberfläche befindet, bietet Zugriff auf Aktionen, Optionen, und Einstellungen, die wiederum in mehrere Kategorien aufgeteilt sind, wird in den folgenden Abschnitten beschrieben.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
Most of the menu actions can also be performed using the keyboard shortcuts displayed in the menu.
|
Die meisten Aktionen des Menüs können auch mit den Tastaturkürzeln ausgeführt werden, die im Menü angezeigt werden.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
@@ -18,7 +18,7 @@ title: Werkzeugleiste
|
|||||||
|
|
||||||
# { title }
|
# { title }
|
||||||
|
|
||||||
The toolbar is located on the left side of the map and is the heart of the application, as it provides access to the main features of **gpx.studio**.
|
Die Symbolleiste befindet sich auf der linken Seite der Karte und ist das Herzstück der Anwendung, da es Zugriff auf die wichtigsten Funktionen von **gpx.studio** bietet.
|
||||||
Jedes Werkzeug wird durch ein Symbol dargestellt und kann durch einen Klick aktiviert werden.
|
Jedes Werkzeug wird durch ein Symbol dargestellt und kann durch einen Klick aktiviert werden.
|
||||||
|
|
||||||
<div class="flex flex-row justify-center text-foreground">
|
<div class="flex flex-row justify-center text-foreground">
|
||||||
@@ -29,4 +29,4 @@ Jedes Werkzeug wird durch ein Symbol dargestellt und kann durch einen Klick akti
|
|||||||
|
|
||||||
As with [edit actions](./menu/edit), most tools can be applied to multiple files at once and to [inner tracks and segments](./gpx).
|
As with [edit actions](./menu/edit), most tools can be applied to multiple files at once and to [inner tracks and segments](./gpx).
|
||||||
|
|
||||||
In den folgenden Abschnitten werden die einzelnen Tools detailliert beschrieben.
|
Die folgenden Abschnitten beschreiben jedes Werkzeug im Detail.
|
||||||
|
@@ -10,17 +10,17 @@ title: Extrahieren
|
|||||||
|
|
||||||
# <Ungroup size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
|
# <Ungroup size="24" class="inline-block" style="margin-bottom: 5px" /> { title }
|
||||||
|
|
||||||
Dieses Tool ermöglicht Ihnen, [tracks (or segments)](../gpx) von Dateien (oder Tracks) zu extrahieren, die mehreren von denen enthalten.
|
Dieses Werkzeug ermöglicht Ihnen [Tracks (oder Segmente)](../gpx) von Dateien (oder Tracks) zu extrahieren, die mehreren von ihnen enthalten.
|
||||||
|
|
||||||
<div class="flex flex-row justify-center">
|
<div class="flex flex-row justify-center">
|
||||||
<Extract class="text-foreground p-3 border rounded-md shadow-lg" />
|
<Extract class="text-foreground p-3 border rounded-md shadow-lg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Wenn Sie das Tool auf eine Datei mit mehreren enthaltenen Tracks anwenden, wird für jeden der darin enthaltenen Tracks eine neue Datei erstellt.
|
Wenn Sie das Werkzeug auf eine Datei mit mehreren enthaltenen Tracks anwenden, wird für jeden der darin enthaltenen Tracks eine neue Datei erstellt.
|
||||||
Similarly, applying the tool to a track containing multiple segments will create (in the same file) a new track for each of the segments it contains.
|
Similarly, applying the tool to a track containing multiple segments will create (in the same file) a new track for each of the segments it contains.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
Beim Extrahieren der Tracks aus einer Datei mit <a href="../gpx">points-of-interest</a>, wird das Tool automatisch jeden Punkt zuordnen, an dem es am nächsten ist.
|
Beim Extrahieren der Tracks aus einer Datei mit <a href="../gpx">points-of-interest</a>, wird das Werkzeug automatisch jeden Punkt zuordnen, an dem es am nächsten ist.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,9 +73,9 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Archivos y estadísticas
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ Puede usar el ratón para acercar o alejar el perfil de elevación y moverse hac
|
|||||||
|
|
||||||
### Datos adicionales
|
### Datos adicionales
|
||||||
|
|
||||||
Usando los botones situados a la derecha del perfil de elevación, puede colorearlo por:
|
Usando el botón <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> en la parte inferior derecha del perfil de elevación, opcionalmente puede colorear el perfil de elevación por:
|
||||||
|
|
||||||
- **pendiente** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> información calculada a partir de los datos de elevación, o
|
- Información de la **pendiente** calculada a partir de los datos de elevación, o
|
||||||
- **superficie** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> datos obtenidos de etiquetas de <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">superficie</a> de <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>.
|
- Datos de **superficie** o **categoría** provenientes de la <a href="https://www.openstreetmap.org/" target="_blank">superficie</a> y etiquetas de <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">autopista</a> de <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">OpenStreetMap</a>.
|
||||||
Solo disponible para archivos creados con **gpx.studio**.
|
Solo disponible para archivos creados con **gpx.studio**.
|
||||||
|
|
||||||
Si su selección lo incluye, puede visualizar datos de **velocidad** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **ritmo cardíaco** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadencia** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperatura** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> y **potencia** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> en el perfil de elevación.
|
Si su selección lo incluye, también puede visualizar datos de **velocidad**, **ritmo cardíaco**, **cadencia**, **temperatura** y **potencia** en el perfil de elevación.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Fichiers et statistiques
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ Vous pouvez également utiliser la molette de la souris pour zoomer ou dézoomer
|
|||||||
|
|
||||||
### Données supplémentaires
|
### Données supplémentaires
|
||||||
|
|
||||||
En utilisant les boutons à droite du profil d'altitude, vous pouvez optionnellement colorier le profil d'altitude en fonction de :
|
En utilisant le bouton <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> en bas à droite du profil d'altitude, vous pouvez optionnellement colorier le profil altimétrique en fonction :
|
||||||
|
|
||||||
- des données de **pente** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> calculées à partir des données d'altitude, ou
|
- des données de **pente** calculées à partir des données d'altitude, ou
|
||||||
- des données de **revêtement** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> venant des tags de <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> d'<a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>.
|
- des données de **revêtement** ou de **catégorie** venant des tags <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> et <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">highway</a> d'<a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>.
|
||||||
Ceci est uniquement disponible pour les fichiers créés avec **gpx.studio**.
|
Ceci est uniquement disponible pour les fichiers créés avec **gpx.studio**.
|
||||||
|
|
||||||
Si votre sélection possède ces données, vous pouvez également visualiser les données de : **vitesse** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **fréquence cardiaque** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **température** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" /> et **puissance** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> sur le profil altimétrique.
|
Si votre sélection possède ces données, vous pouvez également visualiser les données de : **vitesse** , **fréquence cardiaque** , **cadence** , **température** et **puissance** sur le profil altimétrique.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: FAQ
|
title: GYIK
|
||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -10,7 +10,7 @@ title: FAQ
|
|||||||
|
|
||||||
### Do I need to donate to use the website?
|
### Do I need to donate to use the website?
|
||||||
|
|
||||||
No.
|
Nem.
|
||||||
The website is free to use and always will be (as long as it is financially sustainable).
|
The website is free to use and always will be (as long as it is financially sustainable).
|
||||||
However, donations are appreciated and help keep the website running.
|
However, donations are appreciated and help keep the website running.
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -69,14 +69,14 @@ When hovering over the elevation profile, a tooltip will show statistics at the
|
|||||||
To get the statistics for a specific section of the elevation profile, you can drag a selection rectangle on the profile.
|
To get the statistics for a specific section of the elevation profile, you can drag a selection rectangle on the profile.
|
||||||
Click on the profile to reset the selection.
|
Click on the profile to reset the selection.
|
||||||
|
|
||||||
Az egérgörgővel is méretezhetii a magassági profilt. Balra és jobbra mozoghat a profil húzásával, miközben lenyomva tartja a <kbd>Shift</kbd> billentyűt.
|
Az egérgörgővel is méretezheti a magassági profilt. Balra és jobbra mozoghat a profil húzásával, miközben lenyomva tartja a <kbd>Shift</kbd> billentyűt.
|
||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -7,6 +7,6 @@
|
|||||||
Minden alkalommal, amikor GPS-pontokat ad hozzá vagy mozgat, szervereink kiszámítják a legjobb útvonalat az úthálózaton.<a href="https://mapbox.com" target="_blank">Mapbox</a> API-jait használjuk a gyönyörű térképek megjelenítésére, a magassági adatok lekérésére és a helyek keresésére.
|
Minden alkalommal, amikor GPS-pontokat ad hozzá vagy mozgat, szervereink kiszámítják a legjobb útvonalat az úthálózaton.<a href="https://mapbox.com" target="_blank">Mapbox</a> API-jait használjuk a gyönyörű térképek megjelenítésére, a magassági adatok lekérésére és a helyek keresésére.
|
||||||
|
|
||||||
Sajnos ez magas költségű.
|
Sajnos ez magas költségű.
|
||||||
Ha tetszik ezt az alkalmazás, kérjük, fontoljon meg egy kis adományt, hogy a webhely továbbra is ingyenes és hirdetésmentes legyen.
|
Ha tetszik ez az alkalmazás, kérjük, fontoljon meg egy kis adományt, hogy a webhely továbbra is ingyenes és hirdetésmentes legyen.
|
||||||
|
|
||||||
Nagyon szépen köszönöm a támogatást! ❤️
|
Nagyon szépen köszönöm a támogatást! ❤️
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Integration
|
title: Integráció
|
||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@@ -12,6 +12,6 @@ The main menu, located at the top of the interface, provides access to actions,
|
|||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
Most of the menu actions can also be performed using the keyboard shortcuts displayed in the menu.
|
A menüben található műveletek többsége a menüben megjelenített billentyűparancsok segítségével is végrehajtható.
|
||||||
|
|
||||||
</DocsNote>
|
</DocsNote>
|
||||||
|
@@ -29,4 +29,4 @@ Each tool is represented by an icon and can be activated by clicking on it.
|
|||||||
|
|
||||||
As with [edit actions](./menu/edit), most tools can be applied to multiple files at once and to [inner tracks and segments](./gpx).
|
As with [edit actions](./menu/edit), most tools can be applied to multiple files at once and to [inner tracks and segments](./gpx).
|
||||||
|
|
||||||
The next sections describe each tool in detail.
|
A következő szakaszok részletesen ismertetik az egyes eszközöket.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Dati aggiuntivi
|
### Dati aggiuntivi
|
||||||
|
|
||||||
Utilizzando i pulsanti a destra del profilo di elevazione, è possibile colorare opzionalmente il profilo di elevazione mediante:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> informazioni calcolate dai dati di elevazione, o
|
- **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.
|
||||||
È disponibile solo per i file creati con **gpx.studio**.
|
È disponibile solo per i file creati con **gpx.studio**.
|
||||||
|
|
||||||
Se la tua selezione lo prevede puoi visualizzare anche i dati di: **velocità** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **frequenza cardiaca** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadenza** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperatura** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, e **potenza** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> sul profilo altimetrico.
|
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Azione sui File
|
title: Azioni sui File
|
||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -17,7 +17,7 @@ Crea un nuovo file vuoto.
|
|||||||
|
|
||||||
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Apri...
|
### <FolderOpen size="16" class="inline-block" style="margin-bottom: 2px" /> Apri...
|
||||||
|
|
||||||
Open files from your computer.
|
Apre i file dal tuo computer.
|
||||||
|
|
||||||
<DocsNote>
|
<DocsNote>
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ Crea una copia dei file attualmente selezionati.
|
|||||||
|
|
||||||
Close the currently selected files.
|
Close the currently selected files.
|
||||||
|
|
||||||
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" /> Close all
|
### <FileX size="16" class="inline-block" style="margin-bottom: 2px" />Chiudi tutto
|
||||||
|
|
||||||
Chiudi tutti i file.
|
Chiudi tutti i file.
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Puslapis nerastas
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Bestanden en statistieken
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ Je kunt het muiswiel ook gebruiken om in en uit te zoomen op het hoogte profiel,
|
|||||||
|
|
||||||
### Aanvullende gegevens
|
### Aanvullende gegevens
|
||||||
|
|
||||||
Met behulp van de knoppen aan de rechterkant van het hoogteprofiel kunt u het hoogteprofiel optioneel kleuren door:
|
Met behulp van de <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> knoppen aan de rechterkant van het hoogteprofiel kunt u het hoogteprofiel optioneel kleuren door:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> informatie berekend op basis van de hoogtegegevens, of
|
- **helling** informatie berekend uit de hoogtegegevens, of
|
||||||
- **oppervlak** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> data afkomstig van <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>'s <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a> tags.
|
- **oppervlakte** of **categorie** gegevens afkomstig van <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>zijn <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">oppervlak</a> en <a href="https://wiki.openstreetmap.org/wiki/Key:highway" target="_blank">snelweg</a> tags.
|
||||||
Dit is alleen beschikbaar voor bestanden gemaakt met **gpx.studio**.
|
Dit is alleen beschikbaar voor bestanden gemaakt met **gpx.studio**.
|
||||||
|
|
||||||
Als je selectie het bevat, kun je ook visualiseren: **snelheid** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **hartsnelheid** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, en **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> data op het hoogteprofiel.
|
Als je selectie het bevat, kun je ook de volgende gegevens zichtbaar maken op het hoogteprofiel: **snelheid**, **hartritme**, **tempo**, **temperatuur**, en **vermogen**.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Arquivos e estatísticas
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ Você também pode usar a roda do mouse para aumentar e diminuir o zoom no perfi
|
|||||||
|
|
||||||
### Dados adicionais
|
### Dados adicionais
|
||||||
|
|
||||||
Usando os botões à direita do perfil de elevação, você pode opcionalmente colorir o perfil de elevação por:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **inclinação** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> informação computada a partir dos dados de elevação, ou
|
- **slope** information computed from the elevation data, or
|
||||||
- **superfície** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> dados vindos dos marcadores de <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">superfície</a> do <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>.
|
- **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**.
|
Isso só está disponível para arquivos criados com **gpx.studio**.
|
||||||
|
|
||||||
Se sua seleção incluir, você também pode visualizar: **velocidade** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **frequência cardíaca** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadência** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperatura** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />e **energia** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> dados sobre o perfil de elevação.
|
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Файлы и статистика
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ title: Файлы и статистика
|
|||||||
|
|
||||||
### Дополнительные данные
|
### Дополнительные данные
|
||||||
|
|
||||||
С помощью кнопок справа от профиля высоты можно изменить цвет профиля высоты:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **угол наклона** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> информация, вычисленная на основе данных о высоте, или
|
- **slope** information computed from the elevation data, or
|
||||||
- **поверхность** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> данные, полученные из тегов <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> по ключу <a href="https://wiki.openstreetmap.org/wiki/Key:surface" target="_blank">surface</a>.
|
- **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.
|
||||||
Это доступно только для файлов, созданных с помощью **gpx.studio**.
|
Это доступно только для файлов, созданных с помощью **gpx.studio**.
|
||||||
|
|
||||||
Если ваш выбор включает это, вы также можете визуализировать: **скорость** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **частоту сердечных сокращений** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **каденцию** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **температуру** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, и **мощность** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> данные на профиле высоты.
|
If your selection includes it, you can also visualize: **speed**, **heart rate**, **cadence**, **temperature** and **power** data on the elevation profile.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
@@ -3,7 +3,7 @@ title: Files and statistics
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { TriangleRight, BrickWall, Zap, HeartPulse, Orbit, Thermometer, SquareActivity } from 'lucide-svelte';
|
import { ChartNoAxesColumn } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
|||||||
|
|
||||||
### Additional data
|
### Additional data
|
||||||
|
|
||||||
Using the buttons on the right of the elevation profile, you can optionally color the elevation profile by:
|
Using the <kbd><ChartNoAxesColumn size="16" class="inline-block" style="margin-bottom: 2px"/></kbd> button at the bottom-right of the elevation profile, you can optionally color the elevation profile by:
|
||||||
|
|
||||||
- **slope** <TriangleRight size="16" class="inline-block" style="margin-bottom: 2px" /> information computed from the elevation data, or
|
- **slope** information computed from the elevation data, or
|
||||||
- **surface** <BrickWall size="16" class="inline-block" style="margin-bottom: 2px" /> 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> 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.
|
||||||
This is only available for files created with **gpx.studio**.
|
This is only available for files created with **gpx.studio**.
|
||||||
|
|
||||||
If your selection includes it, you can also visualize: **speed** <Zap size="16" class="inline-block" style="margin-bottom: 2px" />, **heart rate** <HeartPulse size="16" class="inline-block" style="margin-bottom: 2px" />, **cadence** <Orbit size="16" class="inline-block" style="margin-bottom: 2px" />, **temperature** <Thermometer size="16" class="inline-block" style="margin-bottom: 2px" />, and **power** <SquareActivity size="16" class="inline-block" style="margin-bottom: 2px" /> 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.
|
||||||
|
4
website/src/lib/types.ts
Normal file
4
website/src/lib/types.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export enum TimestampsMode {
|
||||||
|
PRESERVE_TIMESTAMPS = 'preserve_timestamps',
|
||||||
|
PRESERVE_AVERAGE_SPEED = 'preserve_average_speed',
|
||||||
|
};
|
@@ -12,6 +12,7 @@ import mapboxgl from "mapbox-gl";
|
|||||||
import tilebelt from "@mapbox/tilebelt";
|
import tilebelt from "@mapbox/tilebelt";
|
||||||
import { PUBLIC_MAPBOX_TOKEN } from "$env/static/public";
|
import { PUBLIC_MAPBOX_TOKEN } from "$env/static/public";
|
||||||
import PNGReader from "png.js";
|
import PNGReader from "png.js";
|
||||||
|
import type { DateFormatter } from "@internationalized/date";
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
@@ -215,4 +216,16 @@ export function getURLForLanguage(lang: string | null | undefined, path: string)
|
|||||||
return `${base}${newPath}`;
|
return `${base}${newPath}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDateFormatter(locale: string) {
|
||||||
|
return new Intl.DateTimeFormat(locale, {
|
||||||
|
dateStyle: 'medium',
|
||||||
|
timeStyle: 'medium'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export let df: DateFormatter = getDateFormatter('en');
|
||||||
|
locale.subscribe((l) => {
|
||||||
|
df = getDateFormatter(l ?? 'en');
|
||||||
|
});
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Unpaved",
|
"unpaved": "Unpaved",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Concrete",
|
"concrete": "Concrete",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Cobblestone",
|
"cobblestone": "Cobblestone",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Wood",
|
"wood": "Wood",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Dirt",
|
"dirt": "Dirt",
|
||||||
"ground": "Ground",
|
"ground": "Ground",
|
||||||
"earth": "Earth",
|
"earth": "Earth",
|
||||||
"snow": "Snow",
|
|
||||||
"ice": "Ice",
|
|
||||||
"salt": "Salt",
|
|
||||||
"mud": "Mud",
|
"mud": "Mud",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Grass",
|
"grass": "Grass",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "No pavimentat",
|
"unpaved": "No pavimentat",
|
||||||
"asphalt": "Asfalt",
|
"asphalt": "Asfalt",
|
||||||
"concrete": "Formigó",
|
"concrete": "Formigó",
|
||||||
"chipseal": "Camí asfaltat",
|
|
||||||
"cobblestone": "Llambordes",
|
"cobblestone": "Llambordes",
|
||||||
"unhewn_cobblestone": "Llambordes grosses",
|
|
||||||
"paving_stones": "Camí de pedres",
|
"paving_stones": "Camí de pedres",
|
||||||
"stepping_stones": "Empedrat",
|
|
||||||
"sett": "Establir",
|
"sett": "Establir",
|
||||||
"metal": "Metall",
|
"metal": "Metall",
|
||||||
"wood": "Fusta",
|
"wood": "Fusta",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Terra",
|
"dirt": "Terra",
|
||||||
"ground": "Terreny",
|
"ground": "Terreny",
|
||||||
"earth": "Planeta Terra",
|
"earth": "Planeta Terra",
|
||||||
"snow": "Neu",
|
|
||||||
"ice": "Gel",
|
|
||||||
"salt": "Sal",
|
|
||||||
"mud": "Fang",
|
"mud": "Fang",
|
||||||
"sand": "Sorra",
|
"sand": "Sorra",
|
||||||
"woodchips": "Estella forestal",
|
|
||||||
"grass": "Herba",
|
"grass": "Herba",
|
||||||
"grass_paver": "Gespa"
|
"grass_paver": "Gespa",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connectar les traçades",
|
"merge_traces": "Connectar les traçades",
|
||||||
"merge_contents": "Unir els continguts i mantenir les traçades desconnectades",
|
"merge_contents": "Unir els continguts i mantenir les traçades desconnectades",
|
||||||
"merge_selection": "Combinar la selecció",
|
"merge_selection": "Combinar la selecció",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Unir els elements",
|
"tooltip": "Unir els elements",
|
||||||
"help_merge_traces": "Unir les traçades crearà una única traçada contínua.",
|
"help_merge_traces": "Unir les traçades crearà una única traçada contínua.",
|
||||||
"help_cannot_merge_traces": "Has de sel·leccionar diverses traçades per tal d'unir-les.",
|
"help_cannot_merge_traces": "Has de sel·leccionar diverses traçades per tal d'unir-les.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distancia",
|
"distance": "Distancia",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Pendent",
|
"slope": "Pendent",
|
||||||
"surface": "Superfície",
|
"surface": "Superfície",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Nezpevněné",
|
"unpaved": "Nezpevněné",
|
||||||
"asphalt": "Asfalt",
|
"asphalt": "Asfalt",
|
||||||
"concrete": "Beton",
|
"concrete": "Beton",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Dlažební kostky",
|
"cobblestone": "Dlažební kostky",
|
||||||
"unhewn_cobblestone": "Hrubá dlažba",
|
|
||||||
"paving_stones": "Dlažba",
|
"paving_stones": "Dlažba",
|
||||||
"stepping_stones": "Nášlapné kameny",
|
|
||||||
"sett": "Dlažební kostky",
|
"sett": "Dlažební kostky",
|
||||||
"metal": "Kov",
|
"metal": "Kov",
|
||||||
"wood": "Dřevo",
|
"wood": "Dřevo",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Hlína",
|
"dirt": "Hlína",
|
||||||
"ground": "Pozemek",
|
"ground": "Pozemek",
|
||||||
"earth": "Země",
|
"earth": "Země",
|
||||||
"snow": "Sníh",
|
|
||||||
"ice": "Led",
|
|
||||||
"salt": "Sůl",
|
|
||||||
"mud": "Bláto",
|
"mud": "Bláto",
|
||||||
"sand": "Písek",
|
"sand": "Písek",
|
||||||
"woodchips": "Dřevěné štěpky",
|
|
||||||
"grass": "Tráva",
|
"grass": "Tráva",
|
||||||
"grass_paver": "Zatravňovací dlažba"
|
"grass_paver": "Zatravňovací dlažba",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Připojit trasy",
|
"merge_traces": "Připojit trasy",
|
||||||
"merge_contents": "Sloučit obsah a zachovat trasy oddělené",
|
"merge_contents": "Sloučit obsah a zachovat trasy oddělené",
|
||||||
"merge_selection": "Sloučit výběr",
|
"merge_selection": "Sloučit výběr",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Sloučit položky",
|
"tooltip": "Sloučit položky",
|
||||||
"help_merge_traces": "Připojení vybraných tras vytvoří jednu spojitou trasu.",
|
"help_merge_traces": "Připojení vybraných tras vytvoří jednu spojitou trasu.",
|
||||||
"help_cannot_merge_traces": "Váš výběr musí obsahovat několik tras, které je chcete připojit.",
|
"help_cannot_merge_traces": "Váš výběr musí obsahovat několik tras, které je chcete připojit.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topografická",
|
"ignFrTopo": "IGN Topografická",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satelitní",
|
"ignFrSatellite": "IGN Satelitní",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topografická",
|
"swedenTopo": "Lantmäteriet Topografická",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Zobrazit sklon svahu",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Zobrazit údaje o povrchu",
|
|
||||||
"show_speed": "Zobrazit údaje o rychlosti",
|
|
||||||
"show_pace": "Zobrazit údaje o tempu",
|
|
||||||
"show_heartrate": "Zobrazit údaje o tepové frekvenci",
|
|
||||||
"show_cadence": "Zobrazit údaje o kadenci",
|
|
||||||
"show_temperature": "Zobrazit údaje o teplotě",
|
|
||||||
"show_power": "Zobrazit údaje o energii"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Vzdálenost",
|
"distance": "Vzdálenost",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Energie",
|
"power": "Energie",
|
||||||
"slope": "Sklon",
|
"slope": "Sklon",
|
||||||
"surface": "Povrch",
|
"surface": "Povrch",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Čas",
|
"time": "Čas",
|
||||||
"moving": "V pohybu",
|
"moving": "V pohybu",
|
||||||
"total": "Celkem"
|
"total": "Celkem",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Unpaved",
|
"unpaved": "Unpaved",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Concrete",
|
"concrete": "Concrete",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Cobblestone",
|
"cobblestone": "Cobblestone",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Wood",
|
"wood": "Wood",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Dirt",
|
"dirt": "Dirt",
|
||||||
"ground": "Ground",
|
"ground": "Ground",
|
||||||
"earth": "Earth",
|
"earth": "Earth",
|
||||||
"snow": "Snow",
|
|
||||||
"ice": "Ice",
|
|
||||||
"salt": "Salt",
|
|
||||||
"mud": "Mud",
|
"mud": "Mud",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Grass",
|
"grass": "Grass",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"home_title": "der online GPX Datei Editor",
|
"home_title": "der online GPX Datei Editor",
|
||||||
"app_title": "app",
|
"app_title": "App",
|
||||||
"embed_title": "der online GPX Datei Editor",
|
"embed_title": "der online GPX Datei Editor",
|
||||||
"help_title": "hilfe",
|
"help_title": "hilfe",
|
||||||
"404_title": "Seite nicht gefunden",
|
"404_title": "Seite nicht gefunden",
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
"select_all": "Alle auswählen",
|
"select_all": "Alle auswählen",
|
||||||
"view": "Ansicht",
|
"view": "Ansicht",
|
||||||
"elevation_profile": "Höhenprofil",
|
"elevation_profile": "Höhenprofil",
|
||||||
"vertical_file_view": "Vertical file list",
|
"vertical_file_view": "Vertikale Dateiliste",
|
||||||
"switch_basemap": "Switch to previous basemap",
|
"switch_basemap": "Zur vorherigen Basemap wechseln",
|
||||||
"toggle_overlays": "Toggle overlays",
|
"toggle_overlays": "Toggle overlays",
|
||||||
"toggle_3d": "3D umschalten",
|
"toggle_3d": "3D umschalten",
|
||||||
"settings": "Einstellungen",
|
"settings": "Einstellungen",
|
||||||
@@ -49,21 +49,21 @@
|
|||||||
"language": "Sprache",
|
"language": "Sprache",
|
||||||
"mode": "Design",
|
"mode": "Design",
|
||||||
"system": "System",
|
"system": "System",
|
||||||
"light": "Light",
|
"light": "Hell",
|
||||||
"dark": "Dark",
|
"dark": "Dunkel",
|
||||||
"street_view_source": "Street view source",
|
"street_view_source": "Street View Quelle",
|
||||||
"mapillary": "Mapillary",
|
"mapillary": "Mapillary",
|
||||||
"google": "Google",
|
"google": "Google",
|
||||||
"toggle_street_view": "Street view",
|
"toggle_street_view": "Street View",
|
||||||
"layers": "Map layers...",
|
"layers": "Map layers...",
|
||||||
"distance_markers": "Entfernungsmarkierungen",
|
"distance_markers": "Entfernungsmarkierungen",
|
||||||
"direction_markers": "Direction arrows",
|
"direction_markers": "Direction arrows",
|
||||||
"help": "Hilfe",
|
"help": "Hilfe",
|
||||||
"more": "More...",
|
"more": "Mehr...",
|
||||||
"donate": "Spenden",
|
"donate": "Spenden",
|
||||||
"ctrl": "Strg",
|
"ctrl": "Strg",
|
||||||
"click": "Klick",
|
"click": "Klick",
|
||||||
"drag": "Drag",
|
"drag": "Ziehen",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"button": "Info...",
|
"button": "Info...",
|
||||||
"name": "Bezeichnung",
|
"name": "Bezeichnung",
|
||||||
@@ -77,83 +77,124 @@
|
|||||||
"width": "Breite"
|
"width": "Breite"
|
||||||
},
|
},
|
||||||
"hide": "Verbergen",
|
"hide": "Verbergen",
|
||||||
"unhide": "Unhide",
|
"unhide": "Einblenden",
|
||||||
"center": "Center",
|
"center": "Center",
|
||||||
"open_in": "Open in"
|
"open_in": "Open in"
|
||||||
},
|
},
|
||||||
"toolbar": {
|
"toolbar": {
|
||||||
"routing": {
|
"routing": {
|
||||||
"tooltip": "Plan or edit a route",
|
"tooltip": "Route planen oder bearbeiten",
|
||||||
"activity": "Aktivität",
|
"activity": "Aktivität",
|
||||||
"use_routing": "Routenführung",
|
"use_routing": "Routenführung",
|
||||||
"use_routing_tooltip": "Connect anchor points via road network, or in a straight line if disabled",
|
"use_routing_tooltip": "Connect anchor points via road network, or in a straight line if disabled",
|
||||||
"allow_private": "Allow private roads",
|
"allow_private": "Private Straßen erlauben",
|
||||||
"reverse": {
|
"reverse": {
|
||||||
"button": "Umkehren",
|
"button": "Umkehren",
|
||||||
"tooltip": "Reverse the direction of the route"
|
"tooltip": "Die Richtung der Route umkehren"
|
||||||
},
|
},
|
||||||
"route_back_to_start": {
|
"route_back_to_start": {
|
||||||
"button": "Back to start",
|
"button": "Zurück zum Start",
|
||||||
"tooltip": "Connect the last point of the route with the starting point"
|
"tooltip": "Den letzten Punkt der Route mit dem Startpunkt verbinden"
|
||||||
},
|
},
|
||||||
"round_trip": {
|
"round_trip": {
|
||||||
"button": "Round trip",
|
"button": "Rundfahrt",
|
||||||
"tooltip": "Return to the starting point by the same route"
|
"tooltip": "Kehre mit derselben Route zum Startpunkt zurück"
|
||||||
},
|
},
|
||||||
"start_loop_here": "Schleife hier starten",
|
"start_loop_here": "Schleife hier starten",
|
||||||
"help_no_file": "Select a trace to use the routing tool, or click on the map to start creating a new route.",
|
"help_no_file": "Select a trace to use the routing tool, or click on the map to start creating a new route.",
|
||||||
"help": "Click on the map to add a new anchor point, or drag existing ones to change the route.",
|
"help": "Click on the map to add a new anchor point, or drag existing ones to change the route.",
|
||||||
"activities": {
|
"activities": {
|
||||||
"bike": "Rad",
|
"bike": "Fahrrad",
|
||||||
"racing_bike": "Road bike",
|
"racing_bike": "Rennrad",
|
||||||
"gravel_bike": "Gravel Bike",
|
"gravel_bike": "Gravel Bike",
|
||||||
"mountain_bike": "Mountainbike",
|
"mountain_bike": "Mountainbike",
|
||||||
"foot": "Laufen/Wandern",
|
"foot": "Laufen/Wandern",
|
||||||
"motorcycle": "Moped",
|
"motorcycle": "Motorrad",
|
||||||
"water": "Water",
|
"water": "Wasser",
|
||||||
"railway": "Railway"
|
"railway": "Railway"
|
||||||
},
|
},
|
||||||
"surface": {
|
"surface": {
|
||||||
"unknown": "Unknown",
|
"unknown": "Unbekannt",
|
||||||
"paved": "Gepflastert",
|
"paved": "Gepflastert",
|
||||||
"unpaved": "Unbefestigt",
|
"unpaved": "Unbefestigt",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Beton",
|
"concrete": "Beton",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Kopfsteinpflaster",
|
"cobblestone": "Kopfsteinpflaster",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
"paving_stones": "Verbundsteine",
|
||||||
"paving_stones": "Paving stones",
|
"sett": "Behauenes Steinpflaster",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
|
||||||
"metal": "Metall",
|
"metal": "Metall",
|
||||||
"wood": "Holz",
|
"wood": "Holz",
|
||||||
"compacted": "Compacted gravel",
|
"compacted": "verdichtet",
|
||||||
"fine_gravel": "Fine gravel",
|
"fine_gravel": "Feiner Schotter",
|
||||||
"gravel": "Schotter",
|
"gravel": "Schotter",
|
||||||
"pebblestone": "Kieselsteine",
|
"pebblestone": "Kieselsteine",
|
||||||
"rock": "Fels",
|
"rock": "Fels",
|
||||||
"dirt": "Dreck",
|
"dirt": "Dreck",
|
||||||
"ground": "Boden",
|
"ground": "Boden",
|
||||||
"earth": "Erde",
|
"earth": "Erde",
|
||||||
"snow": "Schnee",
|
|
||||||
"ice": "Eis",
|
|
||||||
"salt": "Salz",
|
|
||||||
"mud": "Matsch",
|
"mud": "Matsch",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Holzhäcksel",
|
|
||||||
"grass": "Gras",
|
"grass": "Gras",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"from": "The start point is too far from the nearest road",
|
"from": "Der Startpunkt ist zu weit von der nächsten Straße entfernt",
|
||||||
"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": "Der Endpunkt ist zu weit von der nächsten Straße entfernt",
|
||||||
"timeout": "Route calculation took too long, try adding points closer together"
|
"timeout": "Route calculation took too long, try adding points closer together"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scissors": {
|
"scissors": {
|
||||||
"tooltip": "Crop or split",
|
"tooltip": "Schneiden oder Teilen",
|
||||||
"crop": "Crop",
|
"crop": "Schneiden",
|
||||||
"split_as": "Split the trace into",
|
"split_as": "Split the trace into",
|
||||||
"help_invalid_selection": "Select a trace to crop or split.",
|
"help_invalid_selection": "Select a trace to crop or split.",
|
||||||
"help": "Use the slider to crop the trace, or split it by clicking on one of the split markers or on the trace itself."
|
"help": "Use the slider to crop the trace, or split it by clicking on one of the split markers or on the trace itself."
|
||||||
@@ -161,11 +202,11 @@
|
|||||||
"time": {
|
"time": {
|
||||||
"tooltip": "Manage time data",
|
"tooltip": "Manage time data",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"end": "End",
|
"end": "Ziel",
|
||||||
"total_time": "Zeit in Bewegung",
|
"total_time": "Zeit in Bewegung",
|
||||||
"pick_date": "Pick a date",
|
"pick_date": "Datum auswählen",
|
||||||
"artificial": "Create realistic time data",
|
"artificial": "Erstelle realistische Zeitdaten",
|
||||||
"update": "Update time data",
|
"update": "Aktualisiere Zeitdaten",
|
||||||
"help": "Use the form to set new time data.",
|
"help": "Use the form to set new time data.",
|
||||||
"help_invalid_selection": "Select a single trace to manage its time data."
|
"help_invalid_selection": "Select a single trace to manage its time data."
|
||||||
},
|
},
|
||||||
@@ -173,7 +214,8 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Auswahl zusammenführen",
|
"merge_selection": "Auswahl zusammenführen",
|
||||||
"tooltip": "Merge items together",
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
|
"tooltip": "Elemente zusammenführen",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
"help_merge_contents": "Merging the contents of the selected items will group all the contents inside the first item.",
|
"help_merge_contents": "Merging the contents of the selected items will group all the contents inside the first item.",
|
||||||
@@ -195,8 +237,8 @@
|
|||||||
"tooltip": "Create and edit points of interest",
|
"tooltip": "Create and edit points of interest",
|
||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
"link": "Link",
|
"link": "Link",
|
||||||
"longitude": "Longitude",
|
"longitude": "Längengrad",
|
||||||
"latitude": "Latitude",
|
"latitude": "Breitengrad",
|
||||||
"create": "Create point of interest",
|
"create": "Create point of interest",
|
||||||
"add": "Add point of interest to file",
|
"add": "Add point of interest to file",
|
||||||
"help": "Fill in the form to create a new point of interest, or click on an existing one to edit it. Click on the map to fill the coordinates, or drag points of interest to move them.",
|
"help": "Fill in the form to create a new point of interest, or click on an existing one to edit it. Click on the map to fill the coordinates, or drag points of interest to move them.",
|
||||||
@@ -204,15 +246,15 @@
|
|||||||
},
|
},
|
||||||
"reduce": {
|
"reduce": {
|
||||||
"tooltip": "Reduce the number of GPS points",
|
"tooltip": "Reduce the number of GPS points",
|
||||||
"tolerance": "Tolerance",
|
"tolerance": "Toleranz",
|
||||||
"number_of_points": "Number of GPS points",
|
"number_of_points": "Anzahl der GPS-Punkte",
|
||||||
"button": "Minify",
|
"button": "Minify",
|
||||||
"help": "Use the slider to choose the number of GPS points to keep.",
|
"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": {
|
||||||
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
|
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
|
||||||
"delete_trackpoints": "Delete GPS points",
|
"delete_trackpoints": "GPS-Punkte löschen",
|
||||||
"delete_waypoints": "Delete points of interest",
|
"delete_waypoints": "Delete points of interest",
|
||||||
"delete_inside": "Delete inside selection",
|
"delete_inside": "Delete inside selection",
|
||||||
"delete_outside": "Delete outside selection",
|
"delete_outside": "Delete outside selection",
|
||||||
@@ -243,19 +285,19 @@
|
|||||||
"basemaps": "Basiskarte",
|
"basemaps": "Basiskarte",
|
||||||
"overlays": "Ebenen",
|
"overlays": "Ebenen",
|
||||||
"custom": "Custom",
|
"custom": "Custom",
|
||||||
"world": "World",
|
"world": "Welt",
|
||||||
"countries": "Countries",
|
"countries": "Länder",
|
||||||
"belgium": "Belgium",
|
"belgium": "Belgien",
|
||||||
"bulgaria": "Bulgarien",
|
"bulgaria": "Bulgarien",
|
||||||
"finland": "Finland",
|
"finland": "Finnland",
|
||||||
"france": "France",
|
"france": "Frankreich",
|
||||||
"new_zealand": "New Zealand",
|
"new_zealand": "Neuseeland",
|
||||||
"norway": "Norway",
|
"norway": "Norwegen",
|
||||||
"spain": "Spain",
|
"spain": "Spanien",
|
||||||
"sweden": "Sweden",
|
"sweden": "Schweden",
|
||||||
"switzerland": "Switzerland",
|
"switzerland": "Schweiz",
|
||||||
"united_kingdom": "United Kingdom",
|
"united_kingdom": "Großbritannien",
|
||||||
"united_states": "United States",
|
"united_states": "USA",
|
||||||
"mapboxOutdoors": "Mapbox Outdoors",
|
"mapboxOutdoors": "Mapbox Outdoors",
|
||||||
"mapboxSatellite": "Mapbox Satellit",
|
"mapboxSatellite": "Mapbox Satellit",
|
||||||
"openStreetMap": "OpenStreetMap",
|
"openStreetMap": "OpenStreetMap",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -294,50 +337,50 @@
|
|||||||
"ignSlope": "IGN Slope",
|
"ignSlope": "IGN Slope",
|
||||||
"ignSkiTouring": "IGN Ski Touring",
|
"ignSkiTouring": "IGN Ski Touring",
|
||||||
"waymarked_trails": "Waymarked Trails",
|
"waymarked_trails": "Waymarked Trails",
|
||||||
"waymarkedTrailsHiking": "Hiking",
|
"waymarkedTrailsHiking": "Wandern",
|
||||||
"waymarkedTrailsCycling": "Cycling",
|
"waymarkedTrailsCycling": "Radfahren",
|
||||||
"waymarkedTrailsMTB": "MTB",
|
"waymarkedTrailsMTB": "MTB",
|
||||||
"waymarkedTrailsSkating": "Skating",
|
"waymarkedTrailsSkating": "Skating",
|
||||||
"waymarkedTrailsHorseRiding": "Horse Riding",
|
"waymarkedTrailsHorseRiding": "Horse Riding",
|
||||||
"waymarkedTrailsWinter": "Winter",
|
"waymarkedTrailsWinter": "Winter",
|
||||||
"points_of_interest": "Points of interest",
|
"points_of_interest": "Points of interest",
|
||||||
"food": "Food",
|
"food": "Food",
|
||||||
"bakery": "Bakery",
|
"bakery": "Bäckerei",
|
||||||
"food-store": "Food Store",
|
"food-store": "Food Store",
|
||||||
"eat-and-drink": "Eat and Drink",
|
"eat-and-drink": "Eat and Drink",
|
||||||
"amenities": "Amenities",
|
"amenities": "Amenities",
|
||||||
"toilets": "Toilets",
|
"toilets": "Toiletten",
|
||||||
"water": "Water",
|
"water": "Trinkwasser",
|
||||||
"shower": "Shower",
|
"shower": "Dusche",
|
||||||
"shelter": "Shelter",
|
"shelter": "Unterstand",
|
||||||
"motorized": "Cars and Motorcycles",
|
"motorized": "Autos und Motorräder",
|
||||||
"fuel-station": "Fuel Station",
|
"fuel-station": "Tankstelle",
|
||||||
"parking": "Parking",
|
"parking": "Parking",
|
||||||
"garage": "Garage",
|
"garage": "Garage",
|
||||||
"barrier": "Barrier",
|
"barrier": "Barriere",
|
||||||
"tourism": "Tourism",
|
"tourism": "Tourismus",
|
||||||
"attraction": "Attraction",
|
"attraction": "Attraction",
|
||||||
"viewpoint": "Viewpoint",
|
"viewpoint": "Aussichtspunkt",
|
||||||
"hotel": "Hotel",
|
"hotel": "Hotel",
|
||||||
"campsite": "Campsite",
|
"campsite": "Campingplatz",
|
||||||
"hut": "Hut",
|
"hut": "Hütte",
|
||||||
"picnic": "Picnic Area",
|
"picnic": "Picknickplatz",
|
||||||
"summit": "Summit",
|
"summit": "Gipfel",
|
||||||
"pass": "Pass",
|
"pass": "Gebirgspass",
|
||||||
"climbing": "Climbing",
|
"climbing": "Climbing",
|
||||||
"bicycle": "Bicycle",
|
"bicycle": "Fahrrad",
|
||||||
"bicycle-parking": "Bicycle Parking",
|
"bicycle-parking": "Bicycle Parking",
|
||||||
"bicycle-rental": "Bicycle Rental",
|
"bicycle-rental": "Fahrradverleih",
|
||||||
"bicycle-shop": "Fahrradgeschäft",
|
"bicycle-shop": "Fahrradgeschäft",
|
||||||
"public-transport": "Öffentliche Verkehrsmittel",
|
"public-transport": "Öffentliche Verkehrsmittel",
|
||||||
"railway-station": "Bahnhof",
|
"railway-station": "Bahnhof",
|
||||||
"tram-stop": "Straßenbahnhaltestelle",
|
"tram-stop": "Straßenbahnhaltestelle",
|
||||||
"bus-stop": "Bushaltestelle",
|
"bus-stop": "Bushaltestelle",
|
||||||
"ferry": "Ferry"
|
"ferry": "Fähre"
|
||||||
},
|
},
|
||||||
"color": {
|
"color": {
|
||||||
"blue": "Blau",
|
"blue": "Blau",
|
||||||
"bluered": "Blue Red",
|
"bluered": "Blau Rot",
|
||||||
"gray": "Grau",
|
"gray": "Grau",
|
||||||
"hot": "Heiß",
|
"hot": "Heiß",
|
||||||
"purple": "Lila",
|
"purple": "Lila",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distanz",
|
"distance": "Distanz",
|
||||||
@@ -361,14 +397,16 @@
|
|||||||
"temperature": "Temperatur",
|
"temperature": "Temperatur",
|
||||||
"speed": "Geschwindigkeit",
|
"speed": "Geschwindigkeit",
|
||||||
"pace": "Tempo",
|
"pace": "Tempo",
|
||||||
"heartrate": "Heart rate",
|
"heartrate": "Herzfrequenz",
|
||||||
"cadence": "Trittfrequenz",
|
"cadence": "Trittfrequenz",
|
||||||
"power": "Leistung",
|
"power": "Leistung",
|
||||||
"slope": "Gefälle",
|
"slope": "Gefälle",
|
||||||
"surface": "Oberfläche",
|
"surface": "Oberfläche",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Zeit",
|
"time": "Zeit",
|
||||||
"moving": "Moving",
|
"moving": "Bewegung",
|
||||||
"total": "Gesamt"
|
"total": "Gesamt",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
@@ -389,8 +427,8 @@
|
|||||||
"power": "W"
|
"power": "W"
|
||||||
},
|
},
|
||||||
"gpx": {
|
"gpx": {
|
||||||
"file": "File",
|
"file": "Datei",
|
||||||
"files": "Files",
|
"files": "Dateien",
|
||||||
"track": "Strecke",
|
"track": "Strecke",
|
||||||
"tracks": "Strecken",
|
"tracks": "Strecken",
|
||||||
"segment": "Abschnitt",
|
"segment": "Abschnitt",
|
||||||
@@ -401,56 +439,56 @@
|
|||||||
"alert": "Alert",
|
"alert": "Alert",
|
||||||
"anchor": "Anchor",
|
"anchor": "Anchor",
|
||||||
"bank": "Bank",
|
"bank": "Bank",
|
||||||
"beach": "Beach",
|
"beach": "Strand",
|
||||||
"bike_trail": "Bike Trail",
|
"bike_trail": "Bike Trail",
|
||||||
"binoculars": "Binoculars",
|
"binoculars": "Binoculars",
|
||||||
"bridge": "Bridge",
|
"bridge": "Brücke",
|
||||||
"building": "Building",
|
"building": "Gebäude",
|
||||||
"campground": "Campsite",
|
"campground": "Campingplatz",
|
||||||
"car": "Car",
|
"car": "Auto",
|
||||||
"car_repair": "Garage",
|
"car_repair": "Garage",
|
||||||
"convenience_store": "Convenience Store",
|
"convenience_store": "Convenience Store",
|
||||||
"crossing": "Crossing",
|
"crossing": "Crossing",
|
||||||
"department_store": "Department Store",
|
"department_store": "Department Store",
|
||||||
"drinking_water": "Water",
|
"drinking_water": "Trinkwasser",
|
||||||
"exit": "Exit",
|
"exit": "Exit",
|
||||||
"lodge": "Hut",
|
"lodge": "Hut",
|
||||||
"lodging": "Accommodation",
|
"lodging": "Accommodation",
|
||||||
"forest": "Forest",
|
"forest": "Wald",
|
||||||
"gas_station": "Fuel Station",
|
"gas_station": "Tankstelle",
|
||||||
"ground_transportation": "Ground Transportation",
|
"ground_transportation": "Ground Transportation",
|
||||||
"hotel": "Hotel",
|
"hotel": "Hotel",
|
||||||
"house": "House",
|
"house": "House",
|
||||||
"information": "Information",
|
"information": "Information",
|
||||||
"park": "Park",
|
"park": "Park",
|
||||||
"parking_area": "Parking",
|
"parking_area": "Parkplatz",
|
||||||
"pharmacy": "Pharmacy",
|
"pharmacy": "Apotheke",
|
||||||
"picnic_area": "Picnic Area",
|
"picnic_area": "Picknickplatz",
|
||||||
"restaurant": "Restaurant",
|
"restaurant": "Restaurant",
|
||||||
"restricted_area": "Restricted Area",
|
"restricted_area": "Restricted Area",
|
||||||
"restroom": "Toilets",
|
"restroom": "Toiletten",
|
||||||
"road": "Road",
|
"road": "Straße",
|
||||||
"scenic_area": "Scenic Area",
|
"scenic_area": "Scenic Area",
|
||||||
"shelter": "Shelter",
|
"shelter": "Unterstand",
|
||||||
"shopping_center": "Shopping Center",
|
"shopping_center": "Einkaufszentrum",
|
||||||
"shower": "Shower",
|
"shower": "Dusche",
|
||||||
"summit": "Summit",
|
"summit": "Gipfel",
|
||||||
"telephone": "Telephone",
|
"telephone": "Telefon",
|
||||||
"tunnel": "Tunnel",
|
"tunnel": "Tunnel",
|
||||||
"water_source": "Water Source"
|
"water_source": "Water Source"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"homepage": {
|
"homepage": {
|
||||||
"website": "Website",
|
"website": "Webseite",
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"app": "App",
|
"app": "App",
|
||||||
"contact": "Contact",
|
"contact": "Kontakt",
|
||||||
"reddit": "Reddit",
|
"reddit": "Reddit",
|
||||||
"x": "X",
|
"x": "X",
|
||||||
"facebook": "Facebook",
|
"facebook": "Facebook",
|
||||||
"github": "GitHub",
|
"github": "GitHub",
|
||||||
"crowdin": "Crowdin",
|
"crowdin": "Crowdin",
|
||||||
"email": "Email",
|
"email": "E-Mail",
|
||||||
"contribute": "Contribute",
|
"contribute": "Contribute",
|
||||||
"supported_by": "supported by",
|
"supported_by": "supported by",
|
||||||
"support_button": "Support gpx.studio on Ko-fi",
|
"support_button": "Support gpx.studio on Ko-fi",
|
||||||
@@ -466,19 +504,19 @@
|
|||||||
"identity_description": "The website is free to use, without ads, and the source code is publicly available on GitHub. This is only possible thanks to the incredible support of the community."
|
"identity_description": "The website is free to use, without ads, and the source code is publicly available on GitHub. This is only possible thanks to the incredible support of the community."
|
||||||
},
|
},
|
||||||
"docs": {
|
"docs": {
|
||||||
"translate": "Improve the translation on Crowdin",
|
"translate": "Verbessere die Übersetzung auf Crowdin",
|
||||||
"answer_not_found": "Did not find what you were looking for?",
|
"answer_not_found": "Did not find what you were looking for?",
|
||||||
"ask_on_reddit": "Ask the community on Reddit",
|
"ask_on_reddit": "Frage die Community auf Reddit",
|
||||||
"search": {
|
"search": {
|
||||||
"search": "Search",
|
"search": "Suche",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
"recent": "Recent searches",
|
"recent": "Letzte Suchanfragen",
|
||||||
"no_recent": "No recent searches",
|
"no_recent": "Keine kürzlichen Suchanfragen",
|
||||||
"save": "Save this search",
|
"save": "Diese Suchanfrage speichern",
|
||||||
"remove": "Remove this search from history",
|
"remove": "Diese Suchanfrage aus dem Verlauf entfernen",
|
||||||
"favorites": "Favorites",
|
"favorites": "Favoriten",
|
||||||
"remove_favorite": "Remove this search from favorites",
|
"remove_favorite": "Diese Suchanfrage aus Favoriten entfernen",
|
||||||
"to_select": "to select",
|
"to_select": "to select",
|
||||||
"to_navigate": "to navigate",
|
"to_navigate": "to navigate",
|
||||||
"to_close": "to close",
|
"to_close": "to close",
|
||||||
@@ -506,7 +544,7 @@
|
|||||||
"preview": "Vorschau",
|
"preview": "Vorschau",
|
||||||
"code": "Integration code"
|
"code": "Integration code"
|
||||||
},
|
},
|
||||||
"webgl2_required": "WebGL 2 is required to display the map.",
|
"webgl2_required": "WebGL 2 ist erforderlich, um die Karte anzuzeigen.",
|
||||||
"enable_webgl2": "Learn how to enable WebGL 2 in your browser",
|
"enable_webgl2": "Erfahren Sie, wie Sie WebGL 2 in Ihrem Browser aktivieren",
|
||||||
"page_not_found": "page not found"
|
"page_not_found": "Seite nicht gefunden"
|
||||||
}
|
}
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Μη ασφαλτοστρωμένο",
|
"unpaved": "Μη ασφαλτοστρωμένο",
|
||||||
"asphalt": "Άσφαλτος",
|
"asphalt": "Άσφαλτος",
|
||||||
"concrete": "Τσιμέντο",
|
"concrete": "Τσιμέντο",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Cobblestone",
|
"cobblestone": "Cobblestone",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Μέταλλο",
|
"metal": "Μέταλλο",
|
||||||
"wood": "Ξύλο",
|
"wood": "Ξύλο",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Βρωμιά",
|
"dirt": "Βρωμιά",
|
||||||
"ground": "Χώμα",
|
"ground": "Χώμα",
|
||||||
"earth": "Γη",
|
"earth": "Γη",
|
||||||
"snow": "Χιόνι",
|
|
||||||
"ice": "Πάγος",
|
|
||||||
"salt": "Αλάτι",
|
|
||||||
"mud": "Λάσπη",
|
"mud": "Λάσπη",
|
||||||
"sand": "Άμμος",
|
"sand": "Άμμος",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Γρασίδι",
|
"grass": "Γρασίδι",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Απόσταση",
|
"distance": "Απόσταση",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Πλαγιά",
|
"slope": "Πλαγιά",
|
||||||
"surface": "Επιφάνεια",
|
"surface": "Επιφάνεια",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Σύνολο"
|
"total": "Σύνολο",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "μέτρα",
|
"meters": "μέτρα",
|
||||||
|
@@ -88,6 +88,8 @@
|
|||||||
"use_routing": "Routing",
|
"use_routing": "Routing",
|
||||||
"use_routing_tooltip": "Connect anchor points via road network, or in a straight line if disabled",
|
"use_routing_tooltip": "Connect anchor points via road network, or in a straight line if disabled",
|
||||||
"allow_private": "Allow private roads",
|
"allow_private": "Allow private roads",
|
||||||
|
"preserve_average_speed": "Maintain average speed",
|
||||||
|
"preserve_timestamps": "Adjust timestamps to fill gaps",
|
||||||
"reverse": {
|
"reverse": {
|
||||||
"button": "Reverse",
|
"button": "Reverse",
|
||||||
"tooltip": "Reverse the direction of the route"
|
"tooltip": "Reverse the direction of the route"
|
||||||
@@ -119,11 +121,8 @@
|
|||||||
"unpaved": "Unpaved",
|
"unpaved": "Unpaved",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Concrete",
|
"concrete": "Concrete",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Cobblestone",
|
"cobblestone": "Cobblestone",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Wood",
|
"wood": "Wood",
|
||||||
@@ -135,15 +134,59 @@
|
|||||||
"dirt": "Dirt",
|
"dirt": "Dirt",
|
||||||
"ground": "Ground",
|
"ground": "Ground",
|
||||||
"earth": "Earth",
|
"earth": "Earth",
|
||||||
"snow": "Snow",
|
|
||||||
"ice": "Ice",
|
|
||||||
"salt": "Salt",
|
|
||||||
"mud": "Mud",
|
"mud": "Mud",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Grass",
|
"grass": "Grass",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +216,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +316,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +390,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +404,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Sin pavimento",
|
"unpaved": "Sin pavimento",
|
||||||
"asphalt": "Asfalto",
|
"asphalt": "Asfalto",
|
||||||
"concrete": "Hormigón",
|
"concrete": "Hormigón",
|
||||||
"chipseal": "Pavimento delgado",
|
|
||||||
"cobblestone": "Adoquinado",
|
"cobblestone": "Adoquinado",
|
||||||
"unhewn_cobblestone": "Adoquín sin labrar",
|
|
||||||
"paving_stones": "Adoquines",
|
"paving_stones": "Adoquines",
|
||||||
"stepping_stones": "Peldaños",
|
|
||||||
"sett": "Adoquín",
|
"sett": "Adoquín",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Madera",
|
"wood": "Madera",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Tierra",
|
"dirt": "Tierra",
|
||||||
"ground": "Tierra",
|
"ground": "Tierra",
|
||||||
"earth": "Tierra natural",
|
"earth": "Tierra natural",
|
||||||
"snow": "Nevado",
|
|
||||||
"ice": "Helado",
|
|
||||||
"salt": "Salado",
|
|
||||||
"mud": "Barro",
|
"mud": "Barro",
|
||||||
"sand": "Arena",
|
"sand": "Arena",
|
||||||
"woodchips": "Virutas de madera",
|
|
||||||
"grass": "Hierba",
|
"grass": "Hierba",
|
||||||
"grass_paver": "Pavimento con césped"
|
"grass_paver": "Pavimento con césped",
|
||||||
|
"clay": "Arcilla",
|
||||||
|
"stone": "Piedra"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Desconocido",
|
||||||
|
"motorway": "Autopista",
|
||||||
|
"motorway_link": "Enlace de autopista",
|
||||||
|
"trunk": "Carretera principal",
|
||||||
|
"trunk_link": "Enlace de carretera principal",
|
||||||
|
"primary": "Carretera principal",
|
||||||
|
"primary_link": "Enlace de carretera principal",
|
||||||
|
"secondary": "Carretera secundaria",
|
||||||
|
"secondary_link": "Enlace de carretera secundaria",
|
||||||
|
"tertiary": "Carretera terciaria",
|
||||||
|
"tertiary_link": "Enlace de carretera terciaria",
|
||||||
|
"unclassified": "Carretera menor",
|
||||||
|
"residential": "Vía residencial",
|
||||||
|
"living_street": "Calle residencial",
|
||||||
|
"service": "Vía de servicio",
|
||||||
|
"track": "Pista",
|
||||||
|
"footway": "Passarela",
|
||||||
|
"path": "Ruta",
|
||||||
|
"pedestrian": "Peatón",
|
||||||
|
"cycleway": "Ciclovia",
|
||||||
|
"steps": "Pasos",
|
||||||
|
"road": "Carretera",
|
||||||
|
"bridleway": "Ruta ecuestre",
|
||||||
|
"platform": "Plataforma",
|
||||||
|
"raceway": "Circuito de carreras",
|
||||||
|
"rest_area": "Área de descanso",
|
||||||
|
"abandoned": "Abandonado",
|
||||||
|
"services": "Servicios",
|
||||||
|
"corridor": "Pasillo",
|
||||||
|
"bus_stop": "Parada de autobús",
|
||||||
|
"busway": "Carril bus",
|
||||||
|
"elevator": "Ascensor",
|
||||||
|
"via_ferrata": "Vía ferrata",
|
||||||
|
"proposed": "Carretera por construir",
|
||||||
|
"construction": "Carretera en construcción"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Senderismo",
|
||||||
|
"mountain_hiking": "Senderismo de montaña",
|
||||||
|
"demanding_mountain_hiking": "Senderismo de montaña exigente",
|
||||||
|
"alpine_hiking": "Senderismo alpino",
|
||||||
|
"demanding_alpine_hiking": "Senderismo alpino exigente",
|
||||||
|
"difficult_alpine_hiking": "Senderismo alpino difícil"
|
||||||
|
},
|
||||||
|
"mtb_scale": "Escala MTB",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Conectar los trazados",
|
"merge_traces": "Conectar los trazados",
|
||||||
"merge_contents": "Combinar los contenidos y mantener los trazados desconectados",
|
"merge_contents": "Combinar los contenidos y mantener los trazados desconectados",
|
||||||
"merge_selection": "Combinar selección",
|
"merge_selection": "Combinar selección",
|
||||||
|
"remove_gaps": "Eliminar intervalos vacíos de tiempo entre trazas",
|
||||||
"tooltip": "Combinar elementos",
|
"tooltip": "Combinar elementos",
|
||||||
"help_merge_traces": "Conectar los trazados seleccionados creará un único trazado continuo.",
|
"help_merge_traces": "Conectar los trazados seleccionados creará un único trazado continuo.",
|
||||||
"help_cannot_merge_traces": "Su selección debe contener varios trazados para conectarlos.",
|
"help_cannot_merge_traces": "Su selección debe contener varios trazados para conectarlos.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satélite",
|
"ignFrSatellite": "IGN Satélite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satélite",
|
||||||
"ordnanceSurvey": "Encuesta Ordnance",
|
"ordnanceSurvey": "Encuesta Ordnance",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Mostrar datos de pendiente",
|
"settings": "Configuración del perfil de elevación"
|
||||||
"show_surface": "Mostrar datos de superficie",
|
|
||||||
"show_speed": "Mostrar datos de velocidad",
|
|
||||||
"show_pace": "Mostrar datos de ritmo",
|
|
||||||
"show_heartrate": "Mostrar datos de ritmo cardíaco",
|
|
||||||
"show_cadence": "Mostrar datos de cadencia",
|
|
||||||
"show_temperature": "Mostrar datos de temperatura",
|
|
||||||
"show_power": "Mostrar datos de potencia"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distancia",
|
"distance": "Distancia",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Potencia",
|
"power": "Potencia",
|
||||||
"slope": "Pendiente",
|
"slope": "Pendiente",
|
||||||
"surface": "Superficie",
|
"surface": "Superficie",
|
||||||
|
"highway": "Categoría",
|
||||||
"time": "Tiempo",
|
"time": "Tiempo",
|
||||||
"moving": "Movimiento",
|
"moving": "Movimiento",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "Datos OpenStreetMap"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Päällystämätön",
|
"unpaved": "Päällystämätön",
|
||||||
"asphalt": "Asfaltti",
|
"asphalt": "Asfaltti",
|
||||||
"concrete": "Betoni",
|
"concrete": "Betoni",
|
||||||
"chipseal": "Öljysora",
|
|
||||||
"cobblestone": "Mukulakivi",
|
"cobblestone": "Mukulakivi",
|
||||||
"unhewn_cobblestone": "Luonnonmukainen mukulakivi",
|
|
||||||
"paving_stones": "Katukivetys",
|
"paving_stones": "Katukivetys",
|
||||||
"stepping_stones": "Astinkivet",
|
|
||||||
"sett": "Kivetys",
|
"sett": "Kivetys",
|
||||||
"metal": "Metalli",
|
"metal": "Metalli",
|
||||||
"wood": "Puu",
|
"wood": "Puu",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Maa",
|
"dirt": "Maa",
|
||||||
"ground": "Maa",
|
"ground": "Maa",
|
||||||
"earth": "Maa",
|
"earth": "Maa",
|
||||||
"snow": "Lumi",
|
|
||||||
"ice": "Jää",
|
|
||||||
"salt": "Suola",
|
|
||||||
"mud": "Muta",
|
"mud": "Muta",
|
||||||
"sand": "Hiekka",
|
"sand": "Hiekka",
|
||||||
"woodchips": "Hake",
|
|
||||||
"grass": "Nurmi",
|
"grass": "Nurmi",
|
||||||
"grass_paver": "Nurmikivi"
|
"grass_paver": "Nurmikivi",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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ä",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Yhdistä reitit",
|
"merge_traces": "Yhdistä reitit",
|
||||||
"merge_contents": "Yhdistä reitit samaan tiedostoon",
|
"merge_contents": "Yhdistä reitit samaan tiedostoon",
|
||||||
"merge_selection": "Yhdistä valitut",
|
"merge_selection": "Yhdistä valitut",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Yhdistä tiedostot",
|
"tooltip": "Yhdistä tiedostot",
|
||||||
"help_merge_traces": "Yhdistäminen luo valituista reiteistä yhden yhtenäisen reitin.",
|
"help_merge_traces": "Yhdistäminen luo valituista reiteistä yhden yhtenäisen reitin.",
|
||||||
"help_cannot_merge_traces": "Valitse useampia reittejä yhdistääksesi ne.",
|
"help_cannot_merge_traces": "Valitse useampia reittejä yhdistääksesi ne.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Maastokartta",
|
"ignFrTopo": "IGN Maastokartta",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Ilmakuva",
|
"ignFrSatellite": "IGN Ilmakuva",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Maastokartta",
|
"swedenTopo": "Lantmäteriet Maastokartta",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Näytä syketiedot",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Näytä lämpötilatiedot",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Kaltevuus",
|
"slope": "Kaltevuus",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Sans revêtement",
|
"unpaved": "Sans revêtement",
|
||||||
"asphalt": "Asphalte",
|
"asphalt": "Asphalte",
|
||||||
"concrete": "Béton",
|
"concrete": "Béton",
|
||||||
"chipseal": "Enduit superficiel routier",
|
|
||||||
"cobblestone": "Pavés",
|
"cobblestone": "Pavés",
|
||||||
"unhewn_cobblestone": "Pavé non taillé",
|
|
||||||
"paving_stones": "Pavage en pierres",
|
"paving_stones": "Pavage en pierres",
|
||||||
"stepping_stones": "Pierres de gué",
|
|
||||||
"sett": "Pavés",
|
"sett": "Pavés",
|
||||||
"metal": "Métal",
|
"metal": "Métal",
|
||||||
"wood": "Bois",
|
"wood": "Bois",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Sol en érosion",
|
"dirt": "Sol en érosion",
|
||||||
"ground": "Sol",
|
"ground": "Sol",
|
||||||
"earth": "Terre",
|
"earth": "Terre",
|
||||||
"snow": "Neige",
|
|
||||||
"ice": "Glace",
|
|
||||||
"salt": "Sel",
|
|
||||||
"mud": "Boue",
|
"mud": "Boue",
|
||||||
"sand": "Sable",
|
"sand": "Sable",
|
||||||
"woodchips": "Plaquette forestière",
|
|
||||||
"grass": "Herbe",
|
"grass": "Herbe",
|
||||||
"grass_paver": "Mélange d'herbe et de pavés"
|
"grass_paver": "Mélange d'herbe et de pavés",
|
||||||
|
"clay": "Argile",
|
||||||
|
"stone": "Pierre"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Inconnu",
|
||||||
|
"motorway": "Autoroute",
|
||||||
|
"motorway_link": "Bretelle d'autoroute",
|
||||||
|
"trunk": "Route principale",
|
||||||
|
"trunk_link": "Liaison de route principale",
|
||||||
|
"primary": "Route principale",
|
||||||
|
"primary_link": "Liaison de route principale",
|
||||||
|
"secondary": "Route secondaire",
|
||||||
|
"secondary_link": "Liaison de route secondaire",
|
||||||
|
"tertiary": "Route tertiaire",
|
||||||
|
"tertiary_link": "Liaison de route tertiaire",
|
||||||
|
"unclassified": "Route mineure",
|
||||||
|
"residential": "Route résidentielle",
|
||||||
|
"living_street": "Rue résidentielle",
|
||||||
|
"service": "Route de service",
|
||||||
|
"track": "Chemin",
|
||||||
|
"footway": "Chemin piéton",
|
||||||
|
"path": "Chemin",
|
||||||
|
"pedestrian": "Piéton",
|
||||||
|
"cycleway": "Voie cyclable",
|
||||||
|
"steps": "Marches",
|
||||||
|
"road": "Route",
|
||||||
|
"bridleway": "Chemin d'équitation",
|
||||||
|
"platform": "Quai",
|
||||||
|
"raceway": "Circuit de course",
|
||||||
|
"rest_area": "Aire de repos",
|
||||||
|
"abandoned": "Abandonné",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Couloir",
|
||||||
|
"bus_stop": "Arrêt de bus",
|
||||||
|
"busway": "Réservé bus",
|
||||||
|
"elevator": "Ascenseur",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Route à construire",
|
||||||
|
"construction": "Route en construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Randonnée",
|
||||||
|
"mountain_hiking": "Randonnée de montagne",
|
||||||
|
"demanding_mountain_hiking": "Randonnée de montagne exigeante",
|
||||||
|
"alpine_hiking": "Randonnée alpine",
|
||||||
|
"demanding_alpine_hiking": "Randonnée alpine exigeante",
|
||||||
|
"difficult_alpine_hiking": "Randonnée alpine difficile"
|
||||||
|
},
|
||||||
|
"mtb_scale": "Échelle VTT",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connecter les traces",
|
"merge_traces": "Connecter les traces",
|
||||||
"merge_contents": "Fusionner les contenus et garder les traces déconnectées",
|
"merge_contents": "Fusionner les contenus et garder les traces déconnectées",
|
||||||
"merge_selection": "Fusionner la sélection",
|
"merge_selection": "Fusionner la sélection",
|
||||||
|
"remove_gaps": "Supprimer les écarts de temps entre les traces",
|
||||||
"tooltip": "Fusionner les éléments",
|
"tooltip": "Fusionner les éléments",
|
||||||
"help_merge_traces": "Connecter les traces sélectionnées créera une seule trace continue.",
|
"help_merge_traces": "Connecter les traces sélectionnées créera une seule trace continue.",
|
||||||
"help_cannot_merge_traces": "Votre sélection doit contenir plusieurs traces pour pouvoir les connecter.",
|
"help_cannot_merge_traces": "Votre sélection doit contenir plusieurs traces pour pouvoir les connecter.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Afficher les données de pente",
|
"settings": "Réglages du profil altimétrique"
|
||||||
"show_surface": "Afficher les données de surface",
|
|
||||||
"show_speed": "Afficher les données de vitesse",
|
|
||||||
"show_pace": "Afficher les données d'allure",
|
|
||||||
"show_heartrate": "Afficher les données de fréquence cardiaque",
|
|
||||||
"show_cadence": "Afficher les données de cadence",
|
|
||||||
"show_temperature": "Afficher les données de température",
|
|
||||||
"show_power": "Afficher les données de puissance"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -365,10 +401,12 @@
|
|||||||
"cadence": "Cadence",
|
"cadence": "Cadence",
|
||||||
"power": "Puissance",
|
"power": "Puissance",
|
||||||
"slope": "Pente",
|
"slope": "Pente",
|
||||||
"surface": "Surface",
|
"surface": "Revêtement",
|
||||||
|
"highway": "Catégorie",
|
||||||
"time": "Temps",
|
"time": "Temps",
|
||||||
"moving": "En mouvement",
|
"moving": "En mouvement",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "Données d'OpenStreetMap"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Unpaved",
|
"unpaved": "Unpaved",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Concrete",
|
"concrete": "Concrete",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Cobblestone",
|
"cobblestone": "Cobblestone",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Wood",
|
"wood": "Wood",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Dirt",
|
"dirt": "Dirt",
|
||||||
"ground": "Ground",
|
"ground": "Ground",
|
||||||
"earth": "Earth",
|
"earth": "Earth",
|
||||||
"snow": "Snow",
|
|
||||||
"ice": "Ice",
|
|
||||||
"salt": "Salt",
|
|
||||||
"mud": "Mud",
|
"mud": "Mud",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Grass",
|
"grass": "Grass",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
"embed_title": "az online GPX szerkesztő",
|
"embed_title": "az online GPX szerkesztő",
|
||||||
"help_title": "súgó",
|
"help_title": "súgó",
|
||||||
"404_title": "az oldal nem található",
|
"404_title": "az oldal nem található",
|
||||||
"description": "GPX-fájlok online megtekintése, szerkesztése és létrehozása fejlett útvonaltervezési képességekkel és fájlfeldolgozó eszközökkel, gyönyörű térképekkel és részletes adatmegjelenítésekkel."
|
"description": "GPX fájlok online megtekintése, szerkesztése és létrehozása fejlett útvonal tervezési képességekkel és fájlfeldolgozó eszközökkel, gyönyörű térképekkel és részletes adatmegjelenítésekkel."
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"new": "Új",
|
"new": "Új",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"select_all": "Összes kijelölése",
|
"select_all": "Összes kijelölése",
|
||||||
"view": "Nézet",
|
"view": "Nézet",
|
||||||
"elevation_profile": "Magassági profil",
|
"elevation_profile": "Magassági profil",
|
||||||
"vertical_file_view": "Függoleges fájl lista",
|
"vertical_file_view": "Függőleges fájl lista",
|
||||||
"switch_basemap": "Váltás az előző alaptérképre",
|
"switch_basemap": "Váltás az előző alaptérképre",
|
||||||
"toggle_overlays": "Átfedés váltása",
|
"toggle_overlays": "Átfedés váltása",
|
||||||
"toggle_3d": "3D nézet bekapcsolása",
|
"toggle_3d": "3D nézet bekapcsolása",
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"street_view_source": "Utcakép nézet forrása",
|
"street_view_source": "Utcakép nézet forrása",
|
||||||
"mapillary": "Mapillary",
|
"mapillary": "Mapillary",
|
||||||
"google": "Google",
|
"google": "Google",
|
||||||
"toggle_street_view": "Street view",
|
"toggle_street_view": "Utcakép nézet",
|
||||||
"layers": "Térképrétegek...",
|
"layers": "Térképrétegek...",
|
||||||
"distance_markers": "Távolsági km szakaszok mutatása",
|
"distance_markers": "Távolsági km szakaszok mutatása",
|
||||||
"direction_markers": "Menetirány mutatása",
|
"direction_markers": "Menetirány mutatása",
|
||||||
@@ -86,11 +86,11 @@
|
|||||||
"tooltip": "Útvonal tervezése vagy szerkesztése",
|
"tooltip": "Útvonal tervezése vagy szerkesztése",
|
||||||
"activity": "Tevékenység",
|
"activity": "Tevékenység",
|
||||||
"use_routing": "Útvonal választása",
|
"use_routing": "Útvonal választása",
|
||||||
"use_routing_tooltip": "Útvonal követés kikapcsolava egyenes vonal rajzolása",
|
"use_routing_tooltip": "Útvonal követés kikapcsolva egyenes vonal rajzolása",
|
||||||
"allow_private": "Magánutak engedélyezése",
|
"allow_private": "Magánutak engedélyezése",
|
||||||
"reverse": {
|
"reverse": {
|
||||||
"button": "Út menetirány váltás",
|
"button": "Út menetirány váltás",
|
||||||
"tooltip": "Útvonal irányát megfordítása"
|
"tooltip": "Útvonal irányának megfordítása"
|
||||||
},
|
},
|
||||||
"route_back_to_start": {
|
"route_back_to_start": {
|
||||||
"button": "Vissza a starthoz",
|
"button": "Vissza a starthoz",
|
||||||
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Földes",
|
"unpaved": "Földes",
|
||||||
"asphalt": "Aszfalt",
|
"asphalt": "Aszfalt",
|
||||||
"concrete": "Beton",
|
"concrete": "Beton",
|
||||||
"chipseal": "Törmelékes",
|
|
||||||
"cobblestone": "Macskaköves",
|
"cobblestone": "Macskaköves",
|
||||||
"unhewn_cobblestone": "Vágatlan nagy kavics",
|
|
||||||
"paving_stones": "Térkő",
|
"paving_stones": "Térkő",
|
||||||
"stepping_stones": "Szikla lépcső",
|
|
||||||
"sett": "Kőlap",
|
"sett": "Kőlap",
|
||||||
"metal": "Fém",
|
"metal": "Fém",
|
||||||
"wood": "Fa",
|
"wood": "Fa",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Piszok",
|
"dirt": "Piszok",
|
||||||
"ground": "Föld",
|
"ground": "Föld",
|
||||||
"earth": "Föld",
|
"earth": "Föld",
|
||||||
"snow": "Hó",
|
|
||||||
"ice": "Jég",
|
|
||||||
"salt": "Só",
|
|
||||||
"mud": "Sár",
|
"mud": "Sár",
|
||||||
"sand": "Homok",
|
"sand": "Homok",
|
||||||
"woodchips": "Faforgács",
|
|
||||||
"grass": "Fű",
|
"grass": "Fű",
|
||||||
"grass_paver": "Gyephézagos térkő"
|
"grass_paver": "Gyephézagos térkő",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -159,20 +200,21 @@
|
|||||||
"help": "Használja a csúszkát az útvonal kivágásához, vagy ossza fel az egyik jelölőre vagy magára az útvonalra kattintva."
|
"help": "Használja a csúszkát az útvonal kivágásához, vagy ossza fel az egyik jelölőre vagy magára az útvonalra kattintva."
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"tooltip": "Manage time data",
|
"tooltip": "Idő beállítása",
|
||||||
"start": "Rajt",
|
"start": "Rajt",
|
||||||
"end": "End",
|
"end": "Befejezés",
|
||||||
"total_time": "Mozgási idő",
|
"total_time": "Mozgási idő",
|
||||||
"pick_date": "Pick a date",
|
"pick_date": "Válassz dátumot",
|
||||||
"artificial": "Create realistic time data",
|
"artificial": "Valósághű időadatok hozzáadása",
|
||||||
"update": "Update time data",
|
"update": "Használd a formot új idő beállításához.",
|
||||||
"help": "Use the form to set new time data.",
|
"help": "Használd a form-ot az új idő beállításához.",
|
||||||
"help_invalid_selection": "Select a single trace to manage its time data."
|
"help_invalid_selection": "Válasszon ki egyetlen nyomvonalat az időadatainak kezeléséhez."
|
||||||
},
|
},
|
||||||
"merge": {
|
"merge": {
|
||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Kösd össze az útvonalakat",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Egyesítés kijelőlés",
|
"merge_selection": "Egyesítés kijelölés",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -184,10 +226,10 @@
|
|||||||
"tooltip": "Extract contents to separate items",
|
"tooltip": "Extract contents to separate items",
|
||||||
"button": "Extract",
|
"button": "Extract",
|
||||||
"help": "Extracting the contents of the selected items will create a separate item for each of their contents.",
|
"help": "Extracting the contents of the selected items will create a separate item for each of their contents.",
|
||||||
"help_invalid_selection": "Your selection must contain items with multiple traces to extract them."
|
"help_invalid_selection": "Több nyomvonalat kell tartalmazzon a kijelölés a kinyeréshez."
|
||||||
},
|
},
|
||||||
"elevation": {
|
"elevation": {
|
||||||
"button": "Request elevation data",
|
"button": "Magassági információk lekérése",
|
||||||
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapbox.",
|
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapbox.",
|
||||||
"help_no_selection": "Select a file item to request elevation data."
|
"help_no_selection": "Select a file item to request elevation data."
|
||||||
},
|
},
|
||||||
@@ -196,23 +238,23 @@
|
|||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
"link": "Link",
|
"link": "Link",
|
||||||
"longitude": "Longitude",
|
"longitude": "Longitude",
|
||||||
"latitude": "Latitude",
|
"latitude": "Szélesség",
|
||||||
"create": "Create point of interest",
|
"create": "POI fájlba mentése",
|
||||||
"add": "Add point of interest to file",
|
"add": "Add point of interest to file",
|
||||||
"help": "Fill in the form to create a new point of interest, or click on an existing one to edit it. Click on the map to fill the coordinates, or drag points of interest to move them.",
|
"help": "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."
|
||||||
},
|
},
|
||||||
"reduce": {
|
"reduce": {
|
||||||
"tooltip": "Reduce the number of GPS points",
|
"tooltip": "Reduce the number of GPS points",
|
||||||
"tolerance": "Tolerance",
|
"tolerance": "Tűréshatár",
|
||||||
"number_of_points": "Number of GPS points",
|
"number_of_points": "GPS pontok száma",
|
||||||
"button": "Minify",
|
"button": "Minify",
|
||||||
"help": "Use the slider to choose the number of GPS points to keep.",
|
"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": {
|
||||||
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
|
"tooltip": "Clean GPS points and points of interest with a rectangle selection",
|
||||||
"delete_trackpoints": "Delete GPS points",
|
"delete_trackpoints": "GPS pontok törlése",
|
||||||
"delete_waypoints": "Delete points of interest",
|
"delete_waypoints": "Delete points of interest",
|
||||||
"delete_inside": "Delete inside selection",
|
"delete_inside": "Delete inside selection",
|
||||||
"delete_outside": "Delete outside selection",
|
"delete_outside": "Delete outside selection",
|
||||||
@@ -222,14 +264,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"layers": {
|
"layers": {
|
||||||
"settings": "Layer settings",
|
"settings": "Réteg beállítások",
|
||||||
"settings_help": "Select the map layers you want to show in the interface, add custom ones, and adjust their settings.",
|
"settings_help": "Select the map layers you want to show in the interface, add custom ones, and adjust their settings.",
|
||||||
"selection": "Layer selection",
|
"selection": "Layer selection",
|
||||||
"custom_layers": {
|
"custom_layers": {
|
||||||
"title": "Custom layers",
|
"title": "Custom layers",
|
||||||
"new": "New custom layer",
|
"new": "New custom layer",
|
||||||
"edit": "Edit custom layer",
|
"edit": "Edit custom layer",
|
||||||
"urls": "URL(s)",
|
"urls": "Webcím(ek)",
|
||||||
"url_placeholder": "WMTS, WMS vagy Mapbox stílus JSON",
|
"url_placeholder": "WMTS, WMS vagy Mapbox stílus JSON",
|
||||||
"max_zoom": "Max nagyítás",
|
"max_zoom": "Max nagyítás",
|
||||||
"layer_type": "Réteg típus",
|
"layer_type": "Réteg típus",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Műhold",
|
"ignFrSatellite": "IGN Műhold",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Hadifelmérés",
|
"ordnanceSurvey": "Hadifelmérés",
|
||||||
"norwayTopo": "Norvégia topográfiai térképe 4",
|
"norwayTopo": "Norvégia topográfiai térképe 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -321,8 +364,8 @@
|
|||||||
"hotel": "Hotel",
|
"hotel": "Hotel",
|
||||||
"campsite": "Kemping",
|
"campsite": "Kemping",
|
||||||
"hut": "Hut",
|
"hut": "Hut",
|
||||||
"picnic": "Picnic Area",
|
"picnic": "Piknikező hely",
|
||||||
"summit": "Summit",
|
"summit": "Csúcs",
|
||||||
"pass": "Pass",
|
"pass": "Pass",
|
||||||
"climbing": "Climbing",
|
"climbing": "Climbing",
|
||||||
"bicycle": "Kerékpár",
|
"bicycle": "Kerékpár",
|
||||||
@@ -333,7 +376,7 @@
|
|||||||
"railway-station": "Vasútállomás",
|
"railway-station": "Vasútállomás",
|
||||||
"tram-stop": "Villamos megálló",
|
"tram-stop": "Villamos megálló",
|
||||||
"bus-stop": "Buszmegálló",
|
"bus-stop": "Buszmegálló",
|
||||||
"ferry": "Ferry"
|
"ferry": "Komp"
|
||||||
},
|
},
|
||||||
"color": {
|
"color": {
|
||||||
"blue": "Kék",
|
"blue": "Kék",
|
||||||
@@ -341,18 +384,11 @@
|
|||||||
"gray": "Szürke",
|
"gray": "Szürke",
|
||||||
"hot": "Legérdekesebb",
|
"hot": "Legérdekesebb",
|
||||||
"purple": "Lila",
|
"purple": "Lila",
|
||||||
"orange": "Orange"
|
"orange": "Narancssárga"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Távolság",
|
"distance": "Távolság",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Erő",
|
"power": "Erő",
|
||||||
"slope": "Erőkifejtési szintkép színekkel",
|
"slope": "Erőkifejtési szintkép színekkel",
|
||||||
"surface": "Szintkép",
|
"surface": "Szintkép",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Idő",
|
"time": "Idő",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Összes"
|
"total": "Összes",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
@@ -383,7 +421,7 @@
|
|||||||
"minutes_per_kilometer": "min/km",
|
"minutes_per_kilometer": "min/km",
|
||||||
"minutes_per_mile": "min/mi",
|
"minutes_per_mile": "min/mi",
|
||||||
"minutes_per_nautical_mile": "min/nm",
|
"minutes_per_nautical_mile": "min/nm",
|
||||||
"knots": "kn",
|
"knots": "csomó",
|
||||||
"heartrate": "bpm",
|
"heartrate": "bpm",
|
||||||
"cadence": "rpm",
|
"cadence": "rpm",
|
||||||
"power": "W"
|
"power": "W"
|
||||||
@@ -499,14 +537,14 @@
|
|||||||
"manual_camera": "Manual camera",
|
"manual_camera": "Manual camera",
|
||||||
"manual_camera_description": "You can move the map below to adjust the camera position.",
|
"manual_camera_description": "You can move the map below to adjust the camera position.",
|
||||||
"latitude": "Latitude",
|
"latitude": "Latitude",
|
||||||
"longitude": "Longitude",
|
"longitude": "Hosszúság",
|
||||||
"zoom": "Zoom",
|
"zoom": "Zoom",
|
||||||
"pitch": "Pitch",
|
"pitch": "Dőlésszög",
|
||||||
"bearing": "Bearing",
|
"bearing": "Irányszög",
|
||||||
"preview": "Előnézet",
|
"preview": "Előnézet",
|
||||||
"code": "Integration code"
|
"code": "Integration code"
|
||||||
},
|
},
|
||||||
"webgl2_required": "WebGL 2 is required to display the map.",
|
"webgl2_required": "A térkép megjelenítéséhez WebGL 2 szükséges. ",
|
||||||
"enable_webgl2": "Learn how to enable WebGL 2 in your browser",
|
"enable_webgl2": "Learn how to enable WebGL 2 in your browser",
|
||||||
"page_not_found": "page not found"
|
"page_not_found": "page not found"
|
||||||
}
|
}
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Non asfaltato",
|
"unpaved": "Non asfaltato",
|
||||||
"asphalt": "Asfalto",
|
"asphalt": "Asfalto",
|
||||||
"concrete": "Calcestruzzo",
|
"concrete": "Calcestruzzo",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Acciottolato",
|
"cobblestone": "Acciottolato",
|
||||||
"unhewn_cobblestone": "Ciottolame",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Pavé",
|
"sett": "Pavé",
|
||||||
"metal": "Metallo",
|
"metal": "Metallo",
|
||||||
"wood": "Legno",
|
"wood": "Legno",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Terra",
|
"dirt": "Terra",
|
||||||
"ground": "Terreno",
|
"ground": "Terreno",
|
||||||
"earth": "Terra",
|
"earth": "Terra",
|
||||||
"snow": "Neve",
|
|
||||||
"ice": "Ghiaccio",
|
|
||||||
"salt": "Sale",
|
|
||||||
"mud": "Fango",
|
"mud": "Fango",
|
||||||
"sand": "Sabbia",
|
"sand": "Sabbia",
|
||||||
"woodchips": "Cippato",
|
|
||||||
"grass": "Erba",
|
"grass": "Erba",
|
||||||
"grass_paver": "Pavimentazione erbosa"
|
"grass_paver": "Pavimentazione erbosa",
|
||||||
|
"clay": "Argilla",
|
||||||
|
"stone": "Pietra"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"from": "Il punto di partenza è troppo lontano dalla strada più vicina",
|
"from": "Il punto di partenza è troppo lontano dalla strada più vicina",
|
||||||
"via": "The via point is too far from the nearest road",
|
"via": "The via point is too far from the nearest road",
|
||||||
@@ -173,12 +214,13 @@
|
|||||||
"merge_traces": "Collega le tracce",
|
"merge_traces": "Collega le tracce",
|
||||||
"merge_contents": "Unisci i contenuti e mantieni le tracce disconnesse",
|
"merge_contents": "Unisci i contenuti e mantieni le tracce disconnesse",
|
||||||
"merge_selection": "Selezione unione",
|
"merge_selection": "Selezione unione",
|
||||||
|
"remove_gaps": "Rimuovere le differenze di tempo tra le tracce",
|
||||||
"tooltip": "Unisci gli elementi insieme",
|
"tooltip": "Unisci gli elementi insieme",
|
||||||
"help_merge_traces": "Collegando le tracce selezionate si creerà una singola traccia continua.",
|
"help_merge_traces": "Collegando le tracce selezionate si creerà una singola traccia continua.",
|
||||||
"help_cannot_merge_traces": "La tua selezione deve contenere diverse tracce per collegarle.",
|
"help_cannot_merge_traces": "La tua selezione deve contenere diverse tracce per collegarle.",
|
||||||
"help_merge_contents": "Unendo il contenuto degli elementi selezionati si raggrupperà tutti i contenuti all'interno del primo elemento.",
|
"help_merge_contents": "Unendo il contenuto degli elementi selezionati si raggrupperà tutti i contenuti all'interno del primo elemento.",
|
||||||
"help_cannot_merge_contents": "La selezione deve contenere diversi elementi per unire il loro contenuto.",
|
"help_cannot_merge_contents": "La selezione deve contenere diversi elementi per unire il loro contenuto.",
|
||||||
"selection_tip": "Tip: use {KEYBOARD_SHORTCUT} to add items to the selection."
|
"selection_tip": "Suggerimento: usa {KEYBOARD_SHORTCUT} per aggiungere elementi alla selezione."
|
||||||
},
|
},
|
||||||
"extract": {
|
"extract": {
|
||||||
"tooltip": "Estrae i contenuti per separare gli elementi",
|
"tooltip": "Estrae i contenuti per separare gli elementi",
|
||||||
@@ -188,8 +230,8 @@
|
|||||||
},
|
},
|
||||||
"elevation": {
|
"elevation": {
|
||||||
"button": "Richiedi dati elevazione",
|
"button": "Richiedi dati elevazione",
|
||||||
"help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapbox.",
|
"help": "Richiedere dati di altitudine cancellerà i dati di altitudine attuali, se presenti, e li rimpiazzerà con quelli provenienti da Mapbox.",
|
||||||
"help_no_selection": "Select a file item to request elevation data."
|
"help_no_selection": "Seleziona un file per richiedere i dati di altitudine."
|
||||||
},
|
},
|
||||||
"waypoint": {
|
"waypoint": {
|
||||||
"tooltip": "Crea e modifica punti di interesse",
|
"tooltip": "Crea e modifica punti di interesse",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "Satellitare IGN",
|
"ignFrSatellite": "Satellitare IGN",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Sondaggio Ordnance",
|
"ordnanceSurvey": "Sondaggio Ordnance",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Mostra dati pendenza",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Mostra dati di superficie",
|
|
||||||
"show_speed": "Mostra dati velocità",
|
|
||||||
"show_pace": "Mostra i dati del ritmo",
|
|
||||||
"show_heartrate": "Mostra i dati della frequenza cardiaca",
|
|
||||||
"show_cadence": "Mostra i dati di cadenza",
|
|
||||||
"show_temperature": "Mostra dati di temperatura",
|
|
||||||
"show_power": "Mostra dati di potenza"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distanza",
|
"distance": "Distanza",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Potenza",
|
"power": "Potenza",
|
||||||
"slope": "Pendenza",
|
"slope": "Pendenza",
|
||||||
"surface": "Superficie",
|
"surface": "Superficie",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Dati temporali",
|
"time": "Dati temporali",
|
||||||
"moving": "Movimento",
|
"moving": "Movimento",
|
||||||
"total": "Totale"
|
"total": "Totale",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "비포장 도로",
|
"unpaved": "비포장 도로",
|
||||||
"asphalt": "아스팔트",
|
"asphalt": "아스팔트",
|
||||||
"concrete": "콘크리트",
|
"concrete": "콘크리트",
|
||||||
"chipseal": "칩씰",
|
|
||||||
"cobblestone": "조약돌",
|
"cobblestone": "조약돌",
|
||||||
"unhewn_cobblestone": "거친 조약돌",
|
|
||||||
"paving_stones": "포장석",
|
"paving_stones": "포장석",
|
||||||
"stepping_stones": "디딤돌",
|
|
||||||
"sett": "정형 자갈",
|
"sett": "정형 자갈",
|
||||||
"metal": "금속",
|
"metal": "금속",
|
||||||
"wood": "목재",
|
"wood": "목재",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "흙길",
|
"dirt": "흙길",
|
||||||
"ground": "지면",
|
"ground": "지면",
|
||||||
"earth": "자연 지면",
|
"earth": "자연 지면",
|
||||||
"snow": "눈",
|
|
||||||
"ice": "얼음",
|
|
||||||
"salt": "소금",
|
|
||||||
"mud": "진흙",
|
"mud": "진흙",
|
||||||
"sand": "모래",
|
"sand": "모래",
|
||||||
"woodchips": "목재 칩",
|
|
||||||
"grass": "잔디",
|
"grass": "잔디",
|
||||||
"grass_paver": "잔디 포장"
|
"grass_paver": "잔디 포장",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN 위성",
|
"ignFrSatellite": "IGN 위성",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "경사 정보 표시",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "지면 정보 표시",
|
|
||||||
"show_speed": "속도 정보 표시",
|
|
||||||
"show_pace": "페이스 정보 표시",
|
|
||||||
"show_heartrate": "심박수 정보 표시",
|
|
||||||
"show_cadence": "케이던스 정보 표시",
|
|
||||||
"show_temperature": "온도 정보 표시",
|
|
||||||
"show_power": "파워 정보 표시"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "거리",
|
"distance": "거리",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "파워",
|
"power": "파워",
|
||||||
"slope": "경사",
|
"slope": "경사",
|
||||||
"surface": "표면",
|
"surface": "표면",
|
||||||
|
"highway": "Category",
|
||||||
"time": "시간",
|
"time": "시간",
|
||||||
"moving": "이동 중",
|
"moving": "이동 중",
|
||||||
"total": "전체"
|
"total": "전체",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Negrįstas",
|
"unpaved": "Negrįstas",
|
||||||
"asphalt": "Asfaltas",
|
"asphalt": "Asfaltas",
|
||||||
"concrete": "Betonas",
|
"concrete": "Betonas",
|
||||||
"chipseal": "Žvyrkelis",
|
|
||||||
"cobblestone": "Grįstas akmenimis",
|
"cobblestone": "Grįstas akmenimis",
|
||||||
"unhewn_cobblestone": "Grįstas nešlifuotais akmenimis",
|
|
||||||
"paving_stones": "Plytelės",
|
"paving_stones": "Plytelės",
|
||||||
"stepping_stones": "Plytelės su tarpais",
|
|
||||||
"sett": "Trinkelės",
|
"sett": "Trinkelės",
|
||||||
"metal": "Metalo",
|
"metal": "Metalo",
|
||||||
"wood": "Medžio",
|
"wood": "Medžio",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Purvas",
|
"dirt": "Purvas",
|
||||||
"ground": "Žemė",
|
"ground": "Žemė",
|
||||||
"earth": "Žemė",
|
"earth": "Žemė",
|
||||||
"snow": "Sniegas",
|
|
||||||
"ice": "Ledas",
|
|
||||||
"salt": "Druska",
|
|
||||||
"mud": "Purvas",
|
"mud": "Purvas",
|
||||||
"sand": "Smėlis",
|
"sand": "Smėlis",
|
||||||
"woodchips": "Medžio drožlės",
|
|
||||||
"grass": "Žolė",
|
"grass": "Žolė",
|
||||||
"grass_paver": "Žolės grindinys"
|
"grass_paver": "Žolės grindinys",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Sujungti trasas",
|
"merge_traces": "Sujungti trasas",
|
||||||
"merge_contents": "Sujungti turinį ir laikyti trasas atskirai",
|
"merge_contents": "Sujungti turinį ir laikyti trasas atskirai",
|
||||||
"merge_selection": "Sujungti pasirinkimą",
|
"merge_selection": "Sujungti pasirinkimą",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Sujungti elementus",
|
"tooltip": "Sujungti elementus",
|
||||||
"help_merge_traces": "Sujungus pasirinktas trasas bus sukurta viena ištisinė trasa.",
|
"help_merge_traces": "Sujungus pasirinktas trasas bus sukurta viena ištisinė trasa.",
|
||||||
"help_cannot_merge_traces": "Turi pasirinkti kelias trasas, kad galėtumėte jas sujungti.",
|
"help_cannot_merge_traces": "Turi pasirinkti kelias trasas, kad galėtumėte jas sujungti.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Rodyti nuolydžio duomenis",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Rodyti paviršiaus duomenis",
|
|
||||||
"show_speed": "Rodyti greičio duomenis",
|
|
||||||
"show_pace": "Rodyti tempo duomenis",
|
|
||||||
"show_heartrate": "Rodyti pulso duomenis",
|
|
||||||
"show_cadence": "Rodyti tempo duomenis",
|
|
||||||
"show_temperature": "Rodyti temperatūros duomenis",
|
|
||||||
"show_power": "Rodyti jėgos duomenis"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Atstumas",
|
"distance": "Atstumas",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Jėga",
|
"power": "Jėga",
|
||||||
"slope": "Nuolydis",
|
"slope": "Nuolydis",
|
||||||
"surface": "Paviršius",
|
"surface": "Paviršius",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Laikas",
|
"time": "Laikas",
|
||||||
"moving": "Judėjimas",
|
"moving": "Judėjimas",
|
||||||
"total": "Bendras"
|
"total": "Bendras",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Unpaved",
|
"unpaved": "Unpaved",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Concrete",
|
"concrete": "Concrete",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Cobblestone",
|
"cobblestone": "Cobblestone",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Wood",
|
"wood": "Wood",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Dirt",
|
"dirt": "Dirt",
|
||||||
"ground": "Ground",
|
"ground": "Ground",
|
||||||
"earth": "Earth",
|
"earth": "Earth",
|
||||||
"snow": "Snow",
|
|
||||||
"ice": "Ice",
|
|
||||||
"salt": "Salt",
|
|
||||||
"mud": "Mud",
|
"mud": "Mud",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Grass",
|
"grass": "Grass",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Onverhard",
|
"unpaved": "Onverhard",
|
||||||
"asphalt": "Asfalt",
|
"asphalt": "Asfalt",
|
||||||
"concrete": "Beton",
|
"concrete": "Beton",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Klinkers",
|
"cobblestone": "Klinkers",
|
||||||
"unhewn_cobblestone": "Ruwe kasseien",
|
|
||||||
"paving_stones": "Straatstenen",
|
"paving_stones": "Straatstenen",
|
||||||
"stepping_stones": "Stapstenen",
|
|
||||||
"sett": "Instellen",
|
"sett": "Instellen",
|
||||||
"metal": "Metaal",
|
"metal": "Metaal",
|
||||||
"wood": "Hout",
|
"wood": "Hout",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Onverhard",
|
"dirt": "Onverhard",
|
||||||
"ground": "Ondergrond",
|
"ground": "Ondergrond",
|
||||||
"earth": "Aarde",
|
"earth": "Aarde",
|
||||||
"snow": "Sneeuw",
|
|
||||||
"ice": "IJs",
|
|
||||||
"salt": "Zout",
|
|
||||||
"mud": "Modder",
|
"mud": "Modder",
|
||||||
"sand": "Zand",
|
"sand": "Zand",
|
||||||
"woodchips": "Houtsnippers",
|
|
||||||
"grass": "Gras",
|
"grass": "Gras",
|
||||||
"grass_paver": "Grastegel"
|
"grass_paver": "Grastegel",
|
||||||
|
"clay": "Klei",
|
||||||
|
"stone": "Steen"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Onbekend",
|
||||||
|
"motorway": "Snelweg",
|
||||||
|
"motorway_link": "Snelweg aansluiting",
|
||||||
|
"trunk": "Primaire weg",
|
||||||
|
"trunk_link": "Aansluiting primaire weg",
|
||||||
|
"primary": "Primaire weg",
|
||||||
|
"primary_link": "Aansluiting primaire weg",
|
||||||
|
"secondary": "Secundaire weg",
|
||||||
|
"secondary_link": "Aansluiting secundaire weg",
|
||||||
|
"tertiary": "Tertiaire weg",
|
||||||
|
"tertiary_link": "Aansluiting tertiaire weg",
|
||||||
|
"unclassified": "Kleine weg",
|
||||||
|
"residential": "Bebouwde kom",
|
||||||
|
"living_street": "Woonstraat",
|
||||||
|
"service": "Ventweg",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Voetpad",
|
||||||
|
"path": "Pad",
|
||||||
|
"pedestrian": "Voetganger",
|
||||||
|
"cycleway": "Fietspad",
|
||||||
|
"steps": "Trappen",
|
||||||
|
"road": "Weg",
|
||||||
|
"bridleway": "Ruiterpad",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Race circuit",
|
||||||
|
"rest_area": "Pauzeplek",
|
||||||
|
"abandoned": "Verlaten",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bushalte",
|
||||||
|
"busway": "Busbaan",
|
||||||
|
"elevator": "Lift",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Geplande weg",
|
||||||
|
"construction": "Weg in aanleg"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiken",
|
||||||
|
"mountain_hiking": "Bergwandelen",
|
||||||
|
"demanding_mountain_hiking": "Veeleisend bergwandelen",
|
||||||
|
"alpine_hiking": "Alpine wandelen",
|
||||||
|
"demanding_alpine_hiking": "Veeleisend alpine wandelen",
|
||||||
|
"difficult_alpine_hiking": "Moeilijke alpiene wandeling"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB schaal",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Verbind de routes",
|
"merge_traces": "Verbind de routes",
|
||||||
"merge_contents": "Voeg de inhoud samen en houd de sporen gescheiden",
|
"merge_contents": "Voeg de inhoud samen en houd de sporen gescheiden",
|
||||||
"merge_selection": "Voeg selectie samen",
|
"merge_selection": "Voeg selectie samen",
|
||||||
|
"remove_gaps": "Verwijder tijdsprongen tussen sporen",
|
||||||
"tooltip": "Items samenvoegen",
|
"tooltip": "Items samenvoegen",
|
||||||
"help_merge_traces": "Het verbinden van de geselecteerde sporen creëert één continu spoor.",
|
"help_merge_traces": "Het verbinden van de geselecteerde sporen creëert één continu spoor.",
|
||||||
"help_cannot_merge_traces": "Uw selectie moet meerdere sporen bevatten om ze te verbinden.",
|
"help_cannot_merge_traces": "Uw selectie moet meerdere sporen bevatten om ze te verbinden.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satelliet",
|
"ignFrSatellite": "IGN Satelliet",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satelliet",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Toon richtingsgegevens",
|
"settings": "Instellingen hoogteprofiel"
|
||||||
"show_surface": "Toon oppervlakte gegevens",
|
|
||||||
"show_speed": "Toon snelheidsgegevens",
|
|
||||||
"show_pace": "Toon oppervlakte gegevens",
|
|
||||||
"show_heartrate": "Toon hartslag gegevens",
|
|
||||||
"show_cadence": "Toon kadans gegevens",
|
|
||||||
"show_temperature": "Toon temperatuurgegevens",
|
|
||||||
"show_power": "Toon energie gegevens"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Afstand",
|
"distance": "Afstand",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Kracht",
|
"power": "Kracht",
|
||||||
"slope": "Helling",
|
"slope": "Helling",
|
||||||
"surface": "Oppervlak",
|
"surface": "Oppervlak",
|
||||||
|
"highway": "Categorie",
|
||||||
"time": "Tijd",
|
"time": "Tijd",
|
||||||
"moving": "Beweging",
|
"moving": "Beweging",
|
||||||
"total": "Totaal"
|
"total": "Totaal",
|
||||||
|
"osm_extensions": "OpenStreetMap gegevens"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Uasfaltert",
|
"unpaved": "Uasfaltert",
|
||||||
"asphalt": "Asfalt",
|
"asphalt": "Asfalt",
|
||||||
"concrete": "Betong",
|
"concrete": "Betong",
|
||||||
"chipseal": "Grov asfalt",
|
|
||||||
"cobblestone": "Brostein",
|
"cobblestone": "Brostein",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metall",
|
"metal": "Metall",
|
||||||
"wood": "Treverk",
|
"wood": "Treverk",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Jord",
|
"dirt": "Jord",
|
||||||
"ground": "Bakke",
|
"ground": "Bakke",
|
||||||
"earth": "Jord",
|
"earth": "Jord",
|
||||||
"snow": "Snø",
|
|
||||||
"ice": "Is",
|
|
||||||
"salt": "Salt",
|
|
||||||
"mud": "Gjørme",
|
"mud": "Gjørme",
|
||||||
"sand": "Sand",
|
"sand": "Sand",
|
||||||
"woodchips": "Treflis",
|
|
||||||
"grass": "Gress",
|
"grass": "Gress",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Slå sammen valgte",
|
"merge_selection": "Slå sammen valgte",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Slå sammen elementer",
|
"tooltip": "Slå sammen elementer",
|
||||||
"help_merge_traces": "Ved å koble sammen de valgte sporene vil det opprettes ett enkelt kontinuerlig spor.",
|
"help_merge_traces": "Ved å koble sammen de valgte sporene vil det opprettes ett enkelt kontinuerlig spor.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Avstand",
|
"distance": "Avstand",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Skråning",
|
"slope": "Skråning",
|
||||||
"surface": "Overflate",
|
"surface": "Overflate",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Totalt"
|
"total": "Totalt",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Nieutwardzona",
|
"unpaved": "Nieutwardzona",
|
||||||
"asphalt": "Asfalt",
|
"asphalt": "Asfalt",
|
||||||
"concrete": "Beton",
|
"concrete": "Beton",
|
||||||
"chipseal": "Nawierzchnia utrwalana powierzchniowo",
|
|
||||||
"cobblestone": "Bruk",
|
"cobblestone": "Bruk",
|
||||||
"unhewn_cobblestone": "Bruk",
|
|
||||||
"paving_stones": "Płyta",
|
"paving_stones": "Płyta",
|
||||||
"stepping_stones": "Bruk",
|
|
||||||
"sett": "Bruk",
|
"sett": "Bruk",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Drewno",
|
"wood": "Drewno",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Ziemia",
|
"dirt": "Ziemia",
|
||||||
"ground": "Teren",
|
"ground": "Teren",
|
||||||
"earth": "Ziemia",
|
"earth": "Ziemia",
|
||||||
"snow": "Śnieg",
|
|
||||||
"ice": "Lód",
|
|
||||||
"salt": "Sól",
|
|
||||||
"mud": "Błoto",
|
"mud": "Błoto",
|
||||||
"sand": "Piasek",
|
"sand": "Piasek",
|
||||||
"woodchips": "Zrębki",
|
|
||||||
"grass": "Trawa",
|
"grass": "Trawa",
|
||||||
"grass_paver": "Płyta ażurowa"
|
"grass_paver": "Płyta ażurowa",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Połącz ślady",
|
"merge_traces": "Połącz ślady",
|
||||||
"merge_contents": "Scal zawartość, ale utrzymaj rozłączone ślady",
|
"merge_contents": "Scal zawartość, ale utrzymaj rozłączone ślady",
|
||||||
"merge_selection": "Scal zaznaczenie",
|
"merge_selection": "Scal zaznaczenie",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Scal elementy razem",
|
"tooltip": "Scal elementy razem",
|
||||||
"help_merge_traces": "Połączenie zaznaczonych śladów stworzy pojedynczy ciągły ślad.",
|
"help_merge_traces": "Połączenie zaznaczonych śladów stworzy pojedynczy ciągły ślad.",
|
||||||
"help_cannot_merge_traces": "Wybór musi zawierać kilka śladów, aby je połączyć.",
|
"help_cannot_merge_traces": "Wybór musi zawierać kilka śladów, aby je połączyć.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Pokaż dane nachylenia",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Pokaż dane nawierzchni",
|
|
||||||
"show_speed": "Pokaż dane prędkości",
|
|
||||||
"show_pace": "Pokaż dane tempa",
|
|
||||||
"show_heartrate": "Pokaż dane tętna",
|
|
||||||
"show_cadence": "Pokaż dane rytmu",
|
|
||||||
"show_temperature": "Pokaż dane temperatury",
|
|
||||||
"show_power": "Pokaż dane mocy"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Dystans",
|
"distance": "Dystans",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Moc",
|
"power": "Moc",
|
||||||
"slope": "Nachylenie",
|
"slope": "Nachylenie",
|
||||||
"surface": "Powierzchnia",
|
"surface": "Powierzchnia",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Czas",
|
"time": "Czas",
|
||||||
"moving": "W ruchu",
|
"moving": "W ruchu",
|
||||||
"total": "Łącznie"
|
"total": "Łącznie",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Não pavimentado",
|
"unpaved": "Não pavimentado",
|
||||||
"asphalt": "Asfalto",
|
"asphalt": "Asfalto",
|
||||||
"concrete": "Cimento",
|
"concrete": "Cimento",
|
||||||
"chipseal": "Pedriscos",
|
|
||||||
"cobblestone": "Empedrado",
|
"cobblestone": "Empedrado",
|
||||||
"unhewn_cobblestone": "Paralelepípedo bruto",
|
|
||||||
"paving_stones": "Paralelepípedo",
|
"paving_stones": "Paralelepípedo",
|
||||||
"stepping_stones": "Caminho de pedras",
|
|
||||||
"sett": "Pedra portuguesa",
|
"sett": "Pedra portuguesa",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Madeira",
|
"wood": "Madeira",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Terra",
|
"dirt": "Terra",
|
||||||
"ground": "Chão",
|
"ground": "Chão",
|
||||||
"earth": "Terra",
|
"earth": "Terra",
|
||||||
"snow": "Neve",
|
|
||||||
"ice": "Gelo",
|
|
||||||
"salt": "Sal",
|
|
||||||
"mud": "Lama",
|
"mud": "Lama",
|
||||||
"sand": "Areia",
|
"sand": "Areia",
|
||||||
"woodchips": "Cavacos de madeira",
|
|
||||||
"grass": "Grama",
|
"grass": "Grama",
|
||||||
"grass_paver": "Pavimentação com grama"
|
"grass_paver": "Pavimentação com grama",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Conecte as trilhas",
|
"merge_traces": "Conecte as trilhas",
|
||||||
"merge_contents": "Mesclar o conteúdo e manter as trilhas desconectadas",
|
"merge_contents": "Mesclar o conteúdo e manter as trilhas desconectadas",
|
||||||
"merge_selection": "Unir seleção",
|
"merge_selection": "Unir seleção",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Unir itens",
|
"tooltip": "Unir itens",
|
||||||
"help_merge_traces": "Conectar as trilhas selecionadas criará uma trilha única contínua.",
|
"help_merge_traces": "Conectar as trilhas selecionadas criará uma trilha única contínua.",
|
||||||
"help_cannot_merge_traces": "Sua seleção deve conter várias trilhas para conectá-las.",
|
"help_cannot_merge_traces": "Sua seleção deve conter várias trilhas para conectá-las.",
|
||||||
@@ -271,8 +313,9 @@
|
|||||||
"ignFrPlan": "IGN Plan",
|
"ignFrPlan": "IGN Plan",
|
||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "Satélite IGN",
|
"ignFrSatellite": "IGN Satélite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satélite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -291,7 +334,7 @@
|
|||||||
"swisstopoMountainBikeClosures": "swisstopo MTB Closures",
|
"swisstopoMountainBikeClosures": "swisstopo MTB Closures",
|
||||||
"swisstopoSkiTouring": "swisstopo Ski Touring",
|
"swisstopoSkiTouring": "swisstopo Ski Touring",
|
||||||
"ignFrCadastre": "IGN Cadastre",
|
"ignFrCadastre": "IGN Cadastre",
|
||||||
"ignSlope": "Inclinação IGN",
|
"ignSlope": "IGN Inclinação",
|
||||||
"ignSkiTouring": "IGN Ski Touring",
|
"ignSkiTouring": "IGN Ski Touring",
|
||||||
"waymarked_trails": "Trilhas demarcadas",
|
"waymarked_trails": "Trilhas demarcadas",
|
||||||
"waymarkedTrailsHiking": "Caminhada",
|
"waymarkedTrailsHiking": "Caminhada",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Mostrar dados de inclinação",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Mostrar dados do terreno",
|
|
||||||
"show_speed": "Mostrar dados de velocidade",
|
|
||||||
"show_pace": "Mostrar dados de ritmo",
|
|
||||||
"show_heartrate": "Mostrar dados de frequência cardíaca",
|
|
||||||
"show_cadence": "Mostrar dados de cadência",
|
|
||||||
"show_temperature": "Mostrar dados de temperatura",
|
|
||||||
"show_power": "Mostrar dados de potência"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distância",
|
"distance": "Distância",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Potência",
|
"power": "Potência",
|
||||||
"slope": "Inclinação",
|
"slope": "Inclinação",
|
||||||
"surface": "Superfície",
|
"surface": "Superfície",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Tempo",
|
"time": "Tempo",
|
||||||
"moving": "Movimento",
|
"moving": "Movimento",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Não pavimentado",
|
"unpaved": "Não pavimentado",
|
||||||
"asphalt": "Asfalto",
|
"asphalt": "Asfalto",
|
||||||
"concrete": "Cimento",
|
"concrete": "Cimento",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Empedrado",
|
"cobblestone": "Empedrado",
|
||||||
"unhewn_cobblestone": "Unhewn cobblestone",
|
|
||||||
"paving_stones": "Paving stones",
|
"paving_stones": "Paving stones",
|
||||||
"stepping_stones": "Stepping stones",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Madeira",
|
"wood": "Madeira",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Terra",
|
"dirt": "Terra",
|
||||||
"ground": "Chão",
|
"ground": "Chão",
|
||||||
"earth": "Terra",
|
"earth": "Terra",
|
||||||
"snow": "Neve",
|
|
||||||
"ice": "Gelo",
|
|
||||||
"salt": "Sal",
|
|
||||||
"mud": "Lama",
|
"mud": "Lama",
|
||||||
"sand": "Areia",
|
"sand": "Areia",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Grama",
|
"grass": "Grama",
|
||||||
"grass_paver": "Grass paver"
|
"grass_paver": "Grass paver",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distância",
|
"distance": "Distância",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Potência",
|
"power": "Potência",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Superfície",
|
"surface": "Superfície",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Tempo",
|
"time": "Tempo",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
@@ -119,11 +119,8 @@
|
|||||||
"unpaved": "Unpaved",
|
"unpaved": "Unpaved",
|
||||||
"asphalt": "Asphalt",
|
"asphalt": "Asphalt",
|
||||||
"concrete": "Concrete",
|
"concrete": "Concrete",
|
||||||
"chipseal": "Chipseal",
|
|
||||||
"cobblestone": "Pavaj",
|
"cobblestone": "Pavaj",
|
||||||
"unhewn_cobblestone": "Pavaj neșlefuit",
|
|
||||||
"paving_stones": "Pavaj din pietre",
|
"paving_stones": "Pavaj din pietre",
|
||||||
"stepping_stones": "Pietre de pașit",
|
|
||||||
"sett": "Sett",
|
"sett": "Sett",
|
||||||
"metal": "Metal",
|
"metal": "Metal",
|
||||||
"wood": "Lemn",
|
"wood": "Lemn",
|
||||||
@@ -135,15 +132,59 @@
|
|||||||
"dirt": "Noroi",
|
"dirt": "Noroi",
|
||||||
"ground": "Sol",
|
"ground": "Sol",
|
||||||
"earth": "Pământ",
|
"earth": "Pământ",
|
||||||
"snow": "Zăpadă",
|
|
||||||
"ice": "Gheață",
|
|
||||||
"salt": "Sare",
|
|
||||||
"mud": "Noroi",
|
"mud": "Noroi",
|
||||||
"sand": "Nisip",
|
"sand": "Nisip",
|
||||||
"woodchips": "Woodchips",
|
|
||||||
"grass": "Iarbă",
|
"grass": "Iarbă",
|
||||||
"grass_paver": "Pavaj cu iarbă"
|
"grass_paver": "Pavaj cu iarbă",
|
||||||
|
"clay": "Clay",
|
||||||
|
"stone": "Stone"
|
||||||
},
|
},
|
||||||
|
"highway": {
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"motorway": "Highway",
|
||||||
|
"motorway_link": "Highway link",
|
||||||
|
"trunk": "Primary road",
|
||||||
|
"trunk_link": "Primary road link",
|
||||||
|
"primary": "Primary road",
|
||||||
|
"primary_link": "Primary road link",
|
||||||
|
"secondary": "Secondary road",
|
||||||
|
"secondary_link": "Secondary road link",
|
||||||
|
"tertiary": "Tertiary road",
|
||||||
|
"tertiary_link": "Tertiary road link",
|
||||||
|
"unclassified": "Minor road",
|
||||||
|
"residential": "Residential road",
|
||||||
|
"living_street": "Living street",
|
||||||
|
"service": "Service road",
|
||||||
|
"track": "Track",
|
||||||
|
"footway": "Footway",
|
||||||
|
"path": "Path",
|
||||||
|
"pedestrian": "Pedestrian",
|
||||||
|
"cycleway": "Cycleway",
|
||||||
|
"steps": "Steps",
|
||||||
|
"road": "Road",
|
||||||
|
"bridleway": "Horseriding path",
|
||||||
|
"platform": "Platform",
|
||||||
|
"raceway": "Racing circuit",
|
||||||
|
"rest_area": "Rest area",
|
||||||
|
"abandoned": "Abandoned",
|
||||||
|
"services": "Services",
|
||||||
|
"corridor": "Corridor",
|
||||||
|
"bus_stop": "Bus stop",
|
||||||
|
"busway": "Busway",
|
||||||
|
"elevator": "Elevator",
|
||||||
|
"via_ferrata": "Via ferrata",
|
||||||
|
"proposed": "Road to be built",
|
||||||
|
"construction": "Road under construction"
|
||||||
|
},
|
||||||
|
"sac_scale": {
|
||||||
|
"hiking": "Hiking",
|
||||||
|
"mountain_hiking": "Mountain hiking",
|
||||||
|
"demanding_mountain_hiking": "Demanding mountain hiking",
|
||||||
|
"alpine_hiking": "Alpine hiking",
|
||||||
|
"demanding_alpine_hiking": "Demanding alpine hiking",
|
||||||
|
"difficult_alpine_hiking": "Difficult alpine hiking"
|
||||||
|
},
|
||||||
|
"mtb_scale": "MTB scale",
|
||||||
"error": {
|
"error": {
|
||||||
"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",
|
||||||
@@ -173,6 +214,7 @@
|
|||||||
"merge_traces": "Connect the traces",
|
"merge_traces": "Connect the traces",
|
||||||
"merge_contents": "Merge the contents and keep the traces disconnected",
|
"merge_contents": "Merge the contents and keep the traces disconnected",
|
||||||
"merge_selection": "Merge selection",
|
"merge_selection": "Merge selection",
|
||||||
|
"remove_gaps": "Remove time gaps between traces",
|
||||||
"tooltip": "Merge items together",
|
"tooltip": "Merge items together",
|
||||||
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
"help_merge_traces": "Connecting the selected traces will create a single continuous trace.",
|
||||||
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
"help_cannot_merge_traces": "Your selection must contain several traces to connect them.",
|
||||||
@@ -272,7 +314,8 @@
|
|||||||
"ignFrTopo": "IGN Topo",
|
"ignFrTopo": "IGN Topo",
|
||||||
"ignFrScan25": "IGN SCAN25",
|
"ignFrScan25": "IGN SCAN25",
|
||||||
"ignFrSatellite": "IGN Satellite",
|
"ignFrSatellite": "IGN Satellite",
|
||||||
"ignEs": "IGN",
|
"ignEs": "IGN Topo",
|
||||||
|
"ignEsSatellite": "IGN Satellite",
|
||||||
"ordnanceSurvey": "Ordnance Survey",
|
"ordnanceSurvey": "Ordnance Survey",
|
||||||
"norwayTopo": "Topografisk Norgeskart 4",
|
"norwayTopo": "Topografisk Norgeskart 4",
|
||||||
"swedenTopo": "Lantmäteriet Topo",
|
"swedenTopo": "Lantmäteriet Topo",
|
||||||
@@ -345,14 +388,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"show_slope": "Show slope data",
|
"settings": "Elevation profile settings"
|
||||||
"show_surface": "Show surface data",
|
|
||||||
"show_speed": "Show speed data",
|
|
||||||
"show_pace": "Show pace data",
|
|
||||||
"show_heartrate": "Show heart rate data",
|
|
||||||
"show_cadence": "Show cadence data",
|
|
||||||
"show_temperature": "Show temperature data",
|
|
||||||
"show_power": "Show power data"
|
|
||||||
},
|
},
|
||||||
"quantities": {
|
"quantities": {
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
@@ -366,9 +402,11 @@
|
|||||||
"power": "Power",
|
"power": "Power",
|
||||||
"slope": "Slope",
|
"slope": "Slope",
|
||||||
"surface": "Surface",
|
"surface": "Surface",
|
||||||
|
"highway": "Category",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"moving": "Moving",
|
"moving": "Moving",
|
||||||
"total": "Total"
|
"total": "Total",
|
||||||
|
"osm_extensions": "OpenStreetMap data"
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
"meters": "m",
|
"meters": "m",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user