improve routing controls logic

This commit is contained in:
vcoppe
2024-04-27 09:33:49 +02:00
parent e83c330ac5
commit 4f79c64fa5

View File

@@ -9,6 +9,7 @@ export class RoutingControls {
map: mapboxgl.Map; map: mapboxgl.Map;
file: Writable<GPXFile>; file: Writable<GPXFile>;
markers: mapboxgl.Marker[] = []; markers: mapboxgl.Marker[] = [];
shownMarkers: mapboxgl.Marker[] = [];
popup: mapboxgl.Popup; popup: mapboxgl.Popup;
popupElement: HTMLElement; popupElement: HTMLElement;
temporaryAnchor: SimplifiedTrackPoint; temporaryAnchor: SimplifiedTrackPoint;
@@ -37,7 +38,7 @@ export class RoutingControls {
}; };
this.createMarker(this.temporaryAnchor); this.createMarker(this.temporaryAnchor);
let marker = this.markers.pop(); // Remove the temporary anchor from the markers list let marker = this.markers.pop(); // Remove the temporary anchor from the markers list
marker.getElement().classList.add('z-0'); // Show below the other markers marker.getElement().classList.remove('z-10'); // Show below the other markers
Object.defineProperty(marker, '_temporary', { Object.defineProperty(marker, '_temporary', {
value: true value: true
}); });
@@ -50,7 +51,6 @@ export class RoutingControls {
this.map.on('move', this.toggleMarkersForZoomLevelAndBoundsBinded); this.map.on('move', this.toggleMarkersForZoomLevelAndBoundsBinded);
this.map.on('click', this.appendAnchorBinded); this.map.on('click', this.appendAnchorBinded);
this.map.on('mousemove', get(this.file)._data.layerId, this.showTemporaryAnchorBinded); this.map.on('mousemove', get(this.file)._data.layerId, this.showTemporaryAnchorBinded);
this.map.on('mousemove', this.hideTemporaryAnchorBinded);
this.unsubscribe = this.file.subscribe(this.updateControls.bind(this)); this.unsubscribe = this.file.subscribe(this.updateControls.bind(this));
} }
@@ -145,6 +145,8 @@ export class RoutingControls {
} }
toggleMarkersForZoomLevelAndBounds() { // Show markers only if they are in the current zoom level and bounds toggleMarkersForZoomLevelAndBounds() { // Show markers only if they are in the current zoom level and bounds
this.shownMarkers.splice(0, this.shownMarkers.length);
let zoom = this.map.getZoom(); let zoom = this.map.getZoom();
this.markers.forEach((marker) => { this.markers.forEach((marker) => {
Object.defineProperty(marker, '_inZoom', { Object.defineProperty(marker, '_inZoom', {
@@ -153,6 +155,7 @@ export class RoutingControls {
}); });
if (marker._inZoom && this.map.getBounds().contains(marker.getLngLat())) { if (marker._inZoom && this.map.getBounds().contains(marker.getLngLat())) {
marker.addTo(this.map); marker.addTo(this.map);
this.shownMarkers.push(marker);
} else { } else {
marker.remove(); marker.remove();
} }
@@ -160,29 +163,61 @@ export class RoutingControls {
} }
showTemporaryAnchor(e: any) { showTemporaryAnchor(e: any) {
if (!this.temporaryAnchor.marker) {
return;
}
if (this.temporaryAnchorCloseToOtherAnchor(e)) {
return;
}
this.temporaryAnchor.point.setCoordinates({ this.temporaryAnchor.point.setCoordinates({
lat: e.lngLat.lat, lat: e.lngLat.lat,
lon: e.lngLat.lng lon: e.lngLat.lng
}); });
this.temporaryAnchor.marker.setLngLat(this.temporaryAnchor.point.getCoordinates()).addTo(this.map); this.temporaryAnchor.marker.setLngLat(this.temporaryAnchor.point.getCoordinates()).addTo(this.map);
this.map.on('mousemove', this.hideTemporaryAnchorBinded);
} }
hideTemporaryAnchor(e: any) { hideTemporaryAnchor(e: any) {
if (this.temporaryAnchor.marker?.getElement().classList.contains('cursor-grabbing')) { if (!this.temporaryAnchor.marker) {
return; return;
} }
if (e.point.dist(this.map.project(this.temporaryAnchor.marker?.getLngLat())) < 20) { if (this.temporaryAnchor.marker.getElement().classList.contains('cursor-grabbing')) { // Do not hide if it is being dragged, and stop listening for mousemove
this.map.off('mousemove', this.hideTemporaryAnchorBinded);
return; return;
} }
if (e.point.dist(this.map.project(this.temporaryAnchor.point.getCoordinates())) > 20 || this.temporaryAnchorCloseToOtherAnchor(e)) { // Hide if too far from the layer
this.temporaryAnchor.marker.remove(); this.temporaryAnchor.marker.remove();
this.map.off('mousemove', this.hideTemporaryAnchorBinded);
return;
} }
this.temporaryAnchor.marker.setLngLat(e.lngLat); // Update the position of the temporary anchor
}
temporaryAnchorCloseToOtherAnchor(e: any) {
for (let marker of this.shownMarkers) {
if (marker === this.temporaryAnchor.marker) {
continue;
}
if (e.point.dist(this.map.project(marker.getLngLat())) < 10) {
return true;
}
}
return false;
}
async moveAnchor(e: any) { // Move the anchor and update the route from and to the neighbouring anchors async moveAnchor(e: any) { // Move the anchor and update the route from and to the neighbouring anchors
let marker = e.target; let marker = e.target;
let anchor = marker._simplified; let anchor = marker._simplified;
if (marker._temporary) { // Temporary anchor, need to find the closest point of the segment and create an anchor for it if (marker._temporary) { // Temporary anchor, need to find the closest point of the segment and create an anchor for it
marker.remove();
anchor = this.getPermanentAnchor(anchor); anchor = this.getPermanentAnchor(anchor);
marker = anchor.marker; marker = anchor.marker;
} }