create new file

This commit is contained in:
vcoppe
2024-04-27 12:18:40 +02:00
parent 0eb9c7b57e
commit ccc26f79e7
7 changed files with 67 additions and 20 deletions

View File

@@ -164,12 +164,19 @@ export class GPXFile extends GPXTreeNode<Track>{
wpt: Waypoint[]; wpt: Waypoint[];
trk: Track[]; trk: Track[];
constructor(gpx: GPXFileType | GPXFile) { constructor(gpx?: GPXFileType | GPXFile) {
super(); super();
this.attributes = cloneJSON(gpx.attributes); if (gpx) {
this.metadata = cloneJSON(gpx.metadata); this.attributes = cloneJSON(gpx.attributes);
this.wpt = gpx.wpt ? gpx.wpt.map((waypoint) => new Waypoint(waypoint)) : []; this.metadata = cloneJSON(gpx.metadata);
this.trk = gpx.trk ? gpx.trk.map((track) => new Track(track)) : []; this.wpt = gpx.wpt ? gpx.wpt.map((waypoint) => new Waypoint(waypoint)) : [];
this.trk = gpx.trk ? gpx.trk.map((track) => new Track(track)) : [];
} else {
this.attributes = {};
this.metadata = {};
this.wpt = [];
this.trk = [new Track()];
}
} }
getChildren(): Track[] { getChildren(): Track[] {
@@ -208,16 +215,20 @@ export class Track extends GPXTreeNode<TrackSegment> {
trkseg: TrackSegment[]; trkseg: TrackSegment[];
extensions?: TrackExtensions; extensions?: TrackExtensions;
constructor(track: TrackType | Track) { constructor(track?: TrackType | Track) {
super(); super();
this.name = track.name; if (track) {
this.cmt = track.cmt; this.name = track.name;
this.desc = track.desc; this.cmt = track.cmt;
this.src = track.src; this.desc = track.desc;
this.link = cloneJSON(track.link); this.src = track.src;
this.type = track.type; this.link = cloneJSON(track.link);
this.trkseg = track.trkseg ? track.trkseg.map((seg) => new TrackSegment(seg)) : []; this.type = track.type;
this.extensions = cloneJSON(track.extensions); this.trkseg = track.trkseg ? track.trkseg.map((seg) => new TrackSegment(seg)) : [];
this.extensions = cloneJSON(track.extensions);
} else {
this.trkseg = [new TrackSegment()];
}
} }
getChildren(): TrackSegment[] { getChildren(): TrackSegment[] {
@@ -266,9 +277,14 @@ export class TrackSegment extends GPXTreeLeaf {
trkptStatistics: TrackPointStatistics; trkptStatistics: TrackPointStatistics;
statistics: GPXStatistics; statistics: GPXStatistics;
constructor(segment: TrackSegmentType | TrackSegment) { constructor(segment?: TrackSegmentType | TrackSegment) {
super(); super();
this.trkpt = segment.trkpt.map((point) => new TrackPoint(point)); if (segment) {
this.trkpt = segment.trkpt.map((point) => new TrackPoint(point));
} else {
this.trkpt = [];
}
this._computeStatistics(); this._computeStatistics();
} }

View File

@@ -6,7 +6,7 @@ export type GPXFileType = {
}; };
export type GPXFileAttributes = { export type GPXFileAttributes = {
creator: string; creator?: string;
[key: string]: string; [key: string]: string;
}; };

View File

@@ -14,7 +14,8 @@
removeSelectedFiles, removeSelectedFiles,
triggerFileInput, triggerFileInput,
selectFiles, selectFiles,
settings settings,
createFile
} from '$lib/stores'; } from '$lib/stores';
import { mode, resetMode, setMode } from 'mode-watcher'; import { mode, resetMode, setMode } from 'mode-watcher';
@@ -51,7 +52,7 @@
<Menubar.Menu> <Menubar.Menu>
<Menubar.Trigger>{$_('menu.file')}</Menubar.Trigger> <Menubar.Trigger>{$_('menu.file')}</Menubar.Trigger>
<Menubar.Content class="border-none"> <Menubar.Content class="border-none">
<Menubar.Item> <Menubar.Item on:click={createFile}>
<Plus size="16" class="mr-1" /> <Plus size="16" class="mr-1" />
{$_('menu.new')} {$_('menu.new')}
<Menubar.Shortcut>⌘N</Menubar.Shortcut> <Menubar.Shortcut>⌘N</Menubar.Shortcut>
@@ -183,7 +184,10 @@
<svelte:window <svelte:window
on:keydown={(e) => { on:keydown={(e) => {
e.stopImmediatePropagation(); e.stopImmediatePropagation();
if (e.key === 'o' && (e.metaKey || e.ctrlKey)) { if (e.key === 'n' && (e.metaKey || e.ctrlKey)) {
createFile();
e.preventDefault();
} else if (e.key === 'o' && (e.metaKey || e.ctrlKey)) {
triggerFileInput(); triggerFileInput();
e.preventDefault(); e.preventDefault();
} else if (e.key === 'd' && (e.metaKey || e.ctrlKey)) { } else if (e.key === 'd' && (e.metaKey || e.ctrlKey)) {

View File

@@ -339,6 +339,13 @@ export class RoutingControls {
this.createMarker(newAnchor); this.createMarker(newAnchor);
segment._data.anchors.push(newAnchor); segment._data.anchors.push(newAnchor);
if (!lastAnchor) {
applyToFileElement(this.file, segment, (segment) => {
segment.replace(0, 0, [newPoint]);
}, true);
return;
}
let success = await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchor.point.getCoordinates(), newAnchor.point.getCoordinates()]); let success = await this.routeBetweenAnchors([lastAnchor, newAnchor], [lastAnchor.point.getCoordinates(), newAnchor.point.getCoordinates()]);
if (!success) { // Route failed, remove the anchor if (!success) { // Route failed, remove the anchor

View File

@@ -25,6 +25,14 @@ export function computeAnchorPoints(segment: TrackSegment) {
} }
export function ramerDouglasPeucker(points: TrackPoint[], epsilon: number = 50, start: number = 0, end: number = points.length - 1): SimplifiedTrackPoint[] { export function ramerDouglasPeucker(points: TrackPoint[], epsilon: number = 50, start: number = 0, end: number = points.length - 1): SimplifiedTrackPoint[] {
if (points.length == 0) {
return [];
} else if (points.length == 1) {
return [{
point: points[0]
}];
}
let simplified = [{ let simplified = [{
point: points[start] point: points[start]
}]; }];

View File

@@ -2,6 +2,8 @@ import { writable, get, type Writable } from 'svelte/store';
import mapboxgl from 'mapbox-gl'; import mapboxgl from 'mapbox-gl';
import { GPXFile, buildGPX, parseGPX, type AnyGPXTreeElement } from 'gpx'; import { GPXFile, buildGPX, parseGPX, type AnyGPXTreeElement } from 'gpx';
import { tick } from 'svelte';
import { _ } from 'svelte-i18n';
export const map = writable<mapboxgl.Map | null>(null); export const map = writable<mapboxgl.Map | null>(null);
export const files = writable<Writable<GPXFile>[]>([]); export const files = writable<Writable<GPXFile>[]>([]);
@@ -72,6 +74,15 @@ export function addFile(file: GPXFile): Writable<GPXFile> {
return fileStore; return fileStore;
} }
export function createFile(): Writable<GPXFile> {
let file = new GPXFile();
file.metadata.name = get(_)("menu.new_filename");
let fileStore = addFile(file);
tick().then(() => get(selectFiles).select(file));
currentTool.set(Tool.ROUTING);
return fileStore;
}
export function triggerFileInput() { export function triggerFileInput() {
const input = document.createElement('input'); const input = document.createElement('input');
input.type = 'file'; input.type = 'file';

View File

@@ -2,6 +2,7 @@
"menu": { "menu": {
"file": "File", "file": "File",
"new": "New", "new": "New",
"new_filename": "new",
"load_desktop": "Load from desktop...", "load_desktop": "Load from desktop...",
"load_drive": "Load from Google Drive...", "load_drive": "Load from Google Drive...",
"duplicate": "Duplicate", "duplicate": "Duplicate",