Monday, August 31, 2009

Free GeoCoding ?

Backup pt http://www.viawindowslive.com/Articles/VirtualEarth/Freereversegeocoding.aspx

This article describes how a website VoyageMap.com utilises a free reverse geocoding
data dump from Geonames.org

I restricted the locations to worldwide cities with greater than 1000 residents. This file was available from http://www.geonames.org/ as a data dump. But you can use their free webservice as well by providing Lat and Long values to http://ws.geonames.org/findNearbyPlaceName?lat=47.3&lng=9



Free reverse geocoding by supplying Lat and Long values.
After downloading Cities data dump and importing into my local database I set up a stored procedure to bring back locations that meet the radius parameter and passed in Lat Long values in following sql


SELECT TOP 3
Country.name as country, City.geonameid,City.name, City.latitude, City.longitude,
Avg(3958.75 * ACos(Sin(@Latitude/57.2958) *
Sin(City.Latitude/57.2958) +
Cos(@Latitude/57.2958) *
Cos(City.Latitude/57.2958) *
Cos(City.Longitude/57.2958 - @Longitude/57.2958))) AS miles
FROM
dbo.GeoNamesCity City
join dbo.GeoNamesCountry Country on City.[country code] = Country.[iso alpha2]
WHERE City.Longitude IS NOT NULL AND City.Longitude <> 0
AND City.Latitude IS NOT NULL AND City.Latitude <> 0
AND @Miles >=
(
3958.75 * ACos(Sin(@Latitude/57.2958) *
Sin(City.Latitude/57.2958) +
Cos(@Latitude/57.2958) *
Cos(City.Latitude/57.2958) *
Cos(City.Longitude/57.2958 - @Longitude/57.2958))
)
GROUP BY Country.name, City.geonameid,City.name, City.latitude, City.longitude
ORDER BY miles
Website users can retrieve upto 3 nearest cities to add travel review by right clicking on map

I used the following code to register the click event


map.AttachEvent("onclick",PopupMenu);
Following is how the event is then handled to popup a menu for users to click on to add review, you can see that left click removes the menu


function PopupMenu(e)
{
if (e.eventName == "onclick")
{
if (e.leftMouseButton)
{
RemovePopupMenu(e);
}
else if (e.rightMouseButton)
{
var menu = document.getElementById('popupmenu');
menu.style.left = e.mapX + 'px' ;
menu.style.top = e.mapY + 'px' ;
menu.style.display='block';
popupmenupoint = DoPixelToLL(e.clientX,e.clientY);
}
}
}


To remove the menu


document.getElementById('popupmenu').style.display='none'
I used a web service to query the database and bring back list of cities (you can also use geonames webservice rather than setup your own), the popupmenupoint variable in javascript holds the LatLong values to run against the geonames data dump.



The site heavily uses AJAX model to give users a seamless experience

Conclusion:
For private websites on a limited budget using MapPoint API is an expensive part of retrieving locations by passing Lat Long values, however with free data sources and web services available you can easily integrate reverse lookup into your website.

I would like to thank geonames.org and viavirtualearth.com to allow me to use their data and code snippets that helped in producing this website.

Article contributed by Mo Majad (VoyageMap.com). Have you got something to contribute?