I'm looking for solution how to get current map size (in kilometers) with current zoom level. Is there a way how to calculate map scale?
1 Answer
Be warned that depending on zoom and tilt the width of map is not constant value, in most extreme cases (like world zoom) the difference can be drastic, but on 2D view and zoomed to city level or so the difference is probably quite small. I assume you want to get width of the visible map view in kilometers, in center or bottom of the map view to calculate scalebar width.
// take 2 map positions, left and right in middle of mapview
ScreenPos sp1 = new ScreenPos(0, mapView.getHeight() / 2);
ScreenPos sp2 = new ScreenPos(mapView.getWidth(), mapView.getHeight() / 2);
MapPos pos1Wgs = mapView.getOptions().getBaseProjection().toWgs84(mapView.screenToMap(sp1));
MapPos pos2Wgs = mapView.getOptions().getBaseProjection().toWgs84(mapView.screenToMap(sp2));
// calculate distance with havershine formula
final double AVERAGE_RADIUS_OF_EARTH = 6378137.0;
double latDistance = Math.toRadians(pos1Wgs.getY() - pos2Wgs.getY());
double lngDistance = Math.toRadians(pos1Wgs.getX() - pos2Wgs.getX());
double a = Math.sin(latDistance / 2.0) * Math.sin(latDistance / 2.0)
+ Math.cos(Math.toRadians(pos1Wgs.getY()))
* Math.cos(Math.toRadians(pos2Wgs.getY()))
* Math.sin(lngDistance / 2.0) * Math.sin(lngDistance / 2.0);
double c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
double distanceMeters = AVERAGE_RADIUS_OF_EARTH * c;
Here is a sample code for Android Java which uses this method to create custom Scalebar: https://github.com/CartoDB/mobile-android-maps-app/blob/master/nuticomponents/src/main/java/com/nutiteq/nuticomponents/customviews/ScaleBarView.java .