adamj
adamj

Reputation: 4782

Get postcode for suburb using Google Places

I'm using Google Place Autocomplete to retrieve the postcode by a suburb name. The code I'm currently using works awesome and does retrieve everything I need, however, it only works for some suburbs for others it doesn't give you the postcode.

For example:

HTML

<input id="supplier-area" type="text">

JS

var autocomplete;

function initialize() {
    autocomplete = new google.maps.places.Autocomplete(
        (document.getElementById('supplier-area')),
        {
            types: ['(cities)'],
            componentRestrictions: {
                country: 'au'
            }
        }
    );

    google.maps.event.addListener(autocomplete, 'place_changed', function() {
        var place = autocomplete.getPlace();
        alert(JSON.stringify(place));
    });
}

initialize();

Upvotes: 2

Views: 9092

Answers (3)

jcrawfor74
jcrawfor74

Reputation: 1742

what Will D, said is correct. A region like Sydney, Melbourne etc will NOT return a postcode, and you therefore need to do a reverse geocode lookup.

I had the exact same problem. I wanted to use the Google Places autocomplete to allow the selection of a suburb and then always return a postcode.

The following JSFiddle shows how to do this. Place Autocomplete Address Form This is the stock code extended with the geocode reverse lookup.

It does to following:

  1. Gets the autocomplete results
  2. If there is no postcode
  3. Get the geo cordinates off the result
  4. Call geocoder.geocode to get an address at the returned co-ordinates
  5. Interrogate the address response and read the city and postcode values off the address returned at those geo coordinates

HTML Changes Add extra fields for lat long

    <tr>
        <td class="label">Lat</td>
        <td class="wideField" colspan="3"><input class="field" id="lat" disabled="true"/></td>
    </tr>
    <tr>
        <td class="label">Long</td>
        <td class="wideField" colspan="3"><input class="field" id="lng" disabled="true"/></td>
    </tr>

Need to ask for not only the address component but geometry so you can get the geo cordinates

autocomplete.setFields(['address_component', 'geometry']);

Function

    function fillInAddress() {
      // Get the place details from the autocomplete object.
      var place = autocomplete.getPlace();

      for (var component in componentForm) {
        document.getElementById(component).value = '';
        document.getElementById(component).disabled = false;
      }

      // Get each component of the address from the place details,
      // and then fill-in the corresponding field on the form.
      for (var i = 0; i < place.address_components.length; i++) {
        var addressType = place.address_components[i].types[0];
        if (componentForm[addressType]) {
          var val = place.address_components[i][componentForm[addressType]];
          document.getElementById(addressType).value = val;
        }    
      }
      // geometry
      var geometry = place.geometry;
      var lat = geometry.location.lat();
      var lng = geometry.location.lng();

      document.getElementById("lat").value = lat;
      document.getElementById("lng").value = lng;

      var postcode = document.getElementById("postal_code");
      if(postcode.value == ""){
        //alert("no postcode use lat/lng to lookup place")
        var geocoder = new google.maps.Geocoder();

        var latlng = {lat: parseFloat(lat), lng: parseFloat(lng)};

         geocoder.geocode({'location': latlng}, function(results, status) {
              if (status === 'OK') {
                if (results[0]) {
                  var faddress = results[0].formatted_address;
                  var addressParts = results[0].address_components;

                  for (var i = 0; i < addressParts.length; i++) {
                    var addressType = addressParts[i].types[0];

                    if (addressType == "postal_code" || addressType == "locality") {
                      var val = addressParts[i][componentForm[addressType]];
                      document.getElementById(addressType).value = val;
                    }    
                  }

                  //alert(faddress);
                } else {
                  window.alert('No results found');
                }
              } else {
                window.alert('Geocoder failed due to: ' + status);
              }
        });

      }
    }

This is based upon the example given by google here Place Autocomplete Address Form

Upvotes: 3

rn3
rn3

Reputation: 1

you can use this

google.maps.event.addListener(autocomplete, 'place_changed', function () {

  var place = autocomplete.getPlace();

  for (var i = 0; i < place.address_components.length; i++) {
    var addressType = place.address_components[i].types[0];
    if (addressType == "postal_code") {
      var postalcode = place.address_components[i].long_name;
      $("#Address_Postcode").val(postalcode);
    }
  }
});

Upvotes: -1

Will D
Will D

Reputation: 884

As Melbourne is a city, it spans many postcodes. Similarly, Richmond is a suburb that spans multiple post codes (3067 in the Northwest and 3121 in most other places).

You need to be more specific in your query to get a postal_code.

If you need the postcode, you can do a reverse geo-code on lat/lng returned from getPlace(). Google typically returns the logical centre of the area you queried (downtown/CBD etc). As the lat/lng is an exact point, not an area, there is no ambiguity and it will have a postcode.

It would have been inappropriate for Google to make this assumption, as it is not correct in all scenarios, but if that is the behaviour your app needs then you can make that decision "deliberately".

Upvotes: 4

Related Questions