Windows Phone - 利用GeoLocation取得對應的Address - 2
接續<Windows Phone - 利用GeoLocation取得對應的Address - 1>說明利用WP 8.0提供的SDK取得反向地理編碼查詢物件的方式,
本篇將介紹利用Google Geocoding API的功能,將取得座標轉換成地址。
〉搭配Google Geocoding API:
利用Google的API是比較常見的使用方法,不過使用這個API如果您的App是希望支援China的話,那建議你不要使用,
China目前仍未支援Google的服務,不一定可以正常使用它。使用該API之前請先閱讀<Google Geocoding API>的相關說明。
使用的URL格式為:
針對paramters從中擷取出幾個重點的參數,如下:
參數 | 說明 |
output | 可用json或xml二種格式。 |
latlng |
將為此文字經/緯度值取得最接近的人類可讀地址,搭配<反向地理編碼>的邏輯。 |
sensor |
指出地理編碼要求的來源裝置是否附有位置感應器。這個值必須是 true 或 false。 |
language |
傳回結果所要使用的語言。請參閱<支援的網域語言清單>。 |
將URL與parameters組合成要用GeoLocation反查Address的URL如下(注意:latlng
請確定兩者之間沒有任何空格):
至於這樣取得的結果與說明,請參考<反向地理編碼 (地址查閱)>的說明。
了解Google API的使用方式後,進一步將整合至Windows Phone的專案裡,我建立了一個專用的Class提供給外部引用者來操作,如下:
(1) 採用json格式操作,需要先將API回傳的JSON結果建立成一個個的JSON類別;
#region GoogleGeoLocationAPIResult的JSON
public class GoogleGeoLocationAPIResult
{
public ResultObject[] results { get; set; }
public string status { get; set; }
}
public class ResultObject
{
public Address_Components[] address_components { get; set; }
public string formatted_address { get; set; }
public Geometry geometry { get; set; }
public string[] types { get; set; }
}
public class Geometry
{
public Location location { get; set; }
public string location_type { get; set; }
public Viewport viewport { get; set; }
public Bounds bounds { get; set; }
}
public class Location
{
public float lat { get; set; }
public float lng { get; set; }
}
public class Viewport
{
public Northeast northeast { get; set; }
public Southwest southwest { get; set; }
}
public class Northeast
{
public float lat { get; set; }
public float lng { get; set; }
}
public class Southwest
{
public float lat { get; set; }
public float lng { get; set; }
}
public class Bounds
{
public Northeast1 northeast { get; set; }
public Southwest1 southwest { get; set; }
}
public class Northeast1
{
public float lat { get; set; }
public float lng { get; set; }
}
public class Southwest1
{
public float lat { get; set; }
public float lng { get; set; }
}
public class Address_Components
{
public string long_name { get; set; }
public string short_name { get; set; }
public string[] types { get; set; }
}
#endregion
需要建立這些類別來做JSON文字與類別的序列化,這樣在程式裡操作可以直接利用物件交易,不需要不斷地拆解JSON格式。
(2) 搭配WebClient支援向Google Geocoding API請求轉換座標為地址:
public class GoogleGeoAPI : IDisposable
{
public delegate void ErrorInvoke(Exception e);
public delegate void SuccessInvoke(string e);
//查詢失敗可操作的事件通知。
public ErrorInvoke Error;
//查詢成功可操作的事件通知。
public SuccessInvoke Completed;
private WebClient gWebClient;
public GoogleGeoAPI()
{
gWebClient = new WebClient();
gWebClient.DownloadStringCompleted += gWebClient_DownloadStringCompleted;
}
void gWebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
this.Error(e.Error);
}
else
{
DataContractJsonSerializer tJsonSerial = null;
MemoryStream tMS = null;
GoogleGeoLocationAPIResult tResultObject = null;
ResultObject tNear = null;
try
{
tJsonSerial = new DataContractJsonSerializer(typeof(GoogleGeoLocationAPIResult));
tMS = new MemoryStream(Encoding.UTF8.GetBytes(e.Result));
tResultObject = tJsonSerial.ReadObject(tMS) as GoogleGeoLocationAPIResult;
//取得第一個最精準的結果
tNear = tResultObject.results.FirstOrDefault();
this.Completed(tNear.formatted_address);
}
catch (Exception ex)
{
this.Error(ex);
}
finally
{
if (tJsonSerial != null) tJsonSerial = null;
if (tMS != null)
{
tMS.Close();
tMS.Dispose();
tMS = null;
}
tResultObject = null;
tNear = null;
}
}
}
/// <summary>
/// 指定座標查詢地址。
/// </summary>
/// <param name="pLatitude">0.000000</param>
/// <param name="pLongitude">0.000000</param>
public void QueryAddressByLocation(string pLatitude, string pLongitude)
{
if (gWebClient.IsBusy == false)
{
string tURL = string.Format("http://maps.googleapis.com/maps/api/geocode/json?latlng={0},{1}&sensor=false&language={2}",
pLatitude, pLongitude, "zh-TW");
gWebClient.DownloadStringAsync(new Uri(tURL, UriKind.Absolute));
}
}
public void Dispose()
{
if (gWebClient.IsBusy)
{
gWebClient.CancelAsync();
}
gWebClient = null;
}
}
(3) 搭配WP中取得座標的結果後,使用(2)所建立好的API:
private void GeoLocationToAddress(GeoCoordinate pLocation)
{
GoogleGeoAPI tGoogleAPI = new GoogleGeoAPI();
tGoogleAPI.Error += (e) =>
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("目前座標無法轉換成地址資訊");
});
};
tGoogleAPI.Completed += (o) =>
{
Dispatcher.BeginInvoke(() =>
{
//顯示地址
MessageBox.Show(o);
});
};
//指定座標latitude, longitude,記得double輸出要給0.000000詳細的字串轉換
tGoogleAPI.QueryAddressByLocation(
pLocation.Latitude.ToString("0.000000"),
pLocation.Longitude.ToString("0.000000"));
}
如果您想知道怎麼把地址或是輸入的一個景點轉換成座標的方式,可參考<Windows Phone 7 - 使用Google Map API將地址轉成座標>。
======
希望對大家有所幫助。