【问题标题】:How to find latitude and longitude using C#如何使用 C# 查找纬度和经度
【发布时间】:2013-01-16 09:20:11
【问题描述】:

我在 C# 中有一个WCF 服务。

在服务调用客户端发送一个城市名称。我想将城市名称转换为纬度和经度,并存储在人口统计下的数据库中。

我打算使用 Google API 来实现上述功能。

我从 Google 获得了一个 API 密钥及其“服务帐户”类型。

如何使用哪些 API 获取经纬度?

我需要安装一些SDK 或任何REST 服务吗?

【问题讨论】:

标签: c# rest google-maps latitude-longitude


【解决方案1】:

您可以尝试使用 NuGet 包 GoogleMaps.LocationServices,或者直接使用它的 source code。它使用 Google 的 REST API 来获取给定地址的纬度/经度,反之亦然,无需 API 密钥。

你可以这样使用它:

public static void Main()
{
    var address = "Stavanger, Norway";

    var locationService = new GoogleLocationService();
    var point = locationService.GetLatLongFromAddress(address);

    var latitude = point.Latitude;
    var longitude = point.Longitude;

    // Save lat/long values to DB...
}

【讨论】:

  • 这个有限制吗?在第一个答案中,谷歌明确表示不能合法使用谷歌地图,并且对请求数量有一定的限制。
  • 与上述答案相同的限制适用于此。它只是 REST API 的 C# 包装器。见the source code
  • 这节省了我解析 XML 的时间。 +1,这是一个优雅的解决方案!
  • 让我的生活更轻松
  • “不需要 API 密钥”但它告诉我我没有被授权
【解决方案2】:

如果您想使用 Google Maps API,请查看他们的 REST API,您无需安装 Google Maps API,只需发送请求即可

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

你会得到一个响应 XML。

对于响应 JSON:

https://maps.googleapis.com/maps/api/geocode/json?address=1600+Estância+Sergipe,&key=**YOUR_API_KEY**

更多信息请查看

https://developers.google.com/maps/documentation/geocoding/index#GeocodingRequests

【讨论】:

【解决方案3】:

您可以在特定的 url 中传递地址.. 并在返回值 dt(datatable) 中获得纬度和经度

string url = "http://maps.google.com/maps/api/geocode/xml?address=" + address+ "&sensor=false";
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);
        DataTable dtCoordinates = new DataTable();
        dtCoordinates.Columns.AddRange(new DataColumn[4] { new DataColumn("Id", typeof(int)),
                    new DataColumn("Address", typeof(string)),
                    new DataColumn("Latitude",typeof(string)),
                    new DataColumn("Longitude",typeof(string)) });
        foreach (DataRow row in dsResult.Tables["result"].Rows)
        {
            string geometry_id = dsResult.Tables["geometry"].Select("result_id = " + row["result_id"].ToString())[0]["geometry_id"].ToString();
            DataRow location = dsResult.Tables["location"].Select("geometry_id = " + geometry_id)[0];
            dtCoordinates.Rows.Add(row["result_id"], row["formatted_address"], location["lat"], location["lng"]);
        }
    }
    return dtCoordinates;
}

【讨论】:

  • 我用过这个,但我需要 ROOFTOP,但在 dsresult 中没有找到 location_type?
  • 好的,我会检查的。
【解决方案4】:
     /*Ready to use code :  simple copy paste GetLatLong*/
    public class AddressComponent
    {
        public string long_name { get; set; }
        public string short_name { get; set; }
        public List<string> types { get; set; }
    }

    public class Northeast
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }

    public class Southwest
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }

    public class Bounds
    {
        public Northeast northeast { get; set; }
        public Southwest southwest { get; set; }
    }

    public class Location
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }

    public class Northeast2
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }

    public class Southwest2
    {
        public double lat { get; set; }
        public double lng { get; set; }
    }

    public class Viewport
    {
        public Northeast2 northeast { get; set; }
        public Southwest2 southwest { get; set; }
    }

    public class Geometry
    {
        public Bounds bounds { get; set; }
        public Location location { get; set; }
        public string location_type { get; set; }
        public Viewport viewport { get; set; }
    }

    public class Result
    {
        public List<AddressComponent> address_components { get; set; }
        public string formatted_address { get; set; }
        public Geometry geometry { get; set; }
        public string place_id { get; set; }
        public List<string> types { get; set; }
    }

    public class RootObject
    {
        public List<Result> results { get; set; }
        public string status { get; set; }
    }


    public static RootObject GetLatLongByAddress(string address)
    {
        var root = new RootObject();

        var url =
            string.Format(
                "http://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=true_or_false", address);
        var req = (HttpWebRequest)WebRequest.Create(url);

        var res = (HttpWebResponse)req.GetResponse();

        using (var streamreader=new StreamReader(res.GetResponseStream()))
        {
            var result = streamreader.ReadToEnd();

            if (!string.IsNullOrWhiteSpace(result))
            {
                root = JsonConvert.DeserializeObject<RootObject>(result);
            }
        }
        return root;


    }


          /* Call This*/

var destination_latLong = GetLatLongByAddress(um.RouteDestination);

var lattitude =Convert.ToString( destination_latLong.results[0].geometry.location.lat, CultureInfo.InvariantCulture);

 var longitude=Convert.ToString( destination_latLong.results[0].geometry.location.lng, CultureInfo.InvariantCulture);

【讨论】:

  • 在我的例子中,谷歌地图给出了地址的结果,而这个方法给出了纬度/经度结果的空值,可能是什么问题?
  • 使用此 API 进行反向地理编码。:maps.google.com/maps/api/geocode/…
  • 不,我想从地址字符串中获取纬度/经度。
【解决方案5】:

Google 的替代品是OpenStreetMap's Nominatim APIs

与 Google 不同,只要您不过度使用它们(每秒超过 1 个请求),它们就没有每日限制。下面的代码适用于 Blazor 服务器。

    [Inject] IJSRuntime _js { get; set; }

    public async Task<Coordinates> GetCoordinates(string city) {
        Coordinates coordinates = new Coordinates();
        string query= String.Format("https://nominatim.openstreetmap.org/search.php?q={0}&format=jsonv2", city);
        string result = GetRequest(query); //returns a stringified array of js objects
        IJSObjectReference objArray= await _js.InvokeAsync<IJSObjectReference>("JSON.parse", result); //parse the string to a js array
        IJSObjectReference obj = await objArray.InvokeAsync<IJSObjectReference>("shift"); //take the first element in the array
        string jsonResult = await _js.InvokeAsync<string>("JSON.stringify", obj);
        dynamic dynamicResult = JObject.Parse(jsonResult);
        coordinates.Latitude= dynamicResult.lat;
        coordinates.Longitude= dynamicResult.lon;
        return coordinates;

    }

    public string GetRequest(string url) {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        using (Stream stream = response.GetResponseStream())
        using (StreamReader reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }

    public class Coordinates {
        public double Longitude { get; set; }
        public double Latitude { get; set; }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-08
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多