項目背景:
一個項目bug,項目中用到高德地圖,默認打開頁面會生成一個marker(下圖紅色icon),然后用戶拖動marker到想要的位置,並且保存。
用戶反映定位不准確,在當前頁面編輯的位置,到后台打開位置就會有偏移。
因為后台打開時候是根據經緯度生成的marker,經過檢查最終確定是前台頁面,拖動marker定位 獲取經緯度 那里出的問題。
這里不得不說下個人情況,此項目是他人開發,而開發人員已經不在公司,bug轉發給我了。自己之前也沒怎么使用過高德,主要使用的是谷歌地圖和mapbox。
在修改這個bug的時候,思緒會受谷歌api一些影響,因為一直覺得他們的api都差不多。
現在我打開自己的頁面,然后拖動marker,拖動結束我會打印一下經緯度,然后把這個經緯度復制下來,並在高德的官方地圖上去搜索獲取到的這個經緯度。
結果確實一直都是有偏差的,而且還偏差值每次都不同。
第一個想法:
看了下代碼,發現在 生成 marker 的時候, 並沒有對自定義的 icon(紅色圖標)設置偏移,為什么要設置偏移呢,因為我們在用這個 圖標 定位的時候,
是認為這個 圖標的底部箭頭 指向的位置 是我們要的位置。如下圖——
如果是用高德自帶的 圖標 ,圖標的箭頭就是指向的當前位置。而如果用自定義圖標的話,默認位置是定義在圖片畫布的左上角 也就是left:0;top:0;如下圖——
所以必須要為自定義圖標設置偏移值,上圖的 圖標 大小是 寬36px 高 42px, 箭頭的位置是left:18px;top:38px,所以下面設置offset偏移是-18,-38
var marker = new AMap.Marker({ icon: new AMap.Icon({ size:new AMap.Size(36,42),//圖標大小 image:"/img/loc.png" }), //這里用/img/loc.png圖片的left:18;top:38指向坐標 offset: new AMap.Pixel(-18,-38), position: map.gaode.map.getCenter(), draggable:true //點標記可拖拽 });
這樣, 當前的經緯度位置就是箭頭位置。
順便這里說下谷歌地圖,谷歌如果用自定義圖片,定位會在圖片中間最底部,如下圖:
// 以下是谷歌的描述: By default, the anchor is located along the center point of the bottom of the image
總之,根據圖片不同,還是要考慮設置偏移值 不管是谷歌還是高德。
偏移值設置了后,發現仍然還有偏差。然后繼續思考。
第二個想法:
其實最后發現問題很簡單, 在谷歌地圖上,不管怎么移動 獲取到的經緯度 都是我的箭頭指向的位置,
而高德不一樣,當我marker拖拽結束后 觸發的“拖拽結束”事件(dragend),獲取的是鼠標位置的經緯度。
高德文檔————

拖拽 我們的 marker 的時候,鼠標的位置是在 marker 上,但是並不一定在箭頭上, 所以不管箭頭指向哪里,獲取到的永遠是鼠標指向
位置的經緯度,所以會有偏差。
解決方法如下:
AMap.event.addListener(marker, 'dragging', function(e){ var lat = e.lnglat.lat, lng = e.lnglat.lng; marker.setPosition(new AMap.LngLat(lng,lat)); });
拖動過程中,獲取當前鼠標的位置,然后把marker定位到鼠標的位置。
這樣就解決了這個bug。
結論:
不同的地圖,確實是有一些不容易發現的差異,有時候看文檔,也會容易漏掉什么。
改他人bug,確實要比改自己bug麻煩一點。