Last Updated: February 25, 2016
·
5.448K
· Jeroen Rosenberg

Optimal zoom level in google maps

I'd like to present a function in coffeescript to calculate the optimal zoom level for google maps. It uses the Haversine formula.

First, we need to define some constants

@MEAN_RADIUS_EARTH_IN_KM = 6371
@DEG_TO_RAD_DIVISOR = 57.2957795
@ZOOM_FACTOR = 1.6446

We need a function to convert degrees to Radians

toRadians = (degrees) ->
     degrees / DEG_TO_RAD_DIVISOR

Then we need the Haversine formula

# Haversine formula to calculate the great-circle distance between two points, i.e. the shortest distance over the earths surface
haversine = (maxLat, minLat, maxLng, minLng) ->
    dLat = maxLat - minLat
    dLng = maxLng - minLng
    a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(minLat) * Math.cos(maxLat) * Math.sin(dLng/2) * Math.sin(dLng/2)
    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
    MEAN_RADIUS_EARTH_IN_KM * c

Last, but not least, we need a function to calculate the optimal zoom level for Google maps

optimalZoomLevel = (maxLat, minLat, maxLng, minLng) ->
     # min of height and width of element which contains the map
     minMapDimension = Math.min.apply @, [window.mapCanvas.width(),window.mapCanvas.height()]

     [maxLat, minLat, maxLng, minLng] = [maxLat, minLat, maxLng, minLng].map (l) -> toRadians(l)
     greatCircleDistance = haversine(maxLat, minLat, maxLng, minLng)
     Math.floor(8 - Math.log(ZOOM_FACTOR * greatCircleDistance / Math.sqrt(2 * (minMapDimension * minMapDimension))) / Math.log (2))

Here the initialization function for the map.

initializeMap = (lat, lng, zoomLevel) ->
     mapOptions = 
          zoom: zoomLevel
          center: new google.maps.LatLng(lat, lng)
          mapTypeId: google.maps.MapTypeId.ROADMAP
          disableDefaultUI: true

     window.map = new google.maps.Map(window.mapCanvas[0], mapOptions)

Create a reference to your map canvas

window.mapCanvas = $('#map_canvas')

Calculate the zoom level

#generate optimal zoom level for Mediterranean area
zoomLevel = optimalZoomLevel(44.4, 35.0, 32.4, -2.5)

And initialize the map

initializeMap(41.0, 11.0, zoomLevel)