Obtenir une matrice de routage

Développeurs de l'Espace économique européen (EEE)

Une matrice de routes est un tableau bidimensionnel d'informations sur les routes, où les lignes correspondent aux origines et les colonnes aux destinations. À partir d'une liste d'origines et de destinations, la classe Route Matrix calcule la distance et la durée d'un itinéraire commençant à chaque origine et se terminant à chaque destination. Utilisez la classe Route Matrix pour calculer la distance et la durée d'un itinéraire pour plusieurs points de départ et destinations.

Afficher l'exemple de code source complet

Cet exemple montre comment utiliser la classe Route Matrix pour calculer les distances et les durées des trajets entre plusieurs points de départ et destinations.

TypeScript

// Initialize and add the map.
let map;
let markers: google.maps.marker.AdvancedMarkerElement[] = [];
let center = { lat: 51.55, lng: -1.8 };

async function initMap(): Promise<void> {
  //  Request the needed libraries.
  //@ts-ignore
  const [{Map}, {Place}, {AdvancedMarkerElement, PinElement}, {RouteMatrix}] = await Promise.all([
    google.maps.importLibrary('maps') as Promise<google.maps.MapsLibrary>,
    google.maps.importLibrary('places') as Promise<google.maps.PlacesLibrary>,
    google.maps.importLibrary('marker') as Promise<google.maps.MarkerLibrary>,
    google.maps.importLibrary('routes') as Promise<google.maps.RoutesLibrary>
  ]);

  const bounds = new google.maps.LatLngBounds();

  map = new Map(document.getElementById('map') as HTMLElement, {
    zoom: 8,
    center: center,
    mapId: 'DEMO_MAP_ID',
  });

  // Build the request using Place instances.
  const origin1 = new Place({
    id: "ChIJ83WZp86p2EcRbMrkYqGncBQ", // Greenwich, London, UK
  });
  const origin2 = new Place({
    id: "ChIJCSkVvleJc0gR8HHaTGpajKc", // Southampton, UK
  });
  const destinationA = new Place({
    id: "ChIJYdizgWaDcUgRH9eaSy6y5I4", // Bristol, UK
  });
  const destinationB = new Place({
    id: "ChIJ9VPsNNQCbkgRDmeGZdsGNBQ", // Cardiff, UK
  });

  await Promise.all([
    origin1.fetchFields({ fields: ['location', 'displayName']}),
    origin2.fetchFields({ fields: ['location', 'displayName']}),
    destinationA.fetchFields({ fields: ['location', 'displayName']}),
    destinationB.fetchFields({ fields: ['location', 'displayName']}),
  ]);

  const request = {
    origins: [origin1, origin2], 
    destinations: [destinationA, destinationB],
    travelMode: 'DRIVING',
    units: google.maps.UnitSystem.METRIC,
    fields: ['distanceMeters', 'durationMillis', 'condition'],
  };

  // Show the request.
  (document.getElementById("request") as HTMLDivElement).innerText =
    JSON.stringify(request, null, 2);

  // Get the RouteMatrix response.
  const response = await RouteMatrix.computeRouteMatrix(request); 

  // Show the response.
  (document.getElementById("response") as HTMLDivElement).innerText =
    JSON.stringify(response, null, 2);

  // Add markers for the origins.
  for (const origin of request.origins) {
    if (origin.location) {
      const pin = new PinElement({
        //@ts-ignore
        glyphText: "O",
        glyphColor: "white",
        background: "#137333",
        borderColor: "white",
      });
      const marker = new AdvancedMarkerElement({
        map,
        position: origin.location,
        content: pin.element,
        title: `Origin: ${origin.displayName}`,
      });
      markers.push(marker);
      bounds.extend(origin.location);
    }
  }

  // Add markers for the destinations.
  for (let i = 0; i < request.destinations.length; i++) {
    const destination = request.destinations[i];
    if (destination.location) {
      const pin = new PinElement({
        //@ts-ignore
        glyphText: "D",
        glyphColor: "white",
        background: "#C5221F",
        borderColor: "white",
      });

      const marker = new AdvancedMarkerElement({
        map,
        position: destination.location,
        content: pin.element,
        title: `Destination: ${destination.displayName}`,
      });

      markers.push(marker);
      bounds.extend(destination.location);
    }
  }

  // Fit the map to the bounds of all markers.
  map.fitBounds(bounds);
}

initMap();

JavaScript

// Initialize and add the map.
let map;
let markers = [];
let center = { lat: 51.55, lng: -1.8 };
async function initMap() {
    //  Request the needed libraries.
    //@ts-ignore
    const [{ Map }, { Place }, { AdvancedMarkerElement, PinElement }, { RouteMatrix }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes')
    ]);
    const bounds = new google.maps.LatLngBounds();
    map = new Map(document.getElementById('map'), {
        zoom: 8,
        center: center,
        mapId: 'DEMO_MAP_ID',
    });
    // Build the request using Place instances.
    const origin1 = new Place({
        id: "ChIJ83WZp86p2EcRbMrkYqGncBQ", // Greenwich, London, UK
    });
    const origin2 = new Place({
        id: "ChIJCSkVvleJc0gR8HHaTGpajKc", // Southampton, UK
    });
    const destinationA = new Place({
        id: "ChIJYdizgWaDcUgRH9eaSy6y5I4", // Bristol, UK
    });
    const destinationB = new Place({
        id: "ChIJ9VPsNNQCbkgRDmeGZdsGNBQ", // Cardiff, UK
    });
    await Promise.all([
        origin1.fetchFields({ fields: ['location', 'displayName'] }),
        origin2.fetchFields({ fields: ['location', 'displayName'] }),
        destinationA.fetchFields({ fields: ['location', 'displayName'] }),
        destinationB.fetchFields({ fields: ['location', 'displayName'] }),
    ]);
    const request = {
        origins: [origin1, origin2],
        destinations: [destinationA, destinationB],
        travelMode: 'DRIVING',
        units: google.maps.UnitSystem.METRIC,
        fields: ['distanceMeters', 'durationMillis', 'condition'],
    };
    // Show the request.
    document.getElementById("request").innerText =
        JSON.stringify(request, null, 2);
    // Get the RouteMatrix response.
    const response = await RouteMatrix.computeRouteMatrix(request);
    // Show the response.
    document.getElementById("response").innerText =
        JSON.stringify(response, null, 2);
    // Add markers for the origins.
    for (const origin of request.origins) {
        if (origin.location) {
            const pin = new PinElement({
                //@ts-ignore
                glyphText: "O",
                glyphColor: "white",
                background: "#137333",
                borderColor: "white",
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                content: pin.element,
                title: `Origin: ${origin.displayName}`,
            });
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }
    // Add markers for the destinations.
    for (let i = 0; i < request.destinations.length; i++) {
        const destination = request.destinations[i];
        if (destination.location) {
            const pin = new PinElement({
                //@ts-ignore
                glyphText: "D",
                glyphColor: "white",
                background: "#C5221F",
                borderColor: "white",
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: destination.location,
                content: pin.element,
                title: `Destination: ${destination.displayName}`,
            });
            markers.push(marker);
            bounds.extend(destination.location);
        }
    }
    // Fit the map to the bounds of all markers.
    map.fitBounds(bounds);
}
initMap();

CSS

/*
 * Always set the map height explicitly to define the size of the div element
 * that contains the map.
 */
/* Optional: Makes the sample page fill the window. */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#container {
  height: 100%;
  display: flex;
}

#sidebar {
  flex-basis: 15rem;
  flex-grow: 1;
  padding: 1rem;
  max-width: 30rem;
  height: 100%;
  box-sizing: border-box;
  overflow: auto;
}

#map {
  flex-basis: 0;
  flex-grow: 4;
  height: 100%;
}

#sidebar {
  flex-direction: column;
}

HTML

<html>
  <head>
    <title>Route matrix</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="container">
      <div id="map"></div>
      <div id="sidebar">
        <h3 style="flex-grow: 0">Request</h3>
        <pre style="flex-grow: 1" id="request"></pre>
        <h3 style="flex-grow: 0">Response</h3>
        <pre style="flex-grow: 1" id="response"></pre>
      </div>
    </div>
    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "beta"});</script>
  </body>
</html>

Essayer l'exemple

Limites de requêtes

La méthode computeRouteMatrix applique les limites de requête suivantes pour les points de repère utilisant des instances d'adresse ou de lieu, et pour les éléments. Les éléments sont les itinéraires entre chaque origine et chaque destination d'une matrice d'itinéraire. Le nombre d'éléments correspond donc au nombre d'origines multiplié par le nombre de destinations. Par exemple, si vous avez 10 origines et 10 destinations, vous avez 100 éléments :

  • Le nombre d'éléments ne peut pas dépasser 625 pour les itinéraires qui ne sont pas des itinéraires TRANSIT.
  • Si vous spécifiez un itinéraire TRANSIT, le nombre d'éléments ne peut pas dépasser 100.
  • Si vous spécifiez TRAFFIC_AWARE_OPTIMAL, le nombre d'éléments ne peut pas dépasser 100.
  • Si vous spécifiez des origines ou des destinations à l'aide d'adresses ou d'instances Place, vous pouvez en spécifier jusqu'à 50 au total.

Pour en savoir plus, consultez Obtenir un itinéraire en transports en commun.

Exemple de requête de matrice de trajets

L'exemple suivant montre un ComputeRouteMatrixRequest. Cet exemple effectue les opérations suivantes :

  • Montre comment spécifier un tableau de deux points de cheminement d'origine et de deux points de cheminement de destination. La méthode calcule un itinéraire de chaque origine à chaque destination. La réponse contient donc quatre itinéraires.
    Dans le tableau, le premier élément se trouve à l'index 0, le deuxième à l'index 1, et ainsi de suite.
  • Spécifie les champs à renvoyer. Dans cet exemple, la requête est configurée pour renvoyer durationMillis, distanceMeters et condition pour chaque itinéraire.

TypeScript

const request = {
  origins: [origin1, origin2], 
  destinations: [destinationA, destinationB],
  travelMode: 'DRIVING',
  units: google.maps.UnitSystem.METRIC,
  fields: ['distanceMeters', 'durationMillis', 'condition'],
};

JavaScript

const request = {
    origins: [origin1, origin2],
    destinations: [destinationA, destinationB],
    travelMode: 'DRIVING',
    units: google.maps.UnitSystem.METRIC,
    fields: ['distanceMeters', 'durationMillis', 'condition'],
};

La réponse contient les quatre itinéraires possibles pour la combinaison de tous les points de cheminement d'origine et de destination, comme le montre l'exemple suivant :

"matrix": {
  "rows": [
    {
      "items": [
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 202587,
          "durationMillis": 10040000
        },
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 252734,
          "durationMillis": 12240000
        }
      ]
    },
    {
      "items": [
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 166135,
          "durationMillis": 6596000
        },
        {
          "condition": "ROUTE_EXISTS",
          "distanceMeters": 216282,
          "durationMillis": 8797000
        }
      ]
    }
  ]
}
    

Identifiez chaque itinéraire dans le résultat en utilisant l'index de point de départ et de destination pour trouver la RouteMatrixItem correspondante dans le tableau 2D. Par exemple, le RouteMatrixItem décrivant l'itinéraire calculé à partir de l'origine à l'index 1 et de la destination 0 dans la requête se trouverait dans le deuxième élément du tableau RouteMatrix.rows et dans le premier élément du tableau RouteMatrixRow.items.

L'extrait de code suivant montre comment identifier RouteMatrixItem pour trouver l'itinéraire d'une origine et d'une destination spécifiques :

// Find the route for origin 'x' and destination 'y'.
const {matrix} = await RouteMatrix.computeRouteMatrix(request);
const myRouteMatrixItem = matrix.rows[x].items[y];
    

Choisir les champs à renvoyer

Lorsque vous demandez une matrice de routes, vous devez utiliser un masque de champ pour spécifier les informations que la réponse doit renvoyer.

L'utilisation d'un masque de champ permet également de s'assurer de ne pas demander de données inutiles, ce qui contribue à réduire la latence des réponses et à éviter de renvoyer des informations dont votre système n'a pas besoin.

Spécifiez la liste des champs dont vous avez besoin en définissant la propriété ComputeRoutesMatrixRequest.fields, comme indiqué dans l'extrait de code suivant :

fields: ['durationMillis', 'distanceMeters', 'condition'],
    

Déterminer les masques de champ à utiliser

Voici comment déterminer les champs à utiliser et créer les masques de champ correspondants :

  1. Demandez tous les champs à l'aide d'un masque de champ ['*'].
  2. Examinez la hiérarchie des champs dans la classe RouteMatrixItem pour les champs souhaités.
  3. Créez vos masques de champ en utilisant la hiérarchie des champs affichée à l'étape précédente, au format suivant :

    topLevelField[.secondLevelField][.thirdLevelField][...]

Par exemple, pour ce RouteMatrixItem :

  "travelAdvisory": {
    "fuelConsumptionMicroliters": 0,
    "tollInfo": {
      "estimatedPrices": [
        {
          "currencyCode": "USD",
          "units": 4,
          "nanos": 400000000
        }
      ]
    }
  },
    

Si vous souhaitez renvoyer uniquement le champ tollInfo pour RouteMatrixItem, votre masque de champ se présente comme suit :

fields: ['travelAdvisory.tollInfo']

Si vous souhaitez plutôt demander la consommation de carburant estimée, votre masque de champ est le suivant :

fields: ['travelAdvisory.fuelConsumptionMicroliters']

Si vous souhaitez demander les deux, votre masque de champ est le suivant :

fields: ['travelAdvisory.fuelConsumptionMicroliters', 'travelAdvisory.tollInfo']

Si vous souhaitez demander l'ensemble complet des conseils aux voyageurs, votre masque de champ est le suivant :

fields: ['travelAdvisory']

Demander une matrice d'itinéraires en transports en commun

Obtenez une matrice d'itinéraires en transports en commun qui utilise les options de transports en commun disponibles dans la région. Les options de transport en commun peuvent inclure les bus, les métros et les trains, entre autres. Pour demander une matrice de trajets en transports en commun :

  • Définissez la valeur de travelMode sur TRANSIT.
  • Demandez le champ travelAdvisory.

En savoir plus sur les itinéraires de transport en commun