(圖片來源:http://www.ibm.com/developerworks/library/j-coordconvert/)
先前利用python寫了一個簡單的小工具接google的api來查詢住址的經緯度-[Python] Google 經緯度查詢Api.最近因為一些需求,需要從經緯度反查住址,所以就把這個小工具更新了一下.
這次更新的部分也是透過GOOGLE提供的API-ReversGeocoding,只要在網址中https://maps.googleapis.com/maps/api/geocode/json?latlng=輸入任意的經緯度,就可以傳回相關資訊.如果就那麼簡單實在是也沒啥好介紹的,但是問題出在他傳回來的json格式長這樣(API連結):
{
"results" : [
{
"address_components" : [
{
"long_name" : "277",
"short_name" : "277",
"types" : [ "street_number" ]
},
{
"long_name" : "Bedford Avenue",
"short_name" : "Bedford Ave",
"types" : [ "route" ]
},
{
"long_name" : "Williamsburg",
"short_name" : "Williamsburg",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Brooklyn",
"short_name" : "Brooklyn",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Kings",
"short_name" : "Kings",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "New York",
"short_name" : "NY",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "11211",
"short_name" : "11211",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "277 Bedford Avenue, Brooklyn, NY 11211, USA",
"geometry" : {
"location" : {
"lat" : 40.714232,
"lng" : -73.9612889
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 40.7155809802915,
"lng" : -73.9599399197085
},
"southwest" : {
"lat" : 40.7128830197085,
"lng" : -73.96263788029151
}
}
},
"place_id" : "ChIJd8BlQ2BZwokRAFUEcm_qrcA",
"types" : [ "street_address" ]
},
... Additional results[] ...
可以看到回傳一堆資訊,假設我們要找的地方是這個經緯度所在的國家,就在第二層的第七個位置(範例中為United States).偏偏麻煩在於每個座標傳回來的階層長得不太一樣像是這個範例:{
"results" : [
{
"address_components" : [
{
"long_name" : "人倫林道支線",
"short_name" : "人倫林道支線",
"types" : [ "route" ]
},
{
"long_name" : "雙龍村",
"short_name" : "雙龍村",
"types" : [ "administrative_area_level_4", "political" ]
},
{
"long_name" : "Xinyi Township",
"short_name" : "Xinyi Township",
"types" : [ "administrative_area_level_3", "political" ]
},
{
"long_name" : "Nantou County",
"short_name" : "Nantou County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Taiwan",
"short_name" : "TW",
"types" : [ "country", "political" ]
},
{
"long_name" : "556",
"short_name" : "556",
"types" : [ "postal_code" ]
}
],
... Additional results[] ...
可以看到這次的國家位置在第二層的第五個位置,所以跟地址查詢不一樣,不能使用無腦算階層的方式來查找,所以這次使用了稍微智慧一點的查找方式:class GeocodeQueryReverse:
def __init__(self, lat =None, lng = None, language='en'):
url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng={0},{1}&language={2}'.format(lat, lng, language)
response = urllib2.urlopen(url)
self.jsonResponse = json.loads(response.read())
def get_country(self):
if len(self.jsonResponse["results"]) is not 0:
for item in self.jsonResponse["results"][0]["address_components"]:
if item["types"][0] == "country":
return item["long_name"]
- 第一步當物件實體化時,同時帶入經緯度.
- 接著get_country這個方法,不再使用算階層的方式,而使帶入for迴圈中,去查找types這個元素的值是不是country,如果是的話,就把同一層的long_name回傳
使用方法如下:
#in python
from geocodequery import GeocodeQueryReverse
gqr = GeocodeQueryReverse(40.714224,-73.961452)
gqr.get_country() #United States
另外為了方便使用,另外做了cmd的指令if __name__ == '__main__':
if (len(sys.argv) != 5):
print 'usage: geocodeQuery.py [reverse] [lat] [lng] [country/addr]'
sys.exit(1)
if (sys.argv[1] == 'reverse' and sys.argv[4] == 'country'):
gqr = GeocodeQueryReverse(sys.argv[2],sys.argv[3])
print gqr.get_country()
讓程式可以在cmd的模式下直接輸入經緯度查找. 完整程式碼可以看brynaynag0528/geocodeQuert
沒有留言:
張貼留言