Wyszukiwanie na trasie za pomocą interfejsu Places API

Z tego dokumentu dowiesz się, jak znaleźć hotel, restaurację lub stację paliw na zaplanowanej trasie. Dowiedz się, jak użyć interfejsu Routes API, aby uzyskać ścieżkę w formie polilinii, i jak użyć jej w zapytaniu Search Along Route (SAR) w interfejsie Places API. Dowiesz się też, jak uzyskać najlepsze wyniki, ustawiając punkt początkowy wyszukiwania na trasie, np. 2 godziny od rozpoczęcia podróży.

Routes API

Aby wyszukiwać miejsca na trasie, użyjemy interfejsu Routes API. Dane trasy z odpowiedzi interfejsu Routes API to seria współrzędnych LatLong od punktu początkowego do docelowego. Dane trasy zawierają odcinki i kroki, które podążają za siecią drogową.

Trasy są też zwracane jako zakodowana linia wielokąta, którą przekazujesz jako parametr wejściowy do żądania SAR. Kodowanie ścieżki to algorytm kompresji bezstratnej, który umożliwia przechowywanie serii współrzędnych w jednym ciągu. Pobieranie łańcucha znaków z interfejsu Routes API nie jest obowiązkowe. Możesz samodzielnie utworzyć dane, ale w tym przykładzie interfejs Routes API jest szybkim i pewnym sposobem na uzyskanie wymaganych danych.

W tym samouczku użyjemy trasy z Londynu (-37.8167,144.9619) do Manchesteru (-37.8155, 144.9663).

Trasa z Londynu do Manchesteru

Trasa w przykładzie: z Londynu do Manchesteru

Krok 1. Pobierz trasę z interfejsu Routes API

Aby uzyskać trasę z interfejsu Routes API, musisz podać te informacje:

  • Miejsce początkowe i miejsce docelowe
  • Środek transportu (jazda samochodem, chodzenie itp.)
  • Punkty pośrednie (opcjonalnie)
  • wszelkie preferencje (np. unikanie dróg płatnych, autostrad itp.);
  • Preferencje kierowania uwzględniające ruch zapewnią Ci najdokładniejsze szacunki, ale będą wymagać więcej zasobów obliczeniowych, co wydłuży czas oczekiwania na odpowiedź.
{"origin":{
    "location": {
        "latLng":{
            "latitude":  -37.8167,
            "longitude": 144.9619
        }
    }
},
"destination":{
    "location": {
        "latLng":{
            "latitude":-37.8155,
            "longitude": 144.9663
        }
    }
},
"routingPreference":"TRAFFIC_AWARE",
"travelMode":"DRIVE"
}

Podczas wywoływania funkcji pamiętaj, aby w polu maski nagłówków umieścić pole „encodedPolyline”.

headers = {
    "Content-Type": "application/json",
    "X-Goog-FieldMask": "routes.distanceMeters,routes.duration,routes.legs,routes.polyline.encodedPolyline"
}

Pełna dokumentacja z przykładami korzystania z funkcji getRoutegetRoutePolyline.

Gdy podasz te informacje w żądaniu, interfejs Routes API zwróci obiekt route. Obiekt trasy zawiera te informacje:

  • Całkowita odległość trasy
  • Łączny czas trwania trasy
  • Odcinki i etapy trasy
  • Zakodowana linia łamana trasy, jej etapów i kroków.
{
  "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

Krok 2. Wyszukaj informacje na trasie

Interfejs Places API Text Search udostępnia żądanie wyszukiwania na trasie, które umożliwia wyszukiwanie miejsc na trasie. Aby przesłać prośbę o wyszukiwanie wzdłuż trasy, musisz podać te informacje:

  • Pole maski określające, które pola są zwracane w odpowiedzi
  • ważny klucz API dla interfejsu API włączonego w konsoli Google Cloud;
  • tekst wyszukiwania określający, czego szukasz, np. „pikantna restauracja wegetariańska”;
  • zakodowana linia łamana trasy pobrana z poprzedniego wywołania interfejsu Routes API,
  • Adres URL punktu końcowego interfejsu Places Text Search API
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)

Przykładowe dane żądania

Prośba o wyszukiwanie na trasie zwróci listę miejsc znajdujących się na trasie. Oto krótki fragment przykładowych danych. Długość odpowiedzi można ograniczyć, ustawiając maksymalną liczbę parametrów wyników, a dodanie kolejnych pól zwiększa oczywiście ilość otrzymywanych danych. Więcej informacji o odpowiedzi interfejsu Places API znajdziesz w dokumentacji.

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

Przykładowe dane odpowiedzi

Podsumowanie trasy i czasy objazdu

Znajdowanie tylko lokalizacji jest świetne, ale warto dodać informacje o tym, ile czasu zajmuje dotarcie do tych miejsc. Wyszukiwanie w interfejsie Places API może też zwracać pole podsumowanie trasy, które zawiera zarówno czas, jak i odległość do przebycia. Pole danych routing summaries jest podrzędne względem głównego elementu odpowiedzi, dlatego w masce pola nie można uwzględnić prefiksu „places.”.

'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel,routingSummaries'

Aby uzyskać podsumowania, musisz też podać parametr lokalizacji źródłowej w wyszukiwaniu, który jest używany do obliczeń.

"routingParameters": {
      "origin": {
        "latitude":  -37.8167,
        "longitude": 144.9619
      }
    }

Gdy otrzymasz odpowiedź, zobaczysz nową sekcję z podsumowaniem trasy, która zawiera odcinki z czasem trwania i odległością w metrach.

"routingSummaries": [
    {
      "legs": [
        {
          "duration": "662s",
          "distanceMeters": 3093
        }
      ]
    },

Teraz wyjaśnimy, jak określić, gdzie na trasie ma się rozpocząć wyszukiwanie.

Krok 3. Uzyskaj lokalizację po 2 godzinach od rozpoczęcia trasy

Weź pod uwagę normalny przypadek użycia, gdy kierowca chce znaleźć restauracje nie na początku trasy, ale dalej. W naszym przykładzie podróż z Londynu do Manchesteru trwa około 4 godzin. Kierowca chce znaleźć restaurację w odległości 2 godziny od miejsca docelowego. Z tego żądania wynika, że czas trwania to 120 minut * 60 sekund = 7200 sekund.

W odpowiedzi interfejsu Routes API otrzymujemy czas trwania każdego etapu trasy oraz każdego kroku etapu. Pamiętaj, aby w prośbie uwzględnić pole „legs”. Przechodź przez etapy i kroki, aż łączny czas osiągnie 2 godziny lub limit 7200 sekund. Następnie znaleźliśmy odcinek i krok, które mają być ustawione jako źródło żądania SAR

Aby przyspieszyć pracę, możesz wypróbować bibliotekę polyline dla Pythona. Możesz go użyć do uzyskania współrzędnych z pola danych polyline.endodedPolyline.

Uruchom te polecenia w terminalu środowiska.

> 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

Teraz, gdy znaleźliśmy lokalizację na trasie, która jest 2 godziny w drodze, możemy użyć jej w prośbie. Wystarczy dodać współrzędne geograficzne w parametrze „origin”, który jest częścią parametru „routingParameters”. Zalecamy pole danych „routingSummaries”, o którym była mowa wcześniej. Możesz też dodać dodatkowe parametry, takie jak tryb podróży i instrukcje dotyczące unikania opłat za przejazd.


"routingParameters": {
    "origin": {
      "latitude": xx.xxxx,
      "longitude": yy.yyyy
    },
    "travelMode":"DRIVE",
    "routeModifiers": {
      "avoidTolls": true
    }
  }

Trasa z wynikami wyszukiwania

Przykładowe wyniki (ikona samochodu dodana, aby pokazać źródło wyszukiwania).

Jak widać na obrazku, interfejs API zwraca miejsca, które są zorientowane na koniec trasy, a wyniki zaczynają się mniej więcej w połowie podróży. Wyszukiwanie nadal korzysta z tych samych danych z platformy Mapy Google, które biorą pod uwagę trafność miejsca i odległość między innymi czynnikami.

Podsumowanie

Z tego samouczka dowiesz się, jak połączyć 2 interfejsy API Google Maps Platform – Routes i Places – aby zaplanować podróż i znaleźć miejsca, w których można zjeść posiłek po 2 godzinach podróży. Aby uzyskać najlepsze wyniki, musisz pobrać zakodowaną linię łamaną zawierającą współrzędne szerokości i długości geograficznej dla każdego kroku trasy oraz ustawić źródło żądania wyszukiwania wzdłuż trasy.

Ta funkcja dodaje nowe, zaawansowane narzędzie do dotychczasowych opcji wyszukiwania tekstowego i wyszukiwania w pobliżu dostępnych w interfejsie Places API. Kolejnym logicznym krokiem będzie dodanie usług lokalizacyjnych, aby można było użyć lokalizacji kierowcy jako punktu początkowego do znalezienia optymalnego miejsca wyszukiwania. Ta funkcja działałaby też doskonale w połączeniu z asystentem głosowym w samochodzie, któremu można by podać preferowane opcje dotyczące restauracji.

Dalsze działania

Sugerowane materiały dodatkowe:

Współtwórcy

Dokument ten jest utrzymywany przez Google. Pierwotnie został on napisany przez tego współtwórcę.

Główny autor: Mikko Toivanen | inżynier ds. rozwiązań Google Maps Platform