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=this.start+(j*this.step)
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.split("</b>")[1]
str=str.substring(str.indexOf("<b>")+3)
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}
