mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-01 08:12:32 +00:00
routing off with elevation
This commit is contained in:
@@ -26,32 +26,6 @@
|
|||||||
unit: $distanceUnits
|
unit: $distanceUnits
|
||||||
});
|
});
|
||||||
|
|
||||||
function toggleTerrain() {
|
|
||||||
if ($map) {
|
|
||||||
if ($map.getPitch() > 0) {
|
|
||||||
if (!$map.getSource('mapbox-dem')) {
|
|
||||||
$map.addSource('mapbox-dem', {
|
|
||||||
type: 'raster-dem',
|
|
||||||
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
|
||||||
tileSize: 512,
|
|
||||||
maxzoom: 14
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!$map.getTerrain()) {
|
|
||||||
$map.setTerrain({ source: 'mapbox-dem', exaggeration: 1 });
|
|
||||||
$map.setFog({
|
|
||||||
color: 'rgb(186, 210, 235)',
|
|
||||||
'high-color': 'rgb(36, 92, 223)',
|
|
||||||
'horizon-blend': 0.1,
|
|
||||||
'space-color': 'rgb(156, 240, 255)'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$map.setTerrain(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
let newMap = new mapboxgl.Map({
|
let newMap = new mapboxgl.Map({
|
||||||
container: 'map',
|
container: 'map',
|
||||||
@@ -98,10 +72,20 @@
|
|||||||
|
|
||||||
newMap.addControl(scaleControl);
|
newMap.addControl(scaleControl);
|
||||||
|
|
||||||
newMap.on('style.load', toggleTerrain);
|
|
||||||
newMap.on('pitch', toggleTerrain);
|
|
||||||
|
|
||||||
newMap.on('style.load', () => {
|
newMap.on('style.load', () => {
|
||||||
|
newMap.addSource('mapbox-dem', {
|
||||||
|
type: 'raster-dem',
|
||||||
|
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
||||||
|
tileSize: 512,
|
||||||
|
maxzoom: 14
|
||||||
|
});
|
||||||
|
newMap.setTerrain({ source: 'mapbox-dem' });
|
||||||
|
newMap.setFog({
|
||||||
|
color: 'rgb(186, 210, 235)',
|
||||||
|
'high-color': 'rgb(36, 92, 223)',
|
||||||
|
'horizon-blend': 0.1,
|
||||||
|
'space-color': 'rgb(156, 240, 255)'
|
||||||
|
});
|
||||||
// add dummy layer to place the overlay layers below
|
// add dummy layer to place the overlay layers below
|
||||||
newMap.addLayer({
|
newMap.addLayer({
|
||||||
id: 'overlays',
|
id: 'overlays',
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
import type { Coordinates } from "gpx";
|
import type { Coordinates } from "gpx";
|
||||||
import { TrackPoint } from "gpx";
|
import { TrackPoint, distance } from "gpx";
|
||||||
import { get, writable } from "svelte/store";
|
import { get, writable } from "svelte/store";
|
||||||
import { settings } from "$lib/db";
|
import { settings } from "$lib/db";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
|
import { map } from "$lib/stores";
|
||||||
|
|
||||||
const { routing, routingProfile, privateRoads } = settings;
|
const { routing, routingProfile, privateRoads } = settings;
|
||||||
|
|
||||||
@@ -38,14 +39,7 @@ export function route(points: Coordinates[]): Promise<TrackPoint[]> {
|
|||||||
if (get(routing)) {
|
if (get(routing)) {
|
||||||
return getRoute(points, brouterProfiles[get(routingProfile)], get(privateRoads));
|
return getRoute(points, brouterProfiles[get(routingProfile)], get(privateRoads));
|
||||||
} else {
|
} else {
|
||||||
return new Promise((resolve) => {
|
return getIntermediatePoints(points);
|
||||||
resolve(points.map(point => new TrackPoint({
|
|
||||||
attributes: {
|
|
||||||
lat: point.lat,
|
|
||||||
lon: point.lon
|
|
||||||
}
|
|
||||||
})));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,4 +95,37 @@ function getSurface(message: string): string {
|
|||||||
return fields[i].substring(8);
|
return fields[i].substring(8);
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> {
|
||||||
|
let route: TrackPoint[] = [];
|
||||||
|
let step = 0.05;
|
||||||
|
|
||||||
|
for (let i = 0; i < points.length - 1; i++) { // Add intermediate points between each pair of points
|
||||||
|
let dist = distance(points[i], points[i + 1]) / 1000;
|
||||||
|
for (let d = 0; d < dist; d += step) {
|
||||||
|
let lat = points[i].lat + d / dist * (points[i + 1].lat - points[i].lat);
|
||||||
|
let lon = points[i].lon + d / dist * (points[i + 1].lon - points[i].lon);
|
||||||
|
route.push(new TrackPoint({
|
||||||
|
attributes: {
|
||||||
|
lat: lat,
|
||||||
|
lon: lon
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
route.push(new TrackPoint({
|
||||||
|
attributes: {
|
||||||
|
lat: points[points.length - 1].lat,
|
||||||
|
lon: points[points.length - 1].lon
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
route.forEach((point) => {
|
||||||
|
point.setSurface("unknown");
|
||||||
|
point.ele = get(map)?.queryTerrainElevation(point.getCoordinates()) ?? undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve) => resolve(route));
|
||||||
|
}
|
@@ -110,9 +110,9 @@ function dexieStore<T>(querier: () => T | Promise<T>, initial?: T): Readable<T>
|
|||||||
export type GPXFileWithStatistics = { file: GPXFile, statistics: GPXStatistics };
|
export type GPXFileWithStatistics = { file: GPXFile, statistics: GPXStatistics };
|
||||||
|
|
||||||
// Wrap Dexie live queries in a Svelte store to avoid triggering the query for every subscriber, also takes care of the conversion to a GPXFile object
|
// Wrap Dexie live queries in a Svelte store to avoid triggering the query for every subscriber, also takes care of the conversion to a GPXFile object
|
||||||
function dexieGPXFileStore(querier: () => GPXFile | undefined | Promise<GPXFile | undefined>): Readable<GPXFileWithStatistics> {
|
function dexieGPXFileStore(querier: () => GPXFile | undefined | Promise<GPXFile | undefined>): Readable<GPXFileWithStatistics> & { destroy: () => void } {
|
||||||
let store = writable<GPXFileWithStatistics>(undefined);
|
let store = writable<GPXFileWithStatistics>(undefined);
|
||||||
liveQuery(querier).subscribe(value => {
|
let query = liveQuery(querier).subscribe(value => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
let gpx = new GPXFile(value);
|
let gpx = new GPXFile(value);
|
||||||
let statistics = gpx.getStatistics();
|
let statistics = gpx.getStatistics();
|
||||||
@@ -127,7 +127,8 @@ function dexieGPXFileStore(querier: () => GPXFile | undefined | Promise<GPXFile
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
subscribe: store.subscribe
|
subscribe: store.subscribe,
|
||||||
|
destroy: query.unsubscribe
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +165,7 @@ function commitFileStateChange(newFileState: ReadonlyMap<string, GPXFile>, patch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fileObservers: Writable<Map<string, Readable<GPXFileWithStatistics | undefined>>> = writable(new Map());
|
export const fileObservers: Writable<Map<string, Readable<GPXFileWithStatistics | undefined> & { destroy: () => void }>> = writable(new Map());
|
||||||
const fileState: Map<string, GPXFile> = new Map(); // Used to generate patches
|
const fileState: Map<string, GPXFile> = new Map(); // Used to generate patches
|
||||||
|
|
||||||
// Observe the file ids in the database, and maintain a map of file observers for the corresponding files
|
// Observe the file ids in the database, and maintain a map of file observers for the corresponding files
|
||||||
@@ -185,6 +186,7 @@ liveQuery(() => db.fileids.toArray()).subscribe(dbFileIds => {
|
|||||||
$files.set(id, dexieGPXFileStore(() => db.files.get(id)));
|
$files.set(id, dexieGPXFileStore(() => db.files.get(id)));
|
||||||
});
|
});
|
||||||
deletedFiles.forEach(id => {
|
deletedFiles.forEach(id => {
|
||||||
|
$files.get(id)?.destroy();
|
||||||
$files.delete(id);
|
$files.delete(id);
|
||||||
fileState.delete(id);
|
fileState.delete(id);
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user