Functional Weave
Code in Python

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 };
}