Click here to Skip to main content
15,878,852 members
Articles / Programming Languages / C#

Reverse Geocoding with C# and MapPoint 2009

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
26 Mar 2009CPOL2 min read 61.6K   1.1K   27   12
Use C# and MapPoint 2009 to find a street address from a latitude/longitude.

Image 1

Introduction

This article demonstrates using C# and MapPoint 2009 to look up a street address from a latitude/longitude. MapPoint does not use a Web Service. All data is stored locally, on the user's machine. From my research, MapPoint provides the most economical solution to perform a reverse geocode locally. Libraries from vendors such as ThinkGeo or GeoFrameworks cost upwards of $3000 while MapPoint costs $300.

Background

You can download the MapPoint North America 2009 trial from http://www.microsoft.com/downloads/details.aspx?FamilyID=60905dfe-5aea-44ec-b5fb-0e4130c3e7e5&DisplayLang=en. The download is a whopping 1.2GB, because it contains all of the geographic information for North America.

MapPoint does not include .NET assemblies, and can only be interfaced through COM. If you are my age (26), you may not have much experience using COM. The Windows SDK includes a tool called tlbimp.exe to generate a .NET assembly from a COM Type Library. The assembly, Interop.MapPoint.dll, is included in the code download, and you can generate it yourself with the command:

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\tlbimp.exe" 
 "C:\Program Files\Microsoft MapPoint 2009\MPNA83.tlb" /out:c:\Interop.MapPoint.dll
 /namespace:Interop.MapPoint

For more information on COM, I recommend http://en.wikipedia.org/wiki/Component_Object_Model.

Using the code

The method Map.ObjectsFromPoint(int x, int y) queries MapPoint for objects at a given latitude/longitude. This method returns street addresses, countries, restaurants, and anything else in the MapPoint database. We implement the method:

C#
private StreetAddress LookupStreetAddress(Location loc)
{
    FindResults arr = _map.ObjectsFromPoint(_map.LocationToX(loc), _map.LocationToY(loc));
    return arr.OfType<location>().Where(o => o.StreetAddress 
       != null).Select(o => o.StreetAddress).FirstOrDefault();
}

to cull the results for a street address. If location does not touch a street, it is unlikely that a street address will be returned. MapPoint does not include a method to find the nearest street address.

Our algorithm for GetNearestAddress

Streets seem to be around .0001 degrees in width, so our algorithm uses a grid of points .0001 degrees apart. We iterate through the points, from closest to farthest from the starting location, calling LookupStreetAddress on each point until a match is found.

C#
public StreetAddress GetNearestAddress(double lat, double lon)
{
    if (lat == double.NaN || lon == double.NaN)
    {
        return null;
    }

    // MapPoint needs to be centered
    _map.GoToLatLong(lat, lon, 1);

    // Zoom level seems to affect what is returned...
    // haven't figured out the pattern here
    for (int i = 0; i < 10; i++)
    {
        _map.ZoomIn();
    }

    // make 10 squares around, each .0001 degrees apart
    StreetAddress addr;
    for (int i = 0; i < 10; i++)
    {
        foreach (Location loc in GetPointsAround(lat, lon, i, .0001))
        {
            if ((addr = LookupStreetAddress(loc)) != null)
            {
                return addr;
            }
        }
    }

    return null;
}

And there you have it. I have used this with a GPS device and was able to accurately see my current address.

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Walter Diego Luque30-Sep-10 9:21
Walter Diego Luque30-Sep-10 9:21 
GeneralI use SQL 2005 to find near address Pin
x89327-Mar-09 15:53
x89327-Mar-09 15:53 
Generalfree Pin
radioman.lt27-Mar-09 1:55
radioman.lt27-Mar-09 1:55 
GeneralRe: free Pin
Richard Marsden27-Mar-09 3:46
Richard Marsden27-Mar-09 3:46 
GeneralRe: free Pin
radioman.lt27-Mar-09 4:28
radioman.lt27-Mar-09 4:28 
GeneralRe: free Pin
Frank Meffert27-Mar-09 7:25
Frank Meffert27-Mar-09 7:25 
GeneralRe: free Pin
james.wren27-Mar-09 7:49
james.wren27-Mar-09 7:49 
GeneralRe: free Pin
Frank Meffert27-Mar-09 9:38
Frank Meffert27-Mar-09 9:38 
GeneralRe: free Pin
Stefano Straus25-Apr-09 22:01
Stefano Straus25-Apr-09 22:01 
GeneralRe: free Pin
Frank Meffert27-Apr-09 5:39
Frank Meffert27-Apr-09 5:39 
GeneralFree but against the Google API terms Re: free Pin
Member 888754525-Apr-12 21:47
Member 888754525-Apr-12 21:47 
GeneralRe: free Pin
james.wren27-Mar-09 7:55
james.wren27-Mar-09 7:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.