@vuemap/vue-amap,高德地图点聚合

申屠俊发
2023-12-01
<script>
	export default {
		watch: {
		    itemId(val) {
		        // 移除地图上的图层,如果不移除的话,只要切换过的项目,项目上的设备、监控,都会全部显示出来(即地图上保留了上一次设备、监控的图层)
		        if (this.clusterList && this.clusterList.length) {
		          this.clusterList.map(dom => {
		            dom.setMap(null)
		          })
		        }
				// 重新设置地图的缩放级别
		        this.map.setZoom(15)
		    }
		},
		methods: {
		   // 点聚合
		    juheFunc(str, list) {
		
		      let _this = this
		
		      let cluster
		
		      let map = this.map
		
		      let gridSize = 60
		      // 数据中需包含经纬度信息字段 lnglat
		      // let points = [
		      // { lnglat: ["108.939621", "34.343147"] },
		      // { lnglat: ["112.985037", "23.15046"] },
		      // ...
		      // ...
		      // ]
		      let points = []
		      // 组装成官方需要的格式
		      if (list && list.length) {
		        list.map(dom => {
		          points.push({
		            lnglat: this.coordinates(dom.BaiduLongitude || dom.longitude || dom.lng, dom.BaiduLatitude || dom.latitude || dom.lat),
		            ...dom
		          })
		        })
		      }
		
		      let count = points.length;
		
		      let length = '100px'
		      if (str == 'task') {
		        length = '80px'
		      }
		
		      // 自定义点聚合后的样式
		      let _renderClusterMarker = function (context) {
		        let div = document.createElement('div');
		        // 聚合的点的个数
		        let span = document.createElement('span')
		        span.innerHTML = context.count
		        div.appendChild(span)
		
		        // 点的显示图标
		        let img = document.createElement('img')
		        img.setAttribute('src', require('@/assets/policeBigData/' + str + '.png'))
		        div.appendChild(img)
		        img.style.width = length
		        img.style.height = length
		        div.style.position = 'relative'
		        span.style.position = 'absolute'
		
		        if (str == 'task') {
		          span.style.top = '51%'
		          span.style.left = '50%'
		          span.style.transform = 'translateX(-50%)'
		        } else {
		          span.style.top = '10px'
		          span.style.right = '24px'
		          span.style.width = '18px'
		          span.style.height = '18px'
		          span.style.background = '#03FBFF'
		          span.style.borderRadius = '50%'
		          span.style.color = '#0E9CFF'
		          span.style.lineHeight = '18px'
		        }
		
		        span.style.fontSize = '12px'
		        span.style.fontWeight = 'bold'
		        span.style.color = '#adfeff'
		
		        let size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20)
		        div.style.width = length
		        div.style.height = length
		
		        context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2))
		        context.marker.setContent(div)
		      }
		
		      // 自定义非聚合状态下的样式(即单个标记点时的样式)
		      let _renderMarker = function (context) {
		        let img = document.createElement('img')
		        img.style.width = length
		        img.style.height = length
		        img.setAttribute('src', require('@/assets/policeBigData/' + str + '.png'))
		
		        let offset = new AMap.Pixel(-9, -9);
		        context.marker.setContent(img)
		        context.marker.setOffset(offset)
		
		        // 设置标记携带的数据,点击事件会使用
		        context.marker.setExtData({
		          ...context.data[0]
		        })
		
		        // 单个标记点击事件
		        context.marker.on('click', ev => {
		          // 当前标记居中, 第一个参数为缩放级别
		          // map.setZoomAndCenter(18, ev.target.getPosition())
		          // 获取标记携带的数据
		          const extData = ev.target.getExtData()
		
		          _this.clusterClickFunc({
		            lnglat: extData.lnglat,
		            clusterData: [extData]
		          }, str)
		        })
		      }
		
		      // 点聚合
		      AMap.plugin('AMap.MarkerCluster', function () {
		        cluster = new AMap.MarkerCluster(map, points, {
		          // 设置网格像素大小
		          gridSize: gridSize,
		          // 自定义聚合点样式
		          renderClusterMarker: _renderClusterMarker,
		          // 自定义非聚合点样式
		          renderMarker: _renderMarker
		        })
		
		        // 标记点的点击事件
		        cluster.on('click', function (clu) {
		          // 当为点聚合时执行下面的操作,单个标记点时不执行(因为在单个标记点时,在上面已经设置了点击事件)
		          if (clu.clusterData && clu.clusterData.length) {
		            _this.clusterClickFunc(clu, str)
		          }
		        })
		      })
		
		      // 用于在切换项目时清空地图上的图层
		      _this.clusterList.push(cluster)
		
		      map.setFitView()
		    },
		    // 点击赋值
		    clusterClickFunc(clu, str) {
		      // 不设置为false的话,在点完一个点后,直接点击下一个点时,信息窗体不会显示
		      this.isShowWindow = false
		
		      // 不能直接用这种赋值的方式,会报错,不知道是什么原因,只能像下面那样单个属性赋值
		      // this.window = {}
		      // let obj = {
		      //   list: list,
		      //   windowShow: true,
		      //   position: this.coordinates(clu.lnglat.lng, clu.lnglat.lat)
		      // }
		      // this.window = obj
		
		      this.window.list = clu.clusterData || []
		      this.window.windowShow = true
		      this.window.type = str
		      // this.window.position = this.coordinates(clu.lnglat.lng, clu.lnglat.lat)
		      this.window.position = [clu.lnglat.lng, clu.lnglat.lat]
		      this.isShowWindow = true
		    },
		}
	}
</script>

官方案例

 类似资料: