|
As of today GMapGeocoder.Util.GetXml should look like this:
public static string GetXml(string address, string key)
{
string url = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?address={0}&key={1}", HttpUtility.UrlEncode(address), key);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
using (Stream stream = request.GetResponse().GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
More changes may be needed to use other functionality.
|
|
|
|
|
A small efficiency improvement to the Util method PlacemarkPointToPoint. Use a static for the character to split on array, and only do the split once, instead of three times.
Also remove the inner try block and replace it with a boolean expression to set p.Unbounded . Since this uses Regex to match zero, I suppose you could also use Regex.Split instead of String.Split.
Add to the file header:
using System.Text.RegularExpressions;
Then the changes to the code:
private static char[] splitChar = { ',' };
private static Regex zero = new Regex(@" *0+ *");
public static Containers.Point PlacemarkPointToPoint(Generated.Point point)
{
try
{
Containers.Point p = new GMapGeocoder.Containers.Point();
string[] coords = point.coordinates.Split(splitChar);
p.Longitude = Convert.ToDouble(coords[0]);
p.Latitude = Convert.ToDouble(coords[1]);
p.Unbounded = (coords.Length > 2 && !zero.IsMatch(coords[2]));
return p;
}
catch
{
return new Containers.Point();
}
}
If you don't like the Regex match for zero you could use:
int unbound = 0;
p.Unbounded = (coords.Length > 2
&& Int32.TryParse(coords[2], out unbound)
&& unbound != 0);
I like TryParse better because it doesn't throw an error. I view Try/Throw/Catch as a relatively expensive operation, better reserved for truly exceptional situations.
Enjoy!
|
|
|
|
|
Is there a plan to upgrade this to the new API, Geocoding V3?
|
|
|
|
|
http://stackoverflow.com/questions/4824348/working-with-the-google-location-api
|
|
|
|
|
I wanted to see if it was possible to do a functional maps application in aspx.vb code behind without using any javascript. I used your geocoder along with the free Subgurim.Controles activex.
If it would help anyone here is the sample application.
Click here for source code.
Thank you Sharmil. Great work.
|
|
|
|
|
|
I need complete seach results from Google Map.when I insert any seach text in google map it only shows me 2 to 3 results.I want information like Name,Address,City,State etc.Which display on the left side to the map.I have a code which gives the data but not which display at google map.I want the solution on this how I get the complete kml file.I have used the same code which you have given
|
|
|
|
|
Hi Sharmil,
Do you know the way around the status 602.
I mean if you received that status - the exact location wasn't found.
Can I query goggle for the closest location instead?
If I look for the same address using http://maps.google.com/ - it shows me couple of close locations, but API returns status 602 and no location result.
If you know what can be done – please help me.
Thank you in advance....
|
|
|
|
|
Hi,
I had some trouble with the culture and UTF-8 encoding.
I advise you to change:
--------------
public static Containers.Point PlacemarkPointToPoint(Generated.Point point)
...
// Parse result independently of the culture
p.Longitude = Double.Parse(point.coordinates.Split(new char[] { ',' })[0], CultureInfo.InvariantCulture.NumberFormat);
p.Latitude = Double.Parse(point.coordinates.Split(new char[] { ',' })[1], CultureInfo.InvariantCulture.NumberFormat);
--------------
public static string GetXml(string address, string key)
{
//Add utf8 argument
string url = string.Format("http://maps.google.com/maps/geo?output=xml&q={0}&key={1}&oe=utf8", HttpUtility.UrlEncode(address), key);
-------------
public static string GetXml(string address, string key)
{
...
//Add Utf8
using (StreamReader readStream = new StreamReader(stream, Encoding.UTF8))
{
return readStream.ReadToEnd();
}
-----------
It's run correctly on some manuel test. I will try your code on a big test case
Thank you for your code and the time saving. 
|
|
|
|
|
Hi Sharmil,
I'm proudly using your GMapGeocoder in a website that I recently developed, but unfortunately when I move to production I receive the following error:
<br />
System.Security.SecurityException: Request for the permission of type 'System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.<br />
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)<br />
at System.Security.CodeAccessPermission.Demand()<br />
at System.Net.HttpWebRequest..ctor(Uri uri, ServicePoint servicePoint)<br />
at System.Net.HttpRequestCreator.Create(Uri Uri)<br />
at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)<br />
at System.Net.WebRequest.Create(String requestUriString)<br />
at GMapGeocoder.Util.GetXml(String address, String key)<br />
at html_aspx_index.Page_Load(Object sender, EventArgs e) in \\wagner\wwwroot$\ mysite.ws\index.aspx.cs:line 34<br />
The action that failed was:<br />
Demand<br />
The type of the first permission that failed was:<br />
System.Net.WebPermission<br />
The Zone of the assembly that failed was:<br />
Internet<br />
It seems to me to be related to permissions to be set in the web.config: can you help me ?
I dunno how to do it nor where to place any directive to allow your .dll safely contact maps.google.com .
Any help will be deeply appreciated!
Thank you in advance,
Luigi
|
|
|
|
|
Very nice and structured piece of code. Congrats.
Also, It helped me a lot as I was late with a project.
|
|
|
|
|
Yes, this is saving me some days also. Thanks again.
|
|
|
|
|
|
How do I use it for multiple addresses? I have 20,000 addresses to geocode and thus far, using the example you provided, I can't get it to work for more than one address.
Thanks in advance. Also, I think the code is great overall.
This is my code:
private void GoogleGeoCode()
{
ExcelFile ef = new ExcelFile();
ef.LoadXls(@"C:\Documents and Settings\Addreses08270801.xls");
ExcelWorksheet ws = ef.Worksheets["Addresses"];
int row = ws.Rows.Count;
int addressesLeft = row - 1;
string addressLocation;
string latitudeLocation;
string longitudeLocation;
GMapGeocoder.Containers.Results results;
GMapGeocoder.Containers.USAddress match1; // = results.Addresses[0];
double lat; // = match1.Coordinates.Latitude;
double longt; // = match1.Coordinates.Longitude;
for (int record = 2; record < (row + 1); record++)
{
AddressesLeft.Content = "Working On Address: " + addressesLeft.ToString();
addressLocation = "E" + record.ToString();
results = GMapGeocoder.Util.Geocode(ws.Cells[addressLocation].Value.ToString(), myGeocodeKey);
match1 = results.Addresses[0];
lat = match1.Coordinates.Latitude;
longt = match1.Coordinates.Longitude;
latitudeLocation = "K" + record.ToString();
longitudeLocation = "L" + record.ToString();
ws.Cells[latitudeLocation].Value = lat;
ws.Cells[longitudeLocation].Value = longt;
addressesLeft--;
}
AddressesLeft.Content = "Saving File....";
ef.SaveXls(@"C:\Documents and Settings\Addreses08270803.xls");
AddressesLeft.Content = "Finished!";
}
|
|
|
|
|
That looks like it should work. You might try setting a break point after the GMapGeocoder.Util.Geocode call, and looking at the results after each iteration of the loop. Might be an issue with your results not getting saved out. Not sure if it makes a difference but you might also create variables referenced only by the loop inside the loop.
So instead of:
addressLocation = "E" + record.ToString(); Use:
string addressLocation = "E" + record.ToString();
I'd do this for results, match1, lat, longt, latitudeLocation, and longitudeLocation. Also I'd be cautious geocoding a list of addresses with google maps since I think it violates there usage terms.
|
|
|
|
|
Hi
Useful article - it would be nice to see some UK address support added though.
Thanks
|
|
|
|
|
I get this error when I use your component.
It works just fine locally, but when I move I get this error.
"
[SocketException (0x274d): No connection could be made because the target machine actively refused it]"
[SocketException (0x274d): No connection could be made because the target machine actively refused it]
System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) +1001890
System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP) +33
System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception) +431
[WebException: Unable to connect to the remote server]
System.Net.HttpWebRequest.GetResponse() +1501755
GMapGeocoder.Util.GetXml(String address, String key) in C:\Development\Lafarge Roofing\GMapGeocoder\Util.cs:39
SYSteamCAB.Custom.RoofConfigurator.Web._Default.Page_Load(Object sender, EventArgs e) in C:\Development\Lafarge Roofing\Roof Configurator\SYSteamCAB.Custom.RoofConfigurator.Web\Clientdata.aspx.cs:645
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.
|
|
|
|
|
I would check if there are firewall rules on the box that you are deploying, which are blocking access to maps.google.com over port 80. If you can remote to the box I'd open a command window and run "telnet maps.google.com 80". Should go to a blank screen if there are no problems. You could also try calling http://maps.google.com/maps/geo?output=xml&key=yourkey&q=someaddress directly from a browser window on that box.
- Sharmil
|
|
|
|
|
Also I'd make sure you're not using a proxy on the deployment box. I think you can add lines to your web.config if you need to specify proxy settings for .Net to use.
|
|
|
|
|
The coordinates returned by Google have the longitude first, then the latitude in the <point><coordinates> node. Your code switched that around.
You need the following change:
public static Containers.Point PlacemarkPointToPoint(Generated.Point point)
{
try
{
Containers.Point p = new GMapGeocoder.Containers.Point();
p.Longitude = Convert.ToDouble(point.coordinates.Split(new char[] { ',' })[0]);
p.Latitude = Convert.ToDouble(point.coordinates.Split(new char[] { ',' })[1]);
try
{
p.Unbounded = Convert.ToBoolean(Convert.ToInt32(point.coordinates.Split(new char[] { ',' })[2]));
}
catch { }
return p;
}
catch
{
return new Containers.Point();
}
}
This just switches the Longitude and Latitude.
Walt
|
|
|
|
|
Should be fixed now. I noticed this too when I started using the code and had addresses in the ocean. haha. Forgot to update the code here though.
|
|
|
|
|
You might want to make the following change to your code in Util.cs:
public static Containers.Results GoogleObjectsToResults(Generated.kml kml)
{
Containers.Results results = new GMapGeocoder.Containers.Results();
results.StatusCode = (StatusCodeOptions)kml.Response.Status.code;
results.Query = kml.Response.name;
if (kml.Response.Placemark != null)
{
foreach (Generated.Placemark p in kml.Response.Placemark)
{
results.Addresses.Add(PlacemarkToUSAddress(p));
}
}
return results;
}
This just checks to see if Placemark is not null before using it.
Nice article. It was very helpful.
Walt
|
|
|
|
|
Thanks, didn't catch this. Should be updated on here now.
|
|
|
|
|
Do you know why I am getting this error? I have my Google key as well
Server Error in '/SeeAjax' Application.
The remote name could not be resolved: 'maps.google.com'
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Net.WebException: The remote name could not be resolved: 'maps.google.com'
Source Error:
Line 15: protected void Page_Load(object sender, EventArgs e)
Line 16: {
Line 17: string xml = GMapGeocoder.Util.GetXml("35 Greville Court Napoleon Road London E5 8TF", "ABQIAAAA_LYa_-GfNtQyBdJspQIboBRa7FnI_mqQJH5Raddl725svEZDkRSDjPurwcgJXErd6JKjFzLWFUbDGg");
Line 18: Response.Write(xml);
Line 19: }
Source File: c:\Inetpub\wwwroot\customers\SeeAjax\Geocode.aspx.cs Line: 17
Stack Trace:
[WebException: The remote name could not be resolved: 'maps.google.com']
System.Net.HttpWebRequest.GetResponse() +1502043
GMapGeocoder.Util.GetXml(String address, String key) +134
Geocode.Page_Load(Object sender, EventArgs e) in c:\Inetpub\wwwroot\customers\SeeAjax\Geocode.aspx.cs:17
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
Version Information: Microsoft .NET Framework Version:2.0.50727.42; ASP.NET Version:2.0.50727.42
|
|
|
|
|
That's an odd error, seems more like a DNS issues where the box this is running on can't find maps.google.com . Can you get to http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&key=ABQIAAAA_LYa_-GfNtQyBdJspQIboBRa7FnI_mqQJH5Raddl725svEZDkRSDjPurwcgJXErd6JKjFzLWFUbDGg directly from your browser on the box running the application?
Tried your exact call on my machine with the library and it seems to be working fine even though google can't resolve that address.
I get a 602 response back:
<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>35 Greville Court Napoleon Road London E5 8TF</name><Status><code>602</code><request>geocode</request></Status></Response></kml>
|
|
|
|