views:

377

answers:

2

I am using the google geocoding api in my app but im finding it hard to parse the returned address information reliably. Im hoping someone has a library or way of parsing the info to prevent me from having to write this my self and cover every case.

Im using the json api and can extract the address line and the coordinates easily enough and store them in a database, but the problem is extracting the other address information in a reliable way so i can store it.

I have had a look at the XAL structured address specification that google uses for the geocoded data but my problem is the fact that it can cater for every address type in every country makes it hard to parse the result.

Something as simple as a postcode can be nested pretty deep inside any combination of parent tags. even inside one country the way the tree appears can vary which makes it harder than expected to parse.

Ironically my end objective is to store it in a tree (think rails acts_as_tree or similar) in my database, so users can locate the items easily later. eg click on country, state, then region, town, then suburb etc

Im working in rails

+1  A: 

I've done this a couple of times. Their (Google's) sample code works, but is brittle -- and the geocoding data you get back from Google is at best incomplete and at worst inconsistent.

Anyway. All geocoders suck, but at least Google's is free and sucks less than the others.. is it too much to ask for consistency? Sigh. Try the following; you pass it a Placemark (note that the getLocations AJAX method may return multiple) and it will normalize the result. If you want to get fancy, use the placemark.address field -- on occasion it will contain more information than the individual fields. Normally, it will only contain the text you actually sent to be geocoded.

function Mark(placemark) {
  this.latitude = 0.0;
  this.longitude = 0.0;
  this.accuracy = 0;
  this.country = null;
  this.region = null;
  this.city = null;
  this.postalCode = null;
  this.street = null;
  this.address = null;
  this.placemark = placemark;

  if (placemark) {
    if (placemark.Point && placemark.Point.coordinates) {
      this.latitude = placemark.Point.coordinates[0];
      this.longitude = placemark.Point.coordinates[1];
    }

    var elem = placemark.AddressDetails;

    if (elem) {
      this.accuracy = elem.Accuracy;

      if (elem.Country) {
        elem = elem.Country;
        this.country = elem.CountryNameCode;
      }

      if (elem.AdministrativeArea) {
        elem = elem.AdministrativeArea;
        this.region = elem.AdministrativeAreaName;
      }

      if (elem.SubAdministrativeArea) {
        elem = elem.SubAdministrativeArea;
      }

      if (elem.Locality) {
        elem = elem.Locality;
        this.city = elem.LocalityName;
      }

      if (elem.PostalCode) {
        this.postalCode = elem.PostalCode.PostalCodeNumber;
      }

      if (elem.Thoroughfare) {
        this.street = elem.Thoroughfare.ThoroughfareName;
      }
    }
  }
}
Maas
thanks for the code, interesting approach doing the heavy lifting with javascript as opposed to ruby . i am going to try this out
ADAM
.. I'm a fool, I didn't even look at the tags. My bad -- just sort of assumed this was a javascript question. When all you have is a hammer, etc.
Maas
+2  A: 

There is a gem and plugin that encapsulates all of this for you. It's called GeoKit.

It is possible to make it use Google, or a handful of other geocoding service providers. If your models have the proper fields, it can also do distance calculations (the really neat thing is the math for this is done in the SQL).

I have been using it for a long time in one of my production applications to calculate distances between zipcodes for example. As I mentioned, I've been using it in production for quite awhile, so I don't have any concerns about the soundness of the code.

Jared
Thanks i have had a look at this. i originally thought i just handled distances between coordinates and returned raw geocode data, but it appears to atleast try to unify the geocoded data
ADAM