Baidu Map API Annotation + Time Axis Component

Keywords: Javascript JSON

When asked to do work, combined with Baidu Map api to make a dynamic display of label changes components, require the map to show a day's label, timeline requirements can dynamically play every day's label changes... Then I began coding....

If there are any bad points, please also point out that I am also a member of Xiaobai. Next, I will start the text.

Dead work:

  1. Apply for Baidu's api key (I haven't written more about the specific method, everyone should be able to)

  2. Learn about Baidu Map API development guidelines and class reference documents (if you are not bothered, you can see Demo examples directly)

First, load the map first, you can use the actual latitude and longitude positioning, browser positioning, ip positioning, according to the city name positioning, you can choose this.

// Create Map instances to set the minimum/maximum level allowed by the map
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // Initialize the map and set the map center with the city name
//map.enableScrollWheelZoom(true); // Enable roll-in and roll-out

centerAndZoom(center:Point, zoom:Number)  

Parametric interpretation:

  1. Point(lng:Number, lat:Number) creates a geographic point coordinate at a specified longitude and latitude.

  2. Zoom: number) Map zoom level

2. Use of labels (covering)

Combining the new icon of Demo setpoint with Baidu Map api example and the example of adding multiple points, we can rewrite it to add multiple map annotations.

//Write custom functions to create annotations
        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), //Central Point Settings
                infoWindowAnchor: new BMap.Size(16, 4) //Message box location 5
            });
            var marker = new BMap.Marker(point, {
                icon: myIcon
            });
            TimerLine.map.addOverlay(marker);
            //Jumping animation
            //                marker.setAnimation(BMAP_ANIMATION_BOUNCE);
            marker.setAnimation(BMAP_ANIMATION_DROP);
            var p = marker.getPosition();
            var content = "<table>";
            content = content + "<tr><td> Serial number:" + label.content + "</td></tr>";
            content = content + "<tr><td> Coordinates:" + p.lng + "," + p.lat + "</td></tr>";
            content = content + "<tr><td> Status:" + status + "</td></tr>";
            content += "</table>";
            var infowindow = new BMap.InfoWindow(content);
            //Adding Binding Events
            addEvent(marker, 'click', getAttr);
            function getAttr() {
                this.openInfoWindow(infowindow);
            }
    }

Baidu map Tags add read, followed by dynamic add tags, and changes with the date, such as showing the dynamic change of garbage bins, 8.3 cleaned up the color green, 8.6 did not clean up red.

Thoughts:

  1. Dynamics: Asynchronous data acquisition using ajax

  2. Change: Use a timer (setInterval or setTimeout)
    setInterval Loop Call

setTimeout Delayed Call Once

  1. Handwritten Plug-in

function addEvent(dom, type, fn) {
    //For browsers that support the DOM2 level event handler addeventListener method
    if (dom.addEventListener) {
        dom.addEventListener(type, fn, false);
    } else if (dom.attachEvent) {
        //Browsers that do not support the addEventListener method but support the attchEvent method    
        dom.attachEvent('on' + type, fn);
    } else {
        //For browsers that do not support the above two, but support on +'event name'
        dom['on' + type] = fn;
    }
}
var TimerLine = {
    data: {
        containerDiv: 'timerline', //Container box id
        datesDiv:'dates',//Date box id
        btnsDiv:'timerlineBtns',
        btns: {
            play: "timerbtn-play",
            stop: "timerbtn-stop",
            pre:"timerbtn-pre",
            next:"timerbtn-next"
        },
        processDiv:'processbar',    //Progress bar div
    },
    protect:{
        lock_play:false,
        lock_stop:false,
        index_label:1,
        index_process:0
    },
    rubbish_datas: [], //Used to store data acquired by ajax
    index: 0, //Change index
    Interval_label: null,
    Interval_process:null,
    map: new BMap.Map("allmap", {
        minZoom: 14,
        maxZoom: 20
    }),
    Utils: {
        //Write custom functions to create annotations
        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), //Central Point Settings
                infoWindowAnchor: new BMap.Size(16, 4) //Message box location 5
            });
            var marker = new BMap.Marker(point, {
                icon: myIcon
            });
            TimerLine.map.addOverlay(marker);
            //Jumping animation
            //                marker.setAnimation(BMAP_ANIMATION_BOUNCE);
            marker.setAnimation(BMAP_ANIMATION_DROP);
            var p = marker.getPosition();
            var content = "<table>";
            content = content + "<tr><td> Serial number:" + label.content + "</td></tr>";
            content = content + "<tr><td> Coordinates:" + p.lng + "," + p.lat + "</td></tr>";
            content = content + "<tr><td> Status:" + status + "</td></tr>";
            content += "</table>";
            var infowindow = new BMap.InfoWindow(content);
            //Adding Binding Events
            addEvent(marker, 'click', getAttr);
            function getAttr() {
                this.openInfoWindow(infowindow);
            }
        },
        /**
         * Map Labeling Method
         * Parameters: datas: Annotation array {date:", info:{}}
         *             index:Ordinal number (date)
         * */
        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()); //latitude
                var p_y = parseFloat(p[1].toString()); //longitude
                //Create label tags
                var label = new BMap.Label(info[info_count].title, {
                    offset: new BMap.Size(20, -10)
                });
                //Create annotations
                var point = new BMap.Point(p_x, p_y);
                //Status (garbage bin status)
                var status = info[info_count].status;            
                //Method of adding annotation
                TimerLine.Utils.addMarker(point, label, status);
                info_count++;
                if(info_count>=info.length){
                    clearInterval(addMarker_Interval);
                }
            },0);

        },
        //Add Date Click Event Binding 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;
                        //Play unlock
                        if(TimerLine.protect.lock_play)    TimerLine.protect.lock_play=false;
                        TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, i,false);
                        TimerLine.Utils.Setprocess(i,false);
                        return ;
                    }
                }
            })
        },
        //Scroll progress bar
        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 initialization
    init: function() {
        this.createMap();
        this.ajaxCreate();
        //Event binding
        this.bindEvent();
    },
    createMap: function() {
        // Create Map instances to set the minimum/maximum level allowed by the map
        var map = this.map;
        map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // Initialize the map and set the map center with the city name
        //map.enableScrollWheelZoom(true); // Enable roll-in and roll-out
    },
    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); //Container id
                That.rubbish_datas = data.result.datas; //
                //console.log(That.rubbish_datas);
                That.create(containerDiv, That.rubbish_datas);
                //Date-time binding
                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>'
        //Create the first day annotation
        this.Utils.mapSetLabel(datas, 0,false);
        
//        console.log(TimerLine.index);
        That.datas = datas;
        containerDiv.innerHTML = datasDiv;
    },
    //Play Suspended Delegation Event - Time Binding
    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;
            //Broadcast events
            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");
                    //Play chains
                    TimerLine.protect.lock_play=true;
                    //Pause unlock
                    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);
                    //Play unlock
                    TimerLine.protect.lock_play=false;
                    //Pause lock
                    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();

The above is my own handwritten component code, and I still know about design patterns in general. I wanted to write in prototype mode, but when setInterval, the method could not call the prototype method, so I changed to the singleton mode.

Introduction to TimeLine Components

  1. data: data container binding

  2. Protect protect protects attributes (for playback, pause, timeline index, annotated index)

  3. Rubbish_data stores data read by ajax

  4. Interval_label Baidu Map Marking Timer

  5. Interval_process timer

  6. Utils Tool Class

  7. init() TimeLine initialization

  8. createMap() Create Baidu Map

  9. ajaxCreate() gets data, creates containers (create()), and bindEvent())

Problems encountered:

  1. When two timers are running, the common index is easy to read. One timer modifies the index and the other timer has not been modified. This causes the creation of annotations to be inconsistent with the current time.

Note: Modify common variables as much as possible in one method. Common variables should not be shared in many ways, and unnecessary BUG s are easy to appear when increasing or decreasing.

  1. The timer should be cleared when it runs to the last day.

The program is shown as follows:

Enclosed Preview address
More content can be subscribed to my Wechat Public Number, together to open the front-end small white advanced world!

I'm sorry you didn't give Demo address. Ha ha
You can pay attention to the Wechat Public Number to reply to Baidu Map Timeline Component, and you can receive Demo's address.

Posted by tudoroprea on Mon, 15 Apr 2019 12:03:32 -0700