以物流業為例,分析了 PostgreSQL 與 Greenplum 在地理位置資訊處理,最佳路徑演算法,機器學習等方面的物流行業應用方法。其中提到了地址轉換成座標的問題,更專業些的名詞應該是“地理編碼”,即知道一個地址,如北京市海淀區上地十街10號,怎麼樣可以獲得到對應的經緯度位置資訊( 40,116),或者反過來。
地理編碼概念
許多地圖相關的廠商都提供了相關的API,我們可以直接利用這些API來得到這些資訊。例如百度的Geocoding API。
Geocoding API是一類接口,用於提供從地址到經緯度坐標或從經緯度坐標到地址的轉換服務,用戶可以使用C# 、C++、Java等開發語言發送請求且接收JSON、XML的返回資料。 Geocoding API包括地址解析和逆地址解析功能:
借用ESRI文檔中更直觀的一張圖
地理編碼:即地址解析,由詳細到街道的結構化地址得到百度經緯度資訊,例如:「北京市海淀區中關村南大街27號」地址解析的結果是「lng:116.31985,lat:39.959836」。同時,地理編碼也支援名勝古蹟、標誌性建築名稱直接解析返回百度經緯度,例如:「百度大廈」地址解析的結果是「lng:116.30815,lat:40.056885」 。
逆地理編碼:即逆地址解析,由百度經緯度信息得到結構化地址信息,例如:“lat:31.325152,lng:120.558957”逆地址解析的結果是“江蘇省蘇州市虎丘區塔園路318號」。
不過,需要說明的一點是,若想使用百度的這套API的前提是,有百度帳號併申請相應的Key。其實,除了百度之外,Google、ESRI、微軟的Bing等都有類似的地理編碼服務。不過這些服務大多沒有專門針對Python的函式庫並且彼此之間的Json結構也不一致。於是乎專治不服的Python大神做了一個專門的地理編碼工具geocoder,將這些不同廠商的服務整合統一起來。
地理編碼工具geocoder
首先看一下它都支援哪些公司的地理編碼服務:
安裝
pip install geocoder
為
import geocoder g = geocoder.google("1403 Washington Ave, New Orleans, LA 70130") g = geocoder.arcgis(u"北京市海淀区上地十街10号") g.latlng
直接用Google嘗試查詢中文地址時失敗
[29.9287839, -90.08421849999999]
輸出為
g.geojson
用百度應該沒問題,不過我沒有申請相應的key。切換到arcgis,能夠成功編碼
{'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'}
輸出為
g = geocoder.google(u"北京市海淀区上地十街10号") g.ok
逆地理編碼
False
輸出為
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
Google轉換成的是英文,但地址比較全。 arcgis雖然是中文,但是詳細的地址居然輸出為了None,這有個X用。
其他
geocoder 的功能不止於此,它還可以查IP(包括自己的)。
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
輸出為
g = geocoder.arcgis([40.050934, 116.30079], method='reverse') print g.address print g.city print g.state print g.country
小結
空間資訊既可以利用行政區劃、自然地理區域等文字資訊描述,也可以用座標系統、數字(郵編等)來識別。利用地理編碼技術,可以將空間資訊的地理定位要素與對應的文字資訊關聯起來。本文主要介紹了geocoder地理編碼這一小工具,可以方便快捷的利用地圖等相關廠商提供的地理編碼服務,將文字描述的位置轉換成地圖上的經緯度,或者透過地圖上的某個位置座標獲得相應的位置資訊文字描述。