【发布时间】:2011-03-10 06:00:03
【问题描述】:
我注意到很多关于如何根据 IP 地址使用 Google 地理定位外观获取您的位置的信息。但我想知道是否以及如何使用此服务输入位置(经度和纬度)并返回当前地址,或者至少是一个城市、州。
我想在 C# 中执行此操作,但我会使用任何语言。
有什么建议吗?
【问题讨论】:
标签: c# google-maps geolocation
我注意到很多关于如何根据 IP 地址使用 Google 地理定位外观获取您的位置的信息。但我想知道是否以及如何使用此服务输入位置(经度和纬度)并返回当前地址,或者至少是一个城市、州。
我想在 C# 中执行此操作,但我会使用任何语言。
有什么建议吗?
【问题讨论】:
标签: c# google-maps geolocation
private string getLocationByGeoLocation(string longitude, string latitude)
{
string locationName = string.Empty;
try
{
if (string.IsNullOrEmpty(longitude) || string.IsNullOrEmpty(latitude))
return "";
string url = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false", latitude, longitude);
WebRequest request = WebRequest.Create(url);
using (WebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
DataSet dsResult = new DataSet();
dsResult.ReadXml(reader);
try
{
foreach (DataRow row in dsResult.Tables["result"].Rows)
{
string fullAddress = row["formatted_address"].ToString();
}
}
catch (Exception)
{
}
}
}
}
catch (Exception ex)
{
lblError.Text = ex.Message;
}
return locationName;
}
【讨论】:
反向地理编码:在 asp.net 中使用谷歌地图地理编码 api 从纬度和经度获取地址
protected void Page_Load(object sender, EventArgs e)
{
GetAddress("53.2734", "-7.77832031");
}
private string GetAddress(string latitude, string longitude)
{
string locationName = "";
string url = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false", latitude, longitude);
XElement xml = XElement.Load(url);
if (xml.Element("status").Value == "OK")
{
locationName = string.Format("{0}",
xml.Element("result").Element("formatted_address").Value);
Label1.Text = locationName;
}
return locationName;
}
【讨论】:
获取地址的一种简单方法是通过 google 的 API。
例如。
using System.Xml;
//Console.WriteLine("enter coordinate:");
string coordinate = "32.797821,-96.781720"; //Console.ReadLine();
XmlDocument xDoc = new XmlDocument();
xDoc.Load("https://maps.googleapis.com/maps/api/geocode/xml?latlng=" + coordinate);
XmlNodeList xNodelst = xDoc.GetElementsByTagName("result");
XmlNode xNode = xNodelst.Item(0);
string FullAddress = xNode.SelectSingleNode("formatted_address").InnerText;
string Number = xNode.SelectSingleNode("address_component[1]/long_name").InnerText;
string Street = xNode.SelectSingleNode("address_component[2]/long_name").InnerText;
string Village = xNode.SelectSingleNode("address_component[3]/long_name").InnerText;
string Area = xNode.SelectSingleNode("address_component[4]/long_name").InnerText;
string County = xNode.SelectSingleNode("address_component[5]/long_name").InnerText;
string State = xNode.SelectSingleNode("address_component[6]/long_name").InnerText;
string Zip = xNode.SelectSingleNode("address_component[8]/long_name").InnerText;
string Country = xNode.SelectSingleNode("address_component[7]/long_name").InnerText;
Console.WriteLine("Full Address: " + FullAddress);
Console.WriteLine("Number: " + Number);
Console.WriteLine("Street: " + Street);
Console.WriteLine("Village: " + Village);
Console.WriteLine("Area: " + Area);
Console.WriteLine("County: " + County);
Console.WriteLine("State: " + State);
Console.WriteLine("Zip: " + Zip);
Console.WriteLine("Country: " + Country);
Console.ReadLine();
附:小心使用不同组件的不同地址。
【讨论】:
protected void Button1_Click(object sender, EventArgs e)
{
this.calcularRota(txtOrigem.Text.Trim(), txtDestino.Text.Trim());
}
public void calcularRota(string latitude, string longitude)
{
//URL do distancematrix - adicionando endereco de origem e destino
string url = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false", latitude, longitude);
XElement xml = XElement.Load(url);
// verifica se o status é ok
if (xml.Element("status").Value == "OK")
{
//Formatar a resposta
Label3.Text = string.Format("<strong>Origem</strong>: {0}",
//Pegar endereço de origem
xml.Element("result").Element("formatted_address").Value);
//Pegar endereço de destino
}
else
{
Label3.Text = String.Concat("Ocorreu o seguinte erro: ", xml.Element("status").Value);
}
}
}
【讨论】:
这是一个 c# 实现。请注意,我不是 c# 程序员——所以代码可能很难看。但它有效。它为您提供的不仅仅是地址。 这是一个控制台应用程序,您应该能够轻松地将其调整为 webforms 或 winforms。
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.XPath;
namespace ReverseGeoLookup
{
// http://code.google.com/apis/maps/documentation/geocoding/#ReverseGeocoding
public static string ReverseGeoLoc(string longitude, string latitude,
out string Address_ShortName,
out string Address_country,
out string Address_administrative_area_level_1,
out string Address_administrative_area_level_2,
out string Address_administrative_area_level_3,
out string Address_colloquial_area,
out string Address_locality,
out string Address_sublocality,
out string Address_neighborhood)
{
Address_ShortName = "";
Address_country = "";
Address_administrative_area_level_1 = "";
Address_administrative_area_level_2 = "";
Address_administrative_area_level_3 = "";
Address_colloquial_area = "";
Address_locality = "";
Address_sublocality = "";
Address_neighborhood = "";
XmlDocument doc = new XmlDocument();
try
{
doc.Load("http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latitude + "," + longitude + "&sensor=false");
XmlNode element = doc.SelectSingleNode("//GeocodeResponse/status");
if (element.InnerText == "ZERO_RESULTS")
{
return ("No data available for the specified location");
}
else
{
element = doc.SelectSingleNode("//GeocodeResponse/result/formatted_address");
string longname="";
string shortname="";
string typename ="";
bool fHit=false;
XmlNodeList xnList = doc.SelectNodes("//GeocodeResponse/result/address_component");
foreach (XmlNode xn in xnList)
{
try
{
longname = xn["long_name"].InnerText;
shortname = xn["short_name"].InnerText;
typename = xn["type"].InnerText;
fHit = true;
switch (typename)
{
//Add whatever you are looking for below
case "country":
{
Address_country = longname;
Address_ShortName = shortname;
break;
}
case "locality":
{
Address_locality = longname;
//Address_locality = shortname; //Om Longname visar sig innehålla konstigheter kan man använda shortname istället
break;
}
case "sublocality":
{
Address_sublocality = longname;
break;
}
case "neighborhood":
{
Address_neighborhood = longname;
break;
}
case "colloquial_area":
{
Address_colloquial_area = longname;
break;
}
case "administrative_area_level_1":
{
Address_administrative_area_level_1 = longname;
break;
}
case "administrative_area_level_2":
{
Address_administrative_area_level_2 = longname;
break;
}
case "administrative_area_level_3":
{
Address_administrative_area_level_3 = longname;
break;
}
default:
fHit = false;
break;
}
if (fHit)
{
Console.Write(typename);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("\tL: " + longname + "\tS:" + shortname + "\r\n");
Console.ForegroundColor = ConsoleColor.Gray;
}
}
catch (Exception e)
{
//Node missing either, longname, shortname or typename
fHit = false;
Console.Write(" Invalid data: ");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("\tX: " + xn.InnerXml + "\r\n");
Console.ForegroundColor = ConsoleColor.Gray;
}
}
//Console.ReadKey();
return (element.InnerText);
}
}
catch (Exception ex)
{
return ("(Address lookup failed: ) " + ex.Message);
}
}
}
【讨论】:
您正在尝试做的是反向地理编码(请参阅 Daniel 的回答)。
PHP 中的示例实现:
/**
* reverse geocoding via google maps api
* convert lat/lon into a name
*/
function reverse_geocode($lat, $lon) {
$url = "http://maps.google.com/maps/api/geocode/json?latlng=$lat,$lon&sensor=false";
$data = json_decode(file_get_contents($url));
if (!isset($data->results[0]->formatted_address)){
return "unknown Place";
}
return $data->results[0]->formatted_address;
}
【讨论】:
您所描述的称为Reverse Geocoding。 Google 提供了一个Geocoding Web Service API,您可以从您的服务器端应用程序(使用任何语言)to do reverse geocoding 调用它。
例如下面的请求:
http://maps.google.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false
... 将返回如下所示的响应(截断):
<GeocodeResponse>
<status>OK</status>
<result>
<type>street_address</type>
<formatted_address>277 Bedford Ave, Brooklyn, NY 11211, USA</formatted_address>
<address_component>
<long_name>277</long_name>
<short_name>277</short_name>
<type>street_number</type>
</address_component>
<address_component>
<long_name>Bedford Ave</long_name>
<short_name>Bedford Ave</short_name>
<type>route</type>
</address_component>
<address_component>
<long_name>Brooklyn</long_name>
<short_name>Brooklyn</short_name>
<type>sublocality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>New York</long_name>
<short_name>New York</short_name>
<type>locality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Kings</long_name>
<short_name>Kings</short_name>
<type>administrative_area_level_2</type>
<type>political</type>
</address_component>
<address_component>
<long_name>New York</long_name>
<short_name>NY</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>United States</long_name>
<short_name>US</short_name>
<type>country</type>
<type>political</type>
</address_component>
<address_component>
<long_name>11211</long_name>
<short_name>11211</short_name>
<type>postal_code</type>
</address_component>
<geometry>
<location>
<lat>40.7142330</lat>
<lng>-73.9612910</lng>
</location>
<location_type>ROOFTOP</location_type>
<viewport>
<southwest>
<lat>40.7110854</lat>
<lng>-73.9644386</lng>
</southwest>
<northeast>
<lat>40.7173806</lat>
<lng>-73.9581434</lng>
</northeast>
</viewport>
</geometry>
</result>
</GeocodeResponse>
但是请注意,Google Maps API Terms of Use 似乎是 prohibit the storage of the results,除非该商店充当将在 Google 地图中使用的数据的缓存。您可能想与 Google 取得联系并通过Google Maps API Premier 进行咨询,以获得更灵活的使用条款来满足您的地理编码要求。
【讨论】:
Google 的 Maps API 会通过 http,因此使用 get 发送请求,然后解析请求...应该可以用任何语言进行。
例如,在 PHP 中:
$ret = file_get_contents("http://maps.google.com/maps/api/geocode/xml?address=" .
urlencode($address) .
"&sensor=false" .
"&key=" . $this->key
);
$xml = new SimpleXMLElement($ret);
$error = $xml->status;
同样适用于所有 API。
【讨论】: