
function GReverseGeocoder(map){this.map=map;this.gdirections=new GDirections();this.geocoder=new GClientGeocoder();this.lastpoint=null;this.closestonroad=null;this.experimental=false;this.ad="";this.step=10;this.start=1;this.gdirectionsrefine=new GDirections();GEvent.bind(this.gdirections,"error",this,this.handleError);GEvent.bind(this.gdirections,"load",this,this.processDirection);GEvent.bind(this.gdirectionsrefine,"error",this,this.handleError);GEvent.bind(this.gdirectionsrefine,"load",this,this.processDirectionRefine);}
GReverseGeocoder.prototype.reverseGeocode=function(point){this.lastpoint=point;this.closestonroad=null;this.gdirections.clear();this.gdirections.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{getSteps:true,locale:"GB",getPolyline:true});}
GReverseGeocoder.prototype.getStatus=function(){return this.gdirections.getStatus();}
GReverseGeocoder.prototype.handleError=function(){GEvent.trigger(this,"error");}
GReverseGeocoder.prototype.processDirection=function(){var source=this;if(this.gdirections.getPolyline()!=null){this.closestonroad=this.gdirections.getPolyline().getVertex(0);;}
var nrroutes=this.gdirections.getNumRoutes();if(nrroutes!=0){var route=this.gdirections.getRoute(0);var nrsteps=route.getNumSteps();if(nrsteps!=0){var step=route.getStep(0);var street=step.getDescriptionHtml();street=this.getStreet(street);var sw=new GLatLng(Number(this.lastpoint.lat())-0.01,Number(this.lastpoint.lng())-0.01);var ne=new GLatLng(Number(this.lastpoint.lat())+0.01,Number(this.lastpoint.lng())+0.01);var bounds=new GLatLngBounds(sw,ne);this.geocoder.setViewport(bounds);this.geocoder.getLocations(street,function(response){var placemark=source.getBestMatchingPlacemark(response);if(placemark!=null){if(source.experimental){source.ad=placemark.address;source.step=10;source.start=1;source.houseNumberSearch();}
else{GEvent.trigger(source,"load",placemark);}}
else{source.handleError();}});}}}
GReverseGeocoder.prototype.getBestMatchingPlacemark=function(response){if(!response||response.Status.code!=200)return null;var j=-1;var mindist=1000000;for(var i=0;i<response.Placemark.length;i++){var place=response.Placemark[i];var point=new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);var temp=this.lastpoint.distanceFrom(point);if(temp<mindist){j=i;mindist=temp;}}
if(j<0)return null;response.Placemark[j].RequestPoint={"coordinates":[this.lastpoint.lng(),this.lastpoint.lat()]}
response.Placemark[j].PointOnRoad={"coordinates":[this.closestonroad.lng(),this.closestonroad.lat()]}
response.Placemark[j].Distance=mindist;response.Placemark[j].DistanceOnRoad=this.closestonroad.distanceFrom(new GLatLng(response.Placemark[j].Point.coordinates[1],response.Placemark[j].Point.coordinates[0]));return response.Placemark[j];}
GReverseGeocoder.prototype.processDirectionRefine=function(){var nrgeocodes=this.gdirectionsrefine.getNumGeocodes();var j=-1;var mindist=100;for(var i=1;i<nrgeocodes;i++){var place=this.gdirectionsrefine.getGeocode(i);var point=new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);if(place.AddressDetails.Accuracy==8){var temp=this.lastpoint.distanceFrom(point);if(temp<mindist){j=i;mindist=temp;}}}
if(j<0){if(this.start+(24*this.step)<2000){this.start=this.start+(25*this.step);this.houseNumberSearch();}
else{this.handleError();}}
else{if(this.step==1){var placemark=this.gdirectionsrefine.getGeocode(j);placemark.RequestPoint={"coordinates":[this.lastpoint.lng(),this.lastpoint.lat()]}
placemark.PointOnRoad={"coordinates":[this.closestonroad.lng(),this.closestonroad.lat()]}
placemark.Distance=mindist;placemark.DistanceOnRoad=this.closestonroad.distanceFrom(new GLatLng(placemark.Point.coordinates[1],placemark.Point.coordinates[0]));GEvent.trigger(this,"load",placemark);}
else{var place=this.gdirectionsrefine.getGeocode(j);var nr=place.address.split(",",1)[0].split(" ");nr=nr[nr.length-1];this.start=nr-10;this.step=1;this.houseNumberSearch();}}}
GReverseGeocoder.prototype.houseNumberSearch=function(){this.gdirectionsrefine.clear();this.gdirectionsrefine.loadFromWaypoints([(""+(this.start+(0*this.step))+" ")+this.ad,(""+(this.start+(1*this.step))+" ")+this.ad,(""+(this.start+(2*this.step))+" ")+this.ad,(""+(this.start+(3*this.step))+" ")+this.ad,(""+(this.start+(4*this.step))+" ")+this.ad,(""+(this.start+(5*this.step))+" ")+this.ad,(""+(this.start+(6*this.step))+" ")+this.ad,(""+(this.start+(7*this.step))+" ")+this.ad,(""+(this.start+(8*this.step))+" ")+this.ad,(""+(this.start+(9*this.step))+" ")+this.ad,(""+(this.start+(10*this.step))+" ")+this.ad,(""+(this.start+(11*this.step))+" ")+this.ad,(""+(this.start+(12*this.step))+" ")+this.ad,(""+(this.start+(13*this.step))+" ")+this.ad,(""+(this.start+(14*this.step))+" ")+this.ad,(""+(this.start+(15*this.step))+" ")+this.ad,(""+(this.start+(16*this.step))+" ")+this.ad,(""+(this.start+(17*this.step))+" ")+this.ad,(""+(this.start+(18*this.step))+" ")+this.ad,(""+(this.start+(19*this.step))+" ")+this.ad,(""+(this.start+(20*this.step))+" ")+this.ad,(""+(this.start+(21*this.step))+" ")+this.ad,(""+(this.start+(22*this.step))+" ")+this.ad,(""+(this.start+(23*this.step))+" ")+this.ad,(""+(this.start+(24*this.step))+" ")+this.ad],{getSteps:true,locale:"GB"});}
GReverseGeocoder.prototype.getStreet=function(street){var str=street.substring(street.lastIndexOf("<b>")+3,street.lastIndexOf("</b>"));if(str.indexOf("/<wbr/>")>0){strs=str.split("/<wbr/>");if(strs[0].charAt(1)>="0"&&strs[0].charAt(1)<="9"){str=strs[1];}
else{str=strs[0];}}
return str;}
GReverseGeocoder.prototype.setExperimentalHouseNumber=function(setting){this.experimental=setting;}
GReverseGeocoder.prototype.getPlacemarkProperty=function(placemark,propertyname){for(var property in placemark){if((property==propertyname)){return String(placemark[property]);}else if(typeof(placemark[property])=='object'){var r=this.getPlacemarkProperty(placemark[property],propertyname);if(r!=null)return r;}}
return null;}