vue 腾讯地图点聚合 点标注添加信息窗口

<template>
  <div id="container"></div>  
</template>
<script>
import { listBuilding } from "@/api/zsj/building";
// 全局map
var map;
export default {
  name: "Buildingmap",
  data() {
    return {
      buildingList: [],
      modelMsg: false, //显示模态框
      address: "", //输入的地址
      mapList: [], //画图地址
      mapVal: "", //创建的地图,赋值用
      colors: [
        "#72A1A2",
        "#56564C",
        "#3593C9",
        "#075279",
        "#F37B84",
        "#E27B2D",
        "#9B4401",
        "#B481B3",
        "#C59C42",
      ],
      url: "https://apis.map.qq.com/ws/district/v1/getchildren",
      queryParams: {
        id: "420600",
        get_polygon: 2,
        key: "BGZBZ-3SYCK-NKGJT-ADFX6-LLFSJ-Z5FT6",
        output: "jsonp",
      },
    };
  },
  //   420600
  //   watch: {
  //     //监听模态框是否显示,显示就执行初始化地图方法
  //     modelMsg(newVal, oldVal) {
  //       console.log(newVal);
  //       if (newVal == true) {
  //         this.initMap(32.018555,112.155652);
  //       }
  //     },
  //   },
  // beforeCreate() {
  //   this.getData();
  // },

  created() {
    listBuilding().then((response) => {
      // this.buildingList = response.rows;
      this.addMultiMarker(response.rows);
      // console.log(response.rows)
    });
    this.initMap(32.018555, 112.155652);
  },
  methods: {
    //框框选中一条触发函数,并再执行初始化地图的方法
    // handleSelect(item) {
    //   this.initMap(item.location.lat, item.location.lng);
    // },
    //监听输入框输入状态,这个方法是实时搜索,并显示地点关键词
    //queryString是传入的关键词,cb是回调函数,就是把获取到的列表赋值到下拉框里
    //这个是element的el-autocomplete官方文档是这么传的,我也不知道为啥.
    // watchInput(queryString, cb) {
    //   this.mapList = [];
    //   console.log(queryString);
    //   const KEY = "BGZBZ-3SYCK-NKGJT-ADFX6-LLFSJ-Z5FT6";
    //   let url = "https://apis.map.qq.com/ws/place/v1/suggestion";
    //   let keyword = queryString; //传入的关键词
    //   this.$jsonp(url, {
    //     key: KEY,
    //     region: "全国",
    //     keyword: keyword,
    //     output: "jsonp",
    //   })
    //     .then((res) => {
    //       let opt = [];
    //       res.data.forEach((res) => {
    //         let opt1 = {
    //           value: res.title + "-" + res.address,
    //           location: res.location,
    //         };
    //         opt.push(opt1);
    //       });
    //       this.mapList = opt;
    //       console.log(this.mapList);
    //       // 调用 callback 返回建议列表的数据
    //       cb(this.mapList);
    //     })
    //     .catch((err) => {
    //       console.log(err);
    //     });
    // },
    //初始化地图
    initMap(lat, lng) {
      let that = this;
      //如果地图存在,就销毁,下面会重新创建一个
      if (that.mapVal) {
        that.mapVal.destroy();
      }
      //定义地图中心点坐标
      this.$nextTick(() => {
        var center = new TMap.LatLng(lat, lng);
        //初始化地图
        map = new TMap.Map("container", {
          center: center, //设置地图中心点坐标
          zoom: 9, //设置地图缩放级别
          pitch: 43.5, //设置俯仰角
          rotation: 45, //设置地图旋转角度
          viewMode: "2D",
        });

        var ps = []; // 边界范围
        var colors = that.colors; //颜色
        that
          .$jsonp(that.url, that.queryParams)
          .then((res) => {
            var resData = res.result[0];
            for (var a = 0; a < resData.length; a++) {
              //   console.log(resData);
              var resDataPolygon = resData[a].polygon[0];
              var path = [];
              for (var b = 0; b < resDataPolygon.length; b = b + 2) {
                path.push(
                  new TMap.LatLng(resDataPolygon[b + 1], resDataPolygon[b])
                );
              }
              ps.push(path);
            }
            // console.log(ps)

            // var LatLngs0 = res.result[0][0].polygon[0]
            // for (var i = 0; i < LatLngs0.length; i=i+2) {
            //   path0.push(new TMap.LatLng(LatLngs0[i+1], LatLngs0[i]))
            // }

            //初始化polygon--------
            var polygon = new TMap.MultiPolygon({
              map, // 显示多边形图层的底图
              styles: {
                // 多边形的相关样式
                polygon0: new TMap.PolygonStyle({
                  color: colors[0], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon1: new TMap.PolygonStyle({
                  color: colors[1], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon2: new TMap.PolygonStyle({
                  color: colors[2], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon3: new TMap.PolygonStyle({
                  color: colors[3], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon4: new TMap.PolygonStyle({
                  color: colors[4], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon5: new TMap.PolygonStyle({
                  color: colors[5], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon6: new TMap.PolygonStyle({
                  color: colors[6], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon7: new TMap.PolygonStyle({
                  color: colors[7], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
                polygon8: new TMap.PolygonStyle({
                  color: colors[8], // 面填充色
                  showBorder: true, // 是否显示拔起面的边线
                  borderColor: "rgba(255,255,255,255)", // 边线颜色
                  borderWidth: 3, // 边线宽度
                 // borderDashArray: [5, 5], // 虚线数组
                }),
              },
              geometries: [
                {
                  id: "polygon0", // 多边形图形数据的标志信息
                  styleId: "polygon0", // 样式id
                  paths: ps[0], // 多边形的位置信息
                },
                {
                  id: "polygon1", // 多边形图形数据的标志信息
                  styleId: "polygon1", // 样式id
                  paths: ps[1], // 多边形的位置信息
                },
                {
                  id: "polygon2", // 多边形图形数据的标志信息
                  styleId: "polygon2", // 样式id
                  paths: ps[2], // 多边形的位置信息
                },
                {
                  id: "polygon3", // 多边形图形数据的标志信息
                  styleId: "polygon3", // 样式id
                  paths: ps[3], // 多边形的位置信息
                },
                {
                  id: "polygon4", // 多边形图形数据的标志信息
                  styleId: "polygon4", // 样式id
                  paths: ps[4], // 多边形的位置信息
                },
                {
                  id: "polygon5", // 多边形图形数据的标志信息
                  styleId: "polygon5", // 样式id
                  paths: ps[5], // 多边形的位置信息
                },
                {
                  id: "polygon6", // 多边形图形数据的标志信息
                  styleId: "polygon6", // 样式id
                  paths: ps[6], // 多边形的位置信息
                },
                {
                  id: "polygon7", // 多边形图形数据的标志信息
                  styleId: "polygon7", // 样式id
                  paths: ps[7], // 多边形的位置信息
                },
                {
                  id: "polygon8", // 多边形图形数据的标志信息
                  styleId: "polygon8", // 样式id
                  paths: ps[8], // 多边形的位置信息
                },
              ],
            });
            //  ------
          })
          .catch((err) => {
            console.log(err);
          });
      });
    },
    // 添加标注点聚合
    addMultiMarker(buildingList) {
      var clusterBubbleList = [];
      var markerGeometries = [];
      var marker = null;
      // var positions = [];
      for (var i = 0; i < buildingList.length; i++) {
        // console.log(buildingList[i])
        var latLng = new TMap.LatLng( buildingList[i].latitude, buildingList[i].longitude);
        markerGeometries.push({position: latLng});
      }

      //创建点聚合对象
      var markerCluster = new TMap.MarkerCluster({
        id: "cluster", //图层id
        map: map, //设置点聚合显示在哪个map对象中(创建map的段落省略)
        enableDefaultStyle: false, //使用默认样式
        minimumClusterSize: 2, //最小聚合点数:2个
        geometries: markerGeometries, //....将您所有要打到图中的坐标点传入进来
        zoomOnClick: true, //点击聚合数字放大展开
        gridSize: 60, //聚合算法的可聚合距离,即距离小于该值的点会聚合至一起,默认为60,以像素为单位
        averageCenter: false, //每个聚和簇的中心是否应该是聚类中所有标记的平均值
        maxZoom: 16, //采用聚合策略的最大缩放级别,若地图缩放级别大于该值,则不进行聚合,标点将全部被展开
      });

    markerCluster.on('cluster_changed', function (e) {
          // 销毁旧聚合簇生成的覆盖物
        if (clusterBubbleList.length) {
        clusterBubbleList.forEach(function (item) {
          item.destroy();
        })
        clusterBubbleList = [];
      }
      markerGeometries = [];
      // 根据新的聚合簇数组生成新的覆盖物和点标记图层
      var clusters = markerCluster.getClusters();
      clusters.forEach(function (item) {
        if (item.geometries.length > 1) {
          let clusterBubble = new ClusterBubble({
            map,
            position: item.center,
            content: item.geometries.length,
          });
          clusterBubble.on('click', () => {
            map.fitBounds(item.bounds);
          });
          clusterBubbleList.push(clusterBubble);
        } else {
          // console.log(item.geometries[0].properties)
          markerGeometries.push({
            position: item.center,
          });
        }
      });
    
    console.log(markerGeometries)
      // ======创建mark
      if (marker) {
        // 已创建过点标记图层,直接更新数据
        marker.setGeometries(markerGeometries);
      } else {
        // 创建点标记图层
        marker = new TMap.MultiMarker({
          id: 'marker-layer',
          map,
          styles: {
            default: new TMap.MarkerStyle({
              'width': 34,
              'height': 42,
              'anchor': {
                x: 17,
                y: 21,
              },
              'src': 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker_blue.png',
            }),
          },
          geometries: markerGeometries
        });
      }
      //初始化infoWindow===
      var infoWindow = new TMap.InfoWindow({
          map: map,
          position: new TMap.LatLng(32.04487,112.13555),
          offset: { x: 0, y: -32 } //设置信息窗相对position偏移像素
      });
      infoWindow.close();//初始关闭信息窗关闭
      // //监听标注点击事件
      marker.on("click", function (evt) {
          //设置infoWindow
          infoWindow.open(); //打开信息窗
          infoWindow.setPosition(evt.geometry.position);//设置信息窗位置
          infoWindow.setContent(evt.geometry.position.toString());//设置信息窗内容
      })
      // =====
    })

    },
  },
};

// ======================
// 以下代码为基于DOMOverlay实现聚合点气泡
function ClusterBubble(options) {
  TMap.DOMOverlay.call(this, options);
}

ClusterBubble.prototype = new TMap.DOMOverlay();

ClusterBubble.prototype.onInit = function (options) {
  this.content = options.content;
  this.position = options.position;
};

// 销毁时需要删除监听器
ClusterBubble.prototype.onDestroy = function() {
  this.dom.removeEventListener('click', this.onClick);
  this.removeAllListeners();
};

ClusterBubble.prototype.onClick = function() {
  this.emit('click');
};

// 创建气泡DOM元素
ClusterBubble.prototype.createDOM = function () {
  var dom = document.createElement('div');
  dom.classList.add('clusterBubble');
  dom.innerText = this.content;
  dom.style.cssText = [
    'width: ' + (40 + parseInt(this.content) * 2) + 'px;',
    'height: ' + (40 + parseInt(this.content) * 2) + 'px;',
    'line-height: ' + (40 + parseInt(this.content) * 2) + 'px;',
  ].join(' ');
    
  // 监听点击事件,实现zoomOnClick
  this.onClick = this.onClick.bind(this);
  dom.addEventListener('click', this.onClick);
  return dom;
};

ClusterBubble.prototype.updateDOM = function () {
  if (!this.map) {
    return;
  }
  // 经纬度坐标转容器像素坐标
  let pixel = this.map.projectToContainer(this.position);

  // 使文本框中心点对齐经纬度坐标点
  let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
  let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
  this.dom.style.transform = `translate(${left}, ${top})`;

  this.emit('dom_updated');
};
window.ClusterBubble = ClusterBubble;
</script>

<style lang="less">
.clusterBubble {
      border-radius: 50%;
      color: #fff;
      font-weight: 500;
      text-align: center;
      opacity: 0.88;
      background-image: linear-gradient(139deg, #4294FF 0%, #295BFF 100%);
      box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.20);
      position: absolute;
      top: 0px;
      left: 0px;
    }
</style> 

效果图

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue实现百度地图聚合,可以按照以下步骤进行操作: 1. 首先,在Vue项目中安装百度地图的JavaScript API。可以通过在`index.html`文件中添加以下代码来引入百度地图的API: ```html <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=YOUR_API_KEY"></script> ``` 确保替换`YOUR_API_KEY`为你自己的百度地图API密钥。 2. 在Vue组件中创建地图容器,并初始化地图。可以在`mounted`钩子函数中添加以下代码: ```javascript mounted() { const map = new BMap.Map("map-container"); // 创建地图实例 const point = new BMap.Point(经度, 纬度); // 设置地图中心坐标 map.centerAndZoom(point, 15); // 初始化地图,设置地图缩放级别 this.map = map; // 将地图实例保存到组件数据中 } ``` 确保替换`经度`和`纬度`为你希望地图显示的中心坐标。 3. 获取需要聚合的标记数据,并使用百度地图的`MarkerClusterer`类进行聚合。可以在`mounted`钩子函数中添加以下代码: ```javascript mounted() { // ... const markers = []; // 存储标记的数组 // 添加标记地图和markers数组中 yourData.forEach((item) => { const point = new BMap.Point(item.lng, item.lat); const marker = new BMap.Marker(point); map.addOverlay(marker); markers.push(marker); }); // 创建聚合器并设置参数 const markerClusterer = new BMapLib.MarkerClusterer(map, { markers: markers, }); // ... } ``` 确保替换`yourData`为你的标记数据数组,每个标记的经度和纬度分别存储在`item.lng`和`item.lat`中。 4. 在Vue组件中添加地图容器的HTML代码。可以在组件模板中添加以下代码: ```html <template> <div id="map-container" style="width: 100%; height: 400px;"></div> </template> ``` 确保根据需要设置地图容器的宽度和高度。 通过以上步骤,你就可以在Vue项目中实现百度地图聚合效果了。记得在百度地图开放平台申请并获取到API密钥,并替换代码中的`YOUR_API_KEY`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值