1. 程式人生 > >用高德js api做h5定位功能

用高德js api做h5定位功能

定位失敗?what

最近專案中有一需求要實現手機定位當前城市功能, 查了高德地圖api,根據文件說明很快就做出來了。
AMap.plugin('AMap.CitySearch', function () {
var citySearch = new AMap.CitySearch()
citySearch.getLocalCity(function (status, result) {
if (status === 'complete' && result.info === 'OK') {
// 查詢成功,result即為當前所在城市資訊
}
})
})
然而在測試階段,出現了一些問題:

當手機連線wifi的時候,明明在北京卻定位到了上海,

或者在浙江的測試人員4g情況下無法定位

更或者河北的直接定位到了鄭州......心裡一片媽賣批。後臺將高德的地圖編碼全都轉成自己對應的資料了,這時候更改定位方式,保不齊要殺我祭天。

於是趕緊滾過去擼一下開發文件:

en ...似乎沒什麼問題

那麼再去看看手機定位的原理吧。

手機定位的原理

一般情況下手機定位的方法有GPS定位、基站定位、WIFI定位、藍芽定位、地磁定位等。其中藍芽定位和地磁定位主要用於室內定位技術,在百度地圖和高德地圖的室內定位技術中應該都曾經嘗試用過這兩項技術,百度還專門投資了一家做地磁定位的芬蘭新創企業IndoorAtlas。這兩種方法一般人都用不到,可暫時略過。

1.GPS定位

利用手機中的GPS模組獲取位置資訊,不僅能獲取經緯度,還能包括海拔高度、方向角度等資訊。眾多周知,GPS是通過三角定位的原理來實現定位的。即為了計算地面的空間座標(x,y,z),理論上GPS接收機只要通過3顆衛星獲取當前位置到三顆衛星的距離,就可以構造三個方程求解三個未知引數x,y,z。但實際上衛星鐘與GPS接收機的石英鐘是不同步,這樣就會出現一個新的未知數-時鐘差,因此就需要同時接收到4顆以上的衛星訊號構造四個方程來求解定位點座標。

在城市高樓林立的環境下,GPS訊號遮擋嚴重,所以定位效果要比在開闊地差很多。除此觀測衛星數量的原因外,複雜的環境也是降低GPS自身的精度的原因所在。


大氣層影響

大氣層中的電離層和對流層對GPS訊號會起到延遲的作用,電離層對電磁波的折射效應使得GPS訊號的傳播速度發生變化,對流層同樣會對電磁波產生折射效應,從而影響GPS訊號的傳播速度。

衛星星曆誤差

衛星星曆是由地面監控站跟蹤監測衛星求定的。由於衛星執行中要受到多種攝動力的複雜影響,而通過地面監控站又難以充分可靠地測定這些作用力或掌握其作用規律,因此在星曆預報時會產生較大的誤差。它不僅嚴重影響單點定位的精度,也是精密相對定位的重要誤差來源。

衛星時鐘誤差

衛星鐘差是指GPS衛星時鐘與GPS標準時間的差別。為了保證時鐘的精度,GPS衛星均採用高精度的原子鐘,但它們與GPS標準時之間的偏差和漂移和漂移總量仍在1ms~0.1ms以內,由此引起的等效誤差將達到300km~30km。這是一個系統誤差必須加於修正。

多徑效應

多徑效應由於接收終端周圍環境的影響,使得接收機所接收到的衛星訊號中還包含有反射和折射訊號的影響,這也是影響在室內和城市樓宇密集的地區定位偏差大的一大因素。

  1. 基站定位

基站定位主要是通過行動網路運營商搭建的基站實現定位。它的基本原理是通過移動裝置測量不同基站的下行導頻訊號,得到不同基站下行導頻的TOA(Time of Arrival,到達時刻)或TDOA(Time Difference of Arrival,到達時間差),根據該測量結果並結合基站的座標採用三角公式估計演算法,就能夠計算出移動裝置的位置。一般而言,移動裝置觀測到的基站數目越多,測量精度越高,定位效能改善越明顯。

所以基站定位精度依賴於基站的密度,密度越大,定位越精確。

  1. WIFI定位

它的原理大概如下:每一個無線AP都有一個全球唯一的MAC地址(中國山寨比較多,所以在中國的WIFI定位技術會更加複雜),並且一般來說無線AP在一段時間內是不會移動的; 裝置在開啟Wi-Fi的情況下,即可掃描並收集周圍的AP訊號,無論是否加密,是否已連線,甚至訊號強度不足以顯示在無線訊號列表中,都可以獲取到AP廣播出來的MAC地址;裝置將這些能夠標示AP的資料傳送到位置伺服器,伺服器檢索出每一個AP的地理位置,並結合每個訊號的強弱程度,計算出裝置的地理位置並返回到使用者裝置.

WIFI定位的精度取決於位置服務商的資料庫的準確度和實時性。有的時候你可能會發現自己搬家到了一個新的地方,把之前的路由器也帶過來了,一段時間內手機定位總是把你定位到之前住的地方,就是這個原因。

各種定位方法自身的缺陷和誤差都會導致定位結果的誤差。當然國內為了國家安全的考量,會對電子地圖供應商的定位結果進行非線性偏移,這種被稱為火星座標系的偏移也會造成定位精度的偏差。

排查問題

在仔細看完定位原理和高德地圖api的文件, 發現高德的citySearch方法僅僅支援ip定位。

地理定位

高德地圖的geolocation定位方式說明中提及了整合了瀏覽器定位、精確IP定位、sdk輔助定位多種手段;

看看文件:
mapObj = new AMap.Map('iCenter');
mapObj.plugin('AMap.Geolocation', function () {
geolocation = new AMap.Geolocation({
enableHighAccuracy: true,//是否使用高精度定位,預設:true
timeout: 10000, //超過10秒後停止定位,預設:無窮大
maximumAge: 0, //定位結果快取0毫秒,預設:0
convert: true, //自動偏移座標,偏移後的座標為高德座標,預設:true
showButton: true, //顯示定位按鈕,預設:true
buttonPosition: 'LB', //定位按鈕停靠位置,預設:'LB',左下角
buttonOffset: new AMap.Pixel(10, 20),//定位按鈕與設定的停靠位置的偏移量,預設:Pixel(10, 20)
showMarker: true, //定位成功後在定位到的位置顯示點標記,預設:true
showCircle: true, //定位成功後用圓圈表示定位精度範圍,預設:true
panToLocation: true, //定位成功後將定位到的位置作為地圖中心點,預設:true
zoomToAccuracy:true //定位成功後調整地圖視野範圍使定位位置及精度範圍視野內可見,預設:false
});
mapObj.addControl(geolocation);
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, 'complete', onComplete);//返回定位資訊
AMap.event.addListener(geolocation, 'error', onError); //返回定位出錯資訊
});
在這段程式碼中有很多配置項,那麼定位是否也能進行配置呢?

找到它 進行配置就可以了。

然而問題並非能這麼快解決的, 高德的ip城市定位和地理定位方法返回的adcode值是不一致的;ip城市定位的adcode 僅僅代表市,比如北京市:110000, 而在地理定位中的adcode 可以直接定位到區,比如城市仍可以繼續顯示北京市,而adcode的值卻變成了 110108。那麼這時,就需要跟後端協商確認是否已經將所有的省市區的編碼入庫。另外仍需要考慮實際問題是全國的各種高新技術開發區或者區與區之間的合併都會引起資料錯誤,也都需要及時進行更新國家標準城市編碼資訊。

如何改善使用者體驗

在定位系統無法做到萬無一失的情況下, 加入手動選擇所在城市是一個不錯的選擇。

例如京東的定位功能然錯把北京的我定位到了湖北,但它附加的手動選擇很好的補全了定位不準的問題。

==嗯,快去跟產品設計好好聊會天了。

前端小白一枚, 歡迎指正。