3

so.. i run into a possibly very common problem.

just started implementing google maps api, and following is my code to resolve a city into lat/lang and center the map there:

function SetMapAddress(address) {  // "London, UK" for example 
  var geocoder = new google.maps.Geocoder();
  if (geocoder) {
     geocoder.geocode({ 'address': address }, function (results, status) {
     if (status == google.maps.GeocoderStatus.OK) {
        var loc = results[0].geometry.location;
        document.map.setCenter(new google.maps.LatLng(loc.lat(),loc.lng(), 13));
     }

the problem is that i am passing a static zoom (13).

if someone types a name of a country, i'd like to zoom out more. if it is a city, i'd like to zoom in more etc..

the only thing i can think of is to figure out appropriate zoom for every city and country, store them in some hash, and try to figure out which is being used, to pass appropriate zoom.

maybe google thought of a more intelligent approach ?

Sonic Soul
  • 23,855
  • 37
  • 130
  • 196

3 Answers3

8

The geocoder returns a "recommended" viewport

Which you can use in your SetMapAddress function like this:

 function SetMapAddress(address) {  // "London, UK" for example 
   var geocoder = new google.maps.Geocoder();
   if (geocoder) {
      geocoder.geocode({ 'address': address }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          document.map.fitBounds(results[0].geometry.viewport);
        }
      });
   }
 }
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • There is also a bounds returned in the result, which the documentation describes as "The precise bounds of this GeocodeResult, if applicable". It might (if it exists) be a closer zoom than the "recommended" viewport. – geocodezip Jul 05 '12 at 02:54
1

The geocoding result provides the address_components array containing the Address component types for the query.

From my very limited testing, the more information is added in the query, the longer this address_components array becomes. When entering "France", it is only the following:

> Object
long_name: "France"
short_name: "FR"

types: Array[2]
> 0: "country"
> 1: "political"

When a city is added, there's a type named "locality". So, you could traverse this array checking if there's a match between the long_names and what the user entered, if only a city or country is typed it is easy, but there are many variations possible, such as Rome/Roma Italy (spelling differences), and if the user entered both a city and country, you have to give priority to the city.

In the end, it sounds like a very fuzzy search-and-match, even if you built your own hash to match user input to possible representations of places.

Here's my lazy approach:

Create var mapZoom = 13; (assume it is a city)

Check if the entire user input is in fact a country name: if it matches a long_name and the entry's type is "country", lower mapZoom to 5.

Apply setCenter with this mapZoom variable.

Tina CG Hoehr
  • 6,721
  • 6
  • 44
  • 57
0

Another (sometimes problematic) solution is to count the length of the address_components array.

As mentioned by Tina CG Hoehr in a different answer, the places object has an address_components array. The array holds the different parts of the address.

You can test the length of the address_components array and set the zoom level appropriately.

Building on your code example,

function SetMapAddress(address) {  // "London, UK" for example 
    var geocoder = new google.maps.Geocoder();
    if (geocoder) {
        geocoder.geocode({ 'address': address }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var loc = results[0].geometry.location;



            // Test address_components
            var ac_length = results[0].address_components.length;

            if (ac_length == 1) {
                // Assume country
                document.map.setCenter(new google.maps.LatLng(loc.lat(),loc.lng(), 3));

            } else if (ac_length == 2) {
                // Assume city
                document.map.setCenter(new google.maps.LatLng(loc.lat(),loc.lng(), 7));

            } else {
                // Everything else can have a standard zoom level
                document.map.setCenter(new google.maps.LatLng(loc.lat(),loc.lng(), 13));
            }



        }
    }
}

This method seems to work okay. Testing it on Australian addresses I found some suburbs had a postcode and some did not - changing the length of the array. The ones without postcodes seemed to be in less populated areas however so having a lower zoom for those was appropriate for my purposes.

Ben
  • 2,143
  • 2
  • 19
  • 27