---
title: "Distance measurement on map | JavaScript maps SDK"
description: "To calculate distances on the map, simply click on different points to create lines that will measure the distances using turf.length."
---

> For AI agents: a documentation index is available at [/llms.txt](https://docs.maptiler.com/llms.txt). Markdown versions of all pages are available by appending .md to any URL.

# Distance measurement on map

To calculate distances on the map, simply click on different points to create lines that will measure the distances using the [turf.length](https://turfjs.org/docs/#length) function. This feature allows you to accurately determine the distance between any two points on the map.

### NPM module setup

```bash
npm install --save @maptiler/sdk @turf/turf
```

#### main.js

```js
import { Map, MapStyle, config } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';
import * as turf from '@turf/turf';

config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
const map = new Map({
    container: 'map',
    style: MapStyle.STREETS, 
    center: [2.3399, 48.8555],
    zoom: 12
});

const distanceContainer = document.getElementById('distance');

// GeoJSON object to hold our measurement features
const geojson = {
    'type': 'FeatureCollection',
    'features': []
};

// Used to draw a line between points
const linestring = {
    'type': 'Feature',
    'geometry': {
        'type': 'LineString',
        'coordinates': []
    }
};

map.on('load', function () {
    map.addSource('geojson', {
        'type': 'geojson',
        'data': geojson
    });

    // Add styles to the map
    map.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', function (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(function (point) {
                return 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(
                function (point) {
                    return point.geometry.coordinates;
                }
            );

            geojson.features.push(linestring);

            // Populate the distanceContainer with total distance
            const value = document.createElement('pre');
            value.textContent =
                'Total distance: ' +
                turf.length(linestring).toLocaleString() +
                'km';
            distanceContainer.appendChild(value);
        }

        map.getSource('geojson').setData(geojson);
    });
});

map.on('mousemove', function (e) {
    const features = map.queryRenderedFeatures(e.point, {
        layers: ['measure-points']
    });
    // UI indicator for clicking/hovering a point on the map
    map.getCanvas().style.cursor = features.length
        ? 'pointer'
        : 'crosshair';
});
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>Distance measurement on map | NPM example</title>
  <link rel="stylesheet" href="./style.css">
</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 type="module" src="./main.js"></script>
</body>
</html>
```

#### style.css

```css
body {margin: 0; padding: 0;}
#map {position: absolute; top: 0; bottom: 0; width: 100%;}
```

### Basic JavaScript setup

```html
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Measure distances</title>
  <script src="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.umd.min.js"></script>
  <link href="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.css" rel="stylesheet" />
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }

    .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>
</head>

<body>
  <div id="map"></div>
  <div id="distance" class="distance-container"></div>

  <script src="https://cdn.jsdelivr.net/npm/@turf/turf@7/turf.min.js"></script>
  <script>
    maptilersdk.config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
    const map = new maptilersdk.Map({
      container: 'map',
      style: maptilersdk.MapStyle.STREETS,
      center: [2.3399, 48.8555],
      zoom: 12
    });

    const distanceContainer = document.getElementById('distance');

    // GeoJSON object to hold our measurement features
    const geojson = {
      'type': 'FeatureCollection',
      'features': []
    };

    // Used to draw a line between points
    const linestring = {
      'type': 'Feature',
      'geometry': {
        'type': 'LineString',
        'coordinates': []
      }
    };

    map.on('load', function () {
      map.addSource('geojson', {
        'type': 'geojson',
        'data': geojson
      });

      // Add styles to the map
      map.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', function (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(function (point) {
            return 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(
            function (point) {
              return point.geometry.coordinates;
            }
          );

          geojson.features.push(linestring);

          // Populate the distanceContainer with total distance
          const value = document.createElement('pre');
          value.textContent =
            'Total distance: ' +
            turf.length(linestring).toLocaleString() +
            'km';
          distanceContainer.appendChild(value);
        }

        map.getSource('geojson').setData(geojson);
      });
    });

    map.on('mousemove', function (e) {
      const features = map.queryRenderedFeatures(e.point, {
        layers: ['measure-points']
      });
      // UI indicator for clicking/hovering a point on the map
      map.getCanvas().style.cursor = features.length
        ? 'pointer'
        : 'crosshair';
    });
  </script>
</body>

</html>
```

## Related examples

### [Show drawn polygon area](https://docs.maptiler.com/sdk-js/examples/mapbox-gl-draw/)

Examples

Use mapbox-gl-draw to draw a polygon and Turf.js to calculate its area in square meters.

### [GeoJSON line layer](https://docs.maptiler.com/sdk-js/examples/geojson-line/)

Tutorials

Add a GeoJSON line overlay to the map application.

### [Get coordinates of the mouse pointer](https://docs.maptiler.com/sdk-js/examples/mouse-position/)

Examples

Show mouse position on hover with coordinates.
