<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> 

效果图

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐