Jim's Blog Ramblings about novels, comics, programming, and other geek topics

14Mar/123

How to convert a street address to longitude and latitude (geocoding) via web services (Google)

Google AdSense

Several years ago, I wrote a blog entry detailing how to use geocoder.us (and Yahoo!) web services to geocode an address. Since then both web services have changed a little and I found myself needing to update my code to support non-US locations. Below is sample code showing how to use Google’s Geocoding web service to get longitude and latitude values for addresses.

6Apr/112

How to append options to CascadingDropDown after initially populated via AJAX Web Service

Google AdSense

The setup: Microsoft ASP.NET and AJAX Control Toolkit components

I needed to add additional dropdown options to a DropDownList web control in use by the Ajax Control Toolkit CascadingDropDown ASP.NET AJAX extender. The CascadingDropDown provided a means to get an automatic population of a set of options called by the web service. This AJAX call also passes in the parent item, so that the list items cascade (show items related to the parent control).

An example could be 2 drop down lists: Automobile Make and Automobile Model. If the user selects “Ford” from the Automobile Make drop down list, then only Ford models are listed in the Automobile Model drop down list. If the user changes the Automobile Make to “Honda”, then the items in the Automobile Model changes to show only Honda models.

I needed a way to append an “All” option to the drop down list, but I didn’t want to automatically include “All” as valid option in my Web Service. I wanted to append it on a specific form rather than as part of the data feed.

To start, you need to have a working set of CascadingDropDown web controls. I’m not to explain that set up, because you need to figure out that before you can add additional elements.

28Sep/100

Troubleshooting HTTP 401.1 errors called from localhost

In troubleshooting a web service for another system to connect to one of my systems, I created a simple web service test client. This test client was a WinForms app that executed the web services and rendered the XML display and data in a DataGrid.

The test client app worked fine from my laptop and another server, however, when I tried to run it from the web server (that hosted the web services), I began receiving 401.1 errors.

HTTP 401.1 - Unauthorized: Logon Failed

Below are the 401.1 error details captured in the system’s event log:

Event Type: Failure Audit
Event Source: Security
Event Category: Logon/Logoff
Description: Logon Failure:
Reason: An error occurred during logon
Authentication Package: NTLM
Status code: 0xC000006D

2Sep/101

WCF Error: An error occurred when verifying security for the message

This is one of the trickiest and most obscure errors that I have encountered. I’ve seen this happen twice over the last year or so. The first time, I tried everything and eventually, after spending nearly a day researching and debugging, found the answer.

11Jul/0823

How to render a ASP.NET User Control within a Web Service and return the generated HTML

My needs:

  • Use ASP.NET AJAX PopUpExtender control to provide a mouseover popup with additional content relevant to the GridView row.
  • Use DynamicContextKey to pass in GridView record's unique identifier.

My wants:

  • Use a User Control to render the HTML response, so I don't need to build the HTML code using a StringBuilder or HtmlTextWriter.
First attempt

My initial code was something similar to the below code:

5Oct/0715

How to convert a street address to longitude and latitude (geocoding) via web services

Several years ago, I had a school project that required converting some addresses to longitude/latitude coordinates. We then took the coordinates and placed them on a street map for a mobile device application. The addresses came from a "Yellow Pages" like system lookup service which provided a phone number, street address, name, and business category. But the Yellow Pages service didn't provide a geographic coordinate.

First, I tracked down a free and very useful web service that provides this functionality. The web site GeoCoder.us provides a few different free web services including geocoding on street address, ZIP code, or city and state. GeoCoder.us offers SOAP, XML-RPC, REST-ful RDF, and REST-ful CSV formats.

We'll use the web service the requires a street address, so we can get a more accurate coordinate.

string street = "1060 west addison street";
string city = "chicago";
string state = "il";

The GeoCoder.us URL requires a specific parameter format. Here we append the street, city, and state to the base URL.  Then we create and load the URL into an XML document. By passing the URL to the XmlDocument Load method, it will handle calling and reading the web response.

string geocoderUri = string.Format(
    "http://rpc.geocoder.us/service/rest?address={0},{1},{2}",
    street, city, state);
XmlDocument geocoderXmlDoc = new XmlDocument();
geocoderXmlDoc.Load(geocoderUri);

Next, we need to add a namespace manager since GeoCoder.us uses the W3.org Basic Geo (WGS84 lat/long) vocabulary.  Below is an example of this vocabulary and the actual response that was loaded into our XmlDocument.

<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" 
         xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" 
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<geo:Point rdf:nodeID="aid62658379">
<dc:description>1060 W Addison St, Chicago IL 60613</dc:description>
<geo:long>-87.655788</geo:long>
<geo:lat>41.947372</geo:lat>
</geo:Point>
</rdf:RDF>

The namespace manager is needed so that we can select the long and lat XML nodes. Below we select the two XML nodes and parse them.

XmlNamespaceManager nsMgr =
    new XmlNamespaceManager(geocoderXmlDoc.NameTable);
nsMgr.AddNamespace("geo",
    @"http://www.w3.org/2003/01/geo/wgs84_pos#");

string sLong = geocoderXmlDoc.DocumentElement.SelectSingleNode(
        @"//geo:long", nsMgr).InnerText;
string sLat = geocoderXmlDoc.DocumentElement.SelectSingleNode(
        @"//geo:lat", nsMgr).InnerText;

double latitude = Double.Parse(sLat);
double longitude = Double.Parse(sLong);

Console.WriteLine("Lat: " + latitude + " Lon: " + longitude);

Finally, the coordinates are printed to the console and appear as:

Lat: 41.947372 Lon: -87.655788

Update: 10/6/2007 Once you have the coordinates, you can perform radius searching. For example, you can query for all records within 5 miles of each other or find the nearest record to another record. Troy DeMonbreun provides an example of how to calculate the distance between two geographic coordinates using a SQL Server UDF (User Defined Function). The GeoCoder.us blog also discusses how to calculate distances using two geographic coordinates.

Update 2: 10/19/2007 Yahoo also provides a very nice Web Service for geocoding at Yahoo! Maps Web Services - GeoCoding API. Yahoo uses the same REST method for the accessing the Web Service, but with separate URL parameters for city, address, and state. Yahoo's XML response doesn't use namespaces and won't require the use of a NamespaceManager. You'll be able to just use SelectSingleNode(@"//Longitude") and SelectSingleNode(@"//Latitude") to collect the geographic coordinates.

 

kick it on DotNetKicks.com