Free Polyline Decoder
Paste an encoded polyline from Google Maps, OSRM, Valhalla or Strava to see its points on a map, or turn coordinates into a polyline.
What is a Polyline Decoder?
An encoded polyline packs a route’s coordinates into a short string of printable characters, which is how Google’s Directions API, OSRM, Valhalla and Strava return route shapes. This tool turns that string back into points on a map, and points back into a string.
It reads Google’s precision-5 format and the precision-6 variant used by OSRM, Valhalla and Mapbox. Errors say exactly what went wrong, from a string cut off when copied to a polyline6 read at the wrong precision.
Key Features
Points on a Map
The decoded line is drawn on a map, with its length and every coordinate in a table.
Precision 5 and 6
Decode Google polylines and polyline6 from OSRM or Valhalla, with a hint when you’ve picked the wrong one.
GeoJSON Output
Get the line as a GeoJSON LineString, with longitude first, ready for a web map.
Encode Too
Turn latitude and longitude pairs, one per line or as a JSON array, into a precision-5 polyline.
Errors That Explain
Truncated strings, missing longitudes, stray spaces and bad characters each get their own message.
Perfect for everyone
- Developers using routing APIs
- Mobile engineers debugging map features
- Analysts working with route data from Strava or delivery apps
How to Use the Polyline Decoder
Paste a polyline to decode it, or coordinates to encode them. The mode you pick decides which way the conversion runs and which precision is used.
Copy the Polyline
Take overview_polyline.points from Google, geometry from OSRM, or summary_polyline from Strava.
Pick the Precision
Use Decode for Google and Strava, and Decode polyline6 for OSRM, Valhalla and Mapbox polyline6.
Check the Map
The line should follow the road. A line in the wrong country usually means the wrong precision.
Export or Encode
Choose To GeoJSON for a map layer, or paste coordinates and choose Encode to make a polyline.
Polylines, Decoded
Each row is a polyline or a list of coordinates, and each answer is this tool’s output in the mode on the chip. The first row is the example from Google’s own documentation.
“_p~iF~ps|U_ulLnnqC_mqNvxq`@”
“_p~iF~ps|U_ulLnnqC_mqNvxq`@”
“_izlhA~rlgdF_{geC~ywl@”
“_izlhA~rlgdF_{geC~ywl@”
“51.50330, -0.11953 51.50083, -0.12463 51.50136, -0.14189”
“_riyH~lV_\\?”
“[[48.85837, 2.29448], [48.86061, 2.33764]]”
“_p~iF~ps|U_”
“_p~iF~ps|U_ulL”
“_p~iF ~ps|U”
How a Coordinate Becomes Characters
Google’s format turns each number into characters in ten steps. Each card is one step, applied to every latitude and longitude in turn.
Take the Difference
Every point after the first is stored as the change from the previous point, which keeps numbers small.
“Is the first point stored as a difference?”
Scale and Round
Multiply by 100,000 (or 1,000,000 for polyline6) and round to a whole number.
“What does -120.2 become at precision 5?”
Shift Left One Bit
Shifting left frees the lowest bit to carry the sign.
“Which bit holds the sign afterwards?”
Invert Negatives
If the original value was negative, invert every bit. This is zigzag encoding.
“What does zigzag encoding turn -1 into?”
Split Into 5-Bit Chunks
Break the number into groups of five bits, starting from the right.
“How many bits per chunk?”
Reverse the Chunks
Chunks are written lowest first, so the decoder can rebuild the number as it reads.
“Which chunk is written first?”
Mark Continuation
OR each chunk except the last with 0x20, meaning another chunk follows.
“Which chunk has no 0x20 bit?”
Add 63
Adding 63 moves every chunk into printable ASCII, from ? to ~.
“Which character is a zero chunk?”
Concatenate
Latitude then longitude for each point, all in one string with no separators.
“Is there a separator between points?”
Escape When Embedding
Backslashes in the result must be doubled inside JSON or JavaScript strings.
“Why do some polylines show \\ in JSON?”
Where Encoded Polylines Come From
Most routing and fitness APIs return route shapes this way, because a polyline is far shorter than a list of numbers. Check which precision each one uses before you decode, since nothing in the string itself says.
Google Directions API
overview_polyline.points for the whole route, and polyline.points on every step, at precision 5.
Google Routes API
polyline.encodedPolyline on each route, at precision 5 unless you ask for GeoJSON instead.
OSRM
geometries=polyline gives precision 5 and geometries=polyline6 gives precision 6.
Valhalla
The shape of each leg is encoded at precision 6 by default.
Mapbox Directions
geometries=polyline or polyline6, matching OSRM’s two options.
Strava API
map.summary_polyline and map.polyline on activities and segments, at precision 5.
Decoding One Value by Hand
To see why a string decodes the way it does, work through a single value. This walks through `_p~iF`, the first latitude in Google’s example, which comes out as 38.5.
Subtract 63 From Each Character
The characters _ p ~ i F have codes 95, 112, 126, 105 and 70. Subtracting 63 gives 32, 49, 63, 42 and 7.
Find Where the Value Ends
A chunk of 32 or more has the continuation bit set, so another chunk follows. The first chunk below 32 is 7, the fifth, so the value is five characters long.
Drop the Continuation Bits
Keep the low five bits of each chunk by subtracting 32 from those that have it. That leaves 0, 17, 31, 10 and 7.
Rebuild the Number
The first chunk is the lowest, so the value is 0 + 17×32 + 31×32² + 10×32³ + 7×32⁴. That adds up to 7,700,000.
Undo the Zigzag
An even number is positive, so halve it to get 3,850,000. An odd number would be negative: add one, halve it, and flip the sign.
Divide by 100,000
At precision 5, 3,850,000 becomes 38.5, the latitude of the first point. Every later value is added to the previous point’s value before dividing.
Precision, Accuracy and Size
The precision decides how many decimal places survive and how long the string gets. These numbers help you choose between precision 5 and 6, and explain why polylines are so much smaller than raw coordinates.
Precision 5 Keeps About 1.1 Metres
Five decimal places of latitude are about 1.1 m on the ground, and longitude a little less away from the equator. That’s finer than the accuracy of most phone GPS fixes.
Precision 6 Keeps About 11 Centimetres
Six decimal places resolve about 11 cm, which suits survey-grade data and lane-level routing. Each value usually costs one more character than at precision 5.
Rounding Doesn’t Pile Up
Each point is rounded before the difference is taken, so the error never grows along the line. The last point is as accurate as the first.
Small Steps, Short Strings
Nearby points have small differences that fit in one or two characters. A dense route often averages four to six characters per point.
Far Smaller Than JSON
A point written as JSON numbers takes around twenty characters. The same point in a polyline usually takes a quarter of that, which matters in API responses and URLs.
The First Point Costs the Most
The first point is stored as its full value, so it takes eight to ten characters. Every later point is only a difference from the one before it.
Polyline Pitfalls
When a decoded line looks wrong, it’s almost always one of these. Each has a quick check, and the error messages above point at the first three directly.
Wrong Precision
A polyline6 read at precision 5 lands ten times too far from 0, 0. Points near the equator may still look valid, so check the map.
Escaped Backslashes
Copied straight from JSON, every backslash is doubled and decoding goes wrong. This tool undoes that automatically.
Truncated Strings
Logs and spreadsheets often cut long strings. A cut-off polyline ends mid-value or loses its last longitude.
Overview Versus Steps
Google’s overview_polyline is simplified. For the exact path, join the polylines of every step.
Latitude First, Unlike GeoJSON
Polylines store latitude then longitude, while GeoJSON stores longitude first. Mixing them up flips the map.
Rounding Is Lossy
Precision 5 rounds to about 1.1 m, so a decoded-then-encoded route may differ slightly from the original data.
Polyline Libraries by Language
The format is simple enough to write yourself, but well-tested libraries exist for most languages. All of these read precision 5 by default and take a parameter for precision 6.
JavaScript
@mapbox/polyline offers decode and encode with an optional precision, plus helpers for GeoJSON. It works in browsers and Node.js.
Python
The polyline package on PyPI decodes and encodes with a precision argument, and the googlemaps client includes its own decoder.
Java and Kotlin
Google’s Maps SDK utility library has PolyUtil.decode and PolyUtil.encode, which Android apps commonly use.
Swift
The Polyline package for iOS decodes into CLLocationCoordinate2D arrays, ready for MapKit overlays.
Go
twpayne/go-polyline encodes and decodes coordinate slices, with a codec type for choosing the precision.
PostGIS
ST_LineFromEncodedPolyline turns a polyline into a geometry and ST_AsEncodedPolyline does the reverse, each taking an optional precision.
Command Line
Python’s polyline package works in a one-line script, and the PostGIS functions above work through psql for quick checks.
When to Decode a Polyline
Whenever a route arrives as a string and you need to see where it goes, or you have points and need the short form an API or a URL expects.
Debugging a Routing Integration
Check that the route your app received follows the roads you expect.
Reading Strava Activities
Decode summary_polyline from the API to see an activity’s shape without the app.
Static Map URLs
Encode a set of points for the path parameter of a static map image.
Comparing Routing Engines
Decode routes from Google, OSRM and Valhalla to see how their paths differ.
Storing Routes Compactly
Encode a route before saving it, since a polyline is far smaller than a list of coordinates.