11

I've been looking through the Leaflet API to see if there is a getScale method or scale property of a map, and have't seen anything.

Does anyone know if Leaflet provides a way to get the current map scale?

2 Answers 2

14

You can get the current zoom level using getZoom().

Assuming that you're using the tile layer system as used by Google Maps, Bing, Open Street Map and Esri, you can use that to infer the scale - see What ratio scales do Google Maps zoom levels correspond to?

If you're not using that tile system, you may need to find another way to infer the scale from the zoom level.

There is a scale control but this only shows a scale bar, not the scale value. As far as I can see, the L.control.scale object doesn't contain the scale value.

enter image description here

1
  • 1
    I like that idea. Just create a web merc mapping of the scales:zoomLevel. No need to worry about DPI pixels per liner measurement. Simple solution!
    – user714157
    Jun 15, 2016 at 19:06
7

If you want just the label:

// add a scale at at your map.
var scale = L.control.scale().addTo(map); 

// Get the label.
var metres = scale._getRoundNum(map.containerPointToLatLng([0, map.getSize().y / 2 ]).distanceTo( map.containerPointToLatLng([scale.options.maxWidth,map.getSize().y / 2 ])))
  label = metres < 1000 ? metres + ' m' : (metres / 1000) + ' km';

  console.log(label);

Now if you know the dimensions of the scale, drawn upon the map, and the geographical distance of the x axis of the map container from one side to the other, you can calculate the dominator, as seen below:

scale = dimension of the map / distance

Notice that from the scale controller, which Stephen shows, maxWidth is taken into account when leaflet calculates that number. More information on how leaflet calculates the number can be found here.

Said that, you can calculate how many meters each pixel represents by:

// Get the y,x dimensions of the map
var y = map.getSize().y,
    x = map.getSize().x;
// calculate the distance the one side of the map to the other using the haversine formula
var maxMeters = map.containerPointToLatLng([0, y]).distanceTo( map.containerPointToLatLng([x,y]));
// calculate how many meters each pixel represents
var MeterPerPixel = maxMeters/x ;

so if your scale is p pixels long, multiple p by MeterPerPixel to find out the scale value you would add.

// say this is your scale
var scale = L.control.scale().addTo(map);    

// This is the scale denominator
console.log(MeterPerPixel*scale.options.maxWidth);   

warning: LF rounds it as per code here

Currently, as far as I know, where isn't a way for a browser to report the dpi or the resolution of the screen which the map is drawn, so you can not reduce the scale to represent 'cm of map equals meters of distance'

5
  • re: the scale controller is exactly half of the map I'm not sure that this is correct - it's only half of my screenshot, which is a fraction of the whole map. Does your formula still work given that? Jun 15, 2016 at 3:39
  • 1
    you are right! I've corrected my answer, and the code as per your note. Thank you for the feedback!
    – nickves
    Jun 15, 2016 at 11:37
  • Well thats a bummer. I was hoping I was just over looking the API documentation and would not have to extend the library to calculate the map's scale. Thanks
    – user714157
    Jun 15, 2016 at 19:02
  • I guess this indicates that Leaflet is written by (and aimed at) people who don't need to know the map's scale. "Normal" people, in other words ;) Jun 15, 2016 at 23:20
  • I had trouble with your MeterPerPixel calculation. It overflow the calculation when showing the map all zoomed out. And I ended up using: var MeterPerPixel = map .containerPointToLatLng([0, y]) .distanceTo(map.containerPointToLatLng([1,y]) Aug 17, 2021 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.