当前位置: 首页 > news >正文

前端利用Turf.js实现对地图上的点聚合算法

Turf.js是一个用于空间分析的js库,经常作用在地图上。目前项目上有一个需求,是使用的高德地图Loca的ZMarkerLayer图层,这个图层没用聚合功能,并且在地图上绘制的点位非常多。

Turf.js官方文档

https://turfjs.org/docs/api/clustersDbscan

官方示例效果就是项目上的效果,只是这样的标牌点位非常多,标牌看起来视觉上非常拥挤。

目前思路是想写一个方法,传入点位,再传入一个半径,算出n多个聚合集合,只取每个聚合集合中的一个集合,成立成一个新数组,渲染再地图上,这样就可以实现一个简单的聚合效果。

方法:

先计获取当前像素距离,然后利用turf.js中的clustersDbscan这个函数拿到一个聚合集合对象,然后取出每个聚合项的一项即可。

可以看到使用clustersDbscan函数返回原数据,只是原来的数据中每个都多了两个字段,cluster和dbscan字段,core代表了聚合,cluster表示索引,表示第几个聚合集合,说明还有其他数据中也有cluster:0,dbscan:'core',然后我们只需要根据这两个字段再次遍历过滤即可。

根据cluster和dbscan手动拿到一个聚合后的集合对象。

function filterCollisionPoints(points, minDistance = 0.5) { // minDistance 默认500米
  let filteredPoints=turf.clustersDbscan(points, minDistance,{minPoints:2})
  console.log(filteredPoints,'filteredPoints')
  let clusterIndex = {}
  // 根据cluster和dbscan字段获得聚合集合对象
  filteredPoints.features.forEach((item)=>{
    if(item.properties.cluster!==undefined){
      if(clusterIndex[item.properties.cluster]){
        clusterIndex[item.properties.cluster].push(item)
      }else{
        clusterIndex[item.properties.cluster]=[item]
      }
    }else{
      if(clusterIndex['noise']){
        clusterIndex['noise'].push(item)
      }else{
        clusterIndex['noise']=[item]
      }
    }
  })
  // console.log(clusterIndex,'clusterIndex')
  // 手动过滤,拿到过滤后的聚合数据。
  let newClusterData=[]
  for(const key in clusterIndex){
    if(key==='noise'){
      clusterIndex[key].forEach((item,index)=>{
        newClusterData.push(item)
      })
    }else {
      newClusterData.push(clusterIndex[key][0])//我这里取得是第一项,也可以随机取其中一个
    }
  }
  console.log(newClusterData,'newClusterData')
  return newClusterData;
}

 调用如下,我用的是高德地图,getResolution获取当前地图分辨率,大概算出合适的半径,传入即可,然后就是监听地图的moveend事件,不断传入新的newData就可以算出当前聚合的数据,然后再地图上再渲染聚合的数据就好了。

let radius = map.getResolution()/10*1.5
const filterData= filterCollisionPoints({
    type: 'FeatureCollection',
    features: newData
},radius)

由于项目上地图上的点位数据比较敏感,暂时不做效果展示,按照上面的方法,可以实现一个简单的聚合效果。

相关文章:

  • 基于HTML5的连连看游戏开发实践
  • 天梯赛L2-003 月饼满分(笔记)
  • 基于mediapipe深度学习的运动人体姿态提取系统python源码
  • 汇川EASY系列之以太网通讯(MODBUS_TCP做从站)
  • RocketMQ分布式场景篇
  • C语言自定义类型【结构体】详解,【结构体内存怎么计算】 详解 【热门考点】:结构体内存对齐
  • tauri2项目在本地启动一个服务器,并支持控制停止还是启动
  • FPGA-DE2115开发板实现流水灯
  • 更改 docker0 IP
  • 第五章-PHP函数
  • 批处理脚本编译vs工程
  • LoRA中黑塞矩阵、Fisher信息矩阵是什么
  • C++中new和delete如何构建简单对象和复杂对象?
  • c++介绍进程间的通信一
  • K8s认证(CKA/CKAD/CKS)哪家强?主流证书对比
  • 《Linux 网络架构:基于 TCP 协议的多人聊天系统搭建详解》
  • Zookeeper 集群部署与管理实践
  • 第4章:Docker安装与环境配置:多平台部署指南
  • 流程图软件推荐,好用的流程图工具分享
  • 解决Qt信号在构造函数中失效的问题
  • 特朗普支持率降至新低:宣布关税后骤降,选民最不满经济表现
  • 习近平举行仪式欢迎肯尼亚总统鲁托访华
  • 山东省检察院答澎湃:惩治网络售假,强化“全链条”刑事打击
  • 游客大理古城买瓜起争执:170克手机称出340克
  • 特斯拉季度利润暴跌71%,马斯克下月开始大幅减少为政府工作时间
  • 载人登月总体进展顺利