OSRM Multi-Segment Path Building
Builds a complete route polyline from an ordered list of waypoints by chaining consecutive OSRM road-snapped segments. Used in the admin map editor when drawing a line's road geometry.
Where It Is Used
apps/web-admin/src/app/services/osrm-routing.service.ts
Called from the line-form component when an admin places waypoints on the Leaflet map. OSRM snaps each waypoint to the nearest drivable road and returns the road-following path between them.
Why Not One OSRM Call?
OSRM's /route endpoint can take multiple waypoints in one call, but the admin workflow places waypoints one at a time and needs to show the partial route as it is being drawn. Chaining pair-by-pair allows incremental display and lets the admin correct mistakes before committing.
Algorithm
Given waypoints [W0, W1, W2, ..., Wn]:
- Initialize
accumulated = []. - For each consecutive pair $(W_i, W_{i+1})$:
- Fetch OSRM segment:
GET /route/v1/driving/{lng1},{lat1};{lng2},{lat2}?geometries=polyline - Decode the returned polyline into coordinate array
segment[]. - If
accumulatedis empty, append the full segment. - Otherwise, skip
segment[0](duplicate of the last accumulated point) and append the rest. - Return
accumulatedas the final connected polyline.
async function buildMultiSegmentPath(
waypoints: [number, number][]
): Promise<[number, number][]> {
const accumulated: [number, number][] = [];
for (let i = 0; i < waypoints.length - 1; i++) {
const segment = await fetchOsrmSegment(waypoints[i], waypoints[i + 1]);
if (accumulated.length === 0) {
accumulated.push(...segment);
} else {
accumulated.push(...segment.slice(1)); // skip duplicate first point
}
}
return accumulated;
}
Complexity: O(n) network calls for n waypoints. Each call is sequential (next call needs the previous endpoint), so this cannot be parallelized.
OSRM Endpoint
https://router.project-osrm.org/route/v1/driving/{lng},{lat};{lng},{lat}?geometries=polyline
Called directly from the browser — no backend proxy. The response's routes[0].geometry is a Google-encoded polyline at 5-decimal precision.
Output
The resulting polyline is encoded with Google Encoded Polyline and saved to Line.polyline via PATCH /lines/:id/polyline.
Related
- Google Encoded Polyline — encodes the output for storage
- Snap to Polyline — used after building the path to snap checkpoint placement to the route