Reverse geocoding

Jan 23, 2009 at 2:40 PM
Hello radioman,

I still haven't found a solution for returning multiple ambiguous addresses when searching, However, here's a little contibution for reverse geocoding(see at end)

You may have to modify it a little to filter unwanted chars and all, but the web request is there. Also instead of optionnally displaying the result in a message box, it would nice if you could private a virtual method similar to drawToolTip to display the result.

By the way, I get an error when zoom = maxZoom in :

public Point FromLatLngToPixel(double lat, double lng, int zoom)
{
Point ret =
new Point();
if(zoom > MaxZoom || zoom < 1)
return ret;double d = Ru[zoom];   <--- Index out of range!

+++++++++++++++++++++++++++++++++

Here's the reverse geoCoding code:

 

 

private string MakeReverseGeoCodeString(PointLatLng pt)
{
    
return string.Format("http://maps.google.com/maps/geo?ll={0},{1}&output=csv", pt.Lat.ToString(CultureInfo.InvariantCulture), pt.Lng.ToString(CultureInfo.InvariantCulture));
}

 

 

public object GetLocations(PointLatLng pt, bool displayResult)
{
    try
    
{
    string url = MakeReverseGeoCodeString(pt);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.ServicePoint.ConnectionLimit = 50;
    request.Proxy =
null; // Proxy != null ? Proxy : WebRequest.DefaultWebProxy;
    request.UserAgent = "Opera/9.62 (Windows NT 5.1; U; en) Presto/2.1.1";
    request.Timeout = 10000;
// Timeout;
    request.ReadWriteTimeout = 60000; // Timeout * 6;

 

    request.KeepAlive =

true;
    string geo;

 

 

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        using (Stream responseStream = response.GetResponseStream())
        {
            using (StreamReader read = new StreamReader(responseStream))
            {
                geo = read.ReadToEnd();
            }
        }
    }

 

 

    //not sure how to interpret the first two codes returned???
    string[] values = geo.Split(new char[] {','}, 3);

 

 

    if (displayResult)
    MessageBox.Show(values[2]);

 

 

    return values;

 

    }

 

    catch (Exception ex)
    {    
        Trace.WriteLine("GetLocations: " + ex.ToString());
    }

 

 

    return null;

 

}

 


 

Coordinator
Jan 23, 2009 at 3:35 PM
ok i correct maxzoom+1, still real max is 17 ;}  anyway can you give me one working url which returns multiply results from google?
Jan 23, 2009 at 3:39 PM
Sorry not yet. I'm using fiddler to "reverse engineer" the requests...
All I got for the moment is the reverse geocoding url I sent above - would be good if you integrated!

I'll keep looking.
Coordinator
Jan 23, 2009 at 3:43 PM
;} but that is my function its long ago created
Jan 23, 2009 at 4:01 PM
I'm a little confused. What I sent

string.Format("http://maps.google.com/maps/geo?ll={0},{1}&output=csv", pt.Lat.ToString(CultureInfo.InvariantCulture), pt.Lng.ToString(CultureInfo.InvariantCulture));

is to return an address (string format)  from a point on the map. for example, after a mouse-up event, converting local xy to lat/long and calling the method returns the address of the location.

I didn't see it in your code. Did I miss something?
Coordinator
Jan 23, 2009 at 4:13 PM
oh its reverse, ;} I miss it really, ok 

http://maps.google.com/maps/geo?ll=54.7290810525512,25.2708721160889&output=json

i'l try to include that function
Coordinator
Jan 23, 2009 at 6:21 PM
done!
  • GetPlacemarkFromGeocoder
Jan 24, 2009 at 9:32 AM
Thanks,

there's just a little problem when splitting the returned address. I'm loosing the last character of the CityName and also the Postal code and city name seem to be crossed in the placemarker - though that could be  due to language specifications.

Last character dissapears in:

 

string tmp = values[3].Remove(values[3].Length-1, 1);

 

 

maybe change to:

 

string tmp = values[3]..Trim()

 



HOWEVER your splitting seems to work for Europe but if you go to Washington in the US the values.Length = 6 so we never enter the creation of the Placemarker.

e.g.   "200,8,\"701 Constitution Ave NW, Washington, DC 20004, USA\""

Maybe the Placemarker should have a value property containing the string returned by google (without the 200,8) with a virtual function for splitting the result into the Placemarker's properties: StreetName, Streetnumber, CityName, PostalCode, State, CountryName, etc...

This may allow some more flexibility.


 

Coordinator
Jan 24, 2009 at 11:14 AM
hm.. it quite the same

the only diif is: 
usa: Washington, DC 20004
eu: Vilnius LT-08013

in usa city is just separated by ',' so it's even easyer to parse ;} give me few minutes
Coordinator
Jan 24, 2009 at 11:36 AM
done!
Jan 24, 2009 at 1:49 PM

Have had a few more goes at it...

Your parsing of the returned result still inverses postalcode and cityname for addresses n switzerland for example. It also removes the last character of the city name.

I have other cases too, for example, when a city name is a combination of names separated by a blank (e.g. "1111 La Praz".

Form experience, addresses are not very well structured, so I still think your placemarker should have a Rsult property which will contained what is returned by google, and a virtual method for parsing:

in the GetPlacemarkFromReverseGeocoderUrl

...

string
[] values = reverse.Split(',');
if(values[0] == "200")

 

placemarker.accuracy = int.Parse(values[1], CultureInfo.InvariantCulture)
placemarker.Result = values[3]

...

 

 

 

    

placemarker class:
{

 

 

public int Accuracy;
public string ThoroughfareName;
public string LocalityName;
public string PostalCodeNumber;
public string CountryName;
public string StateName,
public string StreetNumber;
public string Result;

....

public virtual Parse()
{
    user code to parse Result into the different properties ThoroughfareName, LocalityName, PostalCodeNumber, CountryName, StateName
}

}

Of course the Parse method could have some default parsing.


 

Coordinator
Jan 24, 2009 at 1:52 PM
..i see, good point
Coordinator
Jan 24, 2009 at 2:33 PM
ok!