The
computeRoutes
method (REST) and the
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
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
for
Routes API. For details, see
Configure polyline quality
For more on polylines, see:
Request a basic polyline for a route, leg, or step
A polyline is represented by a
Polyline
(REST) or
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
:
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
.
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:
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:
{
"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:
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:
{
"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
method (REST) and
ComputeRoutes
,
this is controlled by
polylineEncoding
.
The number of points that make up the polyline
The more points there are, the smoother the polyline (especially in
curves).
In
computeRoutes
method (REST) and
ComputeRoutes
,
this is controlled by
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
will be used, or
GEO_JSON_LINESTRING
, meaning the
GeoJSON LineString format
will be used.
For example, in the request body:
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 Poyline 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:
{
"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
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.
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:
{
"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 vs
latency
.
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 -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
object (each leg) and
RouteTravelAdvisory
object (route).
For example:
{
"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
(REST) or
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 end point 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
.
The
startPolylinePointIndex
and
endPolylinePointIndex
values are not
always consecutive. For example:
{
"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
and
Polyline Features for iOS
.
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
(for Android) and
Customize the Polyline
(for iOS).
Android
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));
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)
)
iOS
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;
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