Geocoding APIs

I am building my first Windows Phone 7 Application. As part of the applications requirements, I need to find the geo coordinates of cross streets. Unlike many phone apps, I do not need to gather that information real-time. Rather, I have a database of 700 cross streets (key locations) that I will load into the phone at app start-up and then use the built in GeocordinateWatcher class of the .NET phone framework to compare to this list when the PositionChanged  event is raised. The problem is that the initial list of 700 addresses do not have geocoordinates. I built an application that hits the major map APIs (Yahoo, Bing, Google) to see how well they can create geocoordinates from cross street information that can be used by my phone application.

Bing

I started with Microsoft because this is a .NET application. The really cool thing about the Microsoft API is that I can consume the WCF service so there is no HTTP requests to code or XML/JSON responses to parse.

string queryString = String.Format("{0} AT {1} {2}, NC", intersection.RoadA, intersection.RoadB, crash.City); string results = string.Empty; GeocodeRequest geocodeRequest = new GeocodeRequest(); geocodeRequest.Credentials = new GeocodeService.Credentials(); geocodeRequest.Credentials.ApplicationId = "XXXXXXXXXX"; geocodeRequest.Query = queryString; ConfidenceFilter[] filters = new ConfidenceFilter[1]; filters[0] = new ConfidenceFilter(); filters[0].MinimumConfidence = GeocodeService.Confidence.High; GeocodeOptions geocodeOptions = new GeocodeOptions(); geocodeOptions.Filters = filters; geocodeRequest.Options = geocodeOptions; GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService"); GeocodeResponse geocodeResponse = geocodeServiceClient.Geocode(geocodeRequest); if (geocodeResponse.Results.Length > 0) { if (geocodeResponse.Results[0].Locations[0].Latitude >= 33 && geocodeResponse.Results[0].Locations[0].Latitude <= 36 && geocodeResponse.Results[0].Locations[0].Longitude >= -84 && geocodeResponse.Results[0].Locations[0].Longitude <= -76) { intersection.Latitude = geocodeResponse.Results[0].Locations[0].Latitude; intersection.Longitude = geocodeResponse.Results[0].Locations[0].Longitude; intersection.GeoCodeSource = "Bing"; } }

Getting a developer key was a snap because I already had a liveID.

· Search Result Rating = Medium

· Developer Experience = High

Yahoo

I then went to Yahoo to supplement the data that was not found by Bing. Coding the Yahoo API was a straight Web Request/Response:

StringBuilder queryString = new StringBuilder(); queryString.Append("http://where.yahooapis.com/geocode?"); queryString.Append("?street="); queryString.Append(intersection.RoadA); queryString.Append("&xstreet="); queryString.Append(intersection.RoadB); queryString.Append("&city="); queryString.Append(intersection.City); queryString.Append("&state=NC"); queryString.Append("&appid="); queryString.Append("XXXXXX--"); HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(queryString.ToString()); WebResponse webResponse = webRequest.GetResponse(); Stream stream = webResponse.GetResponseStream(); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(stream); if(xmlDocument != null) { XmlNode rootNode = xmlDocument.DocumentElement; string returnCode = rootNode.SelectSingleNode("Error").InnerText; if (returnCode == "0") { double latitude = Double.Parse(rootNode.SelectSingleNode("Result/latitude").InnerText); double longitude = Double.Parse(rootNode.SelectSingleNode("Result/longitude").InnerText); if (latitude >= 33 && latitude <= 36 && longitude >= -84 && longitude <= -76) { intesection.Latitude = latitude; intesection.Longitude = longitude; intesection.GeoCodeSource = "Yahoo"; } } }

Getting the applicationId was a snap because I already had a YahooId. The one amusing thing to me is that when I went to Yahoo Search and tped in “Maps”, Google’s Map page came up before Yahoo.

clip_image002[4]

· Search Result Rating = Medium

· Developer Experience = Medium

Google

I then tried Google’s API. Coding Google was the same as Yahoo (using HTTP Request and Response) with a slightly less verbose query string:

StringBuilder queryString = new StringBuilder(); queryString.Append("http://maps.googleapis.com/maps/api/geocode/xml?"); queryString.Append("?address="); queryString.Append(intersection.RoadA); queryString.Append(" + and + "); queryString.Append(intersection.RoadB); queryString.Append("&city="); queryString.Append(intersection.City); queryString.Append("&state=NC"); queryString.Append("&sensor="); queryString.Append("false");

The problem was that the data coming back is all wrong. For example, I tried to geocode a major street intersection near my house (you can put this into your browser to see the results):

http://maps.googleapis.com/maps/api/geocode/xml?address=I 440+&+Wake Forest Road+Raleigh,+NC&sensor=false

Check out what I got back:

clip_image001

I then tried this:

http://maps.googleapis.com/maps/api/geocode/xml?address=I 440+and+Wake Forest Road+Raleigh,+NC&sensor=false

clip_image003

At least I am in the country now, but not anywhere near the intersection.  It appears that Bing and Yahaoo have a much better way of geocoding cross streets. After too many false-positives (and no correct hits), I gave up on the Google API. The nice thing about the Google API is that I didn’t have to register for an app id. The not-so-nice thing is that I am limited to 2,500 a day unless I joined something called Premium Developer.

· Search Result Rating = Low

· Developer Experience = Medium

For my project then I am using Bing and supplementing with Yahoo. I am not using Google.

Advertisements

One Response to Geocoding APIs

  1. Jeremy Burns says:

    Great info!! I have been working with maps more than I would like to these days and I am sure I will be able to use the advice you have given here, thanks!! And I think the 2500 limitation to google maps v3 is per IP address, so you actually get way more requests than just 2500 that way…just food for thought incase you were wanting to use it on any projects…thanks for you info!!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: