45

Is there a was of automatically setting the zoom level based on the size of the country that the map has been centered on?

maps.google.com does exactly what I need, so, for example, if I search for Russia I get a zoom level such that Russia just fits on screen, and when I search for Cuba I get a higher zoom level so that Cuba just fits.

Is there some way of giving the Maps Api a country location and getting an appropriate zoom level.

If not, I guess that I would have to manually (ugh!) create my own table for this information. Or is this information freely available somewhere?

Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
krishnaz
  • 649
  • 2
  • 9
  • 11

4 Answers4

73

For V3 this code worked for me:

var geocoder = new google.maps.Geocoder();
   geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        map.setCenter(results[0].geometry.location);
        map.fitBounds(results[0].geometry.viewport);
      }
    });
Mahesh M
  • 1,219
  • 10
  • 18
  • 6
    Worked perfectly. Thanks for adding the updated version for V3. Much appreciated. – Ryan Shih Dec 22 '12 at 21:39
  • 2
    Great. Works with any place. Cities, provinces, countries etc. – Phius Apr 02 '13 at 13:59
  • Are the arguments to `setCenter` and `fitBounds` right? I can't seem to get this working, got a JS error saying "too much recursion" - `map.setCenter(lat, lon);` works. – Alix Axel Jul 06 '13 at 11:40
  • Could `address` be just a country's name? – PlayHardGoPro Jun 06 '19 at 13:58
  • 1
    do people really think this is good? (not the answer) but I mean the actual implementation by Google? some countries barely take up any of the screen. is there no way to set it and say "take up 80% of my container" surely that's implemented somehow? – Red Baron Jun 09 '20 at 20:13
50

For API v3 check this answer.

You can use the Google Maps Client-side Geocoder to get the bounding box of the country, as in the following example:

// API version 2
var geocoder = new GClientGeocoder();

geocoder.getLocations("Russia", function (locations) { 

    var north = locations.Placemark[0].ExtendedData.LatLonBox.north;
    var south = locations.Placemark[0].ExtendedData.LatLonBox.south;
    var east  = locations.Placemark[0].ExtendedData.LatLonBox.east;
    var west  = locations.Placemark[0].ExtendedData.LatLonBox.west;

    var bounds = new GLatLngBounds(new GLatLng(south, west), 
                                   new GLatLng(north, east));

    map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
});

// API version 3
// ... set north, south, east and west ...
var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(south, west), 
                                          new google.maps.LatLng(north, east));
map.fitBounds(bounds);

The screenshots below show the results of the above technique when searching for Russia and Cuba:

Zoom on Russia and Cuba

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
  • 2
    Excellent, that was perfect thanks. I'm working in GWT and it can't yet access ExtendedData, so I had to create some JSNI methods to do that. One thing that got me for a while: make sure the map is visible when calling getBoundsZoomLevel, otherwise it returns a zoom level of zero. – krishnaz Feb 15 '10 at 16:59
  • @krishnaz: Good job. Thanks for sharing the `getBoundsZoomLevel()` tip. – Daniel Vassallo Feb 15 '10 at 17:03
  • 2
    I'm looking at the api and I'm not seeing a way (at the moment) to do this with V3. I'd like to do it for a city as well. – Casey Nov 01 '10 at 01:21
  • I think this is what I was looking for http://stackoverflow.com/questions/3245564/google-maps-v3-automating-zoom-level – Casey Nov 01 '10 at 01:23
  • Im having better luck with VIEWPORT – Daij-Djan Apr 14 '14 at 14:22
  • with API V3 you can do that : map.fitBounds(results[0].geometry.bounds); no need to calculate bounds – altore Jan 06 '15 at 11:37
4

If you don't want to use the geocoder client from google, because of usage limitations you could use your own list. You can get one from this github repo.

Here is a code example using jQuery's getJSON function and google maps API v3:

    function initialize() {
      // read the list of countries
     $.getJSON('countries.json', function (countries) {

         // will use the country with index 40 (Cyprus)
         var index_country = 40;
         var myOptions = {
             center: new google.maps.LatLng(
                 countries[index_country].center_lat,
                 countries[index_country].center_lng),
         }
         var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

         // set the bounds of the map
         var bounds = new google.maps.LatLngBounds(
             new google.maps.LatLng(countries[index_country].sw_lat, countries[index_country].sw_lng),
             new google.maps.LatLng(countries[index_country].ne_lat, countries[index_country].ne_lng) );

         map.fitBounds(bounds);
     });
 }
Mihai Crăiță
  • 3,328
  • 3
  • 25
  • 37
2

If you don't use google maps api and just use their geocoding you can use this formula:

var url = 'http://maps.google.com/maps/geo?q=YOUR_QUERY&output=json&oe=utf8&sensor=false&key=YOUR_KEYback=geoCodeDone';
jQuery.getScript(url);


function geoCodeDone(data)
{
    if (data.Status.code == 200)
    {
        lng = data.Placemark[0].Point.coordinates[0];
        lat = data.Placemark[0].Point.coordinates[1];

        var east  = data.Placemark[0].ExtendedData.LatLonBox.east;
        var west  = data.Placemark[0].ExtendedData.LatLonBox.west;

        var zoom = 11 - Math.round(Math.log(Math.abs(west-east))/Math.log(2));
    }
}
Denis Shishkov
  • 329
  • 2
  • 4