views:

814

answers:

3

Hi

I'm using Google's Geocoder to find lat lng coordinates for a given address.

    var geocoder = new google.maps.Geocoder();
    geocoder.geocode(
    {
        'address':  address,
        'region':   'uk'
    }, function(results, status) {
        if(status == google.maps.GeocoderStatus.OK) {
            lat: results[0].geometry.location.lat(),
            lng: results[0].geometry.location.lng()
    });

address variable is taken from an input field.

I want to search locations only in UK. I thought that specifying 'region': 'uk' should be enough but it's not. When I type in "Boston" it's finding Boston in US and I wanted the one in UK.

How to restrict Geocoder to return locations only from one country or maybe from a certain lat lng range?

Thanks

+2  A: 

According to the docs, the region parameter seems to set a bias only (instead of a real limit to that region). I guess when the API doesn't find the exact address in the UK place, it will expand it search no matter what region you enter.

I've fared pretty well in the past with specifying the country code in the address (in addition to the region). I haven't had much experience with identical place names in different countries yet, though. Still, it's worth a shot. Try

'address': '78 Austin Street, Boston, UK'

it should return no address (Instead of the US Boston), and

'address': '78 Main Street, Boston, UK'

Should return the Boston in the UK because that actually has a Main Street.

Update:

How to restrict Geocoder to return locations only from one country or maybe from a certain lat lng range?

You can set a bounds parameter. See here

You would have to calculate a UK-sized rectangle for that, of course.

Pekka
Typing in "Boston" returns the one in US, typing in "Boston, UK" returns the one in UK. Why if I'm connecting from Europe a US based location is returned first? I can't force my users to type in country code :(
6bytes
Daniel Vassallo
@Daniel that's odd. I get a clear "address not found" when I type in that address in Google Maps. (A geocoding result should come with an extremely low `accuracy` value.)
Pekka
@6bytes: I think that in case of ambiguity, Google tends to select the most popular city (This was discussed on Stack Overflow once: it looks like it chooses the one with the biggest population). Obviously the `region` parameter should be returning the UK city, but apparently it is not reliable yet. The only reliable way I am aware of at the moment is to concatenate ', UK' to your address. If users add the country code and you add the UK part twice, it won't hurt either (even though you might want to check for that).
Daniel Vassallo
@Pekka: Yes in the public Google Maps (maps.google.com). But try it out with the example in my answer, using the Maps API. The Google Maps API and the public Google Maps seem to use different data sets sometimes. I've witnessed this a few times. In some places, even the imagery and the road maps are different.
Daniel Vassallo
@Daniel interesting. I don't have a Maps API environment handy right now (I'm at work)... Can you see what `accuracy` you get for that address? Does that invalidate our approach (adding `,UK` to the address)?
Pekka
@Pekka: Regarding the accuracy value, the version 3 of the Maps API (the one the OP is using apparently), is not returning an accuracy value anymore. It is using an enumaration of the `GeocoderLocationType` class: http://code.google.com/apis/maps/documentation/v3/reference.html#GeocoderLocationType. Both return `RANGE_INTERPOLATED`. Using just `Boston, UK` returns `APPROXIMATE`. As you can see, this cannot be relied upon. I would have expected `Boston, UK` to return `GEOMETRIC_CENTER`, for example, and `78 Austin Street` to return `APPROXIMATE` at least... or maybe `WILD GUESS :)`.
Daniel Vassallo
@Daniel cheers, good to know, I haven't had the opportunity to work with V3 yet. Hmm, crap. Then, there may be no way around either setting `bounds` in the request options (which would mean calculating a country rectangle) or checking the *result* for the country?
Pekka
@Pekka: There is according to the docs, but it is not reliable (at least at the moment). (http://code.google.com/apis/maps/documentation/v3/reference.html#GeocoderRequest). I tried setting the `bounds` to SW: `49.00, -13.00`, NE: `60.00, 3.00`, and the `region` to `uk`, but the Geocoder still returns the Boston in Massachusetts. The only reliable way around this that I am aware of is to ask the Geocoder for `Boston, UK`.
Daniel Vassallo
@Pekka: Unfortunately the `bounds` parameter doesn't work as expected. Check the new example in my updated answer. This may be because of Google Maps v3 is still a Labs version, or else it just acting a hint, as you suggested initially. However the docs of version 3 do not seem to suggest that it is a hint: `bounds is the LatLngBounds within which to search` and `region is the country code top-level domain within which to search`.
Daniel Vassallo
+5  A: 

In addition to what Pekka already suggested, you may want to concatenate ', UK' to your address, as in the following example:

<!DOCTYPE html>
<html> 
<head> 
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
   <title>Google Maps Geocoding only in UK Demo</title> 
   <script src="http://maps.google.com/maps/api/js?sensor=false" 
           type="text/javascript"></script> 
</head> 
<body> 
   <div id="map" style="width: 400px; height: 300px"></div> 

   <script type="text/javascript"> 

   var mapOptions = { 
      mapTypeId: google.maps.MapTypeId.TERRAIN,
      center: new google.maps.LatLng(54.00, -3.00),
      zoom: 5
   };

   var map = new google.maps.Map(document.getElementById("map"), mapOptions);
   var geocoder = new google.maps.Geocoder();

   var address = 'Boston';

   geocoder.geocode({
      'address': address + ', UK'
   }, 
   function(results, status) {
      if(status == google.maps.GeocoderStatus.OK) {
         new google.maps.Marker({
            position:results[0].geometry.location,
            map: map
         });
      }
   });

   </script> 
</body> 
</html>

Screenshot:

Geocoding only in UK

I find that this is very reliable. On the other hand, the following example shows that neither the region parameter, nor the bounds parameter, are having any effect in this case:

<!DOCTYPE html>
<html> 
<head> 
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
   <title>Google Maps Geocoding only in UK Demo with Bounds</title> 
   <script src="http://maps.google.com/maps/api/js?sensor=false" 
           type="text/javascript"></script> 
</head> 
<body> 
   <div id="map" style="width: 500px; height: 300px"></div> 

   <script type="text/javascript"> 

   var mapOptions = { 
      mapTypeId: google.maps.MapTypeId.TERRAIN,
      center: new google.maps.LatLng(50.00, -33.00),
      zoom: 3
   };

   var map = new google.maps.Map(document.getElementById("map"), mapOptions);   
   var geocoder = new google.maps.Geocoder();

   // Define north-east and south-west points of UK
   var ne = new google.maps.LatLng(60.00, 3.00);
   var sw = new google.maps.LatLng(49.00, -13.00);

   // Define bounding box for drawing
   var boundingBoxPoints = [
      ne, new google.maps.LatLng(ne.lat(), sw.lng()),
      sw, new google.maps.LatLng(sw.lat(), ne.lng()), ne
   ];

   // Draw bounding box on map    
   new google.maps.Polyline({
      path: boundingBoxPoints,
      strokeColor: '#FF0000',
      strokeOpacity: 1.0,
      strokeWeight: 2,
      map: map
   });

   // Geocode and place marker on map
   geocoder.geocode({
      'address': 'Boston',
      'region':  'uk',
      'bounds':  new google.maps.LatLngBounds(sw, ne)
   }, 
   function(results, status) {
      if(status == google.maps.GeocoderStatus.OK) {
         new google.maps.Marker({
            position:results[0].geometry.location,
            map: map
         });
      }
   });

   </script> 
</body> 
</html>

Evidence of the above:

Google Maps Geocoding only in UK Demo with Bounds

Daniel Vassallo
This is what I would call a "dirty fix" but I think I'll have to do that :/
6bytes
@6bytes: It may be a hack, but I still have to find a case where it does not work.
Daniel Vassallo
Great research @Daniel!
Pekka
Quite a bug we've found here :) I hope Google knows about this and will fix it soon.
6bytes
You might also want to post this in the public Google Maps API help forum at http://groups.google.com/group/google-maps-api/topics (if you haven't done so already :-)).
John Mueller
Daniel Vassallo
A: 

In my implementation, both the bounds and the bias parameter are ignored.

For example, the map is centered in the UK. I type in "surrey", and I get Surrey, BC Canada.

I've given up and have applied the kludge above. It will break as soon as I need to cross international boundaries.

I won't ever post a bug report in the Google community again. They take every report of a genuine bug as an attack on Mommy, and I won't put up with that childish garbage anymore.

Some Guy