# Duncan's blog

## October 19, 2013

### Google maps – map size

Filed under: Google Maps,Javascript — duncan @ 10:47 am
Tags: , ,

I posted an answer in response to this question on StackOverflow, ‘How can I know the actual scale that my Google maps is currently in?‘.  Which perhaps didn’t exactly answer Joaquín M‘s problem, but I thought was useful enough anyway to warrant its own blog post, in my infrequent Google Map API series.  In his question he stated “The information I need is the actual width in kilometers of my map“, which my answer does do.

What we want to do is have an event listener for whenever the size of the map changes, using the `bounds_changed` event.  This way we get the updated size if the user resizes the window or adjusts the zoom.  And in fact this also happens when the map first appears.  If we try and use `map.getBounds`() within our initialize function, we run the risk of calling it too soon before the map has fully rendered, so we need that event listener.

We can find out the map’s size from its bounds, which represent a rectangular box of what’s currently visible.  But from the bounds object, we can only find out the coordinates for its north-east and south-west corners.  So we’ve still got a bit of work to do to turn this into a distance.

We’ll need to use the geometry library to turn degrees into metres.  So we specify `libraries=geometry` in the Google Maps API URL.

Let’s assume we have a map with its north-east coordinates as (lat1, lng1) and its south-west coordinates as (lat2, lng2), e.g.:

Sidenote: confusingly whenever I look at coordinates I always think of Cartesian coordinates, e.g. (x, y), where the first value x represents the horizontal value, and the second value y represents the vertical value.  However when dealing with LatLng objects in Google Maps it’s always latitude first (degrees north/south from the equator), then longitude second (degrees east/west from the Greenwich meridian).  So that’s how I’ll be referring to them here.

I’m assuming we want to calculate both the width and height of the bounds, not just its area or the diagonal distance between the two corners.  So what we really need to do is work out the vertical distance from lat1 to lat2, and then the horizontal distance from lng1 to lng2.  To do this we have to construct LatLng objects representing the points (lat1, lng1) and (lat2, lng1) [fig 1] for the vertical distance.  And again (lat1, lng1) and (lat1, lng2) [fig 2] for the horizontal.  Or equally we could have done (lat1, lng2) – (lat2, lng2), and then (lat2, lng1) – (lat2, lng2).

Fig 1

Fig 2

I could have simply put all the below into the initialize function.  However certain parts of it made sense to put into their own functions, as they could then easily be re-used, e.g. for any time we might want the distance between any two points on the map, or for calculating the distance of any rectangular area on the map.

```<!DOCTYPE html>
<html>
<title></title>

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 90% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>

<script type="text/javascript">
function initialize() {
var homeLatlng = new google.maps.LatLng(51.476706,0); // London

var myOptions = {
zoom: 15,
center: homeLatlng,
};

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

var bounds = map.getBounds();

var sizes = getBoundsSize(bounds);

\$('#size').text(sizes.horizontalkm + ' km horizontal, ' + sizes.verticalkm + ' km vertical');
});
}

function getBoundsSize(bounds) {
var sizes, NE, SW, lat1, lat2, lng2, lng2, horizontalLatLng1, horizontalLatLng2, verticalLatLng1, verticalLatLng2, horizontal, vertical;

// get the coordinates for the NE and SW corners
NE = bounds.getNorthEast();
SW = bounds.getSouthWest();

// from that, figure out the latitudes and the longitudes
lat1 =  NE.lat();
lat2 =  SW.lat();

lng1 =  NE.lng();
lng2 =  SW.lng();

// construct new LatLngs using the coordinates for the horizontal distance between lng1 and lng2

// construct new LatLngs using the coordinates for the vertical distance between lat1 and lat2

// work out the distance horizontally
horizontal = getDistance(horizontalLatLng1, horizontalLatLng2);

// work out the distance vertically
vertical = getDistance(verticalLatLng1, verticalLatLng2);

// round to kilometres to 1dp
sizes = {
horizontalkm: convertMetresToKm(horizontal),
verticalkm:   convertMetresToKm(vertical)
};

return sizes;
}

function getDistance(point1, point2) {
// computeDistanceBetween is fine if we only have 2 points, but if we have more we need to use computeLength
}

function convertMetresToKm(metres) {
return Math.round(metres / 1000 *10)/10;    // distance in km rounded to 1dp
}

</script>
<body>
<div id="map_canvas"></div>
<div id="size"></div>
</body>
</html>```

And finally you end up with a map looking something like this, and as you zoom or resize the window, the sizes update.