日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

百度地图JavascriptApi Marker平滑移动及车头指向行径方向

發(fā)布時(shí)間:2025/5/22 java 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 百度地图JavascriptApi Marker平滑移动及车头指向行径方向 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  相信只要是使用百度地圖做實(shí)時(shí)定位服務(wù)的朋友都會(huì)遇到這個(gè)問題,在對坐標(biāo)位置進(jìn)行覆蓋物展示的時(shí)候,會(huì)出現(xiàn)由于獲取坐標(biāo)數(shù)據(jù)時(shí)間或者兩個(gè)坐標(biāo)點(diǎn)相距過遠(yuǎn),導(dǎo)致在視覺上看Marker移動(dòng)就像“僵尸跳”一樣,一蹦一蹦的給客戶看分分鐘鄙視你到不能自已。另外如果用的是有指向性圖標(biāo)ICON的時(shí)候,更會(huì)引來吐槽~誒誒誒,你這小車車怎么在這個(gè)立交橋轉(zhuǎn)彎的時(shí)候車頭向著后面呢?怎么搞得嘛你!會(huì)不會(huì)弄啊你!

  所以今天參照百度大大提供的路書開源文件實(shí)現(xiàn)下自己的需求,記錄一下以便提供參考。

  此博的目的就是解決在做實(shí)時(shí)定位監(jiān)控相關(guān)業(yè)務(wù)的時(shí)候遇到的:更新定位數(shù)據(jù)時(shí),標(biāo)注物移動(dòng)太生硬、閃爍 和 標(biāo)注物實(shí)時(shí)移動(dòng)方向問題

  一、覆蓋物在獲取坐標(biāo)數(shù)據(jù)的同時(shí),在坐標(biāo)點(diǎn)之間平滑的移動(dòng)

  首先,之所以會(huì)出現(xiàn)僵尸跳的效果,是因?yàn)轫?xiàng)目是根據(jù)實(shí)時(shí)坐標(biāo)數(shù)據(jù)進(jìn)行定位,所以存在一個(gè)等待新數(shù)據(jù)的過程,而對于覆蓋物的坐標(biāo)改變就是一個(gè)setPosition(BMap.Point)方法而已也就造成了停頓。所以目前暫且解決方案就是:讓他這個(gè)覆蓋物在這個(gè)等待的期間找點(diǎn)事情做,不要一下就直接從起點(diǎn)蹦到終點(diǎn)了,慢慢的移動(dòng)過去。小碎步,平滑的的移動(dòng)過去~~

  怎么移動(dòng)呢?此時(shí)這個(gè)事情就可以轉(zhuǎn)化為已知起始點(diǎn)坐標(biāo),進(jìn)行移動(dòng)覆蓋物的這么過程了,說白了就是讓他覆蓋物在兩個(gè)點(diǎn)連成的這條線上多執(zhí)行幾次setPosition(BMap.Point),一次步子別邁那么大,只要保證在下次新坐標(biāo)來之前到達(dá)就行了。
   那么問題又來了,這兩條線上的點(diǎn)我怎么知道呢? 因?yàn)楂@取到的經(jīng)緯度坐標(biāo)是球面坐標(biāo),所以要先轉(zhuǎn)換為平面坐標(biāo) {BMap.Pixel}= map.getMapType().getProjection().lngLatToPoint(BMap.Point);

   然后小運(yùn)算下(參照路書開源文件)

  

1 /* 2 *緩動(dòng)效果 3 *初始坐標(biāo),目標(biāo)坐標(biāo),當(dāng)前的步長,總的步長 4 *@param{BMap.Pixel} initPos 初始平面坐標(biāo) 5 *@parm{BMap.Pixel} targetPos 目標(biāo)平面坐標(biāo) 6 *@param{number} 當(dāng)前幀數(shù) 7 *@param {number} count 總幀數(shù) 8 */ 9 this.linear = function (initPos, targetPos, currentCount, count) { 10 var b = initPos, c = targetPos - initPos, t = currentCount, 11 d = count; 12 return c * t / d + b; 13 } 14 15    var x = effect(_prvePoint.x, _newPoint.x, currentCount, count), 16 y = effect(_prvePoint.y, _newPoint.y, currentCount, count);

?

?  經(jīng)過計(jì)算得到的是一個(gè)平面坐標(biāo)pixel(x,y)。然后再將平面坐標(biāo)轉(zhuǎn)換為球面坐標(biāo)給Marker進(jìn)行定位即可。(這些方法在百度類庫參考文檔中都可以找得到的。魔法門: http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E5%9C%B0%E5%9B%BE%E7%B1%BB%E5%9E%8B%E7%B1%BB)

    ?var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));

     修改覆蓋物定位坐標(biāo)值。當(dāng)然這個(gè)地方要進(jìn)行多次執(zhí)行也就需要個(gè)setInterval咯? 這里面的

?

      me._em._newPointMark.setPosition(pos);

    ? 完整方法:

    

1 /** 2 *小車移動(dòng) 3 *@param {Point} prvePoint 開始坐標(biāo)(PrvePoint) 4 *@param {Point} newPoint 目標(biāo)點(diǎn)坐標(biāo) 5 *@param {Function} 動(dòng)畫效果 6 *@return 無返回值 7 */ 8 9 this.Move = function (prvePoint, newPoint, effect, setRotation) { 10 var me = this, 11 //當(dāng)前幀數(shù) 12 currentCount = 0, 13 //初始坐標(biāo) 14 _prvePoint = me._projection.lngLatToPoint(prvePoint),//將球面坐標(biāo)轉(zhuǎn)換為平面坐標(biāo) 15 //獲取結(jié)束點(diǎn)的(x,y)坐標(biāo) 16 _newPoint = me._projection.lngLatToPoint(newPoint), 17 //兩點(diǎn)之間要循環(huán)定位的次數(shù) 18 count = me._runTime / me._intervalTimer; 19 //兩點(diǎn)之間勻速移動(dòng) 20 me._intervalFlag = setInterval(function () { 21 //兩點(diǎn)之間當(dāng)前幀數(shù)大于總幀數(shù)的時(shí)候,則說明已經(jīng)完成移動(dòng) 22 if (currentCount >= count) { 23 clearInterval(me._intervalFlag); 24 } else { 25 //動(dòng)畫移動(dòng) 26 currentCount++;//計(jì)數(shù) 27 var x = effect(_prvePoint.x, _newPoint.x, currentCount, count), 28 y = effect(_prvePoint.y, _newPoint.y, currentCount, count); 29 //根據(jù)平面坐標(biāo)轉(zhuǎn)化為球面坐標(biāo) 30 var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y)); 31 //設(shè)置marker角度(兩點(diǎn)之間的距離車的角度保持一致) 32 if (currentCount == 1) { 33 //轉(zhuǎn)換角度 34 setRotation(prvePoint,newPoint, me._em); 35 } 36 //正在移動(dòng) 37 38 me._em._newPointMark.setPosition(pos); 39 } 40 }, me._intervalTimer); 41 me._em._prvePoint = newPoint; 42 }

?

    值得注意的是,這里關(guān)鍵的就是這個(gè)count = me._runTime / me._intervalTimer; 決定了在這兩個(gè)點(diǎn)之間要走多少個(gè)小碎步~~

    這個(gè)count的由來也得根據(jù)自身項(xiàng)目需求計(jì)算。

      1,通過控制覆蓋物移動(dòng)數(shù)據(jù)控制動(dòng)畫效果。這種方法就需要通過 速度與每次執(zhí)行的時(shí)間計(jì)算得到每次執(zhí)行前進(jìn)的距離,然后在與兩點(diǎn)之間的距離做商得到要執(zhí)行的次數(shù)。(這種方法呢適合做歷史軌跡回放這種,所有坐標(biāo)信息都已經(jīng)知道,一個(gè)點(diǎn)執(zhí)行完就跳到下一個(gè)坐標(biāo),只是通過控制速度來控制動(dòng)畫的展示快慢)

      2,通過控制平緩移動(dòng)過程的總時(shí)間與每次執(zhí)行間隔時(shí)間來控制動(dòng)畫效果。此方法就是文中的示例,直接二者做商即可得到要執(zhí)行的次數(shù)。(這種方法適合做實(shí)時(shí)定位使用,因?yàn)橄乱淮味ㄎ粩?shù)據(jù)是間隔多少時(shí)間后接收,這個(gè)使我們可以控制的,所以這個(gè)平緩移動(dòng)的動(dòng)畫過程的總時(shí)間也是可以由我們自己控制的)
    

?    二、車頭指向行徑方向

     這個(gè)功能其實(shí)就是改變覆蓋物的旋轉(zhuǎn)角度em._newPointMark.setRotation(number);

     只是還是那個(gè)原因,因?yàn)榈玫降淖鴺?biāo)點(diǎn)數(shù)據(jù)是球面坐標(biāo),所以還是要先進(jìn)行轉(zhuǎn)為平面坐標(biāo)才好計(jì)算,然后通過三角函數(shù)tan#$%^&*( 計(jì)算后得到兩個(gè)點(diǎn)之間的角度值。此部分沒有太多個(gè)性化的邏輯操作,直接參照百度大大的就行了。

     ?

1 /** 2 *在每個(gè)點(diǎn)的真實(shí)步驟中設(shè)置小車轉(zhuǎn)動(dòng)的角度 3 *@param{BMap.Point} curPos 起點(diǎn) 4 *@param{BMap.Point} targetPos 終點(diǎn) 5 */ 6 this.setRotation = function (curPos, targetPos, em) 7 { 8 var me = this; 9 var deg = 0; 10 curPos = map.pointToPixel(curPos); 11 targetPos = map.pointToPixel(targetPos); 12 if (targetPos.x != curPos.x) { 13 var tan = (targetPos.y - curPos.y) / (targetPos.x - curPos.x), 14 atan = Math.atan(tan); 15 deg = atan * 360 / (2 * Math.PI); 16 if (targetPos.x < curPos.x) { 17 deg = -deg + 90 + 90; 18 } else { 19 deg = -deg; 20 } 21 em._newPointMark.setRotation(-deg); 22 23 } else { 24 var disy = targetPos.y - curPos.y; 25 var bias = 0; 26 if (disy > 0) 27 bias = -1 28 else 29 bias = 1 30 em._newPointMark.setRotation(-bias * 90); 31 } 32 return; 33 }

?

      參考計(jì)算方法就得了~~~

      值此兩個(gè)功能的最基礎(chǔ)的及計(jì)算方法等就這么多,其他的業(yè)務(wù)邏輯需要的邏輯代碼包裹著就是自己的需求實(shí)現(xiàn)代碼了!

      =======2017-10-31=========

      博中僅針對于路書中處理車頭方向及覆蓋物緩動(dòng)的實(shí)現(xiàn)方式進(jìn)行提取,期中涉及到部分個(gè)人業(yè)務(wù)相關(guān)的變量定義,各位在使用的時(shí)候注意甄別使用.

      如若還有疑問可加群討論:641241480

      效果圖

      

?

轉(zhuǎn)載于:https://www.cnblogs.com/peixuanzhihou/p/6540086.html

總結(jié)

以上是生活随笔為你收集整理的百度地图JavascriptApi Marker平滑移动及车头指向行径方向的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。