logistics.route-distance@1.0.0
impl/typescript.ts
1,127 bytes · the TypeScript implementation · view raw
Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import { distance } from "./geo_distance.ts"; ← from geo.distance ^1.0.0 · built alongside by fune
import { type GeoPoint } from "./geo_point_in_polygon.ts"; ← from geo.point-in-polygon ^1.0.0 · built alongside by fune
import { type RouteDistance } from "./logistics_route_distance_types.ts";
/**
* Great-circle length of a route through the stops in order, leg by leg,
* optionally closing back to the first stop.
*/
export function routeDistance(stops: readonly GeoPoint[], returnToStart: boolean): RouteDistance {
if (stops.length === 0) throw new RangeError("stops must not be empty");
const legMetres: number[] = [];
// Each leg is a whole number of millimetres; adding them as integers and
// dividing once avoids floating-point drift (and is the same double everywhere).
let totalMillimetres = 0;
const addLeg = (a: GeoPoint, b: GeoPoint): void => {
const metres = distance(a.lat, a.lng, b.lat, b.lng);
legMetres.push(metres);
totalMillimetres += Math.floor(metres * 1000 + 0.5);
};
for (let i = 1; i < stops.length; i++) addLeg(stops[i - 1], stops[i]);
if (returnToStart && stops.length > 1) addLeg(stops[stops.length - 1], stops[0]);
return { totalMetres: totalMillimetres / 1000, legMetres };
}