使用百度地圖API制作線路軌跡播放


1.使用百度地圖API制作軌跡播放;

可應用於車輛跟蹤、行駛線路回放、跑步行程的記錄等地圖應用場景,

1.1繪制靜態軌跡圖

獲取多個軌跡點point(必須包含經度、緯度)

使用polyline對象依次連接相鄰的2個點(注意polyline的個數比point的少1)

1.2繪制動態軌跡圖(固定間隔時間)

每隔500毫秒讀取一個軌跡點,實現a,b兩個功能

a增加一條polyline

b將marker從先前的point移到當前點

主方法使用setTimeout方法迭代來實現動態循環

Polyline在每條迭代循環體中添加即可,marker的移動則可以通過2中方法來實現:

一、使用removeOverlay除去原marker並在當前point處添加新marker

這是當時做項目時想到的方法,由於先前繪制polyline時使用addOverlay的思維慣性,在繪制marker時也就繼續使用了addOverlay做循環迭代。

window.run = function (){

                     var pts ={?????}//你獲取到的一系列點的數組(通過gps或其他接口)

                     var paths = pts.length;    //獲得有幾個點

                     var carMk = new BMap.Marker(pts[0],{icon:myIcon});

                     map.addOverlay(carMk);

                     i=0;

                     function removeMkPoint(i){

                            if(i < paths){//

                                   setTimeout(function(){

                                          i++;

map.removeOverlay(carMk);//清除前一個marker

                                          removeMkPoint(i);

                                   },100);

                            }

                     }

                     setTimeout(function(){

                            resetMkPoint(5);

                     },100)

 

              });

       }

 

       setTimeout(function(){

              run();

       },1500);

二、使用marker的setPosition方法重新設置marker的位置

在項目完成后,我又讀了一篇百度api的文檔,發現官方demo中使用setPosition方法能很好地實現marker的移動功能

window.run = function (){

                     var pts ={?????}//你獲取到的一系列點的數組(通過gps或其他接口)

                     var paths = pts.length;    //獲得有幾個點

                     var carMk = new BMap.Marker(pts[0],{icon:myIcon});

                     map.addOverlay(carMk);

                     i=0;

                     function resetMkPoint(i){

                            carMk.setPosition(pts[i]);//重新設置marker的position

                            if(i < paths){

                                   setTimeout(function(){

                                          i++;

                                          resetMkPoint(i);

                                   },100);

                            }

                     }

                     setTimeout(function(){

                            resetMkPoint(5);

                     },100)

 

              });

       }

 

       setTimeout(function(){

              run();

       },1500);

注意:marker的opts屬性能自定義marker的icon(汽車、人等圖標)、旋轉方向、大小、偏移等等屬性,另外setAnimation方法還能設置動畫效果。

1.3繪制polyline

軌跡線路是由一個一個polyline首尾相連組合起來的,因此,只需要在每次添加marker時添加一個polyline即可,並且在下一輪迭代循環中不需要清除,每條polyline的首尾2個端點就是當前點和上一個時間段的點

      var pts0,前一個點 var pts1當前點

                        var carPl=new BMap.Polyline([pts0,pts1],{strokeColor:'blue',strokeWeight:4,strokeOpacity:0.8});

                        map.addOverlay(carPl);

pts0=pts1;//每次添加polyline后當前點變為前一個點

 

 

1.4添加播放按鈕控件控制軌跡播放

添加自定義的播放控件,這里需要使用prototype屬性來返回對象類型原型的引用,        這里給出prototype的理解

例如:A.prototype = new B();

理解prototype不應把它和繼承混淆。A的prototype為B的一個實例,可以理解A將B中的方法和屬性全部克隆了一遍。這里強調的是克隆而不是繼承,其區別在於:A的prototype是B的實例,同時B的prototype也可能是A的實例。

A能使用B的方法和屬性,當A、B中都有方法名為f的方法時,A的實例instance調用這個f方法(instance.f)會是A自生的f方法而不是B的f方法,如果A的實例instance想調用B的f方法,需要使用call方法來實現:先new一個B的實例var Binstance=new B(); Binstance.f.call(instance);

 

            function PlayControl(){

                // 默認停靠位置和偏移量

                this.defaultAnchor = BMAP_ANCHOR_BOTTOM_RIGHT;

                this.defaultOffset = new BMap.Size(10, 40);

            }

            // 通過JavaScript的prototype屬性繼承於BMap.Control

            PlayControl.prototype = new BMap.Control();

            // 自定義控件必須實現自己的initialize方法,並且將控件的DOM元素返回

            // 在本方法中創建個input元素作為控件的容器,並將其添加到地圖容器中

            PlayControl.prototype.initialize = function(map){

                // 創建一個DOM元素

                var input = document.createElement("input");

                input.id="playCtrl";

                input.type="image";

                input.src="image/play.png";

                input.onclick=startPlay();//startPlay為上一步開始執行setTimeout迭代

                };

                // 添加DOM元素到地圖中

                map.getContainer().appendChild(input);

                // 將DOM元素返回

                return input;

            };

            // 創建控件

            var myPlayCtrl = new PlayControl();

            // 添加到地圖當中

            map.addControl(myPlayCtrl);

 

 

1.5將播放按鈕設計為可以單擊切換播放和停止的按鈕

   定義一個變量var i=0,在onclick事件觸發時,將i在0和1之間不停切換,根據i的值來判斷執行開始播放方法和停止方法。

   停止播放方法可以通過clearTimeout(timer)來實現(前提是在前面的開始播放方法中將setTimeout語句作為字符串賦值為timer),並使用removeOverlay來清除播放過程中出現的痕跡。

input.onclick=function(){

                    if(i==0){

                        startPlay();//播放開始

                        input.src="image/pause.png";

                        i=1;

                    }else{

                        pausePlay();//播放停止

                        input.src="image/play.png";

                        i=0;

                    }

 

                };

1.6添加播放速度控件

   上一步添加了播放開關,還可以在此基礎上添加播放速度的控件來調節播放的快慢

   其方法與1.4中添加播放開關的方法類似,其中input的type為range(html 5中新的類型),通過讀取range 的value,將value作為setTimeout的時間參數(作為參數傳入播放方法),

 

注意:當滑動range,value發生改變時,要使播放停止,再次點擊播放按鈕時,播放方法讀取新的value;

                input.id="speedCtrl";

                input.type="range";

                input.max="1750";

                input.min="250";

                input.step="250";

                input.value="1000";

                var i=0;

                input.onchange=function(){

                    pausePlay();

                }

總結:

作為一個從學校里剛走出來的非計算機專業的前端新手,實習中的第一次上手項目,就有獨立使用百度地圖API的機會實在幸運。從百度地圖API的具體使用實踐中,我學到了很多,除了百度地圖API以外,還學到了包括prototype、bootstrap(模態框、datetimepicker、validation等插件)等等。

盡管有些不太完善的地方(例如:在infoWindow的content中不能使用bootstrap的模態框等),但百度地圖API的功能仍然十分強大,值得廣大新手學習。特別是隨着移動互聯網的快速發展以及各種帶有gps定位功能的智能設備的爆發式普及,地圖、定位類使用場景越來越多,地圖API的使用需求也將越來越多。

為了更好地練習百度地圖,我打算利用節假日空閑的時間使用百度地圖制作一個小游戲練手,游戲大致構思如下:(未來會在博客中向大家展示!)

1.使用自定義marker作為游戲主角

2.使用自定義控件來操作主角

3.設置關卡或任務,

4.計算獎勵或得分

5.設置障礙

    先實現這幾個初級功能需求,就可以使自己的游戲主角在自己的城市中行走了!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM