Distance matrix
This example calculates a distance matrix using the @smartmaps/routing npm package instead of
calling the REST endpoint directly. Click the map to set the start point, then click one or more
destinations; each one is calculated and listed as soon as you place it.
<!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>
Notes
calcRoute(latlngs, options)takes one flat array: the first point is the start, every other point is a destination. Passing a fresh array on each call (as this example does with[startPoint, ...destinations]) avoids relying on argument-mutation behaviour.- The response has the same shape as the REST endpoint: one feature for the start point, whose
properties.routingDestinationsarray holds{ distanceInMeters, timeInSeconds }per destination, in the order the points were passed in.
See RoutingMatrix for the full class reference, or the
REST version if you'd rather call the endpoint directly.