百度地圖API標注+時間軸組件

工作時被要求到的,結合百度地圖api做一個動態(tài)展示標注變化的組件,要求地圖展示某一天的標注,時間軸要求可以動態(tài)播放每一天的標注變化...然后我就開始coding...

準備工作:

  1. 申請百度api密鑰(具體方法我也不多寫了,大家應該都會)
  2. 了解一下百度地圖API的開發(fā)指南和類參考文檔(如果嫌麻煩的話 可以直接看Demo示例)

一、首先,先加載地圖,你可以用實際的經緯度定位晕翠、瀏覽器定位弟劲、根據ip定位逾一、根據城市名定位,這個你可以自己選擇

// 創(chuàng)建Map實例,設置地圖允許的最小/大級別
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地圖,用城市名設置地圖中心點
//map.enableScrollWheelZoom(true); //啟用滾輪放大縮小

centerAndZoom(center:Point, zoom:Number)

參數解釋:

  1. Point(lng:Number, lat:Number)  以指定的經度和緯度創(chuàng)建一個地理點坐標享幽。
  2. zoom:number         地圖縮放級別

二睹限、標注的使用(覆蓋物)

結合百度地圖api示例Demo 設置點的新圖標和添加多個點示例 結合一下譬猫,就可以改寫成添加多個地圖標注

//編寫自定義函數,創(chuàng)建標注
        addMarker: function(point, label, status) {
            //        var marker = new BMap.Marker(point);
            var myIcon = new BMap.Icon("images/rubbish_" + status + ".png", new BMap.Size(32, 32), {
                anchor: new BMap.Size(16, 32), //中心點設置
                infoWindowAnchor: new BMap.Size(16, 4) //消息框位置5
            });
            var marker = new BMap.Marker(point, {
                icon: myIcon
            });
            TimerLine.map.addOverlay(marker);
            //跳動的動畫
            //                marker.setAnimation(BMAP_ANIMATION_BOUNCE);
            marker.setAnimation(BMAP_ANIMATION_DROP);
            var p = marker.getPosition();
            var content = "<table>";
            content = content + "<tr><td> 編號:" + label.content + "</td></tr>";
            content = content + "<tr><td> 坐標:" + p.lng + "," + p.lat + "</td></tr>";
            content = content + "<tr><td> 狀態(tài):" + status + "</td></tr>";
            content += "</table>";
            var infowindow = new BMap.InfoWindow(content);
            //添加綁定事件
            addEvent(marker, 'click', getAttr);
            function getAttr() {
                this.openInfoWindow(infowindow);
            }
    }

百度地圖標注添加看懂了,接下來就是動態(tài)添加標注,并且隨和日期的變化而變化,比如展示垃圾箱的動態(tài)變化,8.3號清理了顏色為綠色,8.6號沒清理為紅色..

思想:

  1. 動態(tài):就要使用ajax異步獲取數據
  2. 變化:就要使用定時器(setInterval或者 setTimeout)
    setInterval 循環(huán)調用
    setTimeout 延遲調用 1次     具體區(qū)別可以自行百度
  3. 動手寫插件
function addEvent(dom, type, fn) {
    //對于支持DOM2級事件處理程序addeventListener方法的瀏覽器
    if (dom.addEventListener) {
        dom.addEventListener(type, fn, false);
    } else if (dom.attachEvent) {
        //對于不支持addEventListener方法但支持attchEvent方法的瀏覽器    
        dom.attachEvent('on' + type, fn);
    } else {
        //對于不支持以上兩種,但支持on+'事件名'的瀏覽器
        dom['on' + type] = fn;
    }
}
var TimerLine = {
    data: {
        containerDiv: 'timerline', //容器盒子id
        datesDiv:'dates',//日期盒子id
        btnsDiv:'timerlineBtns',
        btns: {
            play: "timerbtn-play",
            stop: "timerbtn-stop",
            pre:"timerbtn-pre",
            next:"timerbtn-next"
        },
        processDiv:'processbar',    //進度條div
    },
    protect:{
        lock_play:false,
        lock_stop:false,
        index_label:1,
        index_process:0
    },
    rubbish_datas: [], //用來存儲ajax獲取到的數據
    index: 0, //變化的index
    Interval_label: null,
    Interval_process:null,
    map: new BMap.Map("allmap", {
        minZoom: 14,
        maxZoom: 20
    }),
    Utils: {
        //編寫自定義函數,創(chuàng)建標注
        addMarker: function(point, label, status) {
            //        var marker = new BMap.Marker(point);
            var myIcon = new BMap.Icon("images/rubbish_" + status + ".png", new BMap.Size(32, 32), {
                anchor: new BMap.Size(16, 32), //中心點設置
                infoWindowAnchor: new BMap.Size(16, 4) //消息框位置5
            });
            var marker = new BMap.Marker(point, {
                icon: myIcon
            });
            TimerLine.map.addOverlay(marker);
            //跳動的動畫
            //                marker.setAnimation(BMAP_ANIMATION_BOUNCE);
            marker.setAnimation(BMAP_ANIMATION_DROP);
            var p = marker.getPosition();
            var content = "<table>";
            content = content + "<tr><td> 編號:" + label.content + "</td></tr>";
            content = content + "<tr><td> 坐標:" + p.lng + "," + p.lat + "</td></tr>";
            content = content + "<tr><td> 狀態(tài):" + status + "</td></tr>";
            content += "</table>";
            var infowindow = new BMap.InfoWindow(content);
            //添加綁定事件
            addEvent(marker, 'click', getAttr);
            function getAttr() {
                this.openInfoWindow(infowindow);
            }
        },
        /**
         * 地圖標注方法
         * 參數:        datas:標注物數組{date:"",info:{}}
         *             index:序數(日期)
         * */
        mapSetLabel: function(datas, n,isInterval) {
            TimerLine.map.clearOverlays();
            var index;
            console.log(TimerLine.protect.index_label);
            if(isInterval){
                TimerLine.protect.index_label++;
                if (TimerLine.protect.index_label >= TimerLine.rubbish_datas.length - 1) {
                    TimerLine.protect.index_label = TimerLine.rubbish_datas.length - 1;
                    clearInterval(TimerLine.Interval_label);
                    TimerLine.protect.lock_play=false;
                }
            }
            
            if (n == null) {
                if(TimerLine.protect.index_label==0){
                    TimerLine.protect.index_label=1
                }
                index = TimerLine.protect.index_label;
            } else {
                index = parseInt(n);
                TimerLine.protect.index_label = index;
            }
            
            var info = datas[index].info;
            var info_count=0;
            var addMarker_Interval=setInterval(function(){
                var p = info[info_count].point.split(',');
                var p_x = parseFloat(p[0].toString()); //緯度
                var p_y = parseFloat(p[1].toString()); //經度
                //創(chuàng)建label標簽
                var label = new BMap.Label(info[info_count].title, {
                    offset: new BMap.Size(20, -10)
                });
                //創(chuàng)建標注點
                var point = new BMap.Point(p_x, p_y);
                //狀態(tài)(垃圾箱狀態(tài))
                var status = info[info_count].status;            
                //添加標注的方法
                TimerLine.Utils.addMarker(point, label, status);
                info_count++;
                if(info_count>=info.length){
                    clearInterval(addMarker_Interval);
                }
            },0);

        },
        //添加日期點擊事件綁定 dates li click
        bindEvent: function() {
            var datesDiv = document.getElementById("dates");
            addEvent(datesDiv,'click',function(e){
                var event = e || window.e;
                var target = event.target || event.srcElement;
                for(var i=0;i<TimerLine.rubbish_datas.length;i++){
                    if(target.innerText==TimerLine.rubbish_datas[i].date){
//        
                        TimerLine.protect.index_process=i;
                        TimerLine.protect.index_label=i;
                        //播放解鎖
                        if(TimerLine.protect.lock_play)    TimerLine.protect.lock_play=false;
                        TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, i,false);
                        TimerLine.Utils.Setprocess(i,false);
                        return ;
                    }
                }
            })
        },
        //進度條滾動
        Setprocess:function(index,isInterval){
            if(isInterval){
                TimerLine.protect.index_process++;
                console.log(TimerLine.protect.index_process);
                console.log(TimerLine.rubbish_datas.length);
                if(TimerLine.protect.index_process >= TimerLine.rubbish_datas.length-1){
                    TimerLine.protect.index_process = TimerLine.rubbish_datas.length-1;
                    clearInterval(TimerLine.Interval_process);
                    TimerLine.protect.lock_play=false;
                }
            }
            var datesDiv = document.getElementById("dates");
            var processDiv = document.getElementById(TimerLine.data.processDiv);
            if(index==null){
                processDiv.style.width =parseInt(processDiv.style.width)+datesDiv.getElementsByTagName('li')[0].offsetWidth+'px';
            }else{
                processDiv.style.width =datesDiv.getElementsByTagName('li')[0].offsetWidth*parseInt(index+1)+'px';
            }
            
        }
        
    },
    //TimerLine初始化
    init: function() {
        this.createMap();
        this.ajaxCreate();
        //事件綁定
        this.bindEvent();
    },
    createMap: function() {
        // 創(chuàng)建Map實例,設置地圖允許的最小/大級別
        var map = this.map;
        map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地圖,用城市名設置地圖中心點
        //map.enableScrollWheelZoom(true); //啟用滾輪放大縮小
    },
    ajaxCreate: function() {
        var That = this;
        var containerDiv = That.data.containerDiv;
        $.ajax({
            type: "get",
            url: "js/json.json",
            dataType: 'json',
            success: function(data) {
                containerDiv = document.getElementById(containerDiv); //容器id
                That.rubbish_datas = data.result.datas; //
                //console.log(That.rubbish_datas);
                That.create(containerDiv, That.rubbish_datas);
                //日期時間綁定
                That.Utils.bindEvent();
            }
        });
    },
    create: function(containerDiv, datas) {
        var That = this;
        var datasDiv ='<div class="processcontainer"><div id="processbar" style="width:120px;"></div></div>';
//        var datasDiv = '<ul id="dates" class="timerlineul dates clearfix">';
        datasDiv += '<ul id="dates" class="timerlineul dates clearfix">';
        for (var i = 0; i < datas.length; i++) {
            datasDiv += '<li>' + datas[i].date + '</li>';
        }
        datasDiv += '</ul>';    
        document.getElementById(That.data.btnsDiv).innerHTML='<div class="timerline-btns clearfix"><div id="timerbtn-pre" class="iconfont icon-shangyishou"></div><div id="timerbtn-play" class="iconfont icon-zanting"></div><div id="timerbtn-next" class="iconfont icon-xiayishou"></div></div>'
        //創(chuàng)建第一天的標注
        this.Utils.mapSetLabel(datas, 0,false);
        
//        console.log(TimerLine.index);
        That.datas = datas;
        containerDiv.innerHTML = datasDiv;
    },
    //播放 暫停 委托事件----時間綁定
    bindEvent: function() {
        if (this.data.btns == null)
            return;
        var That = this;
        addEvent(document.getElementById(That.data.btnsDiv), 'click', function(e) {
            var event = e || window.e;
            var target = event.target || event.srcElement;
            //播放事件
            if (target.id == That.data.btns.play) {
                if(!TimerLine.protect.lock_play){
                    if(TimerLine.protect.index_label >= TimerLine.rubbish_datas.length-1){
                        TimerLine.protect.index_label=0;
                        var processDiv = document.getElementById(TimerLine.data.processDiv);
                        var datesDiv = document.getElementById("dates");
                        processDiv.style.width = datesDiv.getElementsByTagName('li')[0].offsetWidth+'px';
                    }
                    if(TimerLine.protect.index_process >= TimerLine.rubbish_datas.length-1){
                        TimerLine.protect.index_process=0;
                    }
//                
                    TimerLine.Interval_label = setInterval("TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas,null,true)", 1000);
                    TimerLine.Interval_process = setInterval("TimerLine.Utils.Setprocess(null,true)",1000);    
                    $("#timerbtn-play").attr("class","iconfont icon-zanting1");
                    //播放枷鎖
                    TimerLine.protect.lock_play=true;
                    //暫停解鎖
                    TimerLine.protect.lock_stop=false;
                }else if(TimerLine.protect.lock_play){
                    $("#timerbtn-play").attr("class","iconfont icon-zanting");
                    TimerLine.Interval_label&&clearInterval(TimerLine.Interval_label);
                    TimerLine.Interval_process&&clearInterval(TimerLine.Interval_process);
                    //播放解鎖
                    TimerLine.protect.lock_play=false;
                    //暫停加鎖
                    TimerLine.protect.lock_stop=true;
                }
            }
            
            if(target.id == That.data.btns.pre){
                if(TimerLine.protect.index_label==0) return;
                TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, TimerLine.protect.index_label-1,false);
                TimerLine.Utils.Setprocess(TimerLine.protect.index_process-1,false);
                TimerLine.protect.index_process=TimerLine.protect.index_process-1;
            }
            if(target.id == That.data.btns.next){
                if(TimerLine.protect.index_label==TimerLine.rubbish_datas.length-1) return;
                TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, TimerLine.protect.index_label+1,false);
                TimerLine.Utils.Setprocess(TimerLine.protect.index_process+1,false);
                TimerLine.protect.index_process=TimerLine.protect.index_process+1;
            }
        });
    }
}

TimerLine.init();

以上是我自己手寫的組件代碼,對設計模式了解還是一般.本來是想用原型模式寫,不過在setInterval時候,方法沒法調用原型方法,讓后我就改成了單例模式

TimeLine組件介紹

  1. data:數據容器綁定

  2. protect 保護屬性 (對播放、暫停羡疗、時間軸index染服、標注index)

  3. rubbish_datas 存儲ajax讀取的數據

  4. Interval_label 百度地圖標注定時器

  5. Interval_process 時間軸定時器

  6. Utils 工具類

  7. init() TimeLine初始化

  8. createMap() 創(chuàng)建百度地圖

  9. ajaxCreate() 獲取數據,創(chuàng)建容器(create()),時間綁定(bindEvent())

遇到的問題:

  1. 兩個定時器運行時,公共index 容易讀取錯誤,一個定時器修改了index 另一個定時器還沒修改,這樣造成了創(chuàng)建標注與當前時間不符合,

注:要將修改公共變量盡量寫在一個方法中。公共變量最好不要在多個方法中公用叨恨,容易在增減的時候出現不必要的BUG

  1. 定時器運行到最后一天的時候要將定時器清除柳刮。

程序如圖:
百度地圖API標注+時間軸組合的組件效果圖

附上預覽地址
更多內容可以訂閱本人微信公眾號,一起開啟前端小白進階的世界!

前端Demon

不給 Demo 地址 是不是對不起你們秉颗。哈哈??
可以關注微信公眾號 回復百度地圖時間軸組件 ,即可收到 Demo 的地址痢毒。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蚕甥,隨后出現的幾起案子哪替,更是在濱河造成了極大的恐慌,老刑警劉巖菇怀,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凭舶,死亡現場離奇詭異,居然都是意外死亡敏释,警方通過查閱死者的電腦和手機库快,發(fā)現死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钥顽,“玉大人义屏,你說我怎么就攤上這事》浯螅” “怎么了闽铐?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奶浦。 經常有香客問我兄墅,道長,這世上最難降的妖魔是什么澳叉? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任隙咸,我火速辦了婚禮,結果婚禮上成洗,老公的妹妹穿的比我還像新娘五督。我一直安慰自己,他們只是感情好瓶殃,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布充包。 她就那樣靜靜地躺著,像睡著了一般遥椿。 火紅的嫁衣襯著肌膚如雪基矮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天冠场,我揣著相機與錄音家浇,去河邊找鬼。 笑死碴裙,一個胖子當著我的面吹牛蓝谨,可吹牛的內容都是我干的灌具。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼譬巫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了督笆?” 一聲冷哼從身側響起芦昔,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娃肿,沒想到半個月后咕缎,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡料扰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年凭豪,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晒杈。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡嫂伞,死狀恐怖,靈堂內的尸體忽然破棺而出拯钻,到底是詐尸還是另有隱情帖努,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布粪般,位于F島的核電站拼余,受9級特大地震影響,放射性物質發(fā)生泄漏亩歹。R本人自食惡果不足惜匙监,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望小作。 院中可真熱鬧亭姥,春花似錦、人聲如沸躲惰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽础拨。三九已至氮块,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诡宗,已是汗流浹背滔蝉。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留塔沃,地道東北人蝠引。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親螃概。 傳聞我的和親對象是個殘疾皇子矫夯,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內容

  • 發(fā)現 關注 消息 iOS 第三方庫、插件吊洼、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,121評論 4 61
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理训貌,服務發(fā)現,斷路器冒窍,智...
    卡卡羅2017閱讀 134,704評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,302評論 25 707
  • 1 這一周递沪,爸爸媽媽都很辛苦。先是媽媽去了北京综液,主要辦兩件事款慨,其中一個是和我婆婆一起辦美國簽證的面簽,在京的幾天也...
    潤青jingjing閱讀 274評論 0 0
  • 2016年6月20號谬莹,我最后一天在自己的崗位上工作檩奠。沒有和你說感謝,沒有和你說再見届良,我離開了笆凌。不必沮喪,無需失落士葫,...
    不回頭的姑涼閱讀 275評論 0 0