Merge branch 'gpxstudio:main' into nautical-units
This commit is contained in:
commit
7b77cd20e4
5 changed files with 57 additions and 18 deletions
|
|
@ -784,7 +784,7 @@ export class TrackSegment extends GPXTreeLeaf {
|
||||||
let start = simplified[i].point._data.index;
|
let start = simplified[i].point._data.index;
|
||||||
let end = simplified[i + 1].point._data.index;
|
let end = simplified[i + 1].point._data.index;
|
||||||
let dist = statistics.local.distance.total[end] - statistics.local.distance.total[start];
|
let dist = statistics.local.distance.total[end] - statistics.local.distance.total[start];
|
||||||
let ele = simplified[i + 1].point.ele - simplified[i].point.ele;
|
let ele = (simplified[i + 1].point.ele ?? 0) - (simplified[i].point.ele ?? 0);
|
||||||
|
|
||||||
for (let j = start; j < end + (i + 1 === simplified.length - 1 ? 1 : 0); j++) {
|
for (let j = start; j < end + (i + 1 === simplified.length - 1 ? 1 : 0); j++) {
|
||||||
slope.push(0.1 * ele / dist);
|
slope.push(0.1 * ele / dist);
|
||||||
|
|
@ -1326,6 +1326,17 @@ export class GPXStatistics {
|
||||||
}
|
}
|
||||||
|
|
||||||
slice(start: number, end: number): GPXStatistics {
|
slice(start: number, end: number): GPXStatistics {
|
||||||
|
if (start < 0) {
|
||||||
|
start = 0;
|
||||||
|
} else if (start >= this.local.points.length) {
|
||||||
|
return new GPXStatistics();
|
||||||
|
}
|
||||||
|
if (end < start) {
|
||||||
|
return new GPXStatistics();
|
||||||
|
} else if (end >= this.local.points.length) {
|
||||||
|
end = this.local.points.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
let statistics = new GPXStatistics();
|
let statistics = new GPXStatistics();
|
||||||
|
|
||||||
statistics.local.points = this.local.points.slice(start, end + 1);
|
statistics.local.points = this.local.points.slice(start, end + 1);
|
||||||
|
|
@ -1360,7 +1371,13 @@ export class GPXStatistics {
|
||||||
}
|
}
|
||||||
|
|
||||||
const earthRadius = 6371008.8;
|
const earthRadius = 6371008.8;
|
||||||
export function distance(coord1: Coordinates, coord2: Coordinates): number {
|
export function distance(coord1: TrackPoint | Coordinates, coord2: TrackPoint | Coordinates): number {
|
||||||
|
if (coord1 instanceof TrackPoint) {
|
||||||
|
coord1 = coord1.getCoordinates();
|
||||||
|
}
|
||||||
|
if (coord2 instanceof TrackPoint) {
|
||||||
|
coord2 = coord2.getCoordinates();
|
||||||
|
}
|
||||||
const rad = Math.PI / 180;
|
const rad = Math.PI / 180;
|
||||||
const lat1 = coord1.lat * rad;
|
const lat1 = coord1.lat * rad;
|
||||||
const lat2 = coord2.lat * rad;
|
const lat2 = coord2.lat * rad;
|
||||||
|
|
@ -1412,9 +1429,15 @@ function withTimestamps(points: TrackPoint[], speed: number, lastPoint: TrackPoi
|
||||||
|
|
||||||
function withShiftedAndCompressedTimestamps(points: TrackPoint[], speed: number, ratio: number, lastPoint: TrackPoint): TrackPoint[] {
|
function withShiftedAndCompressedTimestamps(points: TrackPoint[], speed: number, ratio: number, lastPoint: TrackPoint): TrackPoint[] {
|
||||||
let start = getTimestamp(lastPoint, points[0], speed);
|
let start = getTimestamp(lastPoint, points[0], speed);
|
||||||
|
let last = points[0];
|
||||||
return points.map((point) => {
|
return points.map((point) => {
|
||||||
let pt = point.clone();
|
let pt = point.clone();
|
||||||
pt.time = new Date(start.getTime() + ratio * (point.time.getTime() - points[0].time.getTime()));
|
if (point.time === undefined) {
|
||||||
|
pt.time = getTimestamp(last, point, speed);
|
||||||
|
} else {
|
||||||
|
pt.time = new Date(start.getTime() + ratio * (point.time.getTime() - points[0].time.getTime()));
|
||||||
|
}
|
||||||
|
last = pt;
|
||||||
return pt;
|
return pt;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -500,12 +500,14 @@
|
||||||
dbUtils.undo();
|
dbUtils.undo();
|
||||||
}
|
}
|
||||||
} else if ((e.key === 'Backspace' || e.key === 'Delete') && (e.metaKey || e.ctrlKey)) {
|
} else if ((e.key === 'Backspace' || e.key === 'Delete') && (e.metaKey || e.ctrlKey)) {
|
||||||
if (e.shiftKey) {
|
if (!targetInput) {
|
||||||
dbUtils.deleteAllFiles();
|
if (e.shiftKey) {
|
||||||
} else {
|
dbUtils.deleteAllFiles();
|
||||||
dbUtils.deleteSelection();
|
} else {
|
||||||
|
dbUtils.deleteSelection();
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
|
||||||
} else if (e.key === 'a' && (e.metaKey || e.ctrlKey)) {
|
} else if (e.key === 'a' && (e.metaKey || e.ctrlKey)) {
|
||||||
if (!targetInput) {
|
if (!targetInput) {
|
||||||
selectAll();
|
selectAll();
|
||||||
|
|
|
||||||
|
|
@ -334,14 +334,14 @@ export class RoutingControls {
|
||||||
let file = get(this.file)?.file;
|
let file = get(this.file)?.file;
|
||||||
|
|
||||||
// Find the point closest to the temporary anchor
|
// Find the point closest to the temporary anchor
|
||||||
let minDistance = Number.MAX_VALUE;
|
let minDetails: any = { distance: Number.MAX_VALUE };
|
||||||
let minAnchor = this.temporaryAnchor as Anchor;
|
let minAnchor = this.temporaryAnchor as Anchor;
|
||||||
file?.forEachSegment((segment, trackIndex, segmentIndex) => {
|
file?.forEachSegment((segment, trackIndex, segmentIndex) => {
|
||||||
if (get(selection).hasAnyParent(new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex))) {
|
if (get(selection).hasAnyParent(new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex))) {
|
||||||
let details: any = {};
|
let details: any = {};
|
||||||
let closest = getClosestLinePoint(segment.trkpt, this.temporaryAnchor.point, details);
|
let closest = getClosestLinePoint(segment.trkpt, this.temporaryAnchor.point, details);
|
||||||
if (details.distance < minDistance) {
|
if (details.distance < minDetails.distance) {
|
||||||
minDistance = details.distance;
|
minDetails = details;
|
||||||
minAnchor = {
|
minAnchor = {
|
||||||
point: closest,
|
point: closest,
|
||||||
segment,
|
segment,
|
||||||
|
|
@ -352,6 +352,15 @@ export class RoutingControls {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (minAnchor.point._data.anchor) {
|
||||||
|
minAnchor.point = minAnchor.point.clone();
|
||||||
|
if (minDetails.before) {
|
||||||
|
minAnchor.point._data.index = minAnchor.point._data.index + 0.5;
|
||||||
|
} else {
|
||||||
|
minAnchor.point._data.index = minAnchor.point._data.index - 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return minAnchor;
|
return minAnchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@
|
||||||
$selection.hasAnyChildren(new ListRootItem(), true, ['waypoints']) &&
|
$selection.hasAnyChildren(new ListRootItem(), true, ['waypoints']) &&
|
||||||
$gpxStatistics.local.points.length > 0;
|
$gpxStatistics.local.points.length > 0;
|
||||||
|
|
||||||
let maxSliderValue = 100;
|
let maxSliderValue = 1;
|
||||||
let sliderValues = [0, 100];
|
let sliderValues = [0, 1];
|
||||||
|
|
||||||
function updateCanCrop() {
|
function updateCanCrop() {
|
||||||
canCrop = sliderValues[0] != 0 || sliderValues[1] != maxSliderValue;
|
canCrop = sliderValues[0] != 0 || sliderValues[1] != maxSliderValue;
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
if (validSelection && $gpxStatistics.local.points.length > 0) {
|
if (validSelection && $gpxStatistics.local.points.length > 0) {
|
||||||
maxSliderValue = $gpxStatistics.local.points.length - 1;
|
maxSliderValue = $gpxStatistics.local.points.length - 1;
|
||||||
} else {
|
} else {
|
||||||
maxSliderValue = 100;
|
maxSliderValue = 1;
|
||||||
}
|
}
|
||||||
await tick();
|
await tick();
|
||||||
sliderValues = [0, maxSliderValue];
|
sliderValues = [0, maxSliderValue];
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,10 @@ import type { TransitionConfig } from "svelte/transition";
|
||||||
import { get } from "svelte/store";
|
import { get } from "svelte/store";
|
||||||
import { map } from "./stores";
|
import { map } from "./stores";
|
||||||
import { base } from "$app/paths";
|
import { base } from "$app/paths";
|
||||||
import { browser } from "$app/environment";
|
|
||||||
import { languages } from "$lib/languages";
|
import { languages } from "$lib/languages";
|
||||||
import { locale } from "svelte-i18n";
|
import { locale, t } from "svelte-i18n";
|
||||||
import type mapboxgl from "mapbox-gl";
|
import type mapboxgl from "mapbox-gl";
|
||||||
import { type TrackPoint, type Coordinates, crossarcDistance } from "gpx";
|
import { type TrackPoint, type Coordinates, crossarcDistance, distance } from "gpx";
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
|
|
@ -75,8 +74,14 @@ export function getClosestLinePoint(points: TrackPoint[], point: TrackPoint | Co
|
||||||
for (let i = 0; i < points.length - 1; i++) {
|
for (let i = 0; i < points.length - 1; i++) {
|
||||||
let dist = crossarcDistance(points[i], points[i + 1], point);
|
let dist = crossarcDistance(points[i], points[i + 1], point);
|
||||||
if (dist < closestDist) {
|
if (dist < closestDist) {
|
||||||
closest = points[i];
|
|
||||||
closestDist = dist;
|
closestDist = dist;
|
||||||
|
if (distance(points[i], point) <= distance(points[i + 1], point)) {
|
||||||
|
closest = points[i];
|
||||||
|
details['before'] = true;
|
||||||
|
} else {
|
||||||
|
closest = points[i + 1];
|
||||||
|
details['before'] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
details['distance'] = closestDist;
|
details['distance'] = closestDist;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue