Show the calculated speed of the route on the map

This commit is contained in:
Martin Asprusten
2025-06-30 14:30:34 +02:00
parent 8f0759fc63
commit f0b4479664
7 changed files with 74 additions and 33 deletions
+7 -1
View File
@@ -69,8 +69,14 @@ export interface Coordinate {
longitude: number
}
export interface PathSegment {
start: Coordinate,
end: Coordinate,
speed: number
}
interface ReturnFullPath {
coordinates: Coordinate[]
pathSegments: PathSegment[]
}
export interface Ring {
+2 -1
View File
@@ -82,7 +82,8 @@ routeWorker.onmessage = e => {
} else if (message.foundPathsFromNode != null) {
mapHandler?.drawEndPoints(message.foundPathsFromNode.endpoints);
} else if (message.returnFullPath != null) {
mapHandler?.drawPath(message.returnFullPath.coordinates);
let settings = getSettings();
mapHandler?.drawPath(message.returnFullPath.pathSegments, settings.minimumSpeed, settings.maximumSpeed);
} else if (message.searchAreaResult != null) {
searchStatusParagraph?.setHTMLUnsafe('Searching. ' + message.searchAreaResult.remainingNodes + ' possible starting points remain.');
let currentTime = Date.now();
+26 -20
View File
@@ -1,13 +1,20 @@
import 'leaflet/dist/leaflet.css';
import L, { FeatureGroup, Marker, Polygon, Polyline, type LatLngTuple } from 'leaflet';
import L, { FeatureGroup, Marker, Polygon, type LatLngTuple } from 'leaflet';
import '@geoman-io/leaflet-geoman-free'
import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css'
import './maphandler.css'
import { greenIcon, redIcon, violetIcon } from './icons.ts'
import type { Endpoint, Coordinate, Polygon as InterfacePolygon } from '../../interfaces.ts'
import type { Endpoint, Polygon as InterfacePolygon, PathSegment } from '../../interfaces.ts'
import type { Position } from 'geojson';
import { createPalette } from 'hue-map';
const viridisPalette = createPalette({
map: 'inferno',
steps: 100
});
interface ClickedMapListener {
(latitude: number, longitude: number): void;
}
@@ -44,7 +51,7 @@ class MapHandler {
startMarker?: Marker;
endMarkers: FeatureGroup;
path?: Polyline;
path: FeatureGroup;
editingPolygons: boolean = false;
@@ -150,6 +157,7 @@ class MapHandler {
this.searchAreaFeatureGroup = new L.FeatureGroup().addTo(this.map);
this.exclusionAreaFeatureGroup = new L.FeatureGroup().addTo(this.map);
this.endMarkers = new L.FeatureGroup().addTo(this.map);
this.path = new L.FeatureGroup().addTo(this.map);
this.map.addEventListener('click', e => {
if (!this.editingPolygons) {
@@ -252,10 +260,7 @@ class MapHandler {
}
public drawStartNode(nodeId: number, latitude: number, longitude: number): void {
if (this.path != null) {
this.map.removeLayer(this.path);
this.path = undefined;
}
this.path.clearLayers();
if (this.startMarker != null) {
this.map.removeLayer(this.startMarker);
@@ -268,10 +273,7 @@ class MapHandler {
public drawEndPoints(endpoints: Endpoint[]): void {
this.endMarkers.clearLayers();
if (this.path != null) {
this.map.removeLayer(this.path);
this.path = undefined;
}
this.path.clearLayers();
var firstMarker = true;
endpoints.forEach(endpoint => {
var settings;
@@ -303,17 +305,21 @@ class MapHandler {
});
}
public drawPath(coordinates: Coordinate[]): void {
if (this.path != null) {
this.map.removeLayer(this.path);
}
public drawPath(pathSegments: PathSegment[], minimumSpeed: number, maximumSpeed: number): void {
this.path.clearLayers();
pathSegments.forEach(pathSegment => {
let startLeafletCoordinate: LatLngTuple = [pathSegment.start.latitude, pathSegment.start.longitude];
let endLeafletCoordinate: LatLngTuple = [pathSegment.end.latitude, pathSegment.end.longitude];
let leafletCoordinates = [startLeafletCoordinate, endLeafletCoordinate];
var leafletCoordinates = coordinates.map(coordinate => {
let latLngTuple: LatLngTuple = [coordinate.latitude, coordinate.longitude];
return latLngTuple;
let intensity = Math.round((pathSegment.speed - minimumSpeed) * 99.0 / (maximumSpeed - minimumSpeed));
intensity = Math.min(Math.max(intensity, 0), 99);
let color = viridisPalette.format('cssHex')[99-intensity];
let polyLine = L.polyline(leafletCoordinates, {color: color}).addTo(this.path);
let speedKmh = pathSegment.speed * 3.6;
polyLine.bindTooltip(Math.round(speedKmh) + '.' + (Math.round(speedKmh * 10.0) % 10) + ' km/h');
});
this.path = L.polyline(leafletCoordinates).addTo(this.map);
}
public enableEditing() {
+28 -10
View File
@@ -1,7 +1,7 @@
import Module, { type AreaSearchEntries, type MainModule, type MultiPolygon } from '../../../native/route_search.js';
import proj4 from 'proj4';
import type { Endpoint, Message, Polygon, SearchAreaResultEntry } from '../../interfaces';
import type { Endpoint, Message, PathSegment, Polygon, SearchAreaResultEntry } from '../../interfaces';
var dataLoaded = false;
var module: MainModule | undefined = undefined;
@@ -133,22 +133,40 @@ onmessage = async (e) => {
sendErrorMessage('Could not get path');
return;
}
var coordinates = [];
for (var i = 0; i < path.size(); i++) {
let pathSegments: PathSegment[] = []
for (var i = 1; i < path.size(); i++) {
let currentPoint = path.get(i);
if (!currentPoint) {
continue;
}
coordinates.push([currentPoint.positionX, currentPoint.positionY]);
let previousPoint = path.get(i-1);
if (!previousPoint) {
continue;
}
let previousUtm = [previousPoint.positionX, previousPoint.positionY];
let currentUtm = [currentPoint.positionX, currentPoint.positionY];
let previousLngLat = proj4('EPSG:32633', 'EPSG:4326', previousUtm);
let currentLngLat = proj4('EPSG:32633', 'EPSG:4326', currentUtm);
let speed = Math.max(previousPoint.currentSpeed, currentPoint.currentSpeed);
let segment: PathSegment = {
start: {
latitude: previousLngLat[1],
longitude: previousLngLat[0]
},
end: {
latitude: currentLngLat[1],
longitude: currentLngLat[0]
},
speed: speed
}
pathSegments.push(segment);
}
path.delete();
coordinates = coordinates.map(utmCoordinate => {
let lngLat = proj4('EPSG:32633', 'EPSG:4326', utmCoordinate);
return {latitude: lngLat[1], longitude: lngLat[0]};
});
let returnMessage: Message = {returnFullPath: {coordinates: coordinates}};
let returnMessage: Message = {returnFullPath: {pathSegments: pathSegments}};
postMessage(returnMessage);
}