Use a web worker to calculate, to avoid locking up the browser. Also, use semicolons between points, and fix bug where it is impossible to calculate route when receiving points in the URL
This commit is contained in:
+29
-24
@@ -1,5 +1,4 @@
|
||||
import MapHandler from './map/maphandler';
|
||||
import Module, { type MainModule } from '../native/salesman.js';
|
||||
import haversine from 'haversine-distance';
|
||||
import './style.css';
|
||||
import { LatLng } from 'leaflet';
|
||||
@@ -8,12 +7,11 @@ import { createUrl, parseUrl } from './url/UrlHandler.js';
|
||||
import { wktToGeoJSON } from '@terraformer/wkt';
|
||||
import PPENHandler from './files/ppenhandler.js';
|
||||
import type { GeoJsonObject } from 'geojson';
|
||||
import type { SearchStatusMessage, StartSearchMessage } from './worker/messages.js';
|
||||
|
||||
// Outside influences
|
||||
let mapHandler = new MapHandler();
|
||||
let module: MainModule = await Module();
|
||||
|
||||
|
||||
let worker = new Worker(new URL('./worker/worker.ts', import.meta.url), {type: 'module'});
|
||||
|
||||
// HTTP elements to be edited
|
||||
let clearMapButton = document.getElementById('clear-map');
|
||||
@@ -57,7 +55,7 @@ mapHandler.addMarkerClickedListener((latLng) => {
|
||||
awaiting(latLng);
|
||||
});
|
||||
awaitingResolutions = [];
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -65,6 +63,7 @@ mapHandler.addMarkerClickedListener((latLng) => {
|
||||
interface State {
|
||||
points: LatLng[] | null,
|
||||
distances: [LatLng, LatLng, number][],
|
||||
calculating: boolean,
|
||||
foundPath: number[] | null,
|
||||
complexPath: GeoJsonObject | null,
|
||||
|
||||
@@ -81,7 +80,8 @@ interface State {
|
||||
let state: State = {
|
||||
points: null,
|
||||
distances: [],
|
||||
foundPath: [],
|
||||
calculating: false,
|
||||
foundPath: null,
|
||||
complexPath: null,
|
||||
|
||||
ppenHandler: null,
|
||||
@@ -122,7 +122,8 @@ function updateState() {
|
||||
// Always just allow the share link button, do nothing here
|
||||
|
||||
// Only allow the calculate route button when we have more than three points, and don't already have a route
|
||||
if (state.points == null || state.points.length < 3 || state.foundPath != null) {
|
||||
// Also, disallow the get route button when currently calculating
|
||||
if (state.points == null || state.points.length < 3 || state.foundPath != null || state.calculating) {
|
||||
allowCalculateRoute = false;
|
||||
}
|
||||
|
||||
@@ -283,16 +284,24 @@ function updateState() {
|
||||
}
|
||||
}
|
||||
|
||||
function calculateRoute(): number[] {
|
||||
// In case of messages from the web worker, do work
|
||||
worker.onmessage = e => {
|
||||
let message = e.data as SearchStatusMessage;
|
||||
state.foundPath = message.path;
|
||||
state.calculating = false;
|
||||
updateState();
|
||||
}
|
||||
|
||||
function calculateRoute(): void {
|
||||
if (!state.points) {
|
||||
return [];
|
||||
return;
|
||||
}
|
||||
|
||||
let points: LatLng[] = state.points;
|
||||
|
||||
let weights = new module.Weights();
|
||||
let weights: number[][] = [];
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
let weightsRow = new module.WeightsRow();
|
||||
let weightsRow: number[] = [];
|
||||
for (var j = 0; j < points.length; j++) {
|
||||
var distance: number;
|
||||
if (i == j) {
|
||||
@@ -312,20 +321,16 @@ function calculateRoute(): number[] {
|
||||
}
|
||||
}
|
||||
|
||||
weightsRow.push_back(distance);
|
||||
weightsRow.push(distance);
|
||||
}
|
||||
weights.push_back(weightsRow);
|
||||
weights.push(weightsRow);
|
||||
}
|
||||
|
||||
let path = module.findShortestPath(weights);
|
||||
var foundPath = [];
|
||||
for (var i = 0; i < path.size(); i++) {
|
||||
let pointIndex = path.get(i);
|
||||
if (typeof pointIndex != 'undefined') {
|
||||
foundPath.push(pointIndex);
|
||||
}
|
||||
}
|
||||
return foundPath;
|
||||
let startSearchMessage: StartSearchMessage = {
|
||||
weights: weights
|
||||
};
|
||||
|
||||
worker.postMessage(startSearchMessage);
|
||||
}
|
||||
|
||||
function populateDistancesTable() {
|
||||
@@ -788,9 +793,9 @@ shareLinkButton?.addEventListener('click', async _ => {
|
||||
|
||||
calculateRouteButton?.addEventListener('click', _ => {
|
||||
if (calculateRouteButton.classList.contains('clickable')) {
|
||||
let path = calculateRoute();
|
||||
state.foundPath = path;
|
||||
state.calculating = true;
|
||||
updateState();
|
||||
calculateRoute();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user