Pesquisar no trajeto com a API Places

Este documento descreve como encontrar um hotel, um restaurante ou um posto de combustível ao longo de um trajeto planejado. Você vai aprender a usar a API Routes para receber uma polilinha de rota e usá-la com uma solicitação Pesquisar ao longo do trajeto (SAR) da API Places. Você também vai aprender a definir a origem da pesquisa ao longo do trajeto para ter os melhores resultados, por exemplo, duas horas após o início da viagem.

API Routes

Para pesquisar lugares ao longo da rota, vamos usar a API Routes. Os dados de rota da resposta da API Routes são uma série de coordenadas LatLong da origem ao destino. Os dados de trajeto contêm trechos e etapas que seguem a malha rodoviária.

As rotas também são retornadas como uma polilinha codificada, que você transmite como um parâmetro de entrada para a solicitação de SAR. A codificação de polilinhas é um algoritmo de compactação com perdas que permite armazenar uma série de coordenadas como uma única string. Não é obrigatório receber a polilinha da API Routes. Você pode criar os dados por conta própria, mas, para fins deste exemplo, a API Routes é uma maneira rápida e segura de conseguir os dados necessários.

Neste tutorial, usamos uma rota de Londres (-37.8167,144.9619) para Manchester (-37.8155, 144.9663).

Trajeto de Londres para Manchester

Trajeto no exemplo: Londres para Manchester

Etapa 1: receber uma rota da API Routes

Para receber uma rota da API Routes, você precisa fornecer as seguintes informações:

  • Os locais de origem e destino
  • O meio de transporte (carro, caminhada etc.)
  • Quaisquer pontos de referência (opcional)
  • Quaisquer preferências (evitar pedágios, rodovias etc.)
  • A preferência de roteamento com reconhecimento de tráfego oferece as estimativas mais precisas, mas é uma operação computacionalmente mais pesada e, portanto, aumenta a latência da resposta.
{"origin":{
    "location": {
        "latLng":{
            "latitude":  -37.8167,
            "longitude": 144.9619
        }
    }
},
"destination":{
    "location": {
        "latLng":{
            "latitude":-37.8155,
            "longitude": 144.9663
        }
    }
},
"routingPreference":"TRAFFIC_AWARE",
"travelMode":"DRIVE"
}

Ao fazer a chamada, inclua o campo "encodedPolyline" na máscara de campo de cabeçalhos.

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

A documentação completa com exemplos de como receber uma rota e receber polilinhas de rota.

Depois que você fornecer essas informações na solicitação, a API Routes vai retornar um objeto de rota. O objeto de rota vai conter as seguintes informações:

  • A distância total do trajeto
  • A duração total do trajeto
  • As pernas e etapas do trajeto
  • A polilinha codificada da rota, dos trechos e das etapas.
{
  "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

Etapa 2: solicitação de pesquisa ao longo do trajeto

A Pesquisa de texto da API Places tem uma solicitação de pesquisa ao longo do trajeto que permite pesquisar lugares ao longo de um trajeto. Para fazer uma solicitação de pesquisa ao longo da rota, você precisa fornecer as seguintes informações mínimas:

  • Máscara de campo dos campos retornados na resposta.
  • Uma chave de API válida para a API ativada no console do Google Cloud
  • String de texto de pesquisa informando os lugares que você está procurando, por exemplo, "restaurante vegetariano apimentado"
  • A polilinha codificada da rota, recuperada da chamada anterior da Routes API
  • URL do endpoint da API Places Text Search.
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)

Exemplo de dados de solicitação

A solicitação de pesquisa ao longo da rota retorna uma lista de lugares localizados ao longo do trajeto. Confira uma pequena parte dos dados de exemplo. O tamanho da resposta pode ser limitado definindo o número máximo de parâmetros de resultados e adicionando mais campos, o que aumenta a quantidade de dados recebidos. Para mais detalhes sobre a resposta da API Places, consulte a documentação.

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

Exemplo de dados de resposta

Resumo do trajeto e tempos de desvio

Encontrar apenas os locais é ótimo, mas seria útil adicionar informações sobre quanto tempo leva para chegar a esses lugares. A SAR na Pesquisa de texto da API Places também pode retornar um campo resumos de rotas que contém a duração e a distância a serem percorridas. O campo de dados "Resumos de rotas" é um filho da raiz da resposta. Portanto, não inclua o prefixo "places." na máscara de campo.

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

Para receber os resumos, você também precisa fornecer o parâmetro de local de origem para a pesquisa, que é usado nos cálculos.

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

Quando você recebe a resposta, ela tem uma nova seção com um resumo do trajeto que contém trechos com duração e distância em metros.

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

Em seguida, vamos ver como definir onde ao longo da rota iniciar a pesquisa.

Etapa 3: receber a localização 2 horas ao longo do trajeto

Considere um caso de uso normal em que o motorista quer encontrar restaurantes não no início do trajeto, mas mais adiante. No nosso exemplo, a viagem de Londres para Manchester dura cerca de 4 horas. O motorista quer encontrar um restaurante a 2 horas do trajeto. Essa solicitação nos dá a duração de 120 minutos * 60 segundos = 7.200 segundos.

Na resposta da API Routes, temos a duração de cada trecho da rota e cada etapa de um trecho. Inclua o campo "legs" na máscara de campo da sua solicitação. Faça um loop pelas pernas e etapas até que a duração acumulada atinja o limite de 2 horas ou 7.200 segundos. Assim, encontramos a perna e a etapa que serão definidas como a origem da solicitação de SAR.

Para acelerar seu trabalho, experimente a biblioteca de polilinhas para Python. Você pode usar esse campo para receber as coordenadas do campo de dados polyline.encodedPolyline".

Execute os seguintes comandos no terminal do ambiente.

> 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

Agora que encontramos o local na rota que fica a duas horas da viagem, podemos usar isso na solicitação. Basta adicionar a latitude e a longitude no parâmetro "origin", que faz parte do parâmetro "routingParameters". O campo de dados "routingSummaries", que abordamos anteriormente, é recomendado. Você também pode adicionar outros parâmetros, como modo de viagem e instruções para evitar pedágios, se quiser.


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

Rota com resultados da pesquisa

Exemplo de resultados (ícone de carro adicionado para mostrar a origem da pesquisa).

Como você pode ver na imagem, a API retorna lugares que são tendenciosos para o final da rota, com resultados começando por volta da metade da viagem. A pesquisa ainda é feita com os mesmos dados da Plataforma Google Maps, que consideram a relevância do lugar e a distância, entre outros fatores.

Conclusão

Neste tutorial, aprendemos a combinar duas APIs da Plataforma Google Maps, Routes e Places, para planejar uma viagem e encontrar lugares para comer após duas horas de viagem. As etapas necessárias são: receber uma polilinha codificada com as coordenadas de latitude e longitude de cada etapa do trajeto e definir a origem da solicitação "Pesquisar ao longo do trajeto" para ter os melhores resultados.

Esse recurso adiciona uma nova ferramenta poderosa à pesquisa de texto e à pesquisa nas proximidades já disponíveis na API Places. A próxima etapa lógica seria adicionar serviços de localização para usar a localização do motorista como ponto de partida para encontrar a origem ideal da pesquisa. Além disso, esse recurso funcionaria perfeitamente com um assistente de voz no carro, em que você poderia falar suas opções de restaurantes preferidas.

Próximas ações

Leituras recomendadas:

Colaboradores

O Google mantém este documento. O seguinte colaborador escreveu originalmente:

Autor principal: Mikko Toivanen | Engenheiro de soluções da Plataforma Google Maps