mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-02 16:52:31 +00:00
routing controls class
This commit is contained in:
100
website/src/lib/components/routing/RoutingControls.ts
Normal file
100
website/src/lib/components/routing/RoutingControls.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import type { Coordinates, GPXFile } from "gpx";
|
||||
import { get, type Writable } from "svelte/store";
|
||||
import { computeAnchorPoints } from "./Simplify";
|
||||
import mapboxgl from "mapbox-gl";
|
||||
import { route } from "./Routing";
|
||||
import { applyToFileStore } from "$lib/stores";
|
||||
|
||||
export class RoutingControls {
|
||||
map: mapboxgl.Map;
|
||||
file: Writable<GPXFile>;
|
||||
markers: mapboxgl.Marker[] = [];
|
||||
unsubscribe: () => void = () => { };
|
||||
|
||||
toggleMarkersForZoomLevelAndBoundsBinded: () => void = this.toggleMarkersForZoomLevelAndBounds.bind(this);
|
||||
extendFileBinded: (e: mapboxgl.MapMouseEvent) => void = this.extendFile.bind(this);
|
||||
|
||||
constructor(map: mapboxgl.Map, file: Writable<GPXFile>) {
|
||||
this.map = map;
|
||||
this.file = file;
|
||||
|
||||
computeAnchorPoints(get(file));
|
||||
this.createMarkers();
|
||||
this.add();
|
||||
}
|
||||
|
||||
add() {
|
||||
this.toggleMarkersForZoomLevelAndBounds();
|
||||
this.map.on('zoom', this.toggleMarkersForZoomLevelAndBoundsBinded);
|
||||
this.map.on('move', this.toggleMarkersForZoomLevelAndBoundsBinded);
|
||||
this.map.on('click', this.extendFileBinded);
|
||||
|
||||
this.unsubscribe = this.file.subscribe(this.updateControls.bind(this));
|
||||
}
|
||||
|
||||
updateControls() {
|
||||
// Update controls
|
||||
console.log('updateControls');
|
||||
}
|
||||
|
||||
remove() {
|
||||
for (let marker of this.markers) {
|
||||
marker.remove();
|
||||
}
|
||||
this.map.off('zoom', this.toggleMarkersForZoomLevelAndBoundsBinded);
|
||||
this.map.off('move', this.toggleMarkersForZoomLevelAndBoundsBinded);
|
||||
this.map.off('click', this.extendFileBinded);
|
||||
|
||||
this.unsubscribe();
|
||||
}
|
||||
|
||||
createMarkers() {
|
||||
for (let segment of get(this.file).getSegments()) {
|
||||
for (let anchor of segment._data.anchors) {
|
||||
let marker = getMarker(anchor.point.getCoordinates(), true);
|
||||
Object.defineProperty(marker, '_simplified', {
|
||||
value: anchor
|
||||
});
|
||||
this.markers.push(marker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toggleMarkersForZoomLevelAndBounds() {
|
||||
let zoom = this.map.getZoom();
|
||||
this.markers.forEach((marker) => {
|
||||
if (marker._simplified.zoom <= zoom && this.map.getBounds().contains(marker.getLngLat())) {
|
||||
marker.addTo(this.map);
|
||||
} else {
|
||||
marker.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async extendFile(e: mapboxgl.MapMouseEvent) {
|
||||
let segments = get(this.file).getSegments();
|
||||
if (segments.length === 0) {
|
||||
return;
|
||||
}
|
||||
let anchors = segments[segments.length - 1]._data.anchors;
|
||||
let lastAnchor = anchors[anchors.length - 1];
|
||||
|
||||
let newPoint = {
|
||||
lon: e.lngLat.lng,
|
||||
lat: e.lngLat.lat
|
||||
};
|
||||
|
||||
let response = await route([lastAnchor.point.getCoordinates(), newPoint]);
|
||||
|
||||
applyToFileStore(this.file, (f) => f.append(response), true);
|
||||
}
|
||||
}
|
||||
|
||||
export function getMarker(coordinates: Coordinates, draggable: boolean = false): mapboxgl.Marker {
|
||||
let element = document.createElement('div');
|
||||
element.className = `h-3 w-3 rounded-full bg-background border-2 border-black cursor-pointer`;
|
||||
return new mapboxgl.Marker({
|
||||
draggable,
|
||||
element
|
||||
}).setLngLat(coordinates);
|
||||
}
|
Reference in New Issue
Block a user