Creating Geocoding Exceptions for MapPoint Web Service Applications
Stephen Pushee wrote this article on resolving geocoding exceptions when using the MapPoint Web Service. "For example, a user might supply St. Thomas as a city name when searching for St. Thomas the island, not knowing that Charlotte Amalie is the main city on St. Thomas."
Introduction
In many MapPoint Web Service applications, a user supplies a postal code
or city name, which is then sent to MapPoint Web Service to be geocoded
(assigned latitude and longitude coordinates). At times, you may need to override
the geocode provided by MapPoint Web Service or provide a geocode for an
entity that the geocoder does not recognize. For example, a user might supply St.
Thomas as a city name when searching for St. Thomas the island, not knowing that Charlotte
Amalie is the main city on St. Thomas.
You can work around this issue by using a GeoException. A GeoException is
an object consisting of a name (usually a postal code or city) and its corresponding
latitude and longitude. By compiling a list of GeoException objects and making
that list available in your application, you can ensure that your application returns
the results that you expect.
This article describes how to create a geocoding exceptions list as an XML document,
format and store the list, and implement geocoding exceptions in your application.
This article assumes that you are already familiar with the MapPoint Web Service
SOAP API and MapPoint Web Service in general. For more information about
MapPoint Web Service or to sign up for a free evaluation account, visit
the MapPoint Web
Service Web site. For more information about programming with MapPoint Web Service,
see the MapPoint Web Service
SDK.
Creating a Geocoding Exceptions List
A common method of creating an exceptions list is to create an XML file, which you
then add to your project.
The following example shows the contents of an XML file that contains a list of GeoExceptions
<GEOEXCEPTIONS>
<GEOEXCEPTION>
<EXCEPTION>03766</EXCEPTION>
<LATITUDE>36.5977347617212</LATITUDE>
<LONGITUDE>-121.896651249168</LONGITUDE>
</GEOEXCEPTION>
<GEOEXCEPTION>
<EXCEPTION>Hanover,New Hampshire</EXCEPTION>
<LATITUDE>36.5977347617212</LATITUDE>
<LONGITUDE>-121.896651249168</LONGITUDE>
</GEOEXCEPTION>
</GEOEXCEPTIONS>
To add another GeoException to the list, you simply add another GeoException element.
Managing Your GeoExceptions
The work of populating and retrieving values from the GeoExceptions list is done
by the GeoExceptionsManager class (download zip), which contains contains the following items:
1. Constructor that takes the XML file path as a parameter.
2. GeoException class that has Exception, Latitude, and Longitude properties
3. PopulateGeoExceptionsCache method that loads the XML file as an XMLDocument object,
creates an array of GeoException objects and loads the array into Cache.
4. GetGeoException function that takes a string and returns the GeoException if found.
Storing a Geocoding Exceptions List
After you create the geocoding exceptions list, the next task is to store the list
in a format that is easily accessible to your application. I've found that
the best option is to use the ASP.NET Cache object, which stores items in name/value
pairs and allows the developer to add/remove/retrieve items in much the same way as
when using the Session or Application objects. More importantly, when using
the Cache class you can set a 'CacheDependency' on a file (your GeoExceptions
XML File) so that if that file is edited the item in Cache will be thrown out,
forcing the application to re-read the XML and build a new GeoExceptions list that
will be added to Cache. The following is the PopulateGeoExceptionsCache method.
' Load the XML Document
Dim GeoExceptionsXMLDocument As XmlDocument = New XmlDocument
GeoExceptionsXMLDocument.Load(GeoExceptionsFile)
' Build array of GeoException objects
Dim myGeoExceptionNodes As XmlNodeList = _
GeoExceptionsXMLDocument.DocumentElement.GetElementsByTagName("GeoException")
Dim myGeoExceptions(myGeoExceptionNodes.Count - 1) As GeoException
Dim i As Integer = 0
For Each GeoException As XmlNode In myGeoExceptionNodes
Dim myGeoException As New GeoException
For Each Item As XmlNode In GeoException.ChildNodes
Select Case Item.Name.ToUpper
Case "EXCEPTION"
myGeoException.Exception = Item.InnerText
Case "LATITUDE"
myGeoException.Latitude = Item.InnerText
Case "LONGITUDE"
myGeoException.Longitude = Item.InnerText
End Select
Next
myGeoExceptions(i) = myGeoException
i = i + 1
Next
GeoCache.Insert("GeoExceptionsList", myGeoExceptions, _
New CacheDependency(GeoExceptionsFile))
This method is called from the GetGeoExceptions function (below) only when Cache does
not contain the GeoExceptions list.
If GeoException.Trim <> "" Then
GeoException = GeoException.ToUpper
If GeoCache("GeoExceptionsList") Is Nothing Then PopulateGeoExceptionsCache()
For Each Item As GeoException In GeoCache("GeoExceptionsList")
If Item.Exception.ToUpper = GeoException Then
Return Item
End If
Next
Return Nothing
Else
Return Nothing
End If
Using GeoExceptions in your application
At this point your GeoExceptions list is sitting in Cache as an array of GeoException
objects. Now your application can check to see if a user inputted entity such
as a postal code or city is on that list before making a geocoding call to the web
service. Following is the VB.NET code that you might use for such a purpose:
' Check to see if entered address is a GeoException
Dim myGeoExceptionsManager As New GeoExceptionsManager("XMLResources\GeoExceptions.xml")
Dim myGeoException As GeoExceptionsManager.GeoException = _
myGeoExceptionsManager.GetGeoException(PC.Text)
If Not myGeoException Is Nothing Then
' Use GeoExceptions lat/long
Else
' Make call to MapPoint Geocoding service
End If
Conclusion
At times, you may need to provide your own geocodes to make sure that your application
returns the results that you expect. Creating a geocoding exceptions list in XML format
and making it available in your application is an easy-to-implement and scalable solution
for these situations.
Steven holds a BA in Russian Studies from the University of New Hampshire and an MBA from Franklin Pierce College.