1. 程式人生 > >百度地圖結合ECharts實現複雜覆蓋物(Overlay)

百度地圖結合ECharts實現複雜覆蓋物(Overlay)

先來看效果圖

一 前置知識

  1. 官方Overlay-覆蓋物的抽象基類
方法 返回值 描述
initialize(map: Map) HTMLElement 抽象方法,用於初始化覆蓋物,當呼叫map.addOverlay時,API將呼叫此方法。自定義覆蓋物時需要實現此方法。自定義覆蓋物時需要將覆蓋物對應的HTML元素返回
isVisible() Boolean 判斷覆蓋物是否可見
draw() none 抽象方法,當地圖狀態發生變化時,由系統呼叫對覆蓋物進行繪製。自定義覆蓋物需要實現此方法
show() none 顯示覆蓋物。對於自定義覆蓋物,此方法會自動將initialize方法返回的HTML元素樣式的display屬性設定為空
hide() none 隱藏覆蓋物。對於自定義覆蓋物,此方法會自動將initialize方法返回的HTML元素樣式的display屬性設定為none
  1. 重點方法講解

    • initialize(map: Map)

      初始化覆蓋物,當呼叫map.addOverlay(--),會自動呼叫,自定義Overlay在此處可以定義呈現在地圖上的HTML元素

    • draw()

      當地圖發生變化,會自動呼叫此方法,進行覆蓋物的重繪工作

    • map.pointToOverlayPixel(point);

      將經緯度座標轉換成螢幕的畫素座標,此畫素座標就是ECharts圖形渲染在地圖中的位置

  2. 自定義實現,需要實現對 initialize 和draw 方法進行實現,達到自定義Overlay的目的

  3. MapPanes

    此類表示地圖上所有覆蓋物的容器集合,沒有建構函式,通過物件字面量形式表示。通過Map的getPanes方法可獲得該物件例項。通過 map.getPanes().labelPane.appendChild(div); 將自定義的div新增到覆蓋物列表

二 實現

  1. 新建complexCustomOverlay.js檔案,廢話少說,直接程式碼
!function(baiduMap) {
        /**
         * 自定義覆蓋物類, 取名 ComplexCustomOverlay 使用時直接 new ComplexCustomOverlay 即可
         * 示例 new ComplexCustomOverlay(121.620483, 31.291102, function(div_obj){});
         * @param {*} lng 經度
         * @param {*} lat 維度
         * @param {*} callback 回撥方法
         */
        ComplexCustomOverlay = function(lng, lat, callback) {
            this._point = new baiduMap.Point(lng, lat);
            this._callback = callback;
        };
        //繼承Overlay基類
        ComplexCustomOverlay.prototype = new baiduMap.Overlay();
        /**
          * 實現initialize方法,此方法在map.addOverlay(--)時會自動呼叫,完成初始化工作
         */
        ComplexCustomOverlay.prototype.initialize = function(map) {
            this._map = map;
            //生成div,用來承載ECharts
            var div = this._div = document.createElement("div");
            // 可以根據情況新增些樣式資訊
            // div.style.backgroundColor = "#fff";
            div.style.zIndex = baiduMap.Overlay.getZIndex(this._point.lat);
            div.style.width = "100px";
            div.style.height = "100px";
            //必須是絕對定位,不然會偏離原來位置
            div.style.position='absolute';
            //將該覆蓋物新增到標籤覆蓋物列表
            map.getPanes().labelPane.appendChild(div);
            //呼叫傳入的回撥方法
            this._callback(div);
            return div;
        };
        /**
          * 當地圖發生變化,會自動呼叫此方法,進行覆蓋物的重繪工作
          * 例如 拖動地圖、地圖放大縮小等操作,都會自動呼叫draw方法進行重繪
         */
        ComplexCustomOverlay.prototype.draw = function(){
            //餅圖的位置設定,需要獲取該地圖點的畫素位置x,y
            var pixel = this._map.pointToOverlayPixel(this._point);
            this._div.style.left = pixel.x + "px";
            this._div.style.top  = (pixel.y - 30) + "px";
        }
}(BMap); // 將BMap作為引數傳入
  1. 呼叫
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>百度地圖結合ECharts實現複雜覆蓋物(Overlay)</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
        }
        #map {
            height: 100%;
            width: 100%; 
        }
    </style>
    <script type="text/javascript" src="./js/echarts.min.js"></script>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=5ieMMexWmzB9jivTq6oCRX9j&callback"></script>
    <script type="text/javascript" src="./js/complexCustomOverlay.js"></script>
</head>
<body>
    <div id="map"></div>
</body>
</html>

<script type="text/javascript">
        var map = new BMap.Map("map");    // 建立Map例項
        map.centerAndZoom(new BMap.Point(121.620523, 31.290215), 18);  
        map.setCurrentCity("上海");
        map.enableScrollWheelZoom(true);
        // 地圖載入完成事件
        // map.addEventListener("tilesloaded",function(){alert("地圖載入完畢");});
        map.addEventListener('zoomend', function(e){
            var zoom = e.target.getZoom();
            if(zoom < 17) { // 小於17級,統計圖
                myCompOverlay.hide();
            } else {
                myCompOverlay.show();
            }
        });

        var drawPie = function(obj) {
            //map.removeOverlay(overlay: Overlay)
            //map.clearOverlays()
            var echarts2 = echarts.init(obj);
            var option = {
                tooltip : {
                    trigger: 'item',
                    formatter: "{b}:{c}"
                },
                series : [
                    {
                        name: '人流統計圖',
                        type: 'pie',
                        radius : ['0', '35%'],
                        data:[
                            {value:679, name:'人流數量'}
                        ],
                        color:['green'],// 餅圖的顏色
                        label: {
                            normal: {
                                show: true,
                                position: 'inside',
                                padding: [0, 0, 20, 0],
                                formatter: '{c}'
                            },
                        },

                        labelLine: {
                            show: false
                        }
                    },
                    {
                        name: '垃圾桶數量統計',
                        type: 'pie',
                        radius : ['40%', '100%'],
                        data:[
                            {value:335, name:'幹垃圾桶'},
                            {value:110, name:'溼垃圾桶'},
                            {value:210, name:'可回收垃圾桶'},
                            {value:410, name:'有害垃圾桶'}
                        ],
                        itemStyle: {
                            emphasis: {
                                shadowBlur: 10,
                                shadowOffsetX: 0,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        },
                        label: {
                            normal: {
                                show: true,
                                position: 'inside',
                                formatter: '{c}'
                            }
                        },
                        labelLine: {
                            show: false
                        }
                    }
                ]
            };
            echarts2.setOption(option);
        };
        // 例項化自定義Overlay,傳入經緯度以及回撥方法
        var myCompOverlay = new ComplexCustomOverlay(121.620483, 31.291102, drawPie);
        map.addOverlay(myCompOverlay);
    
</script>