'Convert Google Map zoom level into km

Can anyone help me to calculate or convert google map camera zoom level into KM distance . I want to send distance to api to get more pin data when user zoom out google map.



Solution 1:[1]

You can calculate the distance between the center of the map and the top left coordinate like this:

VisibleRegion visibleRegion = mMap.getProjection().getVisibleRegion();
double distance = SphericalUtil.computeDistanceBetween(
            visibleRegion.farLeft, mMap.getCameraPosition().target);

enter image description here

Note that I'm using the SphericalUtil.computeDistanceBetween method from the Google Maps Android API Utility Library.

Solution 2:[2]

I have my simple conversion of zoom level (zl) to km. If zl1 = 40,000km and zl2 = 20,000km and so on. So every level will half the km.Therefore,

km = ( 40000/2 ^ zl ) * 2

e.g. zl = 4

km = (40000/2^4) * 2
   = 5000km

Solution 3:[3]

I really like the simplicity of @lambda solution but it seems zoom levels have been rescaled.

When I do my tests I have zl3 = 38Mm , zl6 = 4.8Mm , zl9 = 600km ... BUT this is only reliable on the equator, you have to add another multiplier to account for latitude.

So my final formule looks like this :

km = (38000 / 2 ^ ( zl - 3)) * cos(lat)

with zl = map zoom level and lat = latitude of map's center in degre

For JS user you can copy this :

const km = 38000 / Math.pow(2, zl - 3) * Math.cos(lat * Math.PI / 180);

And now it is time to make the reverse formula :

zl = log2(38000 * cos(lat) / km) + 3

Which translate to JS as :

const zl = Math.log2(38000 * Math.cos ( lat * Math.PI / 180) / km) + 3

PS : I don't know if resolution have an impact, I am using a full HD screen (1920 x 1080)

Solution 4:[4]

A good start can be:

https://developers.google.com/maps/documentation/android-api/utility/#spherical

I myself use the SphericalUtil class but it's not accurate:

https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/SphericalUtil.java

additional code :

private void animateToMeters(int meters, LatLng ll) {
        int mapHeightInDP = 256;
        Resources r = getResources();
        int mapSideInPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mapHeightInDP, r.getDisplayMetrics());

    LatLngBounds latLngBounds = calculateBounds(ll, meters);
    if (latLngBounds != null) {
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(latLngBounds, mapSideInPixels, mapSideInPixels, MARKER_BOUNDS);
        if (gMap != null)
            gMap.animateCamera(cameraUpdate);
    }
}

@NonNull
private LatLngBounds calculateBounds(LatLng center, double radius) {
    return new LatLngBounds.Builder().
            include(SphericalUtil.computeOffset(center, radius, 0)).
            include(SphericalUtil.computeOffset(center, radius, 90)).
            include(SphericalUtil.computeOffset(center, radius, 180)).
            include(SphericalUtil.computeOffset(center, radius, 270)).build();
}


private LatLng centerMapOnMyLocation() {
        Location locationCt = getLastKnownLocation();
        if (locationCt == null) {
            return null;
        }

        LatLng latLng = new LatLng(locationCt.getLatitude(), locationCt.getLongitude());
           .icon(BitmapDescriptorFactory.fromResource(android.R.drawable.ic_menu_add)));

        gMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        return latLng;
    }

Usage:

LatLng ll = centerMapOnMyLocation();
if (ll != null) {
    animateToMeters(1500, ll);
}

EDIT

Zohaib Akram your result, 9504762.698378386, could be because map did not complete loading.

It you tailor your code to a button listener and click this button a few seconds later you will see different result.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 antonio
Solution 2
Solution 3 Alter Lagos
Solution 4