Snap to Roads

The Roads API takes up to 100 GPS points collected along a route, and returns a similar set of data, with the points snapped to the most likely roads the vehicle was traveling along. Optionally, you can request that the points be interpolated, resulting in a path that smoothly follows the geometry of the road.

Requests

A request to snap to road must be sent via HTTPS, and takes the following form:

https://roads.googleapis.com/v1/snapToRoads?parameters&key=YOUR_API_KEY                  

Required parameters

  • path

    The path to be snapped. The path parameter accepts a list of latitude/longitude pairs. Latitude and longitude values should be separated by commas. Coordinates should be separated by the pipe character: "|". For example: path=60.170880,24.942795|60.170879,24.942796|60.170877,24.942796.

    Note: The snapping algorithm works best for points that are not too far apart. If you observe odd snapping behavior, try creating paths that have points closer together. To ensure the best snap-to-road quality, you should aim to provide paths on which consecutive pairs of points are within 300m of each other. This will also help in handling any isolated, long jumps between consecutive points caused by GPS signal loss, or noise.

Optional parameters

  • interpolate

    Whether to interpolate a path to include all points forming the full road-geometry. When true, additional interpolated points will also be returned, resulting in a path that smoothly follows the geometry of the road, even around corners and through tunnels. Interpolated paths will most likely contain more points than the original path. Defaults to false.

Generated from the OpenAPI specification. Edit Report bug

Examples

The following request will snap the specified points to the road geometry. This particular set of data follows a circular road; setting interpolate=true ensure that the returned geometry will match the curvature of the road. With interpolate=false, the snapped path will still follow the road, but the resulting polyline will not be as smooth.

URL

https://roads.googleapis.com/v1/snapToRoads   ?interpolate=true   &path=-35.27801%2C149.12958%7C-35.28032%2C149.12907%7C-35.28099%2C149.12929%7C-35.28144%2C149.12984%7C-35.28194%2C149.13003%7C-35.28282%2C149.12956%7C-35.28302%2C149.12881%7C-35.28473%2C149.12836   &key=YOUR_API_KEY

cURL

curl -L -X GET 'https://roads.googleapis.com/v1/snapToRoads?path=-35.27801%2C149.12958%7C-35.28032%2C149.12907%7C-35.28099%2C149.12929%7C-35.28144%2C149.12984%7C-35.28194%2C149.13003%7C-35.28282%2C149.12956%7C-35.28302%2C149.12881%7C-35.28473%2C149.12836&interpolate=true&key=YOUR_API_KEY'

JavaScript

var axios = require('axios');  var config = {   method: 'get',   url: 'https://roads.googleapis.com/v1/snapToRoads?path=-35.27801%2C149.12958%7C-35.28032%2C149.12907%7C-35.28099%2C149.12929%7C-35.28144%2C149.12984%7C-35.28194%2C149.13003%7C-35.28282%2C149.12956%7C-35.28302%2C149.12881%7C-35.28473%2C149.12836&interpolate=true&key=YOUR_API_KEY',   headers: { } };  axios(config) .then(function (response) {   console.log(JSON.stringify(response.data)); }) .catch(function (error) {   console.log(error); });

Python

import requests  url = "https://roads.googleapis.com/v1/snapToRoads?path=-35.27801%2C149.12958%7C-35.28032%2C149.12907%7C-35.28099%2C149.12929%7C-35.28144%2C149.12984%7C-35.28194%2C149.13003%7C-35.28282%2C149.12956%7C-35.28302%2C149.12881%7C-35.28473%2C149.12836&interpolate=true&key=YOUR_API_KEY"  payload={} headers = {}  response = requests.request("GET", url, headers=headers, data=payload)  print(response.text)

Java

OkHttpClient client = new OkHttpClient().newBuilder()   .build(); Request request = new Request.Builder()   .url("https://roads.googleapis.com/v1/snapToRoads?path=-35.27801%2C149.12958%7C-35.28032%2C149.12907%7C-35.28099%2C149.12929%7C-35.28144%2C149.12984%7C-35.28194%2C149.13003%7C-35.28282%2C149.12956%7C-35.28302%2C149.12881%7C-35.28473%2C149.12836&interpolate=true&key=YOUR_API_KEY")   .method("GET", null)   .build(); Response response = client.newCall(request).execute();

Ruby

require "uri" require "net/http"  url = URI("https://roads.googleapis.com/v1/snapToRoads?path=-35.27801%2C149.12958%7C-35.28032%2C149.12907%7C-35.28099%2C149.12929%7C-35.28144%2C149.12984%7C-35.28194%2C149.13003%7C-35.28282%2C149.12956%7C-35.28302%2C149.12881%7C-35.28473%2C149.12836&interpolate=true&key=YOUR_API_KEY")  https = Net::HTTP.new(url.host, url.port) https.use_ssl = true  request = Net::HTTP::Get.new(url)  response = https.request(request) puts response.read_body

Go

package main  import (   "fmt"   "net/http"   "io/ioutil" )  func main() {    url := "https://roads.googleapis.com/v1/snapToRoads?path=-35.27801,149.12958%7C-35.28032,149.12907%7C-35.28099,149.12929%7C-35.28144,149.12984%7C-35.28194,149.13003%7C-35.28282,149.12956%7C-35.28302,149.12881%7C-35.28473,149.12836&interpolate=true&key=YOUR_API_KEY"   method := "GET"    client := &http.Client {   }   req, err := http.NewRequest(method, url, nil)    if err != nil {     fmt.Println(err)     return   }   res, err := client.Do(req)   if err != nil {     fmt.Println(err)     return   }   defer res.Body.Close()    body, err := ioutil.ReadAll(res.Body)   if err != nil {     fmt.Println(err)     return   }   fmt.Println(string(body)) }

Postman

The OpenAPI specification is also available as a Postman collection.

Run in Postman

Responses

For each valid request, the Roads API will return a response in the format indicated within the request URL such as the following JSON response.

{   "snappedPoints":     [       {         "location":           { "latitude": -35.27800489993019, "longitude": 149.129531998742 },         "originalIndex": 0,         "placeId": "ChIJr_xl0GdNFmsRsUtUbW7qABM",       },       {         "location":           { "latitude": -35.2784195, "longitude": 149.12946589999999 },         "placeId": "ChIJr_xl0GdNFmsRsUtUbW7qABM",       },       {         "location":           { "latitude": -35.2784195, "longitude": 149.12946589999999 },         "placeId": "ChIJ6aXGemhNFmsRZE_zHqhmrG4",       },       {         "location":           { "latitude": -35.2792731, "longitude": 149.12933809999998 },         "placeId": "ChIJ6aXGemhNFmsRZE_zHqhmrG4",       },       {         "location":           { "latitude": -35.2792731, "longitude": 149.12933809999998 },         "placeId": "ChIJTcTdZ2hNFmsRXokM4mWCWfk",       },       {         "location": { "latitude": -35.279557, "longitude": 149.1292973 },         "placeId": "ChIJTcTdZ2hNFmsRXokM4mWCWfk",       },       {         "location": { "latitude": -35.279557, "longitude": 149.1292973 },         "placeId": "ChIJiUfNQmhNFmsRSsAI-1m6y1g",       },       {         "location":           { "latitude": -35.279610999999996, "longitude": 149.1292889 },         "placeId": "ChIJiUfNQmhNFmsRSsAI-1m6y1g",       },       {         "location": { "latitude": -35.2796484, "longitude": 149.1292791 },         "placeId": "ChIJiUfNQmhNFmsRSsAI-1m6y1g",       },       {         "location": { "latitude": -35.2796484, "longitude": 149.1292791 },         "placeId": "ChIJ_RyFQ2hNFmsRoHJAbW7qABM",       },       {         "location":           { "latitude": -35.279947299999996, "longitude": 149.1291894 },         "placeId": "ChIJ_RyFQ2hNFmsRoHJAbW7qABM",       },       {         "location":           { "latitude": -35.279947299999996, "longitude": 149.1291894 },         "placeId": "ChIJOyypT2hNFmsRZBtscGL0htw",       },       {         "location":           { "latitude": -35.280323564795005, "longitude": 149.1290903128365 },         "originalIndex": 1,         "placeId": "ChIJOyypT2hNFmsRZBtscGL0htw",       },       {         "location":           { "latitude": -35.2803426, "longitude": 149.12908529999999 },         "placeId": "ChIJOyypT2hNFmsRZBtscGL0htw",       },       {         "location":           { "latitude": -35.2803426, "longitude": 149.12908529999999 },         "placeId": "ChIJr8xRTGhNFmsRzMb-rxgjspc",       },       {         "location":           { "latitude": -35.280409899999995, "longitude": 149.1290699 },         "placeId": "ChIJr8xRTGhNFmsRzMb-rxgjspc",       },       {         "location": { "latitude": -35.28048179999999, "longitude": 149.129062 },         "placeId": "ChIJr8xRTGhNFmsRzMb-rxgjspc",       },       {         "location": { "latitude": -35.2805541, "longitude": 149.1290623 },         "placeId": "ChIJr8xRTGhNFmsRzMb-rxgjspc",       },       {         "location": { "latitude": -35.280626, "longitude": 149.1290712 },         "placeId": "ChIJr8xRTGhNFmsRzMb-rxgjspc",       },       {         "location": { "latitude": -35.280626, "longitude": 149.1290712 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location":           { "latitude": -35.280695099999996, "longitude": 149.12908489999998 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location": { "latitude": -35.2807629, "longitude": 149.1291046 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location": { "latitude": -35.2808294, "longitude": 149.1291306 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location": { "latitude": -35.2809064, "longitude": 149.1291693 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location":           { "latitude": -35.280968200000004, "longitude": 149.129208 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location":           { "latitude": -35.28101395754623, "longitude": 149.1292430025548 },         "originalIndex": 2,         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location":           { "latitude": -35.28103840000001, "longitude": 149.1292617 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location": { "latitude": -35.2810936, "longitude": 149.1293121 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location": { "latitude": -35.2810979, "longitude": 149.1293176 },         "placeId": "ChIJv5r0smlNFmsR5nunau79Fv4",       },       {         "location": { "latitude": -35.2810979, "longitude": 149.1293176 },         "placeId": "ChIJpYMSrmlNFmsRXkCoIkZxgBg",       },       {         "location":           { "latitude": -35.281152399999996, "longitude": 149.1294256 },         "placeId": "ChIJpYMSrmlNFmsRXkCoIkZxgBg",       },       {         "location":           { "latitude": -35.281152399999996, "longitude": 149.1294256 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2811784, "longitude": 149.1294706 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2812258, "longitude": 149.1295413 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.2812771, "longitude": 149.12960759999999 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.281332, "longitude": 149.1296695 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.2813904, "longitude": 149.12972670000002 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.281451700000005, "longitude": 149.1297788 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.28146506991143, "longitude": 149.12978858234607 },         "originalIndex": 3,         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.28151580000001, "longitude": 149.1298257 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.28158259999999, "longitude": 149.129867 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.281666099999995, "longitude": 149.1299091 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2817377, "longitude": 149.1299379 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.281810899999996, "longitude": 149.1299602 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.281884999999996, "longitude": 149.1299765 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.28194399606459, "longitude": 149.1299842294294 },         "originalIndex": 4,         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.281959799999996, "longitude": 149.12998629999998 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.282035199999996, "longitude": 149.1299895 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2821254, "longitude": 149.1299851 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location":           { "latitude": -35.282199999999996, "longitude": 149.1299743 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2822739, "longitude": 149.1299573 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2823468, "longitude": 149.129934 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2824178, "longitude": 149.1299043 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2824379, "longitude": 149.1298945 },         "placeId": "ChIJ601MoWlNFmsR5mvkfPp2ovA",       },       {         "location": { "latitude": -35.2824379, "longitude": 149.1298945 },         "placeId": "ChIJe9LPnWlNFmsR7mJw8mYHwG0",       },       {         "location":           { "latitude": -35.282472999999996, "longitude": 149.1298835 },         "placeId": "ChIJe9LPnWlNFmsR7mJw8mYHwG0",       },       {         "location": { "latitude": -35.2825375, "longitude": 149.1298525 },         "placeId": "ChIJe9LPnWlNFmsR7mJw8mYHwG0",       },       {         "location":           { "latitude": -35.28257309999999, "longitude": 149.1298319 },         "placeId": "ChIJe9LPnWlNFmsR7mJw8mYHwG0",       },       {         "location":           { "latitude": -35.28257309999999, "longitude": 149.1298319 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location":           { "latitude": -35.282665400000006, "longitude": 149.12974459999998 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location":           { "latitude": -35.28274030000001, "longitude": 149.1296645 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location":           { "latitude": -35.282809799999995, "longitude": 149.12957799999998 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location":           { "latitude": -35.28282136229385, "longitude": 149.12956142620385 },         "originalIndex": 5,         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location": { "latitude": -35.2828744, "longitude": 149.1294854 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location":           { "latitude": -35.282922299999996, "longitude": 149.1294044 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location":           { "latitude": -35.282931500000004, "longitude": 149.1293876 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location": { "latitude": -35.2830263, "longitude": 149.1291788 },         "placeId": "ChIJaUpThGlNFmsRMHWxoH7EOsc",       },       {         "location": { "latitude": -35.2830263, "longitude": 149.1291788 },         "placeId": "ChIJyd3JiWlNFmsR9RUq2ySTTZQ",       },       {         "location": { "latitude": -35.283054, "longitude": 149.1290996 },         "placeId": "ChIJyd3JiWlNFmsR9RUq2ySTTZQ",       },       {         "location": { "latitude": -35.2830794, "longitude": 149.1290094 },         "placeId": "ChIJyd3JiWlNFmsR9RUq2ySTTZQ",       },       {         "location": { "latitude": -35.2830794, "longitude": 149.1290094 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.28313383700836, "longitude": 149.12893500604946 },         "originalIndex": 6,         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.283134499999996, "longitude": 149.12893409999998 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.283190399999995, "longitude": 149.1288668 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location": { "latitude": -35.2832503, "longitude": 149.1288041 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location": { "latitude": -35.2833133, "longitude": 149.1287463 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location": { "latitude": -35.2833794, "longitude": 149.128694 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.283448299999996, "longitude": 149.128647 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location": { "latitude": -35.2835199, "longitude": 149.1286054 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location": { "latitude": -35.2835934, "longitude": 149.1285699 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.283668899999995, "longitude": 149.12854059999998 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.28372649999999, "longitude": 149.1285237 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.28386179999999, "longitude": 149.12849319999998 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location": { "latitude": -35.2839978, "longitude": 149.1284682 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.2840205, "longitude": 149.12846779999998 },         "placeId": "ChIJWSb8ImpNFmsRp_4JAxJFE1A",       },       {         "location":           { "latitude": -35.2840205, "longitude": 149.12846779999998 },         "placeId": "ChIJZe8tFWpNFmsR4brZ1vldk2E",       },       {         "location":           { "latitude": -35.2840524, "longitude": 149.12845969999998 },         "placeId": "ChIJZe8tFWpNFmsR4brZ1vldk2E",       },       {         "location":           { "latitude": -35.284341500000004, "longitude": 149.1284124 },         "placeId": "ChIJZe8tFWpNFmsR4brZ1vldk2E",       },       {         "location": { "latitude": -35.2843875, "longitude": 149.1284034 },         "placeId": "ChIJZe8tFWpNFmsR4brZ1vldk2E",       },       {         "location": { "latitude": -35.2843875, "longitude": 149.1284034 },         "placeId": "ChIJVx7Ta2pNFmsRx9OI9CnN5tI",       },       {         "location": { "latitude": -35.2845916, "longitude": 149.1283726 },         "placeId": "ChIJVx7Ta2pNFmsRx9OI9CnN5tI",       },       {         "location": { "latitude": -35.2845916, "longitude": 149.1283726 },         "placeId": "ChIJtWxAZmpNFmsRlbUCkc6VtnA",       },       {         "location":           { "latitude": -35.28459730000001, "longitude": 149.1283703 },         "placeId": "ChIJtWxAZmpNFmsRlbUCkc6VtnA",       },       {         "location":           { "latitude": -35.284728747199374, "longitude": 149.12834860726772 },         "originalIndex": 7,         "placeId": "ChIJtWxAZmpNFmsRlbUCkc6VtnA",       },     ], }

The response uses the following schema.

SnapToRoadsResponse

Field Required Type Description

snappedPoints

optional Array<SnappedPoint>

An array of snapped points.

See SnappedPoint for more information.

warningMessage

optional string

A string containing a user-visible warning.

Generated from the OpenAPI specification. Edit Report bug

SnappedPoint

Field Required Type Description

location

required LatitudeLongitudeLiteral See LatitudeLongitudeLiteral for more information.

placeId

required string

A unique identifier for a place. All place IDs returned by the Roads API correspond to road segments.

originalIndex

optional number

An integer that indicates the corresponding value in the original request. Each value in the request should map to a snapped value in the response. However, if you've set interpolate=true, then it's possible that the response will contain more coordinates than the request. Interpolated values will not have an originalIndex. These values are indexed from 0, so a point with an originalIndex of 4 will be the snapped value of the 5th latitude/longitude passed to the path parameter.

Generated from the OpenAPI specification. Edit Report bug

LatitudeLongitudeLiteral

An object describing a specific location with Latitude and Longitude in decimal degrees.

Field Required Type Description

latitude

required number

Latitude in decimal degrees

longitude

required number

Longitude in decimal degrees

Generated from the OpenAPI specification. Edit Report bug

Demo

  1. Click around on the map to create a vehicle track. Note that if your points are too far apart, they may not snap correctly.
  2. Double click to snap your track to the road.

View this example full screen.

JavaScript

var apiKey = 'YOUR_API_KEY_HERE';  var map; var drawingManager; var placeIdArray = []; var polylines = []; var snappedCoordinates = [];  function initialize() {   var mapOptions = {     zoom: 17,     center: {lat: -33.8667, lng: 151.1955,}   };   map = new google.maps.Map(document.getElementById('map'), mapOptions);    // Adds a Places search box. Searching for a place will center the map on that   // location.   map.controls[google.maps.ControlPosition.RIGHT_TOP].push(       document.getElementById('bar'));   var autocomplete = new google.maps.places.Autocomplete(       document.getElementById('autoc'));   autocomplete.bindTo('bounds', map);   autocomplete.addListener('place_changed', function() {     var place = autocomplete.getPlace();     if (place.geometry.viewport) {       map.fitBounds(place.geometry.viewport);     } else {       map.setCenter(place.geometry.location);       map.setZoom(17);     }   });    // Enables the polyline drawing control. Click on the map to start drawing a   // polyline. Each click will add a new vertice. Double-click to stop drawing.   drawingManager = new google.maps.drawing.DrawingManager({     drawingMode: google.maps.drawing.OverlayType.POLYLINE,     drawingControl: true,     drawingControlOptions: {       position: google.maps.ControlPosition.TOP_CENTER,       drawingModes: [         google.maps.drawing.OverlayType.POLYLINE       ]     },     polylineOptions: {       strokeColor: '#696969',       strokeWeight: 2,       strokeOpacity: 0.3,     }   });   drawingManager.setMap(map);    // Snap-to-road when the polyline is completed.   drawingManager.addListener('polylinecomplete', function(poly) {     var path = poly.getPath();     polylines.push(poly);     placeIdArray = [];     runSnapToRoad(path);   });     // Clear button. Click to remove all polylines.   document.getElementById('clear').addEventListener('click', function(event) {     event.preventDefault();     for (var i = 0; i < polylines.length; ++i) {       polylines[i].setMap(null);     }     polylines = [];     return false;   }); }  // Snap a user-created polyline to roads and draw the snapped path function runSnapToRoad(path) {   var pathValues = [];   for (var i = 0; i < path.getLength(); i++) {     pathValues.push(path.getAt(i).toUrlValue());   }    $.get('https://roads.googleapis.com/v1/snapToRoads', {     interpolate: true,     key: apiKey,     path: pathValues.join('|')   }, function(data) {     processSnapToRoadResponse(data);     drawSnappedPolyline();   }); }  // Store snapped polyline returned by the snap-to-road service. function processSnapToRoadResponse(data) {   snappedCoordinates = [];   placeIdArray = [];   for (var i = 0; i < data.snappedPoints.length; i++) {     var latlng = new google.maps.LatLng(         data.snappedPoints[i].location.latitude,         data.snappedPoints[i].location.longitude);     snappedCoordinates.push(latlng);     placeIdArray.push(data.snappedPoints[i].placeId);   } }  // Draws the snapped polyline (after processing snap-to-road response). function drawSnappedPolyline() {   var snappedPolyline = new google.maps.Polyline({     path: snappedCoordinates,     strokeColor: '#add8e6',     strokeWeight: 4,     strokeOpacity: 0.9,   });    snappedPolyline.setMap(map);   polylines.push(snappedPolyline); }  $(window).load(initialize);                        

JavaScript + HTML

<!DOCTYPE html> <html>   <head>     <meta name="viewport" content="initial-scale=1.0, user-scalable=no">     <meta charset="utf-8">     <title>Roads API Demo</title>     <style>       html, body, #map {         height: 100%;         margin: 0px;         padding: 0px       }        #panel {         position: absolute;         top: 5px;         left: 50%;         margin-left: -180px;         z-index: 5;         background-color: #fff;         padding: 5px;         border: 1px solid #999;       }        #bar {         width: 240px;         background-color: rgba(255, 255, 255, 0.75);         margin: 8px;         padding: 4px;         border-radius: 4px;       }        #autoc {         width: 100%;         box-sizing: border-box;       }     </style>      <script src="https://www.gstatic.com/external_hosted/jquery2.min.js"></script>     <script       src="https://maps.googleapis.com/maps/api/js?libraries=drawing,places&key=YOUR_API_KEY"></script>     <script> var apiKey = 'YOUR_API_KEY_HERE';  var map; var drawingManager; var placeIdArray = []; var polylines = []; var snappedCoordinates = [];  function initialize() {   var mapOptions = {     zoom: 17,     center: {lat: -33.8667, lng: 151.1955,}   };   map = new google.maps.Map(document.getElementById('map'), mapOptions);    // Adds a Places search box. Searching for a place will center the map on that   // location.   map.controls[google.maps.ControlPosition.RIGHT_TOP].push(       document.getElementById('bar'));   var autocomplete = new google.maps.places.Autocomplete(       document.getElementById('autoc'));   autocomplete.bindTo('bounds', map);   autocomplete.addListener('place_changed', function() {     var place = autocomplete.getPlace();     if (place.geometry.viewport) {       map.fitBounds(place.geometry.viewport);     } else {       map.setCenter(place.geometry.location);       map.setZoom(17);     }   });    // Enables the polyline drawing control. Click on the map to start drawing a   // polyline. Each click will add a new vertice. Double-click to stop drawing.   drawingManager = new google.maps.drawing.DrawingManager({     drawingMode: google.maps.drawing.OverlayType.POLYLINE,     drawingControl: true,     drawingControlOptions: {       position: google.maps.ControlPosition.TOP_CENTER,       drawingModes: [         google.maps.drawing.OverlayType.POLYLINE       ]     },     polylineOptions: {       strokeColor: '#696969',       strokeWeight: 2,       strokeOpacity: 0.3,     }   });   drawingManager.setMap(map);    // Snap-to-road when the polyline is completed.   drawingManager.addListener('polylinecomplete', function(poly) {     var path = poly.getPath();     polylines.push(poly);     placeIdArray = [];     runSnapToRoad(path);   });     // Clear button. Click to remove all polylines.   document.getElementById('clear').addEventListener('click', function(event) {     event.preventDefault();     for (var i = 0; i < polylines.length; ++i) {       polylines[i].setMap(null);     }     polylines = [];     return false;   }); }  // Snap a user-created polyline to roads and draw the snapped path function runSnapToRoad(path) {   var pathValues = [];   for (var i = 0; i < path.getLength(); i++) {     pathValues.push(path.getAt(i).toUrlValue());   }    $.get('https://roads.googleapis.com/v1/snapToRoads', {     interpolate: true,     key: apiKey,     path: pathValues.join('|')   }, function(data) {     processSnapToRoadResponse(data);     drawSnappedPolyline();   }); }  // Store snapped polyline returned by the snap-to-road service. function processSnapToRoadResponse(data) {   snappedCoordinates = [];   placeIdArray = [];   for (var i = 0; i < data.snappedPoints.length; i++) {     var latlng = new google.maps.LatLng(         data.snappedPoints[i].location.latitude,         data.snappedPoints[i].location.longitude);     snappedCoordinates.push(latlng);     placeIdArray.push(data.snappedPoints[i].placeId);   } }  // Draws the snapped polyline (after processing snap-to-road response). function drawSnappedPolyline() {   var snappedPolyline = new google.maps.Polyline({     path: snappedCoordinates,     strokeColor: '#add8e6',     strokeWeight: 4,     strokeOpacity: 0.9,   });    snappedPolyline.setMap(map);   polylines.push(snappedPolyline); }  $(window).load(initialize);     </script>   </head>    <body>     <div id="map"></div>     <div id="bar">       <p class="auto"><input type="text" id="autoc"/></p>       <p><a id="clear" href="#">Click here</a> to clear map.</p>     </div>   </body> </html>

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2021-11-23 UTC.