Show the calculated speed of the route on the map
This commit is contained in:
parent
8f0759fc63
commit
f0b4479664
@ -279,7 +279,7 @@ float calculate_speed(float starting_speed, float horizontal_distance, float hei
|
||||
if (final_speed < minimum_speed) {
|
||||
return -1;
|
||||
} else {
|
||||
return std::min(final_speed, maximum_speed);
|
||||
return std::fmin(final_speed, maximum_speed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,6 +759,8 @@ EMSCRIPTEN_BINDINGS(my_module) {
|
||||
.property("nodeId", &JSNodeInfo::nodeId)
|
||||
.property("positionX", &JSNodeInfo::positionX)
|
||||
.property("positionY", &JSNodeInfo::positionY)
|
||||
.property("positionZ", &JSNodeInfo::positionZ)
|
||||
.property("currentSpeed", &JSNodeInfo::currentSpeed)
|
||||
.property("distanceFromStart", &JSNodeInfo::distanceFromStart);
|
||||
|
||||
emscripten::class_<JSSearchResult>("SearchResult")
|
||||
|
||||
7
package-lock.json
generated
7
package-lock.json
generated
@ -11,6 +11,7 @@
|
||||
"@geoman-io/leaflet-geoman-free": "^2.18.3",
|
||||
"@types/geojson": "^7946.0.16",
|
||||
"@types/leaflet": "^1.9.19",
|
||||
"hue-map": "^1.0.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"proj4": "^2.19.4"
|
||||
},
|
||||
@ -1096,6 +1097,12 @@
|
||||
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/hue-map": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hue-map/-/hue-map-1.0.0.tgz",
|
||||
"integrity": "sha512-L7n6cfthm9ZTdYbqJF1yBflHvI4MaWRg+XMJ4Ifc35jWcOfQlCRBETZ4ntnHLPUyDOse7KeelcsbWxx14Aaa+w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
"@geoman-io/leaflet-geoman-free": "^2.18.3",
|
||||
"@types/geojson": "^7946.0.16",
|
||||
"@types/leaflet": "^1.9.19",
|
||||
"hue-map": "^1.0.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"proj4": "^2.19.4"
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user