Polyline decode routes: how to read Cargoffer route geometry
Polyline decode routes: how to read Cargoffer route geometry without breaking it
If you build anything on top of a routing API β a map, a toll calculation, a distance audit β you will eventually receive a route as an encoded polyline instead of a list of coordinates. It is compact, it is fast, and it breaks in five predictable ways. Decoded wrongly, a truck route snaps to the wrong road, misses toll gantries and reports a distance that is 3% off. This is how the encoding works, what precision each provider uses, and how to prove a decoded route is correct before you trust it.
What is an encoded polyline?
An encoded polyline is a compressed representation of a list of coordinates, published by Google in 1974 and still the default geometry format for most routing and map APIs. It stores each point as the difference from the previous point, encodes those differences as signed integers, and packs them into printable ASCII characters using base-64 offsets from the character ? (ASCII 63).
Three properties follow from that design, and all three matter when you decode:
- The list is cumulative β each point only makes sense added to the previous one;
- The values are signed β the encoder folds positive and negative deltas together with a zigzag transform;
- The scaling is not in the data β the same string decodes to different coordinates depending on the precision multiplier you assume.
That third property is the source of most integration bugs in fleet software.
Which precision does each provider use?
Precision is the multiplier applied before rounding: 1e5 keeps five decimal places, 1e6 keeps six. Decoding a 1e6 string as 1e5 puts every point about 11 km away from where it belongs, which usually lands the route in a field.
| Provider / format | Precision | Coordinate order | Typical error if mismatched |
|---|---|---|---|
| Google encoded polyline | 1e5 | latitude, longitude | ~1.1 m per unit step, ~11 km if read as 1e6 |
| Valhalla (truck routing) | 1e6 | latitude, longitude | ~0.11 m native; 11 km error if decoded at 1e5 |
| Mapbox encoded polyline | 1e5 | latitude, longitude | ~1.1 m native |
| HERE flexible polyline | 1e5 base, variable | header-declared | decode fails loudly if header ignored |
| GeoJSON from the same APIs | none (floats) | longitude, latitude | order inversion, not precision |
Note the last row. GeoJSON uses longitude first, encoded polylines use latitude first. Switching between the two formats without reordering produces a route that is mirrored across the diagonal β valid-looking coordinates, in entirely the wrong place.
How do you decode a polyline step by step?
The algorithm is short and worth understanding rather than copying, because every failure mode is visible in it.
- Read characters one at a time and keep a running cumulative latitude and longitude, both starting at zero.
- For each character, subtract 63 from its ASCII code to get a 6-bit value.
- Accumulate 5-bit chunks while the continuation bit is set, shifting each new chunk left by 5.
- Undo the zigzag: if the accumulated value is odd, take the bitwise complement; then halve it.
- Divide by the precision multiplier (100,000 or 1,000,000).
- Add the result to the running latitude, then repeat steps 2β5 for the longitude.
- Repeat until the string ends, appending each new pair.
Two details break naive implementations: the order is always latitude first, and the sign handling must use the complement form, not a simple multiply, or every negative delta becomes slightly wrong.
How do you verify a decoded route is correct?
Decode and check these five things before using the geometry for anything commercial:
- Endpoint match β the first point equals your origin and the last equals your destination within 30 m;
- Distance agreement β the haversine sum of the decoded points is within 0.5% of the route summary distance;
- Bounds sanity β the bounding box of the points sits inside the countries the route should cross;
- Vertex continuity β no consecutive pair is more than 5 km apart on a motorway route; a jump means a decode error, not a tunnel;
- Toll gantries β the points pass within a few hundred metres of the gantries your toll engine expects on that corridor.
The distance check alone catches nearly every precision mistake, because decoding at the wrong multiplier changes the route length massively while still producing plausible-looking numbers.
Why does polyline accuracy matter for tolls and fuel?
Because tolling is spatial. Distance-based charges and barrier gantries attach to specific sections of road, and a toll engine matches your geometry against those sections. A route decoded with the wrong precision, or simplified to 50 points for a 600 km leg, can miss a gantry entirely or place the truck on the parallel free road.
The same applies to fuel. Consumption depends on gradient and on speed profile, both derived from the geometry. A route that has been aggressively simplified loses the climb data, and a mountain crossing priced as flat terrain understates fuel by 8β15 litres on a loaded 40 t combination β β¬12 to β¬22 that never appears in the quote.
There is a legitimate trade-off: mobil maps use simplified geometries, calculations use full ones. Keep them separate, and never run a toll or cost calculation on a geometry prepared for display.
What breaks most often in practice?
- Decoding a Valhalla route at 1e5 because the last provider used 1e5;
- Swapping latitude and longitude when merging an encoded polyline into GeoJSON;
- Caching geometry without its precision, so a later consumer assumes the wrong multiplier;
- Treating an empty or single-point route as valid and reporting zero distance.
Each of these is silent. Nothing throws, nothing logs, and the map looks nearly right β which is why the verification checks belong in the pipeline, not in a person's head.
FAQ
What is the difference between a polyline and GeoJSON? A polyline is a compressed string of delta-encoded coordinates at a fixed precision; GeoJSON is a list of explicit coordinate pairs, longitude first, with no compression.
Which precision does the Cargoffer and TRANSCEND routing stack use? Valhalla-derived routes come at 1e6 precision while Google-compatible output uses 1e5, so the precision is always declared alongside the geometry rather than assumed.
How accurate is a decoded polyline? At 1e5 precision, about 1.1 m per point; at 1e6, about 0.11 m. The error that matters in practice comes from simplification, not from precision.
How do I test a decode implementation quickly? Encode a known pair of coordinates, decode it back, and assert the round trip returns the original values to five decimals. Then run the distance check on a real route. See how it works for the pipeline TRANSCEND uses.
Why this matters commercially
A route that is 3% wrong in distance is 3% wrong in fuel, and a route that misses a gantry is wrong by the full toll. TRANSCEND decodes full geometries, matches them against real toll sections and prices fuel on the resulting gradient and speed profile, so the cost per load survives contact with the invoice. Book a live demo or check pricing.