<br />

**European Economic Area (EEA) developers**

> [!NOTE]
> If your billing address is in the European Economic Area, effective on 8 July 2025, the [Google Maps Platform EEA Terms of Service](https://cloud.google.com/terms/maps-platform/eea) will apply to your use of the Services. Functionality varies by region. [Learn more](https://developers.google.com/maps/comms/eea/faq.md.txt).

> [!NOTE]
> **Note:** Polylines are not supported by the Compute Route Matrix feature of the Routes API.

The [computeRoutes](https://developers.google.com/maps/documentation/routes/reference/rest/v2/TopLevel/computeRoutes.md.txt) method (REST) and
the
[ComputeRoutes](https://developers.google.com/maps/documentation/routes/reference/rpc/google.maps.routing.v2.md.txt#google.maps.routing.v2.Routes.ComputeRoutes)
method (gRPC) both return the route represented by a polyline as part of the
response. These APIs return two types of polylines:

- **Basic polyline (default)** , represents a route but without traffic
  information embedded in the polyline. Requests that return a basic polyline
  are billed at the Routes Basic rate. [Learn more about
  billing](https://developers.google.com/maps/documentation/routes/usage-and-billing) for Routes API.

- **Traffic-aware polyline** , contain information about the traffic conditions
  along the route. Traffic conditions are expressed in terms of speed
  categories (`NORMAL`, `SLOW`, `TRAFFIC_JAM`) applicable on a given interval
  of the polyline. Requests for traffic-aware polylines are billed at the
  Routes Preferred rate. [Learn more about billing](https://developers.google.com/maps/documentation/routes/usage-and-billing.md.txt) for
  Routes API. For details, see [Configure polyline
  quality](https://developers.google.com/maps/documentation/routes/config_trade_offs#polyline-quality)

For more on polylines, see:

- [Conceptual information on Polylines](https://developers.google.com/maps/documentation/automotive/attributes/concepts/segments#segment_polyline)

- [Interactive Polyline Encoder Utility](https://developers.google.com/maps/documentation/utilities/polylineutility.md.txt)
  lets you create encoded polylines in a UI or decode polylines to display on
  a map. For example, use this utility to decode a polyline created by the
  code below.

  > [!NOTE]
  > **Note:** Special characters in the polylines returned by the REST API are JSON escaped. To display these polylines in the [Interactive Polyline Encoder
  > Utility](https://developers.google.com/maps/documentation/utilities/polylineutility) you must first unescape them. There are many utilities available to perform a JSON unescape. To find one, search for [JSON
  > unescape](https://www.google.com/search?q=json+unescape).

## Request a basic polyline for a route, leg, or step

A polyline is represented by a
[Polyline](https://developers.google.com/maps/documentation/routes/reference/rest/v2/TopLevel/computeRoutes.md.txt#polyline) (REST) or
[Polyline](https://developers.google.com/maps/documentation/routes/reference/rpc/google.maps.routing.v2.md.txt#polyline) (gRPC) object. You can
return a polyline in the response at the route, leg, and step level.

Specify which polyline to return by using the [response field
mask](https://developers.google.com/maps/documentation/routes/choose_fields):

- **At the route level** , return a polyline in the response by including
  `routes.polyline` in the response field mask.

- **At the leg level** , return a polyline in the response for each leg of the
  route by including `routes.legs.polyline`.

  > [!NOTE]
  > **Note:** Each leg corresponds to the trip between two waypoints when `via` is false for the waypoint to indicate a stop on the route. For example, a route with no intermediate waypoints has only one leg. A route that includes an intermediate waypoint with a stop has two legs. A route that includes one intermediate waypoint with `via` set to true has one leg.

- **At the step level** , return a polyline in the response for each step of
  the leg by including `routes.legs.steps.polyline`.

For example, to return a polyline for the entire route, for each leg, and for
each step of each leg:

```console
curl -X POST -d '{
  "origin":{
    "address": "1600 Amphitheatre Parkway, Mountain View, CA"
  },
  "destination":{
    "address": "24 Willie Mays Plaza, San Francisco, CA 94107"
  },
  "travelMode": "DRIVE"
}' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: YOUR_API_KEY' \
-H 'X-Goog-FieldMask: routes.duration,routes.distanceMeters,routes.polyline,routes.legs.polyline,routes.legs.steps.polyline' \
'https://routes.googleapis.com/directions/v2:computeRoutes'
```

This request returns the following response which includes the polyline for the
route, for each leg of the route, and for each step of the leg:

```json
{
  "routes": [
    {
      "legs": [
        {
          "polyline": {
              "encodedPolyline": "ipkcFfich...@Bs@?A?O?SD{A@o@B}@I?qA?_AA_@@_@?"
          }
        },
          "steps": [
              {
                  "polyline": {
                      "encodedPolyline": "kclcF...@sC@YIOKI"
                  }
              },
              {
                  "polyline": {
                      "encodedPolyline": "wblcF~...SZSF_@?"
                  }
              },
              ...
      ],
      "distanceMeters": 56901,
      "duration": "2420s",
      "polyline": {
        "encodedPolyline": "ipkcFfich...@Bs@?A?O?SD{A@o@B}@I?qA?_AA_@@_@?"
      }
    }
  ]
}
```

Because this request only contains an origin and a destination, the returned
route only contains a single leg. Therefore, the polyline for the leg and for
the route are the same.

If you add an intermediate waypoint to the request, then the returned route
contains two legs:

```json
curl -X POST -d '{
  "origin":{
    "address": "1600 Amphitheatre Parkway, Mountain View, CA"
  },
  "destination":{
    "address": "24 Willie Mays Plaza, San Francisco, CA 94107"
  },
  "intermediates": [
    { "address": "450 Serra Mall, Stanford, CA 94305, USA"},
  ],
  "travelMode": "DRIVE",
}' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: YOUR_API_KEY' \
-H 'X-Goog-FieldMask: routes.duration,routes.distanceMeters,routes.polyline,routes.legs.polyline' \
'https://routes.googleapis.com/directions/v2:computeRoutes'
```

This request returns two legs, each with a unique polyline, and a polyline for
the entire route:

```json
{
  "routes": [
    {
      "legs": [
        {
          "polyline": {
            "encodedPolyline": "kclcFfqchV?A...?I@G?GAECCCEKICBAFG"
          }
          "steps": [
            {
                "polyline": {
                    "encodedPolyline": "kclcFfqch...YIOKI"
                }
            },
        ...
        },
        {
          "polyline": {
            "encodedPolyline": "ojmcFtethV?K...QOYQOGA?_@MUG[Ga@G"
          }
          "steps": [
            {
                "polyline": {
                    "encodedPolyline": "uypeFbo`jVgJq...PoBiC"
                }
            },
        ...
        }
      ],
      "distanceMeters": 68403,
      "duration": "3759s",
      "polyline": {
          "encodedPolyline": "kclcFfqchV?A?CBKF[Ha...?GAECCCEKICBAFGJEBE"
      }
    }
  ]
}
```

## Polyline quality

The quality of a polyline can be described in the following terms:

- **The floating-point precision of the points**

  Points are specified as latitude and longitude values, which are represented
  in single-precision floating-point format. This works well for small values
  (which can be represented precisely), but precision decreases as values
  increase because of floating-point rounding errors.

  In
  [computeRoutes](https://developers.google.com/maps/documentation/routes/reference/rest/v2/TopLevel/computeRoutes.md.txt)
  method (REST) and
  [ComputeRoutes](https://developers.google.com/maps/documentation/routes/reference/rpc/google.maps.routing.v2.md.txt#google.maps.routing.v2.Routes.ComputeRoutes),
  this is controlled by [`polylineEncoding`](https://developers.google.com/maps/documentation/routes/traffic_on_polylines.md.txt#polylineEncoding).
- **The number of points that make up the polyline**

  The more points there are, the smoother the polyline (especially in curves).

  In
  [computeRoutes](https://developers.google.com/maps/documentation/routes/reference/rest/v2/TopLevel/computeRoutes.md.txt)
  method (REST) and
  [ComputeRoutes](https://developers.google.com/maps/documentation/routes/reference/rpc/google.maps.routing.v2.md.txt#google.maps.routing.v2.Routes.ComputeRoutes),
  this is controlled by [`polylineQuality`](https://developers.google.com/maps/documentation/routes/traffic_on_polylines.md.txt#polylineQuality).

## Configure polyline encoding type

Use the `polylineEncoding` request option for controlling the polyline type. The
`polylineEncoding` property controls whether the polyline will be encoded as
`ENCODED_POLYLINE` (default), meaning the [Encoded Polyline Algorithm
Format](https://developers.google.com/maps/documentation/utilities/polylinealgorithm) will be used, or
`GEO_JSON_LINESTRING`, meaning the [GeoJSON LineString
format](https://www.rfc-editor.org/rfc/rfc7946#section-3.1.4) will be used.

For example, in the request body:

```json
curl -X POST -d '{
  "origin":{
    "address": "1600 Amphitheatre Parkway, Mountain View, CA"
  },
  "destination":{
    "address": "24 Willie Mays Plaza, San Francisco, CA 94107"
  },
  "travelMode": "DRIVE",
  "polylineEncoding": "ENCODED_POLYLINE"
}' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: YOUR_API_KEY' \
-H 'X-Goog-FieldMask: routes.duration,routes.distanceMeters,routes.polyline,routes.legs.polyline' \
'https://routes.googleapis.com/directions/v2:computeRoutes'
```

## Configure Polyline quality

`polylineQuality` specifies the quality of the polyline as `HIGH_QUALITY` or
`OVERVIEW` (default). With `OVERVIEW`, the polyline is composed using a small
number of points and has a lower request latency than `HIGH_QUALITY`.

For example, in the request body:

```json
{
  "origin":{
    "location":{
      "latLng":{
        "latitude": 37.419734,
        "longitude": -122.0827784
      }
    }
  },
  "destination":{
    "location":{
      "latLng":{
        "latitude": 37.417670,
        "longitude": -122.079595
      }
    }
  },
  "travelMode": "DRIVE",
  "routingPreference": "TRAFFIC_AWARE",
  "polylineQuality": "HIGH_QUALITY",
  "polylineEncoding": "ENCODED_POLYLINE",
  "departureTime": "2023-10-15T15:01:23.045123456Z",
  ...
}
```

## Request a traffic-aware polyline

> [!CAUTION]
> **Caution:** Requests for a traffic-aware polyline are billed at a higher rate. [Learn more about billing](https://developers.google.com/maps/documentation/routes/usage-and-billing.md.txt) for Routes API.

The examples shown above all return basic polylines, meaning polylines without
traffic information. In addition, you can also request that the polyline
contains traffic information for the route and for each leg of the route.

> [!NOTE]
> **Note:** Traffic information is not available in the polyline at the step level.

Traffic-aware polylines contain information about the traffic conditions along
the route. Traffic conditions are expressed in terms of speed categories
(`NORMAL`, `SLOW`, `TRAFFIC_JAM`) for a given interval of the response polyline.
The intervals are defined by the indexes of their starting (inclusive) and
ending (exclusive) polyline points.

For example, the following response shows `NORMAL` traffic between polyline
points 2 and 4:

```json
{
  "startPolylinePointIndex": 2,
  "endPolylinePointIndex": 4,
  "speed": "NORMAL"
}
```

To make a request to compute a traffic-aware polyline, set the following
properties in the request:

- Set the `extraComputations` array field to `TRAFFIC_ON_POLYLINE` to enable
  the traffic calculation.

- Set the `travelMode` to `DRIVE` or `TWO_WHEELER`. Requests for any other
  travel mode return an error.

- Specify either the `TRAFFIC_AWARE` or `TRAFFIC_AWARE_OPTIMAL` routing
  preference in the request. For more information, see [Configure quality
  versus latency](https://developers.google.com/maps/documentation/routes/config_trade_offs).

- Set a response field mask that specifies to return the response properties:

  - **At the route level** , return all travel information in the response by
    including `routes.travelAdvisory` in the response field mask. To return
    just the traffic information, specify
    `routes.travelAdvisory.speedReadingIntervals`

  - **At the leg level** , return all travel information in the response for
    each leg of the route by including `routes.legs.travelAdvisory`. To return
    just the traffic information, specify
    `routes.legs.travelAdvisory.speedReadingIntervals`.

```curl
curl -X POST -d '{
  "origin":{
    "address": "1600 Amphitheatre Parkway, Mountain View, CA"
  },
  "destination":{
    "address": "24 Willie Mays Plaza, San Francisco, CA 94107"
  },
  "travelMode": "DRIVE",
  "extraComputations": ["TRAFFIC_ON_POLYLINE"],
  "routingPreference": "TRAFFIC_AWARE_OPTIMAL"
}' \
-H 'Content-Type: application/json' \
-H 'X-Goog-Api-Key: YOUR_API_KEY' \
-H 'X-Goog-FieldMask: routes.duration,routes.distanceMeters,routes.polyline,routes.legs.polyline,routes.travelAdvisory,routes.legs.travelAdvisory' \
'https://routes.googleapis.com/directions/v2:computeRoutes'
```

### Example response for a traffic-aware polyline

In the response, traffic data is encoded in the polyline and is contained in the
`travelAdvisory` field, of type
[RouteLegTravelAdvisory](https://developers.google.com/maps/documentation/routes/reference/rest/v2/TopLevel/computeRoutes.md.txt#routelegtraveladvisory)
object (each leg) and
[RouteTravelAdvisory](https://developers.google.com/maps/documentation/routes/reference/rest/v2/RouteTravelAdvisory.md.txt) object (route).

For example:

```curl
{
  "routes": [
    {
      "legs": {
        "polyline": {
          "encodedPolyline": "}boeF~zbjVAg@EmB`GWHlD"
        },
        // Traffic data for the leg.
        "travelAdvisory": {
          "speedReadingIntervals": [
            {
              "endPolylinePointIndex": 1,
              "speed": "NORMAL"
            },
            {
              "startPolylinePointIndex": 1,
              "endPolylinePointIndex": 2,
              "speed": "SLOW"
            },
            {
              "startPolylinePointIndex": 2,
              "endPolylinePointIndex": 4,
              "speed": "NORMAL"
            }
          ] 
        }
      },
      "polyline": {
        "encodedPolyline": "}boeF~zbjVAg@EmB`GWHlD"
      },
      // Traffic data for the route.
      "travelAdvisory": {
        "speedReadingIntervals": [
          {
            "endPolylinePointIndex": 1,
            "speed": "NORMAL"
          },
          {
            "startPolylinePointIndex": 1,
            "endPolylinePointIndex": 2,
            "speed": "SLOW"
          },
          {
            "startPolylinePointIndex": 2,
            "endPolylinePointIndex": 4,
            "speed": "NORMAL"
          }
        ] 
      }
    }
  ]
}
```

Both `RouteTravelAdvisory` and `RouteLegTravelAdvisory` include an array field
called `speedReadingIntervals` that contains traffic speed information. Each
object in the array is represented by a
[SpeedReadingInterval](https://developers.google.com/maps/documentation/routes/reference/rest/v2/SpeedReadingInterval.md.txt) (REST) or
[SpeedReadingInterval](https://developers.google.com/maps/documentation/routes/reference/rpc/google.maps.routing.v2.md.txt#speedreadinginterval)
(gRPC) object.

A `SpeedReadingInterval` object includes speed reading for a route interval,
such as `NORMAL`, `SLOW`, or `TRAFFIC_JAM`. The entire array of objects covers
the entire polyline of the route without overlap. The start point of a specified
interval is the same as the endpoint of the preceding interval.

Every interval is described by its `startPolylinePointIndex`,
`endPolylinePointIndex`, and the corresponding speed category. Notice that the
lack of start index within the interval corresponds with index 0 in accordance
with the [proto3
practices](https://developers.google.com/protocol-buffers/docs/proto3#default).

The `startPolylinePointIndex` and `endPolylinePointIndex` values are not always
consecutive. For example:

```json
{
  "startPolylinePointIndex": 2,
  "endPolylinePointIndex": 4,
  "speed": "NORMAL"
}
```

In this case, the traffic conditions were the same from index 2 to index 4.

## Render traffic-aware polylines with Maps SDK

We recommend displaying traffic aware polylines on the map using the various
features offered by Google Maps SDKs including custom coloring, strokes, and
patterns along the polyline stretches. For more details about using polylines,
see [Polyline Features for
Android](https://developers.google.com/maps/documentation/android-sdk/polygon-tutorial#java_4) and [Polyline
Features for iOS](https://developers.google.com/maps/documentation/ios-sdk/shapes).

### Example Polyline rendering

The users of Maps SDK have the opportunity of defining a customized mapping
logic between the speed categories and the polyline rendering schemas. As an
example, one might decide to display "NORMAL" speed as a thick blue line on the
map while "SLOW" speed might be displayed as a thick orange line, for example.

The following snippets add a thick blue polyline with geodesic segments from
Melbourne to Perth. For more information, see [Customizing
appearances](https://developers.google.com/maps/documentation/android-sdk/polygon-tutorial#add_custom_styling_to_your_polyline)
(for Android) and [Customize the
Polyline](https://developers.google.com/maps/documentation/ios-sdk/shapes#customize-a-polyline) (for iOS).

### Android

### Java


```java
Polyline line = map.addPolyline(new PolylineOptions()
    .add(new LatLng(-37.81319, 144.96298), new LatLng(-31.95285, 115.85734))
    .width(25)
    .color(Color.BLUE)
    .geodesic(true));
```

<br />

### Kotlin


```kotlin
val line: Polyline = map.addPolyline(
  PolylineOptions()
    .add(LatLng(-37.81319, 144.96298), LatLng(-31.95285, 115.85734))
    .width(25f)
    .color(Color.BLUE)
    .geodesic(true)
)
```

<br />

### iOS

### Objective-C


```objective-c
GMSMutablePath *path = [GMSMutablePath path];
[path addLatitude:-37.81319 longitude:144.96298];
[path addLatitude:-31.95285 longitude:115.85734];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.strokeWidth = 10.f;
polyline.strokeColor = .blue;
polyline.geodesic = YES;
polyline.map = mapView;
```

<br />

### Swift


```swift
let path = GMSMutablePath()
path.addLatitude(-37.81319, longitude: 144.96298)
path.addLatitude(-31.95285, longitude: 115.85734)
let polyline = GMSPolyline(path: path)
polyline.strokeWidth = 10.0
polyline.geodesic = true
polyline.map = mapView
```

<br />

## Use encoded polylines with Search Along Route

Use Text Search (New) in Places API (New) to search along a
calculated route. You pass the encoded polyline of a precalculated route from
Routes API Compute Routes to the Text Search (New) request. The response
then contains places that match the search criteria and are also located near
the specified route. For details, see [search along a
route](https://developers.google.com/maps/documentation/places/web-service/sar-overview).

For example, to return cafes along the route between the origin and destination:

### Node.js


```javascript
const API_KEY = 'YOUR_API_KEY';
const routes_service = 'https://routes.googleapis.com/directions/v2:computeRoutes';
const textSearch_service = 'https://places.googleapis.com/v1/places:searchText';

function init(){
    const routes_request = {
        "origin":{
            "address": "1600 Amphitheatre Parkway, Mountain View, CA"
        },
        "destination":{
            "address": "24 Willie Mays Plaza, San Francisco, CA 94107"
        },
        "travelMode": "DRIVE"
    };
    const textSearch_request = {
        "textQuery": "cafe",
        "searchAlongRouteParameters": {
            "polyline": {
                "encodedPolyline": ""
            }
        }
    };
    fetchResources(routes_service,routes_request).then(routes => {
        textSearch_request.searchAlongRouteParameters.polyline.encodedPolyline = routes.routes[0].polyline.encodedPolyline;
        fetchResources(textSearch_service,textSearch_request).then(places => {
            console.log(places);
        });
    });
}
async function fetchResources(resource,reqBody){
    const response = await fetch(resource, {
        method: 'POST',
        body: JSON.stringify(reqBody),
        headers: {
            'Content-Type': 'application/json',
            'X-Goog-Api-Key': API_KEY,
            'X-Goog-FieldMask': '*'
        }
    });
    const responseJSON = await response.json();
    return responseJSON;
}
init();
```

<br />