(本文已受權Python中文社區
發佈)html
今天看到一篇阿里雲的文章天下武功,惟快不破,以物流行業爲例,分析了 PostgreSQL 與 Greenplum 在地理位置信息處理,最佳路徑算法,機器學習等方面的物流行業應用方法。其中提到了地址轉換成座標的問題,更專業些的名詞應該是「地理編碼」,即知道一個地址,如北京市海淀區上地十街10號
,怎麼樣能夠獲取到對應的經緯度位置信息(40,116)
,或者反過來。算法
不少地圖相關的廠商都提供了相關的API,咱們能夠直接利用這些API獲得這些信息。好比百度的Geocoding API
。json
Geocoding API是一類接口,用於提供從地址到經緯度座標或者從經緯度座標到地址的轉換服務,用戶可使用C# 、C++、Java等開發語言發送請求且接收JSON、XML的返回數據。Geocoding API包括地址解析和逆地址解析功能:api
借用ESRI文檔中更直觀的一張圖微信
地理編碼:即地址解析,由詳細到街道的結構化地址獲得百度經緯度信息,例如:「北京市海淀區中關村南大街27號」地址解析的結果是「lng:116.31985,lat:39.959836」。同時,地理編碼也支持名勝古蹟、標誌性建築名稱直接解析返回百度經緯度,例如:「百度大廈」地址解析的結果是「lng:116.30815,lat:40.056885」 。機器學習
逆地理編碼:即逆地址解析,由百度經緯度信息獲得結構化地址信息,例如:「lat:31.325152,lng:120.558957」逆地址解析的結果是「江蘇省蘇州市虎丘區塔園路318號」。ide
不過,須要說明的一點是,若想使用百度的這套API的前提是,有百度帳號並申請相應的Key。其實,除了百度以外,谷歌、ESRI、微軟的Bing等都有相似的地理編碼服務。不過這些服務大多沒有專門針對Python的庫而且彼此之間的Json結構也不一致。因而乎專治不服的Python大神作了一個專門的地理編碼工具geocoder
,將這些不一樣廠商的服務整合統一塊兒來。工具
geocoder
首先看一下它都支持哪些公司的地理編碼服務:post
Provider | Optimal | Usage Policy | ||
---|---|---|---|---|
ArcGIS | World | |||
Baidu | China | API key | ||
Bing | World | API key | ||
CanadaPost | Canada | API key | ||
FreeGeoIP | World | |||
Geocoder.ca | CA & US | Rate Limit | ||
GeocodeFarm | World | Policy | ||
GeoNames | World | Username | ||
GeoOttawa | Ottawa | |||
World | Rate Limit, Policy | |||
HERE | World | API key | ||
IPInfo | World | |||
Mapbox | World | API key | ||
MapQuest | World | API key | ||
Mapzen | World | API key | ||
MaxMind | World | |||
OpenCage | World | API key | ||
OpenStreetMap | World | Policy | ||
Tamu | US | API key | ||
TomTom | World | API key | ||
What3Words | World | API key | ||
Yahoo | World | |||
Yandex | Russia | |||
TGOS | Taiwan |
pip install geocoder
import geocoder g = geocoder.google("1403 Washington Ave, New Orleans, LA 70130") g = geocoder.arcgis(u"北京市海淀區上地十街10號") g.latlng
輸出爲學習
[29.9287839, -90.08421849999999]
也能夠查看完整的geojson
g.geojson
輸出爲
{'bbox': [-90.0855674802915, 29.9274349197085, -90.0828695197085, 29.9301328802915], 'geometry': {'coordinates': [-90.08421849999999, 29.9287839], 'type': 'Point'}, 'properties': {'accuracy': u'ROOFTOP', 'address': u'1403 Washington Ave, New Orleans, LA 70130, USA', 'bbox': [-90.0855674802915, 29.9274349197085, -90.0828695197085, 29.9301328802915], 'city': u'New Orleans', 'confidence': 9, 'country': u'US', 'county': u'Orleans Parish', 'encoding': 'utf-8', 'housenumber': u'1403', 'lat': 29.9287839, 'lng': -90.08421849999999, 'location': '1403 Washington Ave, New Orleans, LA 70130', 'neighborhood': u'Garden District', 'ok': True, 'place': u'ChIJGyFHWc2lIIYRYSoneaXAUiw', 'postal': u'70130', 'provider': 'google', 'quality': u'street_address', 'state': u'LA', 'status': 'OK', 'status_code': 200, 'street': u'Washington Ave'}, 'type': 'Feature'}
直接用Google嘗試查詢中文地址時失敗
g = geocoder.google(u"北京市海淀區上地十街10號") g.ok
輸出爲
False
用百度應該沒問題,不過我沒有申請相應的key。切換到arcgis,可以成功編碼
g = geocoder.arcgis(u"北京市海淀區上地十街10號") g.latlng
輸出爲
[40.050934, 116.30079]
g = geocoder.google([29.9287839, -90.08421849999999], method='reverse') print g.address print g.city print g.state print g.country
輸出爲
1403 Washington Ave, New Orleans, LA 70115, USA New Orleans LA US
換成中國的地址
g = geocoder.google([40.050934, 116.30079], method='reverse') print g.address print g.city print g.state print g.country
輸出爲
Bai Du Da Sha, Haidian Qu, Beijing Shi, China, 100193 Beijing Beijing Shi CN
用arcgis的服務試試
g = geocoder.arcgis([40.050934, 116.30079], method='reverse') print g.address print g.city print g.state print g.country
輸出爲
None 北京市 北京市 CHN
Google轉換成的是英文,但地址比較全。arcgis雖然是中文,可是詳細的地址竟然輸出爲了None,這有個X
用。
geocoder
的功能不止於此,它還能夠查IP(包括本身的)。
g = geocoder.ip('199.7.157.0') print g.latlng print g.city g = geocoder.ip('me') print g.latlng print g.city
輸出爲
[43.6934, -79.4857] Toronto [51.05, 13.75] Dresden
查詢一個城市的空間包圍盒
g = geocoder.arcgis(u"山東") g.bbox
輸出爲
{'northeast': [38.976997, 121.976998], 'southwest': [33.022997, 116.022998]}
空間信息既能夠利用行政區劃、天然地理區域等文本信息描述,也能夠用座標系統、數字(郵編等)來標識。利用地理編碼技術,能夠將空間信息的地理定位要素與相應的文本信息關聯起來。本文主要介紹了geocoder
地理編碼這一小工具,能夠方便快捷的利用地圖等相關廠商提供的地理編碼服務,將文字描述的位置轉換成地圖上的經緯度,或者經過地圖上的某個位置座標得到相應的位置信息文字描述。