百度地图结合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";
            // marginLeft marginTop 的设置可以让这个div的中心点和给定的经纬度重合
            div.style.marginLeft = '-50px';
            div.style.marginTop = '-50px';
            //必须是绝对定位,不然会偏离原来位置
            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>

转载于:https://www.cnblogs.com/itgiser/p/11463352.html

在Vue中实现复杂自定义覆盖物可以使用百度地图API中提供的Overlay类和自定义覆盖物。自定义覆盖物是指在地图上添加自己的DOM元素,可以通过DOM元素来实现自己的样式和交互效果。 下面是在Vue中实现复杂自定义覆盖物的步骤: 1. 安装vue-baidu-map 在终端中运行以下命令来安装vue-baidu-map: ``` npm install vue-baidu-map --save ``` 2. 注册vue-baidu-map组件 在Vue组件中注册vue-baidu-map组件: ``` import BaiduMap from 'vue-baidu-map' export default { components: { BaiduMap } } ``` 3. 在模板中添加地图 在模板中添加vue-baidu-map标签,并设置地图的中心点和缩放级别: ``` <template> <div> <BaiduMap :center="center" :zoom="zoom"></BaiduMap> </div> </template> <script> export default { data() { return { center: {lng: 116.404, lat: 39.915}, zoom: 15 } } } </script> ``` 4. 创建自定义覆盖物 在Vue组件的mounted()生命周期函数中,创建自定义覆盖物: ``` mounted() { const map = this.$refs.baiduMap.getBMap() const BMap = window.BMap const CustomOverlay = function(point, options) { this._point = point this._options = options } CustomOverlay.prototype = new BMap.Overlay() CustomOverlay.prototype.initialize = function(map) { this._map = map const div = document.createElement('div') div.style.position = 'absolute' div.style.width = '100px' div.style.height = '100px' div.style.background = '#fff' div.style.borderRadius = '50%' div.style.boxShadow = '0 0 15px rgba(0, 0, 0, 0.3)' div.style.cursor = 'pointer' div.innerHTML = '<span>自定义覆盖物</span>' div.addEventListener('click', () => { console.log('自定义覆盖物被点击了') }) map.getPanes().labelPane.appendChild(div) this._div = div return div } CustomOverlay.prototype.draw = function() { const pixel = this._map.pointToOverlayPixel(this._point) this._div.style.left = pixel.x - 50 + 'px' this._div.style.top = pixel.y - 50 + 'px' } const point = new BMap.Point(116.404, 39.915) const myOverlay = new CustomOverlay(point) map.addOverlay(myOverlay) } ``` 在上面的代码中,我们创建了一个CustomOverlay类,它继承了BMap.Overlay类,用于创建自定义覆盖物。在CustomOverlay类的initialize方法中,我们创建了一个DIV元素,并设置了DIV元素的样式和内容。我们将DIV元素添加到地图的labelPane层中,这样它就可以显示在其他标注之上了。在CustomOverlay类的draw方法中,我们将DIV元素的位置设置为自定义覆盖物的位置。 5. 添加CSS样式 最后,我们需要添加CSS样式来定义自定义覆盖物的样式: ``` <style> .custom-overlay { position: absolute; width: 100px; height: 100px; background: #fff; border-radius: 50%; box-shadow: 0 0 15px rgba(0, 0, 0, 0.3); cursor: pointer; } </style> ``` 在上面的代码中,我们定义了".custom-overlay"类来设置自定义覆盖物的样式。 这样就可以在Vue中实现复杂自定义覆盖物了。可以根据需要修改CustomOverlay类的实现,来实现复杂的自定义覆盖物
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值