Служба Directions

Обзор

С помощью объекта DirectionsService можно планировать маршруты с учетом разных способов передвижения. Этот объект взаимодействует со службой Google Maps API Directions Service, которая получает запросы маршрутов и возвращает наиболее оптимальный. Время в пути является главным критерием выбора, но могут учитываться также расстояние, количество поворотов и прочие факторы. Вы можете обрабатывать эти результаты самостоятельно или использовать для их отображения объект DirectionsRenderer.

При определении источника или пункта назначения в запросе маршрута можно указать строку запроса (например, "Chicago, IL" или "Darwin, NSW, Australia"), значение LatLng или объект Place.

Служба Directions может возвращать маршруты из нескольких частей, используя для этого наборы путевых точек. Маршруты отображаются в виде ломаной линии на карте, которая может сопровождаться текстовым описанием внутри элемента <div> (например, "поверните направо к мосту Уильямсбурга").

Начало работы

Прежде чем использовать сервис Directions в Maps JavaScript API, проверьте в Google Cloud Console, чтобы Directions API был включен в том же проекте, что и Maps JavaScript API.

Чтобы посмотреть список включенных API:

  1. Войдите в Google Cloud Console.
  2. Нажмите кнопку Select a project (Выбрать проект), затем выберите тот же проект, который вы установили для Maps JavaScript API, и нажмите Open (Открыть).
  3. В списке API на панели управления найдите Directions API.
  4. Если этот API присутствует в списке – всё в порядке. Если API в списке нет, включите его:
    1. Вверху страницы нажмите Enable API (Включить API), чтобы перейти на вкладку Library (Библиотека). Вы также можете выбрать в меню слева пункт Library (Библиотека).
    2. Введите запрос для поиска Directions API и выберите API из списка результатов.
    3. Нажмите Включить. Когда всё будет готово, Directions API появится в списке API на панели управления.

Цены и правила

Цены

С 16 июля 2018 г. для API Maps, Routes и Places действует новый тарифный план с оплатой по мере использования. Чтобы узнать больше о новых ценах и лимитах сервиса JavaScript Directions, ищите информацию о Directions API в статье Статистика использования и оплата.

Ограничение частоты запросов

Учитывайте описанные ниже ограничения частоты дополнительных запросов:

Ограничение применяется к каждому пользовательскому сеансу, независимо от количества пользователей проекта. При первой загрузке API вам выделяется исходная квота запросов. Как только она будет израсходована, API задает ограничение на число дополнительных запросов в секунду. Если за определенный период времени их будет отправлено слишком много, API вернет вашему приложению код ответа OVER_QUERY_LIMIT.

Ограничение частоты блокирует пакетные запросы от клиенстких серверов. Для пакетных запросов используйте веб-сервис Directions API.

Правила

Сервис Directions нужно использовать в соответствии с правилами для Directions API.

Запросы маршрутов

Доступ к службе Directions осуществляется асинхронно, поскольку интерфейсу Google Maps API требуется отправить вызов на внешний сервер. По этой причине необходимо передавать метод обратного вызова, который будет выполняться по завершении запроса. Этот метод обратного вызова должен обработать результаты. Обратите внимание на то, что служба может возвращать несколько возможных маршрутов в виде массива значений routes[].

Для использования маршрутов в Maps JavaScript API создайте объект типа DirectionsService и вызовите DirectionsService.route(), чтобы инициировать запрос в службу Directions, передав ей литерал объекта DirectionsRequest (содержит вводные условия и метод обратного вызова для выполнения после получения ответа).

Литерал объекта DirectionsRequest содержит следующие поля:

{
  origin: LatLng | String | google.maps.Place,
  destination: LatLng | String | google.maps.Place,
  travelMode: TravelMode,
  transitOptions: TransitOptions,
  drivingOptions: DrivingOptions,
  unitSystem: UnitSystem,
  waypoints[]: DirectionsWaypoint,
  optimizeWaypoints: Boolean,
  provideRouteAlternatives: Boolean,
  avoidFerries: Boolean,
  avoidHighways: Boolean,
  avoidTolls: Boolean,
  region: String
}

Назначение полей:

  • origin (обязательно) – указывает стартовую точку, от которой следует рассчитать маршрут. Значение может быть задано как объект String (например, "Чикаго, Иллинойс"), координатами LatLng или как объект Place. В объекте Place можно задать place ID, строку запроса или координаты LatLng. Идентификаторы мест можно получить от служб геокодирования, поиска мест и подсказок мест в Maps JavaScript API. Пример использования идентификаторов мест из службы подсказок мест можно найти в документе Подсказки мест и маршруты.
  • destination (обязательно) – указывает конечную точку, до которой нужно рассчитать маршрут. Параметры аналогичны параметрам поля origin (описано выше).
  • travelMode (обязательно) – указывает, какой вид транспорта использовать при расчете направления. Допустимые значения приведены в разделе Способы передвижения ниже.
  • transitOptions (необязательно) – настройки, применяемые к запросу, когда переменной travelMode присвоено значение TRANSIT. Допустимые значения перечислены в разделе Параметры маршрутов на общественном транспорте.
  • drivingOptions (необязательно) – настройки, применяемые к запросу, когда переменной travelMode присвоено значение DRIVING. Допустимые значения перечислены в разделе Параметры автомобильных маршрутов.
  • unitSystem (необязательно) – указывает единицы измерения для отображения результатов. Поддерживаемые значения перечислены в разделе Системы единиц.

  • waypoints[] (необязательно) – определяет массив точек DirectionsWaypoint. Промежуточные точки позволяют изменить маршрут так, чтобы он проходил через указанные места. Промежуточная точка маршрута определяется как литерал объекта со следующими полями:

    • location – определяет местоположение путевой точки как координаты LatLng, объект Place или строку для геокодирования String.
    • stopover – логическое значение, указывающее, что путевая точка является остановкой на маршруте, что приводит к его разделению на две части.

    Подробнее о путевых точках…

  • optimizeWaypoints (необязательно) – указывает, что маршрут можно сократить, поменяв местами путевые точки waypoints. Если выбрано значение true, служба Directions возвращает переупорядоченные значения waypoints в поле waypoint_order. (Подробнее читайте в статье Путевые точки в маршрутах.)
  • provideRouteAlternatives (необязательно) – значение true указывает, что служба Directions может предложить несколько альтернативных маршрутов. Отметим, что в этом случае время ответа сервера может увеличиться. Это возможно только для запросов без промежуточных путевых точек.
  • avoidFerries (необязательно) – значение true указывает, что предпочтительный маршрут должен по возможности избегать паромов.
  • avoidHighways (необязательно) – значение true указывает, что вычисленные маршруты должны по возможности избегать автомагистралей.
  • avoidTolls (необязательно) – значение true указывает, что вычисленные маршруты должны по возможности избегать платных дорог.
  • region (необязательно) – указывает код региона в виде двузначного числа ccTLD (домен верхнего уровня). Подробнее…

Ниже приведен пример запроса DirectionsRequest.

{
  origin: 'Chicago, IL',
  destination: 'Los Angeles, CA',
  waypoints: [
    {
      location: 'Joplin, MO',
      stopover: false
    },{
      location: 'Oklahoma City, OK',
      stopover: true
    }],
  provideRouteAlternatives: false,
  travelMode: 'DRIVING',
  drivingOptions: {
    departureTime: new Date(/* now, or future date */),
    trafficModel: 'pessimistic'
  },
  unitSystem: google.maps.UnitSystem.IMPERIAL
}

Способы передвижения

При расчете маршрутов нужно указать желаемый способ передвижения. В настоящее время поддерживаются следующие значения переменной:

  • DRIVING (по умолчанию) – запрашивает стандартный маршрут для автомобиля.
  • BICYCLING – запрашивает маршрут по велосипедным дорожкам и улицам, где удобнее передвигаться на велосипеде.
  • TRANSIT – запрашивает маршрут на общественном транспорте.
  • WALKING – запрашивает пеший маршрут по пешеходным дорожкам и тротуарам.

Узнайте, какие из этих функций поддерживаются в вашем регионе, в разделе Доступность сервисов платформы Google Карт. Если вы запросите маршрут определенного типа в регионе, где он недоступен, в ответ будет возвращена строка DirectionsStatus="ZERO_RESULTS".

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

Параметры маршрутов на общественном транспорте

Доступные параметры запроса маршрута зависят от способа передвижения. Значения переменных avoidHighways, avoidTolls, waypoints[] и optimizeWaypoints в запросах маршрутов на общественном транспорте игнорируются. Указать специальные параметры для общественного транспорта можно с помощью литерала объекта TransitOptions.

Для маршрутов на общественном транспорте учитывается время. Возвращаются только маршруты, которыми можно воспользоваться с момента запроса.

Литерал объекта TransitOptions содержит следующие поля:

{
  arrivalTime: Date,
  departureTime: Date,
  modes[]: TransitMode,
  routingPreference: TransitRoutePreference
}

Назначение полей:

  • arrivalTime (необязательно) – задает желательное время прибытия в объекте Date. Если указано время прибытия, то время отправления игнорируется.
  • departureTime (необязательно) – задает желательное время отправления в объекте Date. Значение переменной departureTime будет игнорироваться, если задана переменная arrivalTime. Если значения переменных departureTime и arrivalTime не заданы, будет применено текущее время.
  • modes[] (необязательно) – массив, содержащий один или несколько литералов объекта TransitMode. Это поле можно задать, только если в запрос включен ключ API. Объекты TransitMode указывают предпочитаемый способ передвижения. Допускаются следующие значения:
    • BUS – указывает, что предпочтительным способом передвижения по возможности должен быть автобус.
    • RAIL – указывает, что предпочтительным способом передвижения по возможности должен быть поезд, трамвай, метро или легкое метро.
    • SUBWAY – указывает, что предпочтительным способом передвижения по возможности должно быть метро.
    • TRAIN – указывает, что предпочтительным способом передвижения по возможности должен быть поезд.
    • TRAM – указывает, что предпочтительным способом передвижения по возможности должен быть трамвай или легкое метро.
  • routingPreference (необязательно) – задает предпочтения при передвижении на общественном транспорте. С ее помощью вы можете выбирать, какие варианты маршрутов желаете получать вместо оптимальных маршрутов по умолчанию. Значение для этого поля можно задать, только если в запросе есть ключ API. Допускаются следующие значения:
    • FEWER_TRANSFERS – указывает, что в предпочтительном маршруте должно быть как можно меньше пересадок.
    • LESS_WALKING – указывает, что в предпочтительном маршруте должно быть как можно меньшим расстояние, преодолеваемое пешком.

Ниже приведен пример запроса DirectionsRequest для передвижения на общественном транспорте:

{
  origin: 'Hoboken NJ',
  destination: 'Carroll Gardens, Brooklyn',
  travelMode: 'TRANSIT',
  transitOptions: {
    departureTime: new Date(1337675679473),
    modes: ['BUS'],
    routingPreference: 'FEWER_TRANSFERS'
  },
  unitSystem: google.maps.UnitSystem.IMPERIAL
}

Параметры автомобильных маршрутов

Конкретные параметры автомобильного маршрута можно задать с помощью объекта DrivingOptions.

Объект DrivingOptions содержит следующие поля:

{
  departureTime: Date,
  trafficModel: TrafficModel
}

Назначение полей:

  • Переменная departureTime, без которой литерал объекта drivingOptions не будет действителен, задает время отправления в объекте Date. Для этого значения должно быть установлено текущее время или момент времени в будущем. Время в прошлом указать нельзя. Чтобы избежать ошибок с часовыми поясами, API преобразует все даты в формат UTC. Для пользователей Premium-плана платформы Google Карт: если включить в запрос departureTime, API вернет оптимальный маршрут с учетом ожидаемой загруженности дорог и времени задержки в пробках (duration_in_traffic). Если время отъезда не указывать (запрос без поля drivingOptions), API вернет подходящий маршрут без учета дорожной обстановки.
  • trafficModel (необязательно) – определяет выбор модели расчета в зависимости от загруженности дорог. Этот параметр влияет на возвращаемое значение поля duration_in_traffic в ответе (прогнозируемое время в пути с учетом средних статистических показателей). Значение по умолчанию – bestguess. Допускаются следующие значения:
    • bestguess (по умолчанию) – возвращаемое в duration_in_traffic значение должно содержать наиболее вероятную оценку продолжительности поездки с учетом статистики и текущей дорожной обстановки. Чем ближе время отправления departureTime к текущему моменту, тем сильнее результат будет зависеть от текущей ситуации.
    • pessimistic – возвращаемое в duration_in_traffic значение должно быть больше фактической продолжительности поездки по этому маршруту в обычные дни (кроме дней с крайне высокой загруженностью дорог).
    • optimistic – возвращаемое в duration_in_traffic значение должно быть меньше фактической продолжительности поездки по этому маршруту в обычные дни (кроме дней с крайне низкой загруженностью дорог).

Ниже приведен запрос автомобильного маршрута DirectionsRequest:

{
  origin: 'Chicago, IL',
  destination: 'Los Angeles, CA',
  travelMode: 'DRIVING',
  drivingOptions: {
    departureTime: new Date(Date.now() + N),  // for the time N milliseconds from now.
    trafficModel: 'optimistic'
  }
}

Системы единиц

По умолчанию маршруты рассчитываются и отображаются с использованием системы единиц, применяемой в стране или регионе начальной точки. Если пункт отправления задан не адресом, а координатами, по умолчанию всегда используются метрические единицы. Например, маршрут от "Чикаго, Иллинойс" до "Торонто, Онтарио" отображает результаты в милях, а обратный маршрут – в километрах. Единицы измерения можно переопределить, передав в запросе одно из следующих значений UnitSystem:

  • UnitSystem.METRIC – определяет использование метрической системы. Расстояния отображаются в километрах.
  • UnitSystem.IMPERIAL – определяет использование британской системы (расстояние в милях).

Примечание. Этот параметр влияет только на текст, который видит пользователь. Результат также содержит значения расстояний, которые не видны пользователю. Они всегда выражаются в метрах.

Региональные особенности

Служба Google Maps API Directions возвращает адреса в зависимости от домена (страны или территории), откуда была произведена начальная загрузка сценария JavaScript. Поскольку в большинстве случаев загрузка выполняется с https://maps.googleapis.com/, неявно объявляется домен в США. Если загрузка сценария производится из другого поддерживаемого домена, то он будет учтен в возвращаемых результатах. Например, поиск "Сан-Франциско" из приложений, загружающих https://maps.googleapis.com/ (США) и http://maps.google.es/ (Испания), может дать различные результаты.

Вы можете настроить службу Directions так, чтобы результаты возвращались с предпочтением определенного региона. Для этого служит параметр region. Этот параметр принимает код региона, определенный как вложенный тег region из двух символов в формате Unicode (не цифр). Как правило, этот тег соответствует двусимвольному коду в формате ccTLD (например, "uk" в "co.uk"). В некоторых случаях тег region также поддерживает коды ISO-3166-1, которые иногда отличаются от значений ccTLD (например, GB – Великобритания).

При использовании параметра region:

  • Укажите только одну страну или регион. Если указать несколько значений, они будут проигнорированы, а выполнение запроса может завершиться ошибкой.
  • Используйте только двухсимвольные вложенные теги региона (формат CLDR Unicode). Если применить другие входные данные, возникнет ошибка.

Учет региона в запросе возможен только в странах, где поддерживается служба Directions API. Cписок таких стран и регионов вы найдете в статье Доступность сервисов платформы Google Карт.

Прорисовка маршрутов

Выполнение запроса маршрута в DirectionsService с помощью метода route() требует передачи обратного вызова, который выполняется по завершении запроса службы. В ответ возвращается объект DirectionsResult и код DirectionsStatus.

Статус запроса маршрута

Ниже перечислены возможные значения кода DirectionsStatus:

  • OK – ответ содержит допустимый DirectionsResult.
  • NOT_FOUND – не удалось найти геокод как минимум для одного местоположения, указанного в параметрах запроса, таких как пункт отправления, пункт назначения или путевая точка.
  • ZERO_RESULTS – между пунктом отправления и пунктом назначения не найдено ни одного маршрута.
  • MAX_WAYPOINTS_EXCEEDED – в запросе DirectionsRequest слишком много путевых точек DirectionsWaypoint. Ниже вы найдете более подробную информацию о лимитах.
  • MAX_ROUTE_LENGTH_EXCEEDED – запрос нельзя обработать: слишком длинный маршрут. Такая ошибка возникает, когда возвращается слишком сложный маршрут. Попробуйте сократить количество путевых точек, поворотов и инструкций.
  • INVALID_REQUEST – означает, что представленный DirectionsRequest был недопустим. Чаще всего этот код возвращается, если не указан пункт отправления или назначения либо в запрос маршрута с использованием общественного транспорта включены путевые точки.
  • OVER_QUERY_LIMIT – веб-страница отправила слишком много запросов за промежуток времени.
  • REQUEST_DENIED – веб-странице не разрешено использовать службу "Маршруты".
  • UNKNOWN_ERROR – обработка запроса маршрута невозможна из-за ошибки сервера. Если повторить попытку, запрос может оказаться успешным.

Всегда проверяйте этот код перед обработкой результата: в ответ на запрос должен быть возвращен действительный маршрут.

Отображение результата (DirectionsResult)

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

Чтобы отобразить DirectionsResult с помощью DirectionsRenderer, необходимо сделать следующее:

  1. Создайте объект DirectionsRenderer.
  2. Вызовите метод setMap() средства прорисовки для его привязки к переданной карте.
  3. Создайте объект setDirections() и передайте ему коллекцию объектов DirectionsResult. Поскольку средство прорисовки представляет собой объект MVCObject, оно автоматически находит изменения свойств маршрута и обновляет карту.

В следующем примере показан расчет маршрута по шоссе 66, где начальная и конечная точки назначаются с помощью выбора значений "start" и "end" из раскрывающихся списков. Объект DirectionsRenderer обеспечивает прорисовку ломаной линии, соединяющей начальную, конечную и путевые точки, а также маркеров на этих точках.

function initMap() {
  var directionsService = new google.maps.DirectionsService();
  var directionsRenderer = new google.maps.DirectionsRenderer();
  var chicago = new google.maps.LatLng(41.850033, -87.6500523);
  var mapOptions = {
    zoom:7,
    center: chicago
  }
  var map = new google.maps.Map(document.getElementById('map'), mapOptions);
  directionsRenderer.setMap(map);
}

function calcRoute() {
  var start = document.getElementById('start').value;
  var end = document.getElementById('end').value;
  var request = {
    origin: start,
    destination: end,
    travelMode: 'DRIVING'
  };
  directionsService.route(request, function(result, status) {
    if (status == 'OK') {
      directionsRenderer.setDirections(result);
    }
  });
}

В теле кода HTML:

<div>
<strong>Start: </strong>
<select id="start" onchange="calcRoute();">
  <option value="chicago, il">Chicago</option>
  <option value="st louis, mo">St Louis</option>
  <option value="joplin, mo">Joplin, MO</option>
  <option value="oklahoma city, ok">Oklahoma City</option>
  <option value="amarillo, tx">Amarillo</option>
  <option value="gallup, nm">Gallup, NM</option>
  <option value="flagstaff, az">Flagstaff, AZ</option>
  <option value="winona, az">Winona</option>
  <option value="kingman, az">Kingman</option>
  <option value="barstow, ca">Barstow</option>
  <option value="san bernardino, ca">San Bernardino</option>
  <option value="los angeles, ca">Los Angeles</option>
</select>
<strong>End: </strong>
<select id="end" onchange="calcRoute();">
  <option value="chicago, il">Chicago</option>
  <option value="st louis, mo">St Louis</option>
  <option value="joplin, mo">Joplin, MO</option>
  <option value="oklahoma city, ok">Oklahoma City</option>
  <option value="amarillo, tx">Amarillo</option>
  <option value="gallup, nm">Gallup, NM</option>
  <option value="flagstaff, az">Flagstaff, AZ</option>
  <option value="winona, az">Winona</option>
  <option value="kingman, az">Kingman</option>
  <option value="barstow, ca">Barstow</option>
  <option value="san bernardino, ca">San Bernardino</option>
  <option value="los angeles, ca">Los Angeles</option>
</select>
</div>

Посмотреть пример

В следующем примере показаны маршруты между районом Хейт-Эшбери (Haight-Ashbury) и пляжем Оушен-Бич (Ocean Beach) в Сан-Франциско (Калифорния, США) для разных способов передвижения:

function initMap() {
  var directionsService = new google.maps.DirectionsService();
  var directionsRenderer = new google.maps.DirectionsRenderer();
  var haight = new google.maps.LatLng(37.7699298, -122.4469157);
  var oceanBeach = new google.maps.LatLng(37.7683909618184, -122.51089453697205);
  var mapOptions = {
    zoom: 14,
    center: haight
  }
  var map = new google.maps.Map(document.getElementById('map'), mapOptions);
  directionsRenderer.setMap(map);
}

function calcRoute() {
  var selectedMode = document.getElementById('mode').value;
  var request = {
      origin: haight,
      destination: oceanBeach,
      // Note that JavaScript allows us to access the constant
      // using square brackets and a string value as its
      // "property."
      travelMode: google.maps.TravelMode[selectedMode]
  };
  directionsService.route(request, function(response, status) {
    if (status == 'OK') {
      directionsRenderer.setDirections(response);
    }
  });
}

В теле кода HTML:

<div>
<strong>Mode of Travel: </strong>
<select id="mode" onchange="calcRoute();">
  <option value="DRIVING">Driving</option>
  <option value="WALKING">Walking</option>
  <option value="BICYCLING">Bicycling</option>
  <option value="TRANSIT">Transit</option>
</select>
</div>

Посмотреть пример

Объект DirectionsRenderer не только прорисовывает ломаную линию и все маркеры, но и выводит маршрут в виде текстового описания последовательности шагов. Для этого вызовите метод setPanel() объекта DirectionsRenderer, передав ему <div>, в котором должна отображаться эта информация. Это также обеспечит показ информации об авторских правах и всех возможных предупреждений к результатам поиска.

Текстовые указания предоставляются на языке браузера или том, который был определен при загрузке интерфейса API JavaScript в параметре language (см. раздел Локализация). В маршрутов на общественном транспорте время отображается в часовом поясе остановки.

Следующий пример идентичен предыдущему, за исключением панели <div>, в которой отображается описание маршрута:

function initMap() {
  var directionsService = new google.maps.DirectionsService();
  var directionsRenderer = new google.maps.DirectionsRenderer();
  var chicago = new google.maps.LatLng(41.850033, -87.6500523);
  var mapOptions = {
    zoom:7,
    center: chicago
  }
  var map = new google.maps.Map(document.getElementById('map'), mapOptions);
  directionsRenderer.setMap(map);
  directionsRenderer.setPanel(document.getElementById('directionsPanel'));
}

function calcRoute() {
  var start = document.getElementById('start').value;
  var end = document.getElementById('end').value;
  var request = {
    origin:start,
    destination:end,
    travelMode: 'DRIVING'
  };
  directionsService.route(request, function(response, status) {
    if (status == 'OK') {
      directionsRenderer.setDirections(response);
    }
  });
}

В теле кода HTML:

<div id="map" style="float:left;width:70%;height:100%"></div>
<div id="directionsPanel" style="float:right;width:30%;height:100%"></div>

Посмотреть пример

Объект DirectionsResult

При отправке запроса маршрутов в службу DirectionsService вы получаете ответ, содержащий код состояния и результат в виде объекта DirectionsResult. DirectionsResult – это литерал объекта со следующими полями:

  • geocoded_waypoints[] содержит массив объектов DirectionsGeocodedWaypoint, каждый из которых содержит геокоды начальной, конечной и путевых точек маршрута.
  • routes[] – содержит массив объектов DirectionsRoute. Каждый маршрут указывает путь перемещения от начально до конечной точки, запрошенный в DirectionsRequest. Обычно в ответ на запрос возвращается только один маршрут, однако если в поле provideRouteAlternatives установлено значение true, может быть возвращено несколько.

Примечание. Свойство via_waypoint больше не поддерживается в альтернативных маршрутах. Версия 3.27 – последняя, в которой это свойство поддерживалось. В версиях API 3.28 и выше вы можете продолжить использование перетаскиваемых маршрутов с помощью службы Directions, если отключите перетаскивание в альтернативных маршрутах. Перетаскивание должно быть включено только для основного маршрута. Так пользователи смогут перетаскивать его, пока тот не совпадет с альтернативным.

Путевые точки с геокодами

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

DirectionsGeocodedWaypoint – это литерал объекта со следующими полями:

  • geocoder_status – код состояния, полученный от операции геокодирования. Это поле может принимать следующие значения:
    • "OK" – указывает на отсутствие ошибок. Синтаксический анализ адреса выполнен успешно. Был получен по крайней мере один геокод.
    • "ZERO_RESULTS" – означает, что геокодирование успешно выполнено, однако результаты не найдены. Такое может произойти, если геокодеру был передан несуществующий адрес address.
  • partial_match – указывает, что геокодер не вернул точное совпадение для исходного запроса, хотя и обнаружил частичное совпадение с запрашиваемым адресом. Рекомендуется проверить исходный запрос на наличие в нем опечаток и/или неполного адреса.

    В большинстве случаев частичные совпадения возникают при использовании почтовых адресов, которые отсутствуют в местности, указанной в запросе. Частичные совпадения могут также возвращаться для запросов, в которых имеется соответствие нескольким местоположениям в пределах одной местности. Например, запрос "улица Генр, Бристоль, Великобритания" вернет частично совпадающие результаты для "улица Генри" и "улица Генриетты". Обратите внимание: если запрос содержит ошибки в написании адреса, сервис геокодирования может предложить альтернативный адрес. Такие предложения также будут помечены как частичные совпадения.

  • place_id – уникальный идентификатор места, который можно использовать и с другими API Google. Например, вы можете использовать place_id с библиотекой Google Places API для получения подробной информации о местной организации (номер телефона, часы работы, отзывы клиентов и т. д.). Подробнее об ID места…
  • types[] – массив, указывающий тип возвращенного результата. Этот массив содержит набор из одного или нескольких тегов, определяющих тип возвращаемого элемента. Например, геокодирование для "Chicago" возвращает тег "locality", указывающий, что Чикаго является городом, а также тег "political", указывающий, что этот объект является также административной единицей.

Объект DirectionsRoute

Примечание. Объект DirectionsTrip был переименован в DirectionsRoute. Теперь под маршрутом подразумевается весь путь от начала до конца поездки, а не отрезок основного пути.

Объект DirectionsRoute содержит один результат для указанных начальной и конечной точек. Маршрут может состоять из одного или нескольких участков (DirectionsLeg) в зависимости от того, были ли указаны путевые точки. Также маршрут может содержать информацию об авторских правах и предупреждения, которые выводятся пользователю в дополнение к информации о маршруте.

DirectionsRoute – это литерал объекта со следующими полями:

  • legs[] – массив объектов DirectionsLeg, каждый из которых содержит информацию об отрезке между двумя точками на маршруте. Для каждой путевой или конечной точки используется отдельный отрезок (маршрут без путевых точек содержит единственный объект DirectionsLeg.) Каждый отрезок состоит из последовательности шагов DirectionStep.
  • waypoint_order – массив, определяющий порядок путевых точек на рассчитанном маршруте. Порядок может быть изменен в целях оптимизации маршрута, если объекту DirectionsRequest был передан параметр optimizeWaypoints: true.
  • overview_path – массив координат LatLng для отрисовки отрисовки приблизительной (сглаженной) линии маршрута.
  • overview_polyline – содержит единственный объект points с маршрутом в форме кодированной ломаной линии. Эта ломаная линия представляет собой приблизительный (сглаженный) отрезок маршрута.
  • bounds – массив LatLngBounds, ограничивающий отрисовку ломаной линии вдоль этого маршрута.
  • copyrights – текст об авторских правах для этого маршрута.
  • warnings[] – массив предупреждений, которые выдаются с этим маршрутом. Если вы не используете объект DirectionsRenderer, то должны сами позаботиться об обработке и показе этих предупреждений.
  • fare – общая стоимость билетов по маршруту. Возвращается только для маршрутов на общественном транспорте с доступной информацией о стоимости проезда по всем участкам. Содержит:
    • currency – код валюты ISO 4217, в которой приведена стоимость проезда;
    • value – общую стоимость проезда в этой валюте.

Отрезки маршрута

Примечание. Объект DirectionsRoute был переименован в DirectionsLeg.

DirectionsLeg – определяет один отрезок в составе вычисленного маршрута от начальной до конечной точки. Маршруты без путевых точек состоят всего из одного отрезка, а маршруты с одной или несколькими путевыми точками – из нескольких.

DirectionsLeg – это литерал объекта со следующими полями:

  • steps[] – содержит массив объектов DirectionsStep с информацией о каждом отдельном отрезке маршрута.
  • distance – указывает расстояние этого отрезка в виде поля Distance со следующими элементами:

    • value – значение в метрах.
    • text – строковое представление расстояния, по умолчанию отображается в единицах измерения, используемых в исходной точке (например, в США используются мили). Систему единиц измерения можно переопределить, задав UnitSystem в исходном запросе. Вне зависимости от используемой системы единиц измерения, поле distance.value всегда содержит значение в метрах.

    Когда расстояние неизвестно, эти поля могут быть не определены.

  • duration – указывает общую продолжительность поездки по отрезку как объект Duration следующей формы:

    • value – продолжительность в секундах.
    • text – строковое представление продолжительности.

    Когда время поездки неизвестно, эти поля могут быть не определены.

  • duration_in_traffic – общее время поездки по этому участку с учетом текущей дорожной ситуации. Значение duration_in_traffic возвращается, только если соблюдены следующие условия:

    • Запрос не содержит промежуточных остановок (нет путевых точек stopover со значением true).
    • Запрашиваются автомобильные маршруты: для параметра mode установлено значение driving.
    • Время departureTime включено в запрос в поле drivingOptions.
    • Сведения о дорожной ситуации доступны для запрошенного маршрута.

    Объект duration_in_traffic содержит следующие поля:

    • value – продолжительность в секундах.
    • text – продолжительность в удобочитаемом формате.
  • arrival_time – расчетное время прибытия в конечную точку этого участка. Это свойство возвращается только для маршрутов на общественном транспорте и выражается объектом Time со следующими атрибутами:
    • value – время в виде объекта JavaScript Date;
    • text – время в виде строкового значения (используется часовой пояс, в котором находится остановка);
    • time_zone – часовой пояс остановки в формате IANA (например, "America/New_York").
  • departure_time – примерное время начала этого отрезка, указанное в виде объекта Time. departure_time доступно только для маршрутов на общественном транспорте.
  • start_location – содержит координаты LatLng исходной точки отрезка. Для расчета маршрута служба Directions использует ближайшую к начальной и конечной точкам линию транспорта (обычно дорогу). Поэтому start_location может отличаться от указанной в запросе начальной точки отрезка (например, если дорога находится далеко от нее).
  • end_location – содержит координаты LatLng конечной точки отрезка. Для расчета маршрута служба DirectionsService использует ближайшую к начальной и конечной точкам линию транспорта (обычно дорогу). Поэтому end_location может отличаться от указанной в запросе конечной точки отрезка (например, если дорога находится далеко от нее).
  • start_address – содержит читаемый адрес (обычно улицу и номер дома) стартовой точки отрезка.

    Этот текст читается как есть. Не подставляйте отформатированный адрес программным способом.
  • end_address – содержит читаемый адрес (обычно улицу и номер дома) конечной точки отрезка.

    Этот текст читается как есть. Не подставляйте отформатированный адрес программным способом.

Шаги маршрута

DirectionsStep – самая маленькая единица измерения маршрута, которая содержит одну подсказку по маршруту (например, "Поверните налево на 4-й улице"), а также данные о расстоянии и времени поездки, позволяющие сопоставить этот шаг со следующим. Например, длительность шага "Поверните на М-80" может составлять "37 миль" или "40 минут". Это означает, что следующий шаг наступит через 37 миль или 40 минут после выполнения этого поворота.

Если маршрут вычисляется с использованием общественного транспорта, шаги могут содержать дополнительные данные в виде объекта transit. Если используются разные способы передвижения, в массив steps[] включаются шаги для пеших и автомобильных участков. Например, это может быть пеший шаг маршрута с указанием начальной и конечной точек ("Пройдите по Иннс-авеню до Фитч-стрит"). В массиве steps[] содержатся подробные подсказки, такие как "Направляйтесь на северо-восток", "Поверните налево на Арелиус-вокер", "Поверните налево на Иннс-авеню".

DirectionsStep – литерал объекта со следующими полями:

  • instructions – инструкции для этого шага в текстовой строке.
  • distance – расстояние отрезка, соответствующее шагу, в виде объекта Distance. (См. описание выше в разделе DirectionsLeg.) Если расстояние неизвестно, это поле может остаться без определения.
  • duration – приблизительное время, необходимое для прохождения этого шага, в виде объекта Duration. (См. описание выше в разделе DirectionsLeg.) Если время в пути неизвестно, это поле может быть не определено.
  • start_location – координаты LatLng начальной точки этого шага.
  • end_location – координаты LatLng конечной точки этого шага.
  • polyline – содержит единственный объект points с участком в форме кодированной ломаной линии. Эта ломаная линия представляет собой приблизительный (сглаженный) отрезок маршрута, соответствующий данному шагу.
  • steps[] (литерал объекта DirectionsStep) – содержит подробные подсказки для перемещения пешком или на общественном транспорте. Подшаги доступны только для маршрутов на общественном транспорте.
  • travel_mode – значение TravelMode для этого шага. Маршруты для общественного транспорта могут сочетать участки, преодолеваемые пешком и на транспорте.
  • path – массив координат LatLngs, описывающих путь этого шага.
  • transit – специальная информация об общественном транспорте, например время прибытия и отправления, наименование маршрута.

Данные общественного транспорта

Для маршрутов на общественном транспорте возвращается дополнительная информация, не применимая к другим способам передвижения. Эти дополнительные свойства передаются через объект TransitDetails, который возвращается как свойство объекта DirectionsStep. При помощи объекта TransitDetails, который подробно рассматривается ниже, можно получить сведения об остановках TransitStop, линиях общественного транспорта TransitLine, предоставляющих информацию транспортных агентствах TransitAgency и типах транспортных средств VehicleType.

Сведения об общественном транспорте

Ниже перечислены свойства объекта TransitDetails.

  • arrival_stop – объект TransitStop, определяющий остановку или станцию прибытия, со следующими свойствами:
    • name – название остановки общественного транспорта, например Union Square;
    • location – координаты LatLng остановки общественного транспорта.
  • departure_stop – содержит объект TransitStop, определяющий остановку или станцию отправления.
  • arrival_time – содержит время прибытия в виде объекта Time со следующими свойствами:
    • value – время в виде объекта JavaScript Date;
    • text – время в виде строки (используется часовой пояс, в котором находится остановка);
    • time_zone – часовой пояс остановки в формате IANA (например, "America/New_York").
  • departure_time – содержит время отправления в виде объекта Time.
  • headsign – направление линии общественного транспорта, в котором следует ехать (как указано на транспортном средстве или остановке). Обычно это конечная остановка маршрута.
  • headway (если доступно) – частота отправления транспорта с этой остановки в секундах. Например, если значение headway равно 600, это означает, что следующий автобус придет через 10 минут.
  • line – содержит литерал объекта TransitLine с информацией о маршруте общественного транспорта на этом шаге. TransitLine – название маршрута и обслуживающей его транспортной компании, а также другие данные, описанные в справочной документации к объекту TransitLine.
  • num_stops – содержит количество остановок на этом шаге. Включает остановку прибытия, но не остановку отъезда. Например, если вы выезжаете с остановки A, проезжаете остановки B и C и выходите на остановке D, значение num_stops будет равно 3.

Маршрут общественного транспорта

Ниже перечислены свойства объекта TransitLine.

  • name – полное название маршрута, например "7 Avenue Express" или "14th St Crosstown".
  • Поле short_name содержит краткое наименование маршрута. Как правило, это номер маршрута, например 2 или M14.
  • agencies – массив, содержащий единственный объект TransitAgency. Каждый объект TransitAgency содержит информацию об операторе этого маршрута:
    • name – полное название транспортного агентства.
    • phone – телефон транспортного агентства.
    • url – URL сайта транспортного агентства.

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

  • url – URL страницы маршрута, предоставленный транспортным агентством.
  • icon – URL значка этого маршрута. В большинстве городов используются стандартные значки для разных видов общественного транспорта. Для некоторых маршрутов общественного транспорта, таких как Нью-Йоркский метрополитен, используются специальные значки.
  • color – цвет, которым обозначается этот маршрут. Цвет указывается в виде шестнадцатеричной строки, например: #FF0033.
  • text_color – цвет текста, обычно используемого в знаках этого вида транспорта. Цвет указывается в виде шестнадцатеричной строки.
  • vehicle – содержит объект Vehicle со следующими свойствами:
    • name – тип транспортного средства на маршруте, например "метро";
    • typetype – вид транспорта на этом маршруте (см. поддерживаемые значения);
    • icon – URL значка, которым обозначается вид транспорта.
    • local_icon – содержит URL значка, которым обозначается вид транспорта в том или ином городе.

Вид транспорта

Ниже указаны свойства объекта VehicleType.

Значение Описание
VehicleType.RAIL Железная дорога
VehicleType.METRO_RAIL Легкорельсовый транспорт
VehicleType.SUBWAY Подземный легкорельсовый транспорт
VehicleType.TRAM Наземный легкорельсовый транспорт
VehicleType.MONORAIL Монорельс
VehicleType.HEAVY_RAIL Городской рельсовый транспорт
VehicleType.COMMUTER_TRAIN Электропоезд
VehicleType.HIGH_SPEED_TRAIN Скоростной поезд
VehicleType.BUS Автобус
VehicleType.INTERCITY_BUS Междугородный автобус
VehicleType.TROLLEYBUS Троллейбус
VehicleType.SHARE_TAXI Маршрутное такси (автобус с возможностью посадки и высадки в любой точке маршрута)
VehicleType.FERRY Паром
VehicleType.CABLE_CAR Канатная дорога (транспорт, обычно наземный, приводимый в движение с помощью троса). Воздушные канатные дороги могут относиться к типу VehicleType.GONDOLA_LIFT
VehicleType.GONDOLA_LIFT Воздушная канатная дорога
VehicleType.FUNICULAR Фуникулер (канатная дорога для подъема в гору, как правило, состоящая из двух вагонов, служащих противовесом друг другу)
VehicleType.OTHER Все другие транспортные средства

Проверка DirectionsResults

Компоненты DirectionsResults (DirectionsRoute, DirectionsLeg, DirectionsStep и TransitDetails) можно проверять и обрабатывать при анализе ответа.

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

В следующем примере показаны пешие маршруты к некоторым достопримечательностям Нью-Йорка. Мы проверяем объект DirectionsStep, чтобы добавить маркеры для каждого шага и присоединить информацию к InfoWindow с пояснительным текстом.

Примечание. Поскольку рассчитываются пешеходные маршруты, мы выводим предупреждения для пользователя на отдельной панели <div>.

var map;
var directionsRenderer;
var directionsService;
var stepDisplay;
var markerArray = [];

function initMap() {
  // Instantiate a directions service.
  directionsService = new google.maps.DirectionsService();

  // Create a map and center it on Manhattan.
  var manhattan = new google.maps.LatLng(40.7711329, -73.9741874);
  var mapOptions = {
    zoom: 13,
    center: manhattan
  }
  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  // Create a renderer for directions and bind it to the map.
  var rendererOptions = {
    map: map
  }
  directionsRenderer = new google.maps.DirectionsRenderer(rendererOptions)

  // Instantiate an info window to hold step text.
  stepDisplay = new google.maps.InfoWindow();
}

function calcRoute() {

  // First, clear out any existing markerArray
  // from previous calculations.
  for (i = 0; i < markerArray.length; i++) {
    markerArray[i].setMap(null);
  }

  // Retrieve the start and end locations and create
  // a DirectionsRequest using WALKING directions.
  var start = document.getElementById('start').value;
  var end = document.getElementById('end').value;
  var request = {
      origin: start,
      destination: end,
      travelMode: 'WALKING'
  };

  // Route the directions and pass the response to a
  // function to create markers for each step.
  directionsService.route(request, function(response, status) {
    if (status == "OK") {
      var warnings = document.getElementById("warnings_panel");
      warnings.innerHTML = "" + response.routes[0].warnings + "";
      directionsRenderer.setDirections(response);
      showSteps(response);
    }
  });
}

function showSteps(directionResult) {
  // For each step, place a marker, and add the text to the marker's
  // info window. Also attach the marker to an array so we
  // can keep track of it and remove it when calculating new
  // routes.
  var myRoute = directionResult.routes[0].legs[0];

  for (var i = 0; i < myRoute.steps.length; i++) {
      var marker = new google.maps.Marker({
        position: myRoute.steps[i].start_point,
        map: map
      });
      attachInstructionText(marker, myRoute.steps[i].instructions);
      markerArray[i] = marker;
  }
}

function attachInstructionText(marker, text) {
  google.maps.event.addListener(marker, 'click', function() {
    stepDisplay.setContent(text);
    stepDisplay.open(map, marker);
  });
}

В теле кода HTML:

<div>
<strong>Start: </strong>
<select id="start">
  <option value="penn station, new york, ny">Penn Station</option>
  <option value="grand central station, new york, ny">Grand Central Station</option>
  <option value="625 8th Avenue New York NY 10018">Port Authority Bus Terminal</option>
  <option value="staten island ferry terminal, new york, ny">Staten Island Ferry Terminal</option>
  <option value="101 E 125th Street, New York, NY">Harlem - 125th St Station</option>
</select>
<strong>End: </strong>
<select id="end" onchange="calcRoute();">
  <option value="260 Broadway New York NY 10007">City Hall</option>
  <option value="W 49th St & 5th Ave, New York, NY 10020">Rockefeller Center</option>
  <option value="moma, New York, NY">MOMA</option>
  <option value="350 5th Ave, New York, NY, 10118">Empire State Building</option>
  <option value="253 West 125th Street, New York, NY">Apollo Theatre</option>
  <option value="1 Wall St, New York, NY">Wall St</option>
</select>
<div>

Посмотреть пример

Путевые точки в маршрутах

В запросе DirectionsRequest для расчета пешего, автомобильного или велосипедного маршрута можно указать путевые точки (объекты типа DirectionsWaypoint). Путевые точки недоступны для маршрутов на общественном транспорте. Если вы добавите путевые точки, то рассчитанный маршрут будет проходить через них.

waypoint состоит из следующих полей:

  • location (обязательно) – адрес путевой точки.
  • stopover (необязательно) – указывает, является ли эта путевая точка остановкой на маршруте true или же маршрут просто должен проходить через указанное место false. По умолчанию применяется значение true.

По умолчанию маршрут прокладывается через путевые точки в том порядке, в котором они указаны. Также вы можете использовать параметр optimizeWaypoints: true в запросе DirectionsRequest, чтобы служба Directions могла оптимизировать маршрут, поменяв очередность путевых точек. (Эта оптимизация является практическим примером решения Задачи коммивояжера.) Время в пути является главным критерием оптимизации, но могут учитываться также расстояние, количество поворотов и прочие факторы. Для оптимизации маршрута службой Directions все путевые точки должны быть остановками.

Если дать указание службе Directions оптимизировать порядок путевых точек, их последовательность будет показана в поле waypoint_order объекта DirectionsResult.

В следующем примере приведен расчет маршрутов через Соединенные Штаты Америки с использованием разных начальных, конечных и путевых точек. (Чтобы добавить несколько путевых точек, выбирайте элементы в списке, удерживая нажатой клавишу Ctrl.) Мы проверяем routes.start_address и routes.end_address, которые предоставляют текстовые значения для начальных и конечных точек маршрута.

TypeScript

function initMap(): void {
  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer();
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 6,
      center: { lat: 41.85, lng: -87.65 },
    }
  );

  directionsRenderer.setMap(map);

  (document.getElementById("submit") as HTMLElement).addEventListener(
    "click",
    () => {
      calculateAndDisplayRoute(directionsService, directionsRenderer);
    }
  );
}

function calculateAndDisplayRoute(
  directionsService: google.maps.DirectionsService,
  directionsRenderer: google.maps.DirectionsRenderer
) {
  const waypts: google.maps.DirectionsWaypoint[] = [];
  const checkboxArray = document.getElementById(
    "waypoints"
  ) as HTMLSelectElement;

  for (let i = 0; i < checkboxArray.length; i++) {
    if (checkboxArray.options[i].selected) {
      waypts.push({
        location: (checkboxArray[i] as HTMLOptionElement).value,
        stopover: true,
      });
    }
  }

  directionsService
    .route({
      origin: (document.getElementById("start") as HTMLInputElement).value,
      destination: (document.getElementById("end") as HTMLInputElement).value,
      waypoints: waypts,
      optimizeWaypoints: true,
      travelMode: google.maps.TravelMode.DRIVING,
    })
    .then((response) => {
      directionsRenderer.setDirections(response);

      const route = response.routes[0];
      const summaryPanel = document.getElementById(
        "directions-panel"
      ) as HTMLElement;

      summaryPanel.innerHTML = "";

      // For each route, display summary information.
      for (let i = 0; i < route.legs.length; i++) {
        const routeSegment = i + 1;

        summaryPanel.innerHTML +=
          "<b>Route Segment: " + routeSegment + "</b><br>";
        summaryPanel.innerHTML += route.legs[i].start_address + " to ";
        summaryPanel.innerHTML += route.legs[i].end_address + "<br>";
        summaryPanel.innerHTML += route.legs[i].distance!.text + "<br><br>";
      }
    })
    .catch((e) => window.alert("Directions request failed due to " + status));
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer();
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 6,
    center: { lat: 41.85, lng: -87.65 },
  });

  directionsRenderer.setMap(map);
  document.getElementById("submit").addEventListener("click", () => {
    calculateAndDisplayRoute(directionsService, directionsRenderer);
  });
}

function calculateAndDisplayRoute(directionsService, directionsRenderer) {
  const waypts = [];
  const checkboxArray = document.getElementById("waypoints");

  for (let i = 0; i < checkboxArray.length; i++) {
    if (checkboxArray.options[i].selected) {
      waypts.push({
        location: checkboxArray[i].value,
        stopover: true,
      });
    }
  }

  directionsService
    .route({
      origin: document.getElementById("start").value,
      destination: document.getElementById("end").value,
      waypoints: waypts,
      optimizeWaypoints: true,
      travelMode: google.maps.TravelMode.DRIVING,
    })
    .then((response) => {
      directionsRenderer.setDirections(response);

      const route = response.routes[0];
      const summaryPanel = document.getElementById("directions-panel");

      summaryPanel.innerHTML = "";

      // For each route, display summary information.
      for (let i = 0; i < route.legs.length; i++) {
        const routeSegment = i + 1;

        summaryPanel.innerHTML +=
          "<b>Route Segment: " + routeSegment + "</b><br>";
        summaryPanel.innerHTML += route.legs[i].start_address + " to ";
        summaryPanel.innerHTML += route.legs[i].end_address + "<br>";
        summaryPanel.innerHTML += route.legs[i].distance.text + "<br><br>";
      }
    })
    .catch((e) => window.alert("Directions request failed due to " + status));
}

window.initMap = initMap;

Лимиты и ограничения для путевых точек

Действуют следующие лимиты и ограничения:

  • Максимальное допустимое количество путевых точек при использовании службы Directions в Maps JavaScript API равно 25, плюс начальная и конечная. Такие же лимиты Directions API действуют и для веб-сервисов.
  • Для пользователей веб-службы Directions API ограничение составляет 25 точек, плюс начальная и конечная.
  • Для пользователей Premium-плана платформы Google Карт ограничение составляет 25 точек, плюс начальная и конечная.
  • Путевые точки не поддерживаются в маршрутах на общественном транспорте.

Перетаскиваемые маршруты

Пользователи смогут перетаскивать велосипедные, пешие или автомобильные маршруты, отрисованные с помощью объекта DirectionsRenderer, если вы установили для свойства draggable значение true. Маршруты на общественном транспорте нельзя сделать перетаскиваемыми.

Если маршрут перетаскиваемый, пользователь может выбрать любую точку пути (или путевую точку) на полученном изображении и переместить эту точку в новое место. DirectionsRenderer динамически обновится, чтобы отрисовать измененный путь. Когда пользователь отпустит кнопку мыши, на карте появится промежуточная путевая точка, обозначенная маленьким белым маркером. Если вы перетащите отрезок, то будет изменен участок маршрута, а если перетащите путевую точку (включая начальную и конечную) – будут изменены участки маршрута, проходящие через нее.

Поскольку перетаскиваемые маршруты изменяются и отрисовываются на стороне клиента, приложению нужно отслеживать и обрабатывать событие directions_changed объекта DirectionsRenderer – оно информирует приложение об изменении, внесенном пользователем.

В примере ниже задан маршрут из Перта в Сидней (с западного на восточное побережье Австралии). Коде отслеживает событие directions_changed, чтобы обновлять данные о суммарном расстоянии всех отрезков пути.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -24.345, lng: 134.46 }, // Australia.
    }
  );

  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer({
    draggable: true,
    map,
    panel: document.getElementById("panel") as HTMLElement,
  });

  directionsRenderer.addListener("directions_changed", () => {
    const directions = directionsRenderer.getDirections();

    if (directions) {
      computeTotalDistance(directions);
    }
  });

  displayRoute(
    "Perth, WA",
    "Sydney, NSW",
    directionsService,
    directionsRenderer
  );
}

function displayRoute(
  origin: string,
  destination: string,
  service: google.maps.DirectionsService,
  display: google.maps.DirectionsRenderer
) {
  service
    .route({
      origin: origin,
      destination: destination,
      waypoints: [
        { location: "Adelaide, SA" },
        { location: "Broken Hill, NSW" },
      ],
      travelMode: google.maps.TravelMode.DRIVING,
      avoidTolls: true,
    })
    .then((result: google.maps.DirectionsResult) => {
      display.setDirections(result);
    })
    .catch((e) => {
      alert("Could not display directions due to: " + e);
    });
}

function computeTotalDistance(result: google.maps.DirectionsResult) {
  let total = 0;
  const myroute = result.routes[0];

  if (!myroute) {
    return;
  }

  for (let i = 0; i < myroute.legs.length; i++) {
    total += myroute.legs[i]!.distance!.value;
  }

  total = total / 1000;
  (document.getElementById("total") as HTMLElement).innerHTML = total + " km";
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -24.345, lng: 134.46 }, // Australia.
  });
  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer({
    draggable: true,
    map,
    panel: document.getElementById("panel"),
  });

  directionsRenderer.addListener("directions_changed", () => {
    const directions = directionsRenderer.getDirections();

    if (directions) {
      computeTotalDistance(directions);
    }
  });
  displayRoute(
    "Perth, WA",
    "Sydney, NSW",
    directionsService,
    directionsRenderer
  );
}

function displayRoute(origin, destination, service, display) {
  service
    .route({
      origin: origin,
      destination: destination,
      waypoints: [
        { location: "Adelaide, SA" },
        { location: "Broken Hill, NSW" },
      ],
      travelMode: google.maps.TravelMode.DRIVING,
      avoidTolls: true,
    })
    .then((result) => {
      display.setDirections(result);
    })
    .catch((e) => {
      alert("Could not display directions due to: " + e);
    });
}

function computeTotalDistance(result) {
  let total = 0;
  const myroute = result.routes[0];

  if (!myroute) {
    return;
  }

  for (let i = 0; i < myroute.legs.length; i++) {
    total += myroute.legs[i].distance.value;
  }

  total = total / 1000;
  document.getElementById("total").innerHTML = total + " km";
}

window.initMap = initMap;
Посмотреть пример

Примеры кода