Zum Inhalt

Distanzmatrix

Dieses Beispiel berechnet eine Distanzmatrix über das npm-Paket @smartmaps/routing, statt den REST-Endpunkt direkt aufzurufen. Klicken Sie auf die Karte, um den Startpunkt zu setzen, danach auf ein oder mehrere Ziele; jedes wird berechnet und aufgelistet, sobald Sie es setzen.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script src="https://cdn.smartmaps.cloud/packages/smartmaps/routing/umd/routing.min.js"></script>
        <script src="https://cdn.smartmaps.cloud/packages/smartmaps/smartmaps-gl/v2/umd/smartmaps-gl.min.js"></script>
        <style>
            body {
                margin: 0;
                padding: 0;
                display: flex;
            }

            #map {
                flex: 1;
                height: 100vh;
            }

            #panel {
                width: 260px;
                height: 100vh;
                background-color: rgba(255, 255, 255, 0.9);
                padding: 10px;
                font: 13px sans-serif;
                box-sizing: border-box;
                overflow-y: auto;
            }

            #reset-button {
                display: block;
                margin-top: 10px;
                background-color: #18345c;
                color: white;
                border: none;
                padding: 8px 14px;
                cursor: pointer;
                border-radius: 4px;
            }

            #results div {
                margin-top: 8px;
                padding-top: 8px;
                border-top: 1px solid rgba(0, 0, 0, 0.1);
            }

            .marker-number {
                background: #0a5fa0;
                color: #fff;
                width: 22px;
                height: 22px;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                font: 700 12px sans-serif;
                border: 2px solid #fff;
                box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
            }
        </style>
    </head>

    <body>
        <div id="panel">
            <strong>Click the map to set the start point, then click one or more destinations.</strong>
            <div id="results"></div>
            <button id="reset-button">Reset</button>
        </div>

        <div id="map"></div>

        <script>
            const apiKey = '[INSERT API-KEY]';
            const map = new smartmapsgl.Map({
                apiKey,
                container: 'map',
                center: { lat: 49.02164948779226, lng: 8.439330018049352 },
                zoom: 11,
                style: smartmapsgl.MapStyle.LIGHT
            });

            const matrixService = new smartmaps.routingService.RoutingMatrix(apiKey);

            const resultsEl = document.getElementById('results');

            let startPoint = null;
            let destinations = [];
            let markers = [];

            function numberedMarker(n) {
                const el = document.createElement('div');
                el.className = 'marker-number';
                el.textContent = n;
                return new smartmapsgl.Marker({ element: el });
            }

            function reset() {
                startPoint = null;
                destinations = [];
                markers.forEach((marker) => marker.remove());
                markers = [];
                resultsEl.innerHTML = '';
            }

            document.getElementById('reset-button').addEventListener('click', reset);

            async function calculateMatrix() {
                resultsEl.innerHTML = 'Calculating…';

                try {
                    // calcRoute() takes the FIRST point as the start and treats every
                    // other point as a destination — pass a fresh array so the
                    // destinations state array itself is never mutated.
                    const result = await matrixService.calcRoute(
                        [startPoint, ...destinations],
                        { speedProfile: 'FAST' }
                    );

                    // Same response shape as the REST endpoint: one feature for the
                    // start point, with the legs listed in the order the destinations
                    // were passed in.
                    const legs = result.features[0].properties.routingDestinations;

                    resultsEl.innerHTML = legs
                        .map((leg, i) => {
                            const km = (leg.distanceInMeters / 1000).toFixed(1);
                            const min = Math.round(leg.timeInSeconds / 60);
                            return `<div><strong>Destination ${i + 1}:</strong> ${km} km, ${min} min</div>`;
                        })
                        .join('');
                } catch (error) {
                    console.error('Error fetching matrix:', error);
                    resultsEl.innerHTML = 'Failed to calculate the matrix. Please try again.';
                }
            }

            map.on('click', (event) => {
                const point = { longitude: event.lngLat.lng, latitude: event.lngLat.lat };

                if (!startPoint) {
                    startPoint = point;
                    markers.push(new smartmapsgl.Marker({ color: '#18345c' }).setLngLat(event.lngLat).addTo(map));
                    resultsEl.innerHTML = 'Now click one or more destinations.';
                    return;
                }

                destinations.push(point);
                markers.push(numberedMarker(destinations.length).setLngLat(event.lngLat).addTo(map));
                calculateMatrix();
            });
        </script>
    </body>
</html>

Hinweise

  • calcRoute(latlngs, options) erwartet ein flaches Array: der erste Punkt ist der Start, jeder weitere Punkt ist ein Ziel. Übergeben Sie bei jedem Aufruf ein frisches Array (wie in diesem Beispiel mit [startPoint, ...destinations]), statt sich auf ein bestimmtes Mutationsverhalten des Arguments zu verlassen.
  • Die Antwort hat dieselbe Form wie beim REST-Endpunkt: ein Feature für den Startpunkt, dessen Array properties.routingDestinations { distanceInMeters, timeInSeconds } je Ziel liefert, in der Reihenfolge, in der die Punkte übergeben wurden.

Die vollständige Klassenreferenz finden Sie unter RoutingMatrix, oder nutzen Sie die REST-Version, wenn Sie den Endpunkt direkt aufrufen möchten.