我有一个使用C#编写的 WCF
服务。
在服务调用中,客户端发送城市名称。我想将城市名称转换为经纬度并存储在人口统计信息下的数据库中。
我计划使用Google API来实现上述功能。
我已经从Google获取了一个API密钥,它是“服务账户”类型。
我该如何使用哪些API来获取经纬度?
我是否需要安装某个SDK
或者只需要使用REST
服务就可以了?
我有一个使用C#编写的 WCF
服务。
在服务调用中,客户端发送城市名称。我想将城市名称转换为经纬度并存储在人口统计信息下的数据库中。
我计划使用Google API来实现上述功能。
我已经从Google获取了一个API密钥,它是“服务账户”类型。
我该如何使用哪些API来获取经纬度?
我是否需要安装某个SDK
或者只需要使用REST
服务就可以了?
你可以像这样使用:
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...
}
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
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())
{
DataTable dtCoordinates = new DataTable();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
DataSet dsResult = new DataSet();
dsResult.ReadXml(reader);
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;
}
/*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);
除了谷歌,OpenStreetMap的Nominatim APIs是一个可选方案。
与谷歌不同,只要您不过度使用(每秒钟超过1个请求),它们就没有每日限制。以下代码适用于Blazor Server。
[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; }
}