Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

How to Geocode an Address by Postcode / Zipcode and Streetnumber / Housenumber

0.00/5 (No votes)
15 Aug 2014CPOL2 min read 46.5K  
This will explain how to geocode an address only by postalcode / zipcode and streetnumber

Introduction

Geocoding is the process of converting an address (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic coordinates (like latitude 37.423021 and longitude -122.083739).

The Google maps API is a great API to get location information like this. But the fuzzy address parameter (basically an array separated by commas) can be quite cumbersome if you want to get a detailed location but want to use as little information as possible. For instance, to avoid typos. Because when spelling a street name or city wrong, there will be zero results (so much for the fuzzy).

Background

Nowadays, the housenumber (streetnumber) and postalcode (zipcode) combination is sufficient enough in a lot of countries getting a unique specific location of an address without explicitly specifying the street and city.

It would be nice if the Address parameter of the Google maps APIs would support this, but unfortunately that is not the case. Most parts of the address parameter are mandatory as for instance a street name and/or city. So you need at least a street name and a city to get proper results.

In the processing of trial and error, I tried to use wildcards in the address parameter but that is also not supported.

But here's a solution.

Using the Code

Unfortunately, it can't be done in 1 call. To get an appropriate address by housenumber and postalcode, we have basically to perform 3 calls:

  1. Supply the postcode and get the LatLng coordinates
  2. Supply these LatLng coordinates and get the streetname
  3. Finally, combine streetname and housenumber to get the exact coordinates of the address

And this is how we do it (this is JavaScript, don't forget to include the Google maps API in a script tag):

JavaScript
var  geocoder = new google.maps.Geocoder();
var housenumber = 1;
var postalcode = 5171 KW;

geocoder.geocode({ 'componentRestrictions':
{ 'postalCode': postalcode }, region: "nl" }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
    // get the LatLng of the postalcode
    var result = results[0].geometry.location;
}

This will supply the proper LatLng coordinates. Notice we don't use the address parameter at this point yet. Usually we use componentRestrictions in combination with the address parameter, for instance to restrict results to a country only. But you can use componentRestrictions only and it has an important advantage: instead of the fuzzy address parameter, you can explicitly tell it to use the postalcode (and only that) as a search parameter.

Notice that I also used the region parameter to restrict results to a specific country only. You could also use the country parameter instead of the region:

JavaScript
geocoder.geocode({ 'componentRestrictions': 
{ 'postalCode': postalcode, 'country': "nl" }}

But the downside of this is that it always returns a result, even when the postalcode doesn't exist. It returns some kind of global result of the country instead. We don't want that, we want zero results and you should therefore use region.

The next step is to get the global address information of this particular LatLng combination:

JavaScript
var  geocoder = new google.maps.Geocoder();
var housenumber = 1;
var postalcode = 5171 KW;

geocoder.geocode({ 'componentRestrictions':
{ 'postalCode': postalcode }, region: "nl" }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
    // get the LatLng of the postalcode
    var result = results[0].geometry.location;
    geocoder.geocode({ latLng: results[0].geometry.location }, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
        var address;
        // get the streetname:
        if (results[0].types[0] == 'street_address' && results[0].address_components[1]) {
            address = results[0].address_components[1].long_name + " " + housenumber;
        }
        else if (results[0].types[0] == 'route') {
            address = results[0].address_components[0].long_name + " " + housenumber;
        }
    }
}

Now you will have the proper streetname. The next step is to combine the streetname and housenumber and get the exact geocode:

JavaScript
var  geocoder = new google.maps.Geocoder();
var housenumber = 1;
var postalcode = 5171 KW;
var exactAdresLocation;

geocoder.geocode({ 'componentRestrictions':
{ 'postalCode': postalcode }, region: "nl" }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
    // get the LatLng of the postalcode
    var result = results[0].geometry.location;
    geocoder.geocode({ latLng: results[0].geometry.location }, function (results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
        var streetname;
        // get the streetname:
        if (results[0].types[0] == 'street_address' && results[0].address_components[1]) {
            streetname = results[0].address_components[1].long_name ;
        }
        else if (results[0].types[0] == 'route') {
            streetname = results[0].address_components[0].long_name;
        }

        // now combine everything:
        var address = streetname + " " + housenumber;
        geocoder.geocode({ 'address': address, 'componentRestrictions':
        { 'postalCode': postalcode }, region: "nl" }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                exactAdresLocation = results[0].geometry.location;
            }
        });
    }
}

That's it. It took me a while to figure out. I'll hope it will help someone.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)