如何从 C# 代码调用 Google 地理编码服务
Posted
技术标签:
【中文标题】如何从 C# 代码调用 Google 地理编码服务【英文标题】:How to call Google Geocoding service from C# code 【发布时间】:2013-04-29 08:42:28 【问题描述】:我有一个 C# 类库。从那里我必须调用 Google 服务并获取纬度和经度。
我知道如何在页面上使用 AJAX,但我想直接从我的 C# 类文件中调用 Google 地理编码服务。
有什么方法可以做到这一点,或者我可以使用其他任何服务。
【问题讨论】:
到目前为止你有没有尝试过? 看看HttpWebRequest
类
@SonerGönül 我试图在本教程中这样做friism.com/c-and-google-geocoding-web-service-v3
【参考方案1】:
你可以这样做:
string address = "123 something st, somewhere";
string requestUri = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?key=1&address=0&sensor=false", Uri.EscapeDataString(address), YOUR_API_KEY);
WebRequest request = WebRequest.Create(requestUri);
WebResponse response = request.GetResponse();
XDocument xdoc = XDocument.Load(response.GetResponseStream());
XElement result = xdoc.Element("GeocodeResponse").Element("result");
XElement locationElement = result.Element("geometry").Element("location");
XElement lat = locationElement.Element("lat");
XElement lng = locationElement.Element("lng");
您还需要验证响应状态并捕获任何 WebExceptions。看看Google Geocoding API。
【讨论】:
确保添加using System.Xml.Linq;
(如果缺少相应的引用 - System.Xml.Linq.dll)。
惊讶于这是多么容易。头脑=吹!
这样的问题是,如果你输入无效的地址,它会崩溃。如果您输入无效地址但输入有效城市,它仍会返回近似值
在 SSIS 包中使用 Visual C# 2008 和 .NET 3.5,我必须先将响应加载到 Stream
和 StreamReader
,然后将阅读器加载到 XDocument
。仅 .NET 4.0+ 支持将流直接加载到 XDcoument 中(来源:msdn.microsoft.com/en-us/library/cc838349(v=vs.110).aspx)。
这不起作用了,你必须获取一个 API 密钥并在查询字符串中使用它。【参考方案2】:
我没有评论的声誉,但只想说 Chris Johnson 的代码就像一个魅力。程序集是:
using System.Net;
using System.Xml.Linq;
【讨论】:
不知道程序集并不愚蠢。很多人都很欣赏有人发布了这个【参考方案3】:您还可以使用经常与 Asp.Net Web Api 或 Asp.Net 5.0 一起使用的 HttpClient 类。
您还拥有一个免费的 http 状态代码、asyn/await 编程模型和使用 HttpClient 处理异常非常容易。
var address = "paris, france";
var requestUri = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address=0&sensor=false", Uri.EscapeDataString(address));
using (var client = new HttpClient())
var request = await client.GetAsync(requestUri);
var content = await request.Content.ReadAsStringAsync();
var xmlDocument = XDocument.Parse(content);
【讨论】:
【参考方案4】:这是一个老问题。但我今天有同样的问题,并提出了这个作为解决方案:C# GeoCoding / Address Validation API(支持包括谷歌地图在内的多个提供商)。
IGeocoder geocoder = new GoogleGeocoder() ApiKey = "this-is-my-optional-google-api-key" ;
IEnumerable<Address> addresses = await geocoder.GeocodeAsync("1600 pennsylvania ave washington dc");
Console.WriteLine("Formatted: " + addresses.First().FormattedAddress);
// Formatted: 1600 Pennsylvania Ave SE, Washington, DC 20003, USA
Console.WriteLine("Coordinates: " + addresses.First().Coordinates.Latitude + ", " + addresses.First().Coordinates.Longitude);
// Coordinates: 38.8791981, -76.9818437
这里是对应的 NuGet 包:
安装包Geocoding.Google
【讨论】:
【参考方案5】:您可以调用 Web 服务并使用 json/xml 响应。
http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true
这会返回一个您可以使用的 json 响应。
正如您在使用条款中所读到的,您只有在出示谷歌地图时才能使用他们的网络服务。
在这里您可以找到有关该服务的所有信息:https://developers.google.com/maps/documentation/geocoding/
要了解如何处理 json 响应,请查看此主题:Google Maps v3 geocoding server-side
编辑: 刚找到这篇文章:http://www.codeproject.com/Tips/505361/Google-Map-Distance-Matrix-and-Geocoding-API-V3-we
我没有对此进行测试,但也许它对你有用:)
EDIT2: codeproject 示例似乎不起作用 :( 那里提到的 url 返回总是相同的,无论输入的地址点是什么... 但是,无论如何您都应该尝试使用 JSON 或 XML 结果,因为这是我想说的最佳实践。
【讨论】:
【参考方案6】:更新:此处提到的先前软件包已弃用 - 有一个最新版本适合 .Net Core。
这个答案可能为时已晚,但对于那些仍在寻找使用 Google Places 或地理编码 API 的简单方法的人来说,我写了这个简单的 nuget called GuigleCore,它可以像这样使用:
var googleGeocodingApi = new GoogleGeocodingApi("GoogleApiKey");
var address = await googleGeocodingApi.SearchAddressAsync(httpClient, "123 Street, Suburb A");
或
var googlePlacesApi = new GooglePlacesApi("GoogleApiKey");
var place = await googlePlacesApi.FindPlaces(httpClient, "123 Street, Suburb A"));
您可以像这样为 DI 注册它:
services.AddScoped(typeof(IGooglePlacesApi), x => new GooglePlacesApi(Configuration["GoogleApiKey"]));
我喜欢它的一点是,您可以从 API 响应中获取完整的对象,因此您可以轻松访问所有内容,并且可以使用 Linq 和其他集合助手轻松从中检索数据。
您可以使用 nuget 命令 Install-Package GuigleCore 安装它 或fork it here。
【讨论】:
【参考方案7】:要完成 JP Hellemons 的回答,请使用 Geocoding.net 并仅检索城市名称,例如:
IGeocoder geocoder = new GoogleGeocoder() ApiKey = "API_Key" ;
IEnumerable<Address> addresses = await geocoder.GeocodeAsync("address");
foreach(var component in ((GoogleAddress)addresses.First()).Components)
foreach(var type in component.Types)
if(type == GoogleAddressType.Locality)
return component.LongName;
【讨论】:
【参考方案8】:这可能不多,但我只想对@Chris Johnson 代码进行一项改进,如果您只想以双重形式获得 lat 和 lng 值,chris johnson 的 var lat 和 var lng 具有这种格式的价值 ...数字...
所以如果你传递的值是一个字符串来获取数值你必须这样做
double latitude = Double.Pars(lat.Value)
double longitude = Double.Pars(lng.Value)
【讨论】:
【参考方案9】:这是我在 .Net Core API 中使用的方法,在这种情况下,我们只需要 Lat 和 Lng 值来匹配我们的内部 LocationModel:
public async Task<LocationModel> GetAddressLocation(string address)
try
var targetUrl = $"https://maps.googleapis.com/maps/api/geocode/json" +
$"?address=address" +
$"&inputtype=textquery&fields=geometry" +
$"&key=_apiKey";
_logger.LogDebug($"GetAddressLocation : targetUrl:targetUrl");
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, targetUrl);
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var stream = await response.Content.ReadAsStreamAsync();
if (response.IsSuccessStatusCode)
if (stream == null || stream.CanRead == false)
return null;
using var sr = new StreamReader(stream);
var jsonString = sr.ReadToEnd();
dynamic responseObject = JObject.Parse(jsonString);
var results = responseObject["results"];
var lat = results[0]?["geometry"]?["location"]?["lat"];
var lng = results[0]?["geometry"]?["location"]?["lng"];
var result = new LocationModel Latitude = lat, Longitude = lng ;
return result;
else
await HandleApiError(response, stream);
throw new DomainException($"UNKNOWN ERROR USING GEOCODING API :: response");
catch (Exception ex)
_logger.LogError("ERROR USING Geocoding Service", ex);
throw;
【讨论】:
以上是关于如何从 C# 代码调用 Google 地理编码服务的主要内容,如果未能解决你的问题,请参考以下文章
C# Google 地理编码:即使遵循所需的步骤,也会不断拒绝权限
如何正确限制对 Android 和 iOS 应用程序(用 Flutter 编写)的 Google 地图(地点、地理编码)API 调用?