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
Hi, If you want the country instead of the full address use "place = response.Placemark[0]" then "place.address" and this should return the country name. This is what is being used on Click For Country.
By Daft Logic on 03/05/2008
nice job there!
I'm wondering how difficult this will be to simply output the country...
When you zoom out of this version and click, it bugs out displaying several addresses
By Bitcloud on 23/04/2008