Measure distances
Click points on a map to create lines that measure distanced using turf.length.
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Measure distances</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"><link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet"><script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script><style>body { margin: 0; padding: 0; }#map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><style>.distance-container {position: absolute;top: 10px;left: 10px;z-index: 1;} .distance-container > * {background-color: rgba(0, 0, 0, 0.5);color: #fff;font-size: 11px;line-height: 18px;display: block;margin: 0;padding: 5px 10px;border-radius: 3px;}</style> <div id="map"></div><div id="distance" class="distance-container"></div> <script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script><script> // TO MAKE THE MAP APPEAR YOU MUST // ADD YOUR ACCESS TOKEN FROM // https://account.mapbox.com mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';const map = new mapboxgl.Map({container: 'map',// Choose from Mapbox's core styles, or make your own style with Mapbox Studiostyle: 'mapbox://styles/mapbox/streets-v12',center: [2.3399, 48.8555],zoom: 12}); const distanceContainer = document.getElementById('distance'); // GeoJSON object to hold our measurement featuresconst geojson = {'type': 'FeatureCollection','features': []}; // Used to draw a line between pointsconst linestring = {'type': 'Feature','geometry': {'type': 'LineString','coordinates': []}}; map.on('load', () => {map.addSource('geojson', {'type': 'geojson','data': geojson}); // Add styles to the mapmap.addLayer({id: 'measure-points',type: 'circle',source: 'geojson',paint: {'circle-radius': 5,'circle-color': '#000'},filter: ['in', '$type', 'Point']});map.addLayer({id: 'measure-lines',type: 'line',source: 'geojson',layout: {'line-cap': 'round','line-join': 'round'},paint: {'line-color': '#000','line-width': 2.5},filter: ['in', '$type', 'LineString']}); map.on('click', (e) => {const features = map.queryRenderedFeatures(e.point, {layers: ['measure-points']}); // Remove the linestring from the group// so we can redraw it based on the points collection.if (geojson.features.length > 1) geojson.features.pop(); // Clear the distance container to populate it with a new value.distanceContainer.innerHTML = ''; // If a feature was clicked, remove it from the map.if (features.length) {const id = features[0].properties.id;geojson.features = geojson.features.filter((point) => point.properties.id !== id);} else {const point = {'type': 'Feature','geometry': {'type': 'Point','coordinates': [e.lngLat.lng, e.lngLat.lat]},'properties': {'id': String(new Date().getTime())}}; geojson.features.push(point);} if (geojson.features.length > 1) {linestring.geometry.coordinates = geojson.features.map((point) => point.geometry.coordinates); geojson.features.push(linestring); // Populate the distanceContainer with total distanceconst value = document.createElement('pre');const distance = turf.length(linestring);value.textContent = `Total distance: ${distance.toLocaleString()}km`;distanceContainer.appendChild(value);} map.getSource('geojson').setData(geojson);});}); map.on('mousemove', (e) => {const features = map.queryRenderedFeatures(e.point, {layers: ['measure-points']});// Change the cursor to a pointer when hovering over a point on the map.// Otherwise cursor is a crosshair.map.getCanvas().style.cursor = features.length? 'pointer': 'crosshair';});</script> </body></html>