changemaker.lite/api/dist/modules/map/canvass/canvass-route.service.js

62 lines
2.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateWalkingRoute = calculateWalkingRoute;
const spatial_1 = require("../../../utils/spatial");
const WALKING_SPEED_MPS = 5000 / 60; // 5 km/h in meters per minute
const MINUTES_PER_DOOR = 2;
/**
* Nearest-neighbor walking route algorithm.
* Starts from volunteer GPS position or cut polygon centroid.
*/
function calculateWalkingRoute(locations, startLat, startLng, cutGeojson) {
if (locations.length === 0) {
return { orderedLocations: [], totalDistanceMeters: 0, estimatedMinutes: 0 };
}
// Determine starting point
let currentLat;
let currentLng;
if (startLat !== undefined && startLng !== undefined) {
currentLat = startLat;
currentLng = startLng;
}
else if (cutGeojson) {
const polygons = (0, spatial_1.parseGeoJsonPolygon)(cutGeojson);
const centroid = (0, spatial_1.calculateCentroid)(polygons[0]);
currentLat = centroid.lat;
currentLng = centroid.lng;
}
else {
// Use first location as starting point
currentLat = locations[0].latitude;
currentLng = locations[0].longitude;
}
const remaining = [...locations];
const ordered = [];
let totalDistance = 0;
while (remaining.length > 0) {
let nearestIdx = 0;
let nearestDist = Infinity;
for (let i = 0; i < remaining.length; i++) {
const loc = remaining[i];
const dist = (0, spatial_1.haversineDistance)(currentLat, currentLng, loc.latitude, loc.longitude);
if (dist < nearestDist) {
nearestDist = dist;
nearestIdx = i;
}
}
const nearest = remaining.splice(nearestIdx, 1)[0];
ordered.push(nearest);
totalDistance += nearestDist;
currentLat = nearest.latitude;
currentLng = nearest.longitude;
}
const walkingMinutes = totalDistance / WALKING_SPEED_MPS;
const doorMinutes = ordered.length * MINUTES_PER_DOOR;
const estimatedMinutes = Math.round(walkingMinutes + doorMinutes);
return {
orderedLocations: ordered,
totalDistanceMeters: Math.round(totalDistance),
estimatedMinutes,
};
}
//# sourceMappingURL=canvass-route.service.js.map