事情是這樣的,我有一大堆用戶的的個人數據,數據中包含用戶的”住址“這個字段。住址可能來源于身份證上的地址,也有可能是手工錄入的地址,比如地址是“南京金陵飯店”。為了對用戶住址進行更精確的定位,需要將地址轉換成更加規范的格式,形如(省,市,區,街道,街道號)這樣的形式。“南京金陵飯店”就會被映射為(江蘇省,南京市,鼓樓區,漢中路, 2號).
使用手工的方式來轉換肯定是不現實的,一定需要借助于工具。開始考慮過通過關鍵字匹配的方式進行轉換,比如把地址中包含“鼓樓區”的映射到(江蘇省,南京市,鼓樓區,,)。 但這樣有兩個弱點:
- 覆蓋率低,很多地址是XXX小區,或直接寫成XXX街道XX號。
- 準確率低,只能精確到區縣級別。
最后選擇是用百度地圖提供的API (http://lbsyun.baidu.com/ )來進行轉換。百度地圖提供了
a. 地址解析,將文本描述的地址轉換成坐標。
b.逆地址解析, 將坐標轉換陳格式化的地址。
基本思路是 輸入文本->獲取坐標->轉換成格式化的文本。
但是現在的問題是API對調用次數有限制,未認證用戶每天限6000次,大致算了下,差不多要10多天才算的完。我又不想去弄個認證,咋辦呢?
百度地圖API提供一個演示平臺 http://lbsyun.baidu.com/jsdemo.htm#i7_1
image.png
支持通過編輯代碼來執行自己的功能,而在這里執行的代碼是 沒有 API調用次數限制的。但是前端執行的代碼,數據輸出是一個大問題。內容不能直接輸出成文件,更不能輸出到數據庫了。最常用的輸出也就是輸出到控制臺上,但是對于大量數據來說,如何把console上的數據采集回來有是一個問題。 我們選擇把數據存儲到localstorage中去,這樣既能保持數據的格式良好,又便于數據的收集。要做的事情也很簡單
- 定義一個大的數組
- 通過setInterval的方式調用下面的函數,先進行地址轉換得到坐標,再進行逆地址轉換得到格式化的地址,最后存入localstorage。
function getLocation(address)
{
var currentLocation = address;
myGeo.getPoint(currentLocation, function(point){
if (point) {
myGeo.getLocation(point, function(rs){
if(rs && rs.addressComponents){
var addComp = rs.addressComponents;
var newAddress = addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber;
localStorage.setItem(currentLocation, newAddress);
}
});
}else{
//alert("您選擇地址沒有解析到結果!");
}
}, "重慶市");
}
問題
對轉換結果進行分析,絕大部分轉換還是很準確,但還存在如下問題:
- 有些地址本身并沒有精確到街道號,但是轉換出來的地址中竟然包含街道號。我猜想在進行地址->坐標的轉換時,API會把這個地址映射到系統內部定義好的并和輸入的地址盡可能近的坐標,但是系統內已定義的地址和輸入的地址并不是完全一致。而在進行逆地址解析時返回的就是系統已定義的地址。
- 對錯別字的容忍度較低。