如何从C#代码调用Google Geocoding服务

时间:2013-04-29 08:42:29

标签: c# google-api

我在C#中有一个类库。从那里我必须打电话给谷歌服务&得到纬度&经度。

我知道如何在页面上使用AJAX,但我想直接从我的C#类文件中调用Google Geocoding服务。

有没有办法做到这一点,还是有其他任何我可以使用的服务。

9 个答案:

答案 0 :(得分:99)

你可以这样做:

string address = "123 something st, somewhere";
string requestUri = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false", Uri.EscapeDataString(address));

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

答案 1 :(得分:32)

我没有评论的声誉,但只是想说Chris Johnsons代码就像魅力一样。对于像我这样愚蠢的人来说,集会是:

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

答案 2 :(得分:7)

您还可以使用经常与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);

}

答案 3 :(得分:4)

您可以调用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结果,因为这是我会说的最佳实践。

答案 4 :(得分:4)

对于这个答案来说可能有点太迟了,但是对于那些仍在寻找使用Google Geocoding API的简单方法的人来说,我写了这个简单的nugget called Guigle API并且它可以像这样使用:

GoogleGeocodingAPI.GoogleAPIKey = "YOUR API KEY";
AddressResponse result = await GoogleGeocodingAPI.SearchAddressAsync("100 Market St, Southbank");

OR

var result = await GoogleGeocodingAPI.GetCityFromCoordinatesAsync(11.1111, 22.2222);
var city = result.Item1;
var country = result.Item3;
  • 我喜欢它的一件事是你从API响应中获得完整的对象,因此你可以轻松访问所有内容,并且可以使用Linq和其他集合助手轻松地从中检索数据。例如,对于地址,您可以使用以下类型:

    public class AddressResponse
    {
        public List<Address> Results { get; set; }
        public string Status { get; set; }
    }
    public class Address
    {
        public List<AddressComponent> AddressComponents { get; set; }
        public string FormattedAddress { get; set; }
        public Geometry Geometry { get; set; }
        public string PlaceId { get; set; }
        public List<string> Types { get; set; }
    }

所以你可以这样做:

(...)
var state = addressComponentes.FirstOrDefault(r => r.Types.Contains(AddressType.administrative_area_level_1.ToString()))?.ShortName;
  • 它也可用于Google Places API查询。
  • 所有方法都有一个重载选项,如果您打算进行多次调用,可以传递自己的HttpClient,这样您就可以自己打开/关闭它。
  • 很抱歉,它尚未完全实施/测试,但对于这些基本搜索,它完全正常工作。

这些方法易于使用,并有摘要和详细解释。

您可以使用nuget命令安装它安装包Easyforce.GuigleAPI

如果您只想要源代码,则GitHub上的项目可用。随意为您的贡献制作公关=)

答案 5 :(得分:2)

这是一个老问题。但我今天也遇到了同样的问题并提出了解决方案: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

答案 6 :(得分:1)

这可能不是很多,但我只想在@Chris Johnson代码中进行一次改进,如果你只想以双重格式得到lat和lng值,那么chris johnson的var lat和var lng具有这种格式的值&lt ; LAT&GT; ...数...&LT; / LAT&GT;

因此,如果你传递的值是一个字符串来获取数值,你必须这样做

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

答案 7 :(得分:1)

要完成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 :(得分:0)

这是我在 .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;
    }
}