Google Maps Reverse Geocoder
Last Updated 21st February 2008
This reverse geo-coder will convert a point on a map to an address. In practice this means the nearest available address.
Feedback
Instructions
- Click anywhere on the map of Belfast
- You should then get a popup window telling you the address of the location you have just clicked.
Credits To
Mapperz Blog (News on Map and GIS Stuff)
Full Credit to Nico Goeminne
Javascript Used
<script type="text/javascript">
// Example reverse geocoding code, using the Google Maps API only.
// Author Nico.Goeminne@UGent.be (modified by Mapperz for UK)
// The algorithm :
// 1. Select the GLatLng point and save it in a variable. (See lastpoint)
// 2. Use the GDirections without a html counterpart,
// use it to find a road between the the point and itself:
// gdir.loadFromWaypoints(lastpoint, lastpoint)
// 3. Using Route, Steps, get the last step, this returns something like
// "East on <b>SOMEROAD.</b>
// 4. Cut out SOMEROAD and use it in the GClientGeocoder
// (in combination with a country location, obtained for example
// by the browers regional settings) -> e.g. SOMEROAD Belgium
// 5. This returns a number of matches (Placemarks)
// Someroad, city 1, belgium, latlng point
// Someroad, city 2, belguim, latlng point
// ...
// 6. Use the distance between the original saved latlngpoint and each
// candidate, and select the one with minimum distance (and for example
// check if the distances is at least less then 1 km)
// 7. Display the selected location and adress on the map.
//<![CDATA[
var map = null; // the GMap
var gdir = null; // the GDirections
var geocoder = null; // the GClientGeoCoder
var lastpoint = null; // the GLatLng point we try to reverse geocode
// this method sets up the map, gdrir and geocoder
function Gload() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(54.59625989280132,-5.92961311340332), 15);
// GDirections without html counterpart.
gdir = new GDirections();
geocoder = new GClientGeocoder();
GEvent.addListener(map, "click", handleClicks);
GEvent.addListener(gdir, "load", onGDirectionsLoad);
GEvent.addListener(gdir, "error", handleErrors);
}
}
function handleClicks(marker, point){
// 1. Select the GLatLng point and save it in a variable
// when the user clicks on the map
lastpoint = point;
// Set the geocoder viewport to reduce the number of results later on (optional)
geocoder.setViewport(map.getBounds());
// delete the marker if it is there (previously reversed geocoded)
if(marker){
map.removeOverlay(marker);
}
else {
// clear the GDirections from previouse load requests.
gdir.clear();
// 2. Use it to find a road between the the point and itself
// Be sure to set the geSteps true, to obtain all the steps
// The locale is not important, the result will be in dutch saying
// Oost on <b>someroad</b> or if you use en_US it will be
// Turn east on <b>someroad</b>
var way = ([point, point]);
gdir.loadFromWaypoints(way,{getSteps: true, locale: "GB"});
}
}
// 3. Using Route, Steps, get the last step
function onGDirectionsLoad(){
var nrroutes = gdir.getNumRoutes();
if (nrroutes != 0) {
var route = gdir.getRoute(0);
var nrsteps = route.getNumSteps();
if (nrsteps != 0) {
var step = route.getStep(0);
// 4. returns "Turn east on <b>someroad</b>", so cut out the street
// and use it in the GClientGeocoder
var street = getStreet(step.getDescriptionHtml());
// The GClientGeoCoder sometimes performs better if we cut out Road, Rd, Rue, Avenue, Way, ...
// -> This should be the "Did you mean" function
street = generalize(street);
// TODO : Should detect the country e.g. by browser region settings
street = street + " UK"
// just checking the street (todo remove alert)
//alert(street);
geocoder.getLocations(street, refine);
}
}
}
// cuts out the street from the step.getDescriptionHtml()
// If the street is a highway the surrounding tags are <wbr> instead of <b>
function getStreet(str){
var street = str.substring(str.lastIndexOf("<b>")+3,str.lastIndexOf("</b>"));
if (street.lastIndexOf("/<wbr/>") > 0) {
street = street.substring(0, street.lastIndexOf("/<wbr/>"));
}
return street;
}
// Not used right now
function generalize(street){
// var temp = street.replace(/straat/,"");
// temp = temp.replace(/sesteenweg/,"");
// temp = temp.replace(/steenweg/,"");
// temp = temp.replace(/weg/,"");
// temp = temp.replace(/laan/,"");
// temp = temp.replace(/rue/,"");
return street;
}
// 5. This returns a number of matches (Placemarks)
// Someroad, city 1, belgium, latlng point
// Someroad, city 2, belguim, latlng point
function refine(response) {
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode that address");
}
else {
// 6. Use the distance between the original saved latlngpoint and each
// candidate, and select the one with minimum distance.
var place = getBestMatchingPlacemark(response);
// 7. Display the selected location and adress on the map.
if (place != null) {
var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
var icon = new GMarker(lastpoint, {draggable: true});
icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
document.getElementById("message").innerHTML = lastpoint.toString();
map.addOverlay(icon);
icon.openInfoWindowHtml(place.address + '<br>' + '<b>Country code:</b> ' +
place.AddressDetails.Country.CountryNameCode);
document.getElementById("address").innerHTML = place.address + '<br>' + '<b>Country code:</b> ' +
place.AddressDetails.Country.CountryNameCode.toString();
}
else {
//alert("Sorry, we were unable to geocode that address");
}
}
}
// 6. Use the distance between the original saved latlngpoint and each
// candidate, and select the one with minimum distance.
function getBestMatchingPlacemark(response){
var i = 0;
var j = -1;
// the result should be at least within 1 km.
var mindist = 1000;
for (i = 0; i < response.Placemark.length; i++){
var place = response.Placemark[i];
// Just listing the posibilties (todo : remove alert)
alert(place.address);
var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
var temp = lastpoint.distanceFrom(point);
if (temp < mindist) {
j = i;
mindist = temp;
}
}
if(j < 0 ) return null;
return response.Placemark[j];
}
//]]>
</script>
Previous Comments For This Page