Skip to content

Along-Route Distance Accumulation

Calculates the true road distance between two points on a polyline by summing Haversine distances over consecutive segments, rather than computing a straight-line distance between the endpoints.


Where It Is Used

apps/passengers-app/src/app/pages/route-detail/route-detail.page.ts

Used to compute how far a bus still has to travel along its route before reaching the passenger's boarding stop, which feeds the ETA calculation.


Why Straight-Line Distance Is Not Enough

A bus on a curved urban route travels considerably more distance than the straight line between two points. On winding streets, the road distance can be 1.5–2× the geodesic distance. Summing polyline segments gives the actual road distance the bus must cover.

Bus ●─────┐
          │   ← actual road: ~450 m
          └───────────●  Boarding stop
  straight-line: 310 m

Algorithm

Given a decoded polyline pts[] and two indices fromIdx (bus position) and toIdx (boarding stop):

$$d_{\text{road}} = \sum_{i=\text{fromIdx}}^{\text{toIdx}-1} \text{Haversine}(pts[i],\, pts[i+1])$$

function alongRouteDistance(
  pts: [number, number][],
  fromIdx: number,
  toIdx: number
): number {
  let total = 0;
  const start = Math.min(fromIdx, toIdx);
  const end   = Math.max(fromIdx, toIdx);
  for (let i = start; i < end; i++) {
    total += haversineMeters(pts[i][0], pts[i][1], pts[i+1][0], pts[i+1][1]);
  }
  return total;
}

Complexity: O(n) where n = number of polyline segments between the two indices.


Finding the Nearest Polyline Index

Before calling alongRouteDistance, the nearest index to a lat/lng point is found with a brute-force Haversine scan:

function nearestPolylineIdx(lat: number, lng: number, pts: [number, number][]): number {
  let best = 0, bestDist = Infinity;
  for (let i = 0; i < pts.length; i++) {
    const d = haversineMeters(lat, lng, pts[i][0], pts[i][1]);
    if (d < bestDist) { bestDist = d; best = i; }
  }
  return best;
}