Skip to content

Google Encoded Polyline

Encodes and decodes route geometries using Google's Encoded Polyline Algorithm Format at 5-decimal-place precision (~1.1 m accuracy). Used to store and transmit route shapes compactly as ASCII strings.


Where It Is Used

File Role
apps/web-admin/src/app/utils/polyline.ts Admin map: draw and persist line geometry
apps/passengers-app/src/app/core/utils/polyline.ts Passenger app: decode route shapes for display
apps/mobile-driver/src/app/core/utils/polyline.ts Driver app: decode route shape for trip tracking

Line.polyline in the database stores the encoded string. All clients decode it at runtime.


Encoding

Converts an array of [lat, lng] pairs into a compact ASCII string.

Steps for each coordinate delta:

  1. Multiply the floating-point delta by 1e5 and round to an integer.
  2. Left-shift by 1 bit: value <<= 1.
  3. If negative, invert all bits: value = ~value.
  4. Repeatedly extract the lowest 5 bits (value & 0x1F), set the continuation bit (0x20) if more chunks remain, add 63, and emit as an ASCII character.
  5. Right-shift by 5 and repeat until the value is zero.
function encodePolyline(coords: [number, number][]): string {
  let output = '';
  let prevLat = 0, prevLng = 0;

  for (const [lat, lng] of coords) {
    for (const value of [lat - prevLat, lng - prevLng]) {
      let v = Math.round(value * 1e5);
      v <<= 1;
      if (v < 0) v = ~v;
      while (v >= 0x20) {
        output += String.fromCharCode((0x20 | (v & 0x1F)) + 63);
        v >>= 5;
      }
      output += String.fromCharCode(v + 63);
    }
    prevLat = lat;
    prevLng = lng;
  }
  return output;
}

Decoding

Reverses the process: reads chunks of ASCII characters, reconstructs deltas, and accumulates coordinates.

function decodePolyline(encoded: string): [number, number][] {
  const coords: [number, number][] = [];
  let index = 0, lat = 0, lng = 0;

  while (index < encoded.length) {
    for (let i = 0; i < 2; i++) {
      let b, shift = 0, result = 0;
      do {
        b = encoded.charCodeAt(index++) - 63;
        result |= (b & 0x1F) << shift;
        shift += 5;
      } while (b >= 0x20);
      const delta = (result & 1) ? ~(result >> 1) : (result >> 1);
      if (i === 0) lat += delta;
      else lng += delta;
    }
    coords.push([lat / 1e5, lng / 1e5]);
  }
  return coords;
}

Precision

Format Precision factor Accuracy
Google Encoded Polyline (syncc routes) 1e5 ~1.1 m
Valhalla routing responses 1e6 ~0.11 m

Valhalla responses use 1e6 precision and require a separate decoder — see Valhalla Polyline Decoder.