Pobieranie macierzy tras

Deweloperzy z Europejskiego Obszaru Gospodarczego (EOG)

Macierz tras to dwuwymiarowa tablica informacji o trasie, w której wiersze odpowiadają punktom początkowym, a kolumny – punktom docelowym. Na podstawie listy punktów początkowych i docelowych klasa macierzy tras oblicza odległość i czas trwania trasy, która zaczyna się w każdym punkcie początkowym i kończy w każdym punkcie docelowym. Użyj klasy macierz tras, aby obliczyć odległość i czas trwania trasy dla wielu punktów początkowych i docelowych.

Zobacz kompletny przykładowy kod źródłowy

Ten przykład pokazuje, jak używać klasy macierz tras 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: google.maps.Map;
const markers: google.maps.marker.AdvancedMarkerElement[] = [];
const center = { lat: 51.55, lng: -1.8 };

async function init(): Promise<void> {
    //  Request the needed libraries.
    const [
        { Map },
        { Place },
        { AdvancedMarkerElement, PinElement },
        { RouteMatrix },
        { LatLngBounds, UnitSystem },
    ] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes'),
        google.maps.importLibrary('core'),
    ]);

    const bounds = new LatLngBounds();

    map = new Map(document.getElementById('map')!, {
        zoom: 8,
        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 destinations = [destinationA, destinationB];
    const origins = [origin1, origin2];
    const request: google.maps.routes.ComputeRouteMatrixRequest = {
        origins,
        destinations,
        travelMode: 'DRIVING',
        units: 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 origins) {
        if (origin.location) {
            const pin = new PinElement({
                glyphText: 'O',
                glyphColor: 'white',
                background: '#137333',
                borderColor: 'white',
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                title: `Origin: ${origin.displayName}`,
            });
            marker.append(pin);
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }

    // Add markers for the destinations.
    for (const destination of destinations) {
        if (destination.location) {
            const pin = new PinElement({
                glyphText: 'D',
                glyphColor: 'white',
                background: '#C5221F',
                borderColor: 'white',
            });

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

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

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

void init();

JavaScript

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

async function init() {
    //  Request the needed libraries.
    const [
        { Map },
        { Place },
        { AdvancedMarkerElement, PinElement },
        { RouteMatrix },
        { LatLngBounds, UnitSystem },
    ] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('routes'),
        google.maps.importLibrary('core'),
    ]);

    const bounds = new LatLngBounds();

    map = new Map(document.getElementById('map'), {
        zoom: 8,
        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 destinations = [destinationA, destinationB];
    const origins = [origin1, origin2];
    const request = {
        origins,
        destinations,
        travelMode: 'DRIVING',
        units: 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 origins) {
        if (origin.location) {
            const pin = new PinElement({
                glyphText: 'O',
                glyphColor: 'white',
                background: '#137333',
                borderColor: 'white',
            });
            const marker = new AdvancedMarkerElement({
                map,
                position: origin.location,
                title: `Origin: ${origin.displayName}`,
            });
            marker.append(pin);
            markers.push(marker);
            bounds.extend(origin.location);
        }
    }

    // Add markers for the destinations.
    for (const destination of destinations) {
        if (destination.location) {
            const pin = new PinElement({
                glyphText: 'D',
                glyphColor: 'white',
                background: '#C5221F',
                borderColor: 'white',
            });

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

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

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

void init();

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>
        <script>
            // prettier-ignore
            (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: "GOOGLE_MAPS_API_KEY"
            });
        </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>
    </body>
</html>

Skorzystaj z przykładu

Limity żądań

Metoda computeRouteMatrix wymusza te limity żądań dotyczące punktów pośrednich, które używają instancji adresów lub miejsc, oraz elementów. Elementy to trasy między każdym miejscem początkowym a docelowym w macierzy tras, więc liczba elementów to liczba miejsc początkowych pomnożona przez liczbę miejsc docelowych. Jeśli na przykład masz 10 miejsc początkowych i 10 miejsc 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 trasę TRANSIT, 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 miejsca rozpoczęcia lub zakończenia podróży za pomocą adresów lub instancji miejsc, możesz w ten sposób podać maksymalnie 50 miejsc.

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

Przykładowe żądanie macierzy tras

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

  • Pokazuje, jak określić tablicę z 2 punktami początkowymi i 2 punktami docelowymi. Metoda oblicza trasę z każdego miejsca początkowego do każdego miejsca docelowego, więc odpowiedź zawiera 4 trasy.
    W tablicy pierwszy element ma indeks 0, drugi 1 itd.
  • Określa pola, które mają zostać zwrócone. W tym przykładzie żądanie jest skonfigurowane tak, aby zwracać durationMillis, distanceMeters i condition dla każdej trasy.

TypeScript

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

JavaScript

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

Odpowiedź zawiera 4 możliwe trasy dla kombinacji wszystkich punktów orientacyjnych miejsca rozpoczęcia 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 rozpoczęcia i miejsca docelowego, aby znaleźć odpowiedni element RouteMatrixItem w tablicy dwuwymiarowej. Na przykład RouteMatrixItem opisujący trasę obliczoną od punktu początkowego o indeksie 1 do punktu docelowego o indeksie 0 w żądaniu będzie drugim elementem tablicy RouteMatrix.rows i pierwszym elementem tablicy RouteMatrixRow.items.

Poniższy fragment kodu pokazuje, jak zidentyfikować RouteMatrixItem, aby znaleźć trasę dla określonego miejsca rozpoczęcia i zakończenia podróży:

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

Wybierz pola, które mają być zwracane

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

Użycie maski pola gwarantuje też, że nie będziesz prosić o niepotrzebne dane, co z kolei pomaga skrócić czas oczekiwania na odpowiedź i pozwala 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

Oto jak możesz określić, których pól chcesz używać, i utworzyć dla nich maski:

  1. Poproś o wszystkie pola, używając maski pola ['*'].
  2. Sprawdź hierarchię pól w klasie RouteMatrixItem, aby znaleźć odpowiednie pola.
  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 elementu 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 szacowane 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 zaleceń dotyczących podróży, maska pola będzie wyglądać tak:

fields: ['travelAdvisory']

Żądanie macierzy 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 tranzytowych.