Get map meters per pixel

by amay077

HTML

<script src="https://api.mapbox.com/mapbox-gl-js/v1.6.1/mapbox-gl.js"></script>
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v1.6.1/mapbox-gl.css">
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
<div style="height: 25px;">
  <span id="label" style="margin: 4px;">Move or Zooom map</span>
</div>
<div id="map" style="width:100%; height: calc(100vh - 25px);"></div>

CSS

body {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
}

JavaScript

const spanElem = document.getElementById('label');

const map = new mapboxgl.Map({
  container: 'map',
  center: [-122.486052, 37.830348],
  zoom: 15,
  style: {
    version: 8,
    sources: {
      OSM: {
        type: "raster",
        tiles: [
          "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
        ],
        tileSize: 256,
        attribution:
        "OpenStreetMap",
      },
    },
    layers: [{
      id: "BASEMAP",
      type: "raster",
      source: "OSM",
      minzoom: 0,
      maxzoom: 18,
    }],
  },      
});

map.addControl(new mapboxgl.NavigationControl({
  showCompass: false,
}));

map.once('load', () => {

  map.on('moveend', e => {
    const clientWidth = window.innerWidth;
    const distance = getMapDistance();
    const metersPerPixel = distance / clientWidth;
    spanElem.innerHTML = `${metersPerPixel.toFixed(2)} meters/pixel`;
  });

});

function getMapDistance() {
  const bounds = map.getBounds();
  const ne = bounds.getNorthEast();
  const sw = bounds.getSouthWest();
  const topLeft = turf.point([ne.lng, ne.lat]);
  const topRight = turf.point([sw.lng, ne.lat]);
  const bottomLeft = turf.point([ne.lng, sw.lat]);
  const bottomRight = turf.point([sw.lng, sw.lat]);

  const middleLeft = turf.midpoint(topLeft, bottomLeft);
  const middleRight = turf.midpoint(topRight, bottomRight);
  const distance = turf.distance(middleLeft, middleRight, { units: 'meters' });
  return distance;
}