В этом документе описывается, как найти отель, ресторан или заправку на запланированном маршруте. Вы узнаете, как использовать Routes API для получения ломаной линии маршрута и использовать её с запросом Places API Search Along Route (SAR). Вы также узнаете, как получить наилучшие результаты, установив начало поиска на маршруте, например, через 2 часа после начала поездки.
API маршрутов
Для поиска мест на маршруте мы воспользуемся API маршрутов. Данные маршрута из ответа API маршрутов представляют собой последовательность координат LatLong от начальной точки до конечной. Данные маршрута содержат этапы и шаги, соответствующие дорожной сети.
Маршруты также возвращаются в виде закодированной ломаной линии , которую вы передаёте в качестве входного параметра в запрос SAR. Кодирование ломаной линии — это алгоритм сжатия с потерями, позволяющий хранить ряд координат в виде одной строки. Получение ломаной линии из Routes API не является обязательным. Вы можете создать данные самостоятельно, но для целей данного примера Routes API — это быстрый и надёжный способ получить необходимые данные.
В этом уроке мы используем маршрут из Лондона (-37.8167,144.9619) в Манчестер (-37.8155, 144.9663).
Маршрут в примере: Лондон — Манчестер
Шаг 1: Получите маршрут из Routes API
Чтобы получить маршрут из Routes API, вам необходимо предоставить следующую информацию:
- Место отправления и пункт назначения
- Способ передвижения (на автомобиле, пешком и т. д.)
- Любые путевые точки (необязательно)
- Любые предпочтения (избегать платных дорог, избегать автомагистралей и т. д.)
- Предпочтения в отношении маршрутизации с учетом трафика дадут вам наиболее точные оценки, но это более трудоемкая операция с точки зрения вычислений и, следовательно, увеличивает задержку ответа.
{"origin":{
"location": {
"latLng":{
"latitude": -37.8167,
"longitude": 144.9619
}
}
},
"destination":{
"location": {
"latLng":{
"latitude":-37.8155,
"longitude": 144.9663
}
}
},
"routingPreference":"TRAFFIC_AWARE",
"travelMode":"DRIVE"
}
При выполнении вызова обязательно включите поле «encodedPolyline» в маску полей заголовков.
headers = {
"Content-Type": "application/json",
"X-Goog-FieldMask": "routes.distanceMeters,routes.duration,routes.legs,routes.polyline.encodedPolyline"
}
Полная документация с примерами того, как получить маршрут и получить полилинии маршрута .
После того, как вы предоставите эту информацию в запросе, API маршрутов вернет объект маршрута. Объект маршрута будет содержать следующую информацию:
- Общая протяженность маршрута
- Общая продолжительность маршрута
- Этапы и этапы маршрута
- Закодированная полилиния маршрута, этапов и ступеней.
{
"routes": [
{
"legs": [
{
"distanceMeters": 321799,
"duration": "15401s",
"staticDuration": "14518s",
"polyline": {
"encodedPolyline": "y_kyH`_XOr@q@xKGnBBZ|AlGPj@Y^k@^MEqAfAQLK?eI … <rest of content removed for readability>"
},
"startLocation": {
"latLng": {
"latitude": 51.507334500000006,
"longitude": -0.1280107
}
},
"endLocation": {
"latLng": {
"latitude": 53.4808513,
"longitude": -2.2425864
}
},
"steps": [
{
"distanceMeters": 320,
"staticDuration": "82s",
"polyline": {
"encodedPolyline": "y_kyH`_XOr@q@xKGnBBZ|AlG"
},
"startLocation": {
"latLng": {
"latitude": 51.507334500000006,
"longitude": -0.1280107
}
},
"endLocation": {
"latLng": {
"latitude": 51.507207,
"longitude": -0.1323681
}
},
"navigationInstruction": {
"maneuver": "DEPART",
"instructions": "Head northwest on Trafalgar Sq/A4 toward Spring Gardens\nContinue to follow A4\nLeaving toll zone\nEntering toll zone\nLeaving toll zone in 210m at Haymarket"
},
"localizedValues": {
"distance": {
"text": "0.3 km"
},
"staticDuration": {
"text": "1 min"
}
},
# rest of the response removed for readability
Шаг 2: Поиск по запросу «Маршрут»
В текстовом поиске Places API есть запрос «Поиск вдоль маршрута», который позволяет искать места вдоль маршрута. Для выполнения запроса «Поиск вдоль маршрута» вам необходимо предоставить следующую минимальную информацию:
- Маска поля, поля которого возвращаются в ответе
- Действительный ключ API для API, включенного в консоли Google Cloud.
- Введите текстовую строку поиска, указывающую, какие места вы ищете, например, «острый вегетарианский ресторан».
- Закодированная полилиния маршрута, полученная из предыдущего вызова API маршрутов
- URL для конечной точки API текстового поиска Places
import requests
url = 'https://places.googleapis.com/v1/places:searchText'
api_key = 'YOUR_API_KEY' # Replace with your actual API key
route_polyline = 'YOUR_ROUTE_POLYLINE' # Replace with your encoded route polyline
headers = {
'Content-Type': 'application/json',
'X-Goog-Api-Key': api_key,
'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel'
}
data = {
"textQuery":
"Spicy Vegetarian Food",
"searchAlongRouteParameters": {
"polyline": {
"encodedPolyline": route_polyline
}
}
}
response = requests.post(url, headers=headers, json=data)
Пример запроса данных
Запрос «Поиск вдоль маршрута» вернёт список мест, расположенных вдоль маршрута. Ниже приведён краткий фрагмент примера данных. Длина ответа может быть ограничена установкой максимального количества параметров результата, а добавление дополнительных полей, естественно, увеличивает объём получаемых данных. Подробнее об ответе API Places см. в документации .
{
"places": [
{
"formattedAddress": "33 Haymarket, London SW1Y 4HA, UK",
"displayName": {
"text": "xxx",
"languageCode": "en"
}
},
{
"formattedAddress": "224 Piccadilly, London W1J 9HP, UK",
"priceLevel": "PRICE_LEVEL_MODERATE",
"displayName": {
"text": "yyy",
"languageCode": "en"
}
},
{
"formattedAddress": "63 Neal St, London WC2H 9PJ, UK",
"displayName": {
"text": "zzz",
"languageCode": "en"
}
},
Пример данных ответа
Сводка маршрута и время объезда
Поиск только местоположений — это хорошо, но будет полезно добавить информацию о времени, которое занимает поездка до них. SAR в текстовом поиске Places API также может возвращать поле с данными о маршруте , содержащее как длительность, так и расстояние в пути. Поле данных с данными о маршруте является дочерним элементом корневого элемента ответа, поэтому префикс « places. » в маске поля включать нельзя.
'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel,routingSummaries'
Чтобы получить сводки, необходимо также указать параметр местоположения источника поиска, который будет использоваться для расчетов.
"routingParameters": {
"origin": {
"latitude": -37.8167,
"longitude": 144.9619
}
}
При получении ответа в нем будет новый раздел со сводкой маршрута , содержащей этапы с указанием продолжительности и расстояния в метрах.
"routingSummaries": [
{
"legs": [
{
"duration": "662s",
"distanceMeters": 3093
}
]
},
Далее мы рассмотрим, как можно определить, с какой точки маршрута начать поиск.
Шаг 3: Определите местоположение через 2 часа по маршруту
Рассмотрим обычный сценарий использования: водитель хочет найти рестораны не в начале маршрута, а дальше по дороге. В нашем примере поездка из Лондона в Манчестер занимает около 4 часов. Водитель хочет найти ресторан, расположенный через 2 часа пути. Этот запрос даёт нам длительность поездки 120 минут * 60 секунд = 7200 секунд.
В ответе API маршрутов указана длительность каждого этапа маршрута и каждого этапа. Обязательно включите поле « legs » в маску полей запроса. Перебирайте этапы и этапы, пока суммарная длительность не достигнет предела в 2 часа или 7200 секунд. Таким образом, мы находим этап и этап, которые следует указать в качестве отправной точки запроса SAR.
Чтобы ускорить работу, попробуйте библиотеку полилиний для Python . С её помощью можно получить координаты из поля данных « polyline.endodedPolyline» .
Выполните следующие команды в терминале вашей среды.
> pip install polyline
import requests
import polyline
# We've covered getting a Routes API response earlier,
data = response.json()
# Extract the first route and its encoded polyline
route = data["routes"][0]
polyline_points = polyline.decode(route["polyline"]["encodedPolyline"])
# Calculate total duration of the route in seconds
total_duration_seconds = route["duration"]
# Calculate the desired time offset in seconds, 2h = 120 minutes * 60
desired_time_offset_seconds = time_offset_minutes * 60
# Iterate through the legs and steps to find the point at the desired time offset
elapsed_time_seconds = 0
for leg in route["legs"]:
for step in leg["steps"]:
step_duration_seconds = step["staticDuration"]
# Check if the desired time offset falls within this step, remove last "s" from string and convert to int
second_value = int(step_duration_seconds[:-1])
if elapsed_time_seconds + second_value >= desired_time_offset_seconds:
# Interpolate to find the exact point within the step
fraction_of_step = (desired_time_offset_seconds - elapsed_time_seconds) / second_value
step_polyline_points = polyline.decode(step["polyline"]["encodedPolyline"])
index = int(len(step_polyline_points) * fraction_of_step)
return step_polyline_points[index]
elapsed_time_seconds += second_value
# If the point is not found (e.g., time offset exceeds route duration)
return None
Теперь, когда мы нашли местоположение на маршруте, до которого осталось два часа, мы можем использовать его в запросе. Просто добавьте широту и долготу в параметр «origin», который, в свою очередь, является частью параметра «routingParameters». Рекомендуется использовать поле данных «routingSummaries», о котором мы говорили ранее. Вы также можете добавить дополнительные параметры, такие как способ передвижения и инструкции по объезду платных дорог, если хотите.
"routingParameters": {
"origin": {
"latitude": xx.xxxx,
"longitude": yy.yyyy
},
"travelMode":"DRIVE",
"routeModifiers": {
"avoidTolls": true
}
}
Примеры результатов (добавлен значок автомобиля для обозначения источника поиска).
Как видно на изображении, API возвращает места, смещенные ближе к концу маршрута, начиная примерно с середины. Поиск по-прежнему основан на тех же данных платформы Google Карт, которые учитывают релевантность места и расстояние до него, а также другие факторы.
Заключение
В этом уроке мы узнали, как объединить два API платформы Google Карт, Routes и Places, чтобы спланировать поездку и найти места, где можно поесть, уже через два часа. Необходимо получить закодированную ломаную линию с координатами широты и долготы для каждого этапа пути и задать источник запроса Search Along Route для получения наилучших результатов.
Эта функция добавляет мощный новый инструмент к уже существующему текстовому поиску и поиску поблизости, доступным в API Places. Логичным продолжением было бы добавление сервисов определения местоположения, чтобы вы могли использовать местоположение водителя в качестве отправной точки для поиска оптимального места поиска. Кроме того, эта функция будет идеально работать с голосовым помощником в автомобиле, которому вы сможете озвучивать предпочтительные рестораны.
Следующие действия
- Попробуйте примеры в документации.
- Оставить отзыв.
Рекомендуемая дополнительная литература:
Авторы
Этот документ поддерживается Google. Его автором является следующий участник.
Основной автор: Микко Тойванен | Инженер по решениям платформы Google Maps