资讯专栏INFORMATION COLUMN

百度地图API标注+时间轴组件

30e8336b8229 / 2094人阅读

摘要:公共变量最好不要在多个方法中公用,容易在增减的时候出现不必要的定时器运行到最后一天的时候要将定时器清除。程序如图附上预览地址更多内容可以订阅本人微信公众号,一起开启前端小白进阶的世界不给地址是不是对不起你们。

工作时被要求到的,结合百度地图api做一个动态展示标注变化的组件,要求地图展示某一天的标注,时间轴要求可以动态播放每一天的标注变化...然后我就开始coding...

如有不好的地方,还请大家指出,我也是小白中的一员,接下来开始正文

准备工作:

申请百度api密钥(具体方法我也不多写了,大家应该都会)    

了解一下百度地图API的开发指南和类参考文档(如果嫌麻烦的话 可以直接看Demo示例)

一、首先,先加载地图,你可以用实际的经纬度定位、浏览器定位、根据ip定位、根据城市名定位,这个你可以自己选择
// 创建Map实例,设置地图允许的最小/大级别
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地图,用城市名设置地图中心点
//map.enableScrollWheelZoom(true); //启用滚轮放大缩小

centerAndZoom(center:Point, zoom:Number)  

参数解释:

Point(lng:Number, lat:Number)  以指定的经度和纬度创建一个地理点坐标。

zoom:number         地图缩放级别

二、标注的使用(覆盖物)

结合百度地图api示例Demo 设置点的新图标和添加多个点示例 结合一下,就可以改写成添加多个地图标注

//编写自定义函数,创建标注
        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 = "";
            content = content + "";
            content = content + "";
            content = content + "";
            content += "
编号:" + label.content + "
坐标:" + p.lng + "," + p.lat + "
状态:" + status + "
"; var infowindow = new BMap.InfoWindow(content); //添加绑定事件 addEvent(marker, "click", getAttr); function getAttr() { this.openInfoWindow(infowindow); }     }

百度地图标注添加看懂了,接下来就是动态添加标注,并且随和日期的变化而变化,比如展示垃圾箱的动态变化,8.3号清理了颜色为绿色,8.6号没清理为红色..

思想:

动态:就要使用ajax异步获取数据

变化:就要使用定时器(setInterval或者 setTimeout)
setInterval 循环调用

setTimeout 延迟调用 1次     具体区别可以自行百度

动手写插件

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: {
        //编写自定义函数,创建标注
        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 = "";
            content = content + "";
            content = content + "";
            content = content + "";
            content += "
编号:" + label.content + "
坐标:" + p.lng + "," + p.lat + "
状态:" + status + "
"; 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()); //经度 //创建label标签 var label = new BMap.Label(info[info_count].title, { offset: new BMap.Size(20, -10) }); //创建标注点 var point = new BMap.Point(p_x, p_y); //状态(垃圾箱状态) 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-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() { // 创建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 ="
"; // var datasDiv = "
    "; datasDiv += "
      "; for (var i = 0; i < datas.length; i++) { datasDiv += "
    • " + datas[i].date + "
    • "; } datasDiv += "
    "; document.getElementById(That.data.btnsDiv).innerHTML="
    " //创建第一天的标注 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组件介绍

data:数据容器绑定

protect 保护属性 (对播放、暂停、时间轴index、标注index)

rubbish_datas 存储ajax读取的数据

Interval_label 百度地图标注定时器

Interval_process 时间轴定时器

Utils 工具类

init() TimeLine初始化

createMap() 创建百度地图

ajaxCreate() 获取数据,创建容器(create()),时间绑定(bindEvent())

遇到的问题:

两个定时器运行时,公共index 容易读取错误,一个定时器修改了index 另一个定时器还没修改,这样造成了创建标注与当前时间不符合,

注:要将修改公共变量尽量写在一个方法中。公共变量最好不要在多个方法中公用,容易在增减的时候出现不必要的BUG

定时器运行到最后一天的时候要将定时器清除。

程序如图:

附上预览地址
更多内容可以订阅本人微信公众号,一起开启前端小白进阶的世界!

不给 Demo 地址 是不是对不起你们。哈哈?
可以关注微信公众号 回复百度地图时间轴组件 ,即可收到 Demo 的地址。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86903.html

相关文章

  • vue.js下引入百度地图jsApi的两种方法

    摘要:下引入百度地图的两种方法前言今天有个项目需要用到百度地图,一般我们在移动端使用百度地图,都是直接通过这样的方式,直接引入百度地图的。通过模块化引入的方法实际上百度地图官方去年已经开源了基于的和的对应开源组件,我们可以直接通过安装,然后使用。 vue.js下引入百度地图jsApi的两种方法 前言 今天有个项目需要用到百度地图,一般我们在移动端使用百度地图,都是直接通过这样的方式,直接引入...

    muddyway 评论0 收藏0
  • AngularJS中使用百度地图

    摘要:尤其,对于组件化起了非常大的作用。今天就简单介绍一下我的一个懒人组件百度地图。后面详细介绍该对象参数字符串,是你在百度开放平台申请的,没有这个,你的地图显示不出来的表达式,用来控制离线后的友好支持,后面详细介绍各参数。 前言 AngularJS作为一个成功的框架,营造出了完备的生态系统。尤其Directive,对于组件化起了非常大的作用。很多时候,如我这般懒人,网上搜一搜,就找到一个合...

    沈建明 评论0 收藏0

发表评论

0条评论

30e8336b8229

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<