Rechercher sur le trajet avec l'API Places

Ce document explique comment trouver un hôtel, un restaurant ou une station-service sur un trajet planifié. Vous allez apprendre à utiliser l'API Routes pour obtenir une polyligne de parcours et l'utiliser avec la requête Search Along Route (SAR) de l'API Places. Vous découvrirez également comment obtenir les meilleurs résultats en définissant le point de départ de la recherche sur l'itinéraire, par exemple deux heures après le début du trajet.

API Routes

Pour rechercher des lieux le long de l'itinéraire, nous allons utiliser l'API Routes. Les données de route de la réponse de l'API Routes sont une série de coordonnées de latitude-longitude de l'origine à la destination. Les données de parcours contiennent des sections et des étapes qui suivent le réseau routier.

Les itinéraires sont également renvoyés sous forme de polyligne encodée, que vous transmettez en tant que paramètre d'entrée à la requête SAR. L'encodage de polyligne est un algorithme de compression avec perte qui vous permet de stocker une série de coordonnées sous la forme d'une seule chaîne. Il n'est pas obligatoire d'obtenir la polyligne à partir de l'API Routes. Vous pouvez créer les données vous-même, mais pour les besoins de cet exemple, l'API Routes est un moyen rapide et sûr d'obtenir les données requises.

Dans ce tutoriel, nous utilisons un itinéraire de Londres (-37.8167,144.9619) à Manchester (-37.8155, 144.9663).

Itinéraire de Londres à Manchester

Itinéraire de l'exemple: Londres à Manchester

Étape 1: Obtenir un itinéraire à partir de l'API Routes

Pour obtenir un itinéraire à partir de l'API Routes, vous devez fournir les informations suivantes:

  • Les lieux de départ et d'arrivée
  • Mode de transport (voiture, à pied, etc.)
  • Points de repère (facultatif)
  • Préférences (éviter les péages, éviter les voies rapides, etc.)
  • La préférence de routage tenant compte du trafic vous donnera les estimations les plus précises, mais il s'agit d'une opération plus lourde en termes de calcul, ce qui augmente la latence de la réponse.
{"origin":{
    "location": {
        "latLng":{
            "latitude":  -37.8167,
            "longitude": 144.9619
        }
    }
},
"destination":{
    "location": {
        "latLng":{
            "latitude":-37.8155,
            "longitude": 144.9663
        }
    }
},
"routingPreference":"TRAFFIC_AWARE",
"travelMode":"DRIVE"
}

Lorsque vous effectuez l'appel, veillez à inclure le champ "encodedPolyline" dans le masque de champ des en-têtes.

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

Documentation complète avec des exemples d'obtenir un itinéraire et d'obtenir des polylignes d'itinéraire.

Une fois que vous avez fourni ces informations dans la requête, l'API Routes renvoie un objet de parcours. L'objet "route" contient les informations suivantes:

  • Distance totale du trajet
  • Durée totale de l'itinéraire
  • Les étapes du trajet
  • Polyligne encodée de l'itinéraire, des sections et des étapes.
{
  "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

Étape 2: Requête de recherche le long du trajet

La recherche textuelle de l'API Places dispose d'une requête "Search Along Route" (Rechercher sur un itinéraire) qui vous permet de rechercher des lieux sur un itinéraire. Pour effectuer une requête de recherche le long d'un itinéraire, vous devez fournir les informations minimales suivantes:

  • Masque de champ des champs renvoyés dans la réponse
  • Une clé API valide pour l'API activée dans la console Google Cloud
  • Chaîne de texte de recherche indiquant les lieux que vous recherchez, par exemple "restaurant végétarien épicé"
  • Polyligne encodée de l'itinéraire, récupérée à partir de l'appel précédent de l'API Routes
  • URL du point de terminaison de l'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)

Exemple de données de requête

La requête Search Along Route renvoie une liste des lieux situés le long de l'itinéraire. Voici un extrait de l'exemple de données. La longueur de la réponse peut être limitée en définissant le nombre maximal de paramètres de résultats. L'ajout de champs augmente bien entendu la quantité de données reçues. Pour en savoir plus sur la réponse de l'API Places, consultez la documentation.

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

Exemple de données de réponse

Résumé du calcul d'itinéraire et temps de déviation

Il est bien de trouver les lieux, mais il est également utile d'ajouter le temps nécessaire pour s'y rendre. La recherche SAR dans Text Search de l'API Places peut également renvoyer un champ résumés de calcul d'itinéraire contenant à la fois la durée et la distance à parcourir. Le champ de données des récapitulatifs d'itinéraire est un enfant de la racine de la réponse. Vous ne devez donc pas inclure le préfixe places. dans le masque de champ.

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

Pour obtenir les récapitulatifs, vous devez également fournir le paramètre de lieu d'origine de la recherche, qui est utilisé pour les calculs.

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

Lorsque vous recevez la réponse, une nouvelle section Récapitulatif de l'itinéraire contenant des étapes avec la durée et la distance en mètres s'affiche.

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

Nous allons ensuite voir comment définir l'endroit où commencer la recherche le long du trajet.

Étape 3: Obtenir la position à deux heures du trajet

Imaginons un cas d'utilisation normal où le conducteur souhaite trouver des restaurants non pas au début de l'itinéraire, mais plus loin. Dans notre exemple, le trajet de Londres à Manchester dure environ quatre heures. Le conducteur souhaite trouver un restaurant à deux heures de route. Cette requête nous donne la durée de 120 minutes * 60 secondes = 7 200 secondes.

Dans la réponse de l'API Routes, nous avons la durée de chaque étape du trajet et de chaque étape d'une étape. Veillez à inclure le champ legs dans le masque de champ de votre requête. Parcourez les étapes et les segments jusqu'à ce que la durée cumulée atteigne la limite de deux heures ou 7 200 secondes. Nous avons ensuite trouvé l'étape et l'étape à définir comme origine de la demande de SAR.

Pour accélérer votre travail, vous pouvez essayer la bibliothèque polyline pour Python. Vous pouvez l'utiliser pour obtenir les coordonnées du champ de données polyline.encodedPolyline.

Exécutez les commandes suivantes dans le terminal de votre environnement.

> 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

Maintenant que nous avons trouvé l'emplacement sur le trajet qui se trouve à deux heures du trajet, nous pouvons l'utiliser dans la requête. Il vous suffit d'ajouter la latitude et la longitude dans le paramètre "origin", qui fait partie du paramètre "routingParameters". Nous vous recommandons d'utiliser le champ de données "routingSummaries" que nous avons abordé précédemment. Si vous le souhaitez, vous pouvez également ajouter des paramètres supplémentaires tels que le mode de transport et des instructions pour éviter les péages.


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

Itinéraire avec résultats de recherche

Exemple de résultats (icône de voiture ajoutée pour indiquer l'origine de la recherche)

Comme vous pouvez le voir sur l'image, l'API renvoie des lieux qui sont biaisés vers la fin de l'itinéraire, les résultats commençant vers le milieu du trajet. La recherche est toujours optimisée par les mêmes données Google Maps Platform, qui tiennent compte de la pertinence des lieux et de la distance, entre autres facteurs.

Conclusion

Dans ce tutoriel, vous avez appris à combiner deux API Google Maps Platform, Routes et Places, pour planifier un trajet et trouver des endroits où manger au bout de deux heures de route. Pour obtenir les meilleurs résultats, vous devez obtenir une polyligne encodée contenant les coordonnées de latitude et de longitude pour chaque étape du trajet, puis définir l'origine de la requête "Rechercher le long du trajet".

Cette fonctionnalité ajoute un nouvel outil puissant à la recherche textuelle et à la recherche à proximité déjà disponibles dans l'API Places. La suite logique consiste à ajouter des services de localisation afin de pouvoir utiliser la position du conducteur comme point de départ pour trouver l'origine de recherche optimale. De plus, cette fonctionnalité fonctionnerait parfaitement avec un assistant vocal embarqué auquel vous pourriez indiquer vos options de restauration préférées.

Étapes suivantes

Autres ressources recommandées:

Participants

Google gère ce document. Le contributeur suivant l'a initialement rédigé.

Auteur principal: Mikko Toivanen | Ingénieur solutions Google Maps Platform