Привязать к дорогам

Roads API принимает до 100 точек GPS, собранных вдоль маршрута, и возвращает аналогичный набор данных, при этом точки привязаны к наиболее вероятным дорогам, по которым двигался автомобиль. При желании можно запросить интерполяцию точек, в результате чего будет построен маршрут, плавно повторяющий геометрию дороги.

Запросы

Для привязки к дороге необходимо отправлять запросы по протоколу HTTPS в следующем формате:

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

Необходимые параметры

  • путь

    Путь, по которому будет сделана привязка. Параметр path принимает список пар широта/долгота. Значения широты и долготы должны быть разделены запятыми. Координаты должны быть разделены символом вертикальной черты: "|". Например: path=60.170880,24.942795|60.170879,24.942796|60.170877,24.942796 .

    Примечание: Алгоритм привязки лучше всего работает для точек, расположенных не слишком далеко друг от друга. Если вы наблюдаете странное поведение привязки, попробуйте создать маршруты, в которых точки находятся ближе друг к другу. Для обеспечения наилучшего качества привязки к дороге следует стремиться к созданию маршрутов, на которых последовательные пары точек находятся в пределах 300 м друг от друга. Это также поможет справиться с любыми изолированными, длинными скачками между последовательными точками, вызванными потерей сигнала GPS или шумом.

Дополнительные параметры

  • интерполировать

    Интерполировать ли путь, чтобы включить все точки, образующие полную геометрию дороги. Если true, будут возвращены дополнительные интерполированные точки, в результате чего путь будет плавно следовать геометрии дороги, даже на поворотах и ​​через туннели. Интерполированные пути, скорее всего, будут содержать больше точек, чем исходный путь. По умолчанию — false .

Примеры

Следующий запрос привязывает указанные точки к геометрии дороги. Данный набор данных соответствует круговой дороге; установка interpolate=true позволяет получить геометрию, соответствующую кривизне дороги. При interpolate=false привязанный путь по-прежнему следует за дорогой, но результирующая полилиния не такая гладкая.

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'

Ответы

Для каждого корректного запроса Roads API возвращает ответ в формате, указанном в URL-адресе запроса, например, в формате JSON, как показано ниже.

{
  "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",
      },
    ],
}

В ответе используется следующая схема.

SnapToRoadsResponse

Поле Необходимый Тип Описание
необязательный Массив <SnappedPoint>

Массив привязанных точек.

Дополнительную информацию см. на сайте SnappedPoint .

необязательный нить

Строка, содержащая видимое пользователю предупреждение.

SnappedPoint

Поле Необходимый Тип Описание
необходимый ШиротаДолготаБуквальный Дополнительную информацию см. в разделе LatitudeLongitudeLiteral .
необходимый нить

Уникальный идентификатор места. Все идентификаторы мест, возвращаемые API дорог, соответствуют участкам дорог.

необязательный число

Целочисленное значение, указывающее на соответствующее значение в исходном запросе. Каждое значение в запросе должно соответствовать зафиксированному значению в ответе. Однако, если вы установили interpolate=true или используете ближайшие дороги, то ответ может содержать больше координат, чем запрос. Интерполированные значения не будут иметь originalIndex . Эти значения индексируются с 0 , поэтому точка с originalIndex, равным 4 будет зафиксированным значением 5-й широты/долготы, переданной в параметр path. Точки ближайших дорог могут содержать несколько точек для одной и той же координаты с различным местоположением или placeId.

ШиротаДолготаБуквальный

Объект, описывающий конкретное местоположение с указанием широты и долготы в десятичных градусах.

Поле Необходимый Тип Описание
необходимый число

Широта в десятичных градусах

необходимый число

Долгота в десятичных градусах

Демо

  1. Щёлкайте по карте, чтобы создать траекторию движения транспортного средства. Обратите внимание, что если точки расположены слишком далеко друг от друга, они могут некорректно привязаться.
  2. Дважды щелкните, чтобы привязать свой след к дороге.

Просмотрите этот пример в полноэкранном режиме .

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>