简体   繁体   English

如何从 C# 代码调用 Google 地理编码服务

[英]How to call Google Geocoding service from C# code

I have one class library in C#.我在 C# 中有一个类库。 From there I have to call Google service & get latitude & longitude.从那里我必须调用 Google 服务并获取纬度和经度。

I know how to do it using AJAX on page, but I want to call Google Geocoding service directly from my C# class file.我知道如何在页面上使用 AJAX,但我想直接从我的 C# 类文件中调用 Google 地理编码服务。

Is there any way to do this or are there any other services which I can use for this.有什么方法可以做到这一点,或者我可以使用任何其他服务。

You could do something like this:你可以这样做:

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");

You will also want to validate the response status and catch any WebExceptions.您还需要验证响应状态并捕获任何 WebExceptions。 Have a look at Google Geocoding API .看看Google Geocoding API

I don't have the reputation to comment, but just wanted to say that Chris Johnsons code works like a charm.我没有评论的声誉,但只是想说 Chris Johnson 的代码很有魅力。 The assemblies are:这些程序集是:

using System.Net;
using System.Xml.Linq;

You can also use the HttpClient class which is often used with Asp.Net Web Api or Asp.Net 5.0.您还可以使用 HttpClient 类,它经常与 Asp.Net Web Api 或 Asp.Net 5.0 一起使用。

You have also a http state codes for free, asyn/await programming model and exception handling with HttpClient is easy as pie.你还有一个免费的 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);

}

It's an old question.这是一个老问题。 But I had the same question today and came up with this as a solution: C# GeoCoding / Address Validation API (supports several providers including Google Maps).但我今天遇到了同样的问题,并提出了一个解决方案: 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

Here is the corresponding NuGet package :这是相应的 NuGet 包:

Install-Package Geocoding.Google安装包Geocoding.Google

You can call the web service and work with the json/xml response.您可以调用 Web 服务并使用 json/xml 响应。

http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true

this returns a json response which you can work with.这将返回一个您可以使用的 json 响应。

As you can read in the terms of usage, you are only allowed to use their web service if you show a google map.正如您在使用条款中所读到的那样,如果您显示谷歌地图,您只能使用他们的网络服务。

Here you can find all information about the service: https://developers.google.com/maps/documentation/geocoding/您可以在此处找到有关该服务的所有信息: https : //developers.google.com/maps/documentation/geocoding/

To see how to handle the json response, take a look at this topic: Google Maps v3 geocoding server-side要了解如何处理 json 响应,请查看此主题: Google Maps v3 geocoding server-side

EDIT: I just found this article: http://www.codeproject.com/Tips/505361/Google-Map-Distance-Matrix-and-Geocoding-API-V3-we编辑:我刚刚找到这篇文章: http : //www.codeproject.com/Tips/505361/Google-Map-Distance-Matrix-and-Geocoding-API-V3-we

I didn't test this, but maybe it works for you :)我没有测试这个,但也许它对你有用:)

EDIT2: The codeproject example doesn't seem to work :( the url mentioned there returns always the same, no matter what address point is the input... EDIT2: codeproject 示例似乎不起作用:( 那里提到的 url 总是返回相同的,无论输入的地址点是什么...
However you should try to work with the JSON or XML result anyway, as this is the best practice I would say.但是,无论如何您都应该尝试使用 JSON 或 XML 结果,因为这是我要说的最佳实践。

UPDATED: The previous package mentioned here is deprecated - there's a new version that is up-to-date and suits .Net Core.更新:此处提到的先前软件包已弃用 - 有一个最新版本且适合 .Net Core。

It might be a bit too late for this answer, but for those still getting here looking for an easy way to use Google Places or Geocoding APIs, I wrote this simple nuget called GuigleCore and it can be used like this:这个答案可能有点太晚了,但对于那些仍在寻找使用 Google Places 或地理编码 API 的简单方法的人来说,我写了一个名为 GuigleCore 的简单nuget ,它可以像这样使用:

var googleGeocodingApi = new GoogleGeocodingApi("GoogleApiKey");
var address = await googleGeocodingApi.SearchAddressAsync(httpClient, "123 Street, Suburb A");

OR要么

var googlePlacesApi = new GooglePlacesApi("GoogleApiKey");
var place = await googlePlacesApi.FindPlaces(httpClient, "123 Street, Suburb A"));

You can register it for DI like this:您可以像这样为 DI 注册它:

services.AddScoped(typeof(IGooglePlacesApi), x => new GooglePlacesApi(Configuration["GoogleApiKey"]));

One thing that I like about it is that you get full objects from the API responses, so you have easy access to everything and you can use Linq and other collection helpers to easily retrieve data from it.我喜欢它的一件事是,您可以从 API 响应中获取完整的对象,因此您可以轻松访问所有内容,并且可以使用 Linq 和其他集合助手轻松从中检索数据。

You can install it with the nuget command Install-Package GuigleCore or fork it here .您可以使用 nuget 命令Install-Package GuigleCore安装它或在此处 fork it

To complete JP Hellemons's answer, to use Geocoding.net and retrieve only the name of the city for example:要完成 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;
        }
    }
}

This may not be much but I just want to make one improvement in @Chris Johnson code if you just want to get the lat and lng value in double form the var lat and var lng of chris johnson has value with this format < lat>...number...< /lat>这可能不多,但我只想对@Chris Johnson 代码进行一项改进,如果您只想以双倍形式获取 lat 和 lng 值,chris johnson 的 var lat 和 var lng 具有这种格式 < lat> 的价值。 ..数字...</lat>

So if you pass the value is a string to get numeric value you have to do like this所以如果你传递的值是一个字符串来获取数值,你必须这样做

  double latitude = Double.Pars(lat.Value)
 double longitude = Double.Pars(lng.Value)

Here is the approach I use within my .Net Core API(s), in this case we only need Lat and Lng values to match our internal LocationModel:这是我在 .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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM