Pobieranie macierzy tras

Deweloperzy z Europejskiego Obszaru Gospodarczego (EOG)

Macierz tras to dwuwymiarowa tablica informacji o trasach, w której wiersze odpowiadają punktom początkowym, a kolumny – punktom docelowym. Klasa Route Matrix oblicza odległość i czas trwania trasy rozpoczynającej się w każdym punkcie początkowym i kończącej się w każdym punkcie docelowym na podstawie listy punktów początkowych i docelowych. Użyj klasy Route Matrix, aby obliczyć odległość i czas trwania trasy dla wielu punktów początkowych i docelowych.

Zobacz pełny przykładowy kod źródłowy

Ten przykład pokazuje, jak używać klasy Route Matrix do obliczania odległości i czasu podróży między wieloma punktami początkowymi i docelowymi.

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>

Wypróbuj

Limity żądań

Metoda computeRouteMatrix wymusza te limity żądań dotyczące punktów pośrednich z użyciem adresów lub instancji miejsc oraz elementów. Elementy to trasy między poszczególnymi miejscami wyjazdu i docelowymi w macierzy tras, więc liczba elementów to liczba miejsc wyjazdu pomnożona przez liczbę miejsc docelowych. Jeśli na przykład masz 10 punktów początkowych i 10 punktów docelowych, masz 100 elementów:

  • Liczba elementów nie może przekraczać 625 w przypadku tras, które nie są trasami TRANSIT.
  • Jeśli określisz TRANSITtrasę, liczba elementów nie może przekraczać 100.
  • Jeśli podasz TRAFFIC_AWARE_OPTIMAL, liczba elementów nie może przekraczać 100.
  • Jeśli określasz punkty początkowe lub docelowe za pomocą adresów lub instancji miejsca, możesz określić w ten sposób maksymalnie 50 punktów.

Więcej informacji znajdziesz w artykule Wyznaczanie trasy transportu publicznego.

Przykładowe żądanie macierzy tras

Poniższy przykład przedstawia ComputeRouteMatrixRequest. Ten przykład wykonuje te czynności:

  • Pokazuje określanie tablicy 2 punktów pośrednich miejsca odjazdu i 2 punktów pośrednich miejsca docelowego. Metoda oblicza trasę z każdego punktu początkowego do każdego punktu docelowego, więc odpowiedź zawiera 4 trasy.
    W tablicy pierwszy element ma indeks 0, drugi 1 itd.
  • Określa pola, które mają być zwracane. W tym przykładzie żądanie jest skonfigurowane tak, aby zwracać wartości durationMillis, distanceMeterscondition dla każdej trasy.

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'],
};

Odpowiedź zawiera 4 możliwe trasy dla kombinacji wszystkich punktów pośrednich miejsca odjazdu i miejsca docelowego, jak pokazano w tym przykładzie:

"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
        }
      ]
    }
  ]
}
    

Zidentyfikuj każdą trasę w wyniku, używając indeksu miejsca docelowego i miejsca wylotu, aby znaleźć odpowiedni element RouteMatrixItem w tablicy dwuwymiarowej. Na przykład element RouteMatrixItem opisujący trasę obliczoną na podstawie miejsca początkowego o indeksie 1 i miejsca docelowego 0 w żądaniu znajdowałby się w 2 elemencie tablicy RouteMatrix.rows i 1 elemencie tablicy RouteMatrixRow.items.

Poniższy fragment kodu pokazuje, jak zidentyfikować RouteMatrixItem, aby znaleźć trasę dla określonego miejsca odjazdu i miejsca docelowego:

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

Wybierz pola do zwrócenia

Gdy wysyłasz żądanie macierzy tras, musisz użyć maski pola, aby określić, jakie informacje powinna zwrócić odpowiedź.

Użycie maski pola zapewnia też, że nie będziesz prosić o niepotrzebne dane, co z kolei pomaga zmniejszyć opóźnienie odpowiedzi i uniknąć zwracania informacji, których Twój system nie potrzebuje.

Określ listę potrzebnych pól, ustawiając właściwość ComputeRoutesMatrixRequest.fields, jak pokazano w tym fragmencie kodu:

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

Określanie masek pól do użycia

Aby określić, których pól chcesz użyć, i utworzyć dla nich maski pól:

  1. Poproś o wszystkie pola, używając maski pola ['*'].
  2. Sprawdź hierarchię pól w klasie RouteMatrixItem w przypadku wybranych pól.
  3. Utwórz maski pól, korzystając z hierarchii pól pokazanej w poprzednim kroku, w tym formacie:

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

Na przykład w przypadku tego RouteMatrixItem:

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

Jeśli chcesz zwrócić tylko pole tollInfo dla RouteMatrixItem, maska pola będzie wyglądać tak:

fields: ['travelAdvisory.tollInfo']

Jeśli chcesz poprosić o szacunkowe zużycie paliwa, maska pola będzie wyglądać tak:

fields: ['travelAdvisory.fuelConsumptionMicroliters']

Jeśli chcesz poprosić o oba te elementy, maska pola będzie wyglądać tak:

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

Jeśli chcesz poprosić o pełny zestaw ostrzeżeń dotyczących podróży, maska pola będzie wyglądać tak:

fields: ['travelAdvisory']

Prośba o macierz tras transportu publicznego

Uzyskaj macierz tras transportu publicznego, która korzysta z opcji transportu publicznego dostępnych w regionie. Opcje transportu publicznego mogą obejmować m.in. autobusy, metro i pociągi. Aby poprosić o macierz tras transportu publicznego:

  • Ustaw wartość travelMode na TRANSIT.
  • Poproś o pole travelAdvisory.

Dowiedz się więcej o trasach transportu publicznego.