利用Cesium和JS实现地点点聚合功能

news2025/2/25 3:29:14

引言

在实现基于地图的业务场景时,当地图上需要展示过多的标记点时,大量的分散点会使地图上显得杂乱无章,导致标记点对地图上的其他重要信息造成遮挡和混淆,降低地图整体的可读性。

标记点的聚合就很好的解决了这些痛点的同时,还可以清晰的展示数据的分布模式和主要区域,便于用户直观的理解,提高地图的加载和交互的效率,便于对数据镜像更深层次的开阔和分析。

CesiumAPI 中本身自带聚合的方法,但是提供的聚合场景只适用于一些简单的标记点或者 POI 中使用

在实际的开发过程中,我们需要展示的标记点样式大多较为复杂甚至是视频等自定义的样式,标记点内实际会使用到点击、显示隐藏、调整等交互。

那么怎样利用 JSCesium 实现地图点位的聚合呢?

本文将在实际的业务使用场景中,带大家了解如何利用 cesiumJS 实现地图标记点位的聚合实现原理及方法。

实现思路:

  1. 首先是实现标记点的实现,通过监听相机角度的变化,达到的效果的地图的拖动缩放,标记点都会根据固定的点位移动;

  2. 通过简单的算法实现聚合,达到两个标记点通过放大和缩小,显示成具体的标记点数量

完成效果:



具体实现:

1.引入cesium,并初始化数据;

 //引入cesium文件
<script src="/Cesium/Cesium.js"></script>
//初始化cesium
Const viewerGis = new BIMCC_GIS_Base.Viewer('container');

2.监听相机视角变化

//开启相机视角变化
viewerGis.MouseCustomEvent.registerCameraChange();
// 监听相机视角变化事件
viewerGis.on('cameraChange', () => {
//相机视角变化调用下一步的方法获取屏幕坐标
});

3.经纬度坐标转换为屏幕坐标

经纬度坐标转换是实现聚合的最核心的一步。

Cesium 中,将经纬度坐标转换为屏幕坐标的过程主要涉及到相机视图矩阵和模型矩阵的计算。

其实现原理是将 3D世界坐标 转换为 2D画布坐标

其原理是通过Uniform(统一变量)将当前的模型视图投影矩阵应用到指定的世界坐标上,进而得到屏幕坐标。

最后将屏幕坐标转换为画布坐标系中的位置。

//假设viewer是Cesium的Viewer实例,worldPosition是一个Cesium.Cartesian实例,表示世界坐标中的一个经纬度坐标点
var canvasCoordinates = viewerGis.Coordinate?.getCanvasByWgs(worldPosition);
// 如果转换成功,canvasCoordinates将是一个包含x和y属性的对象,表示在画布上的位置
if (canvasCoordinates){
	console.log(`画布坐标: (${canvasCoordinates.x}, ${canvasCoordinates.y})`)
}

在实际开发中,我们是对 Cesium 进行了二次开发,调用的方法名有所变化,但是其原理是一样的。

获取到屏幕坐标我们就可以很容易地将标记点放入到指定的位置。

并通过上一步的监听相机位置变化,获取到每次缩放拖动后的屏幕坐标。

4.标记的聚合实现

标记的聚合实现主要算法有很多,参考高德地图,主要的算法有:直接网格法网格距离法直接距离法K-D树方法

这里我们使用直接距离法,初始时没有任何已知聚合点,然后对每个点进行迭代,计算一个点的外包正方形

若此点的外包正方形与现有的聚合点的外包正方形不相交,则新建聚合点(这里不是计算点与点间的距离,而是计算一个点的外包正方形,正方形的变长由用户指定或程序设置一个默认值)

若相交,则把该点聚合到该聚合点中,若点与多个已知的聚合点的外包正方形相交,则计算该点到到聚合点的距离,聚合到距离最近的聚合点中

如此循环,直到所有点都遍历完毕。

每个缩放级别都重新遍历所有原始点要素。

优点:运算速度相对较快,每个原始点只需计算一次,可能会有点与点距离计算,聚合点较精确的反映了所包含的原始点要素的位置信息。

缺点:速度不如完全基于网格的速度快,此法还有个缺点,就是各个点迭代顺序不同导致最终结果不同。

因此涉及到制定迭代顺序的问题。

//处理聚合数据,传参data是所有标记点
const collectMakers = (data) => {
  collectList.value = [];
  data.forEach((maker) => {
    let flag = false;
    collectList.value.forEach((item) => {
      if (flag) return;
      item.forEach((i) => {
        if (i.id == maker.id) {
          flag = true;
          return;
        }
      });
    });
    if (flag) return;
    const filterList = data.filter(
      (item) => Math.abs(maker.style.left - item.style.left) < maker.style.width && Math.abs(maker.style.top - item.style.top) < maker.style.height
    );
	//filterList就是聚合的数据
    collectList.value.push(filterList);
  });
}

通过以上几步就可以通过 JSCesium 上实现标记以及聚合的效果。

– 欢迎点赞、关注、转发、收藏【我码玄黄】,gonghao同名

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1824115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理解Es的DSL语法(二):聚合

前一篇已经系统介绍过查询语法&#xff0c;详细可直接看上一篇文章&#xff08;理解DSL语法&#xff08;一&#xff09;&#xff09;&#xff0c;本篇主要介绍DSL中的另一部分&#xff1a;聚合 理解Es中的聚合 虽然Elasticsearch 是一个基于 Lucene 的搜索引擎&#xff0c;但…

单通道触摸感应开关RH6016

1.简介 SOT23-6 RH6016 封装和丝印 RH6016 是一款内置稳压模块的单通道电容式触摸感应控制开关IC&#xff0c;可以替代传统的机械式开关。 RH6016可在有介质(如玻璃、亚克力、塑料、陶瓷等)隔离保护的情况下实现触摸功能&#xff0c;安全性高。 RH6016内置高精度稳压、上电复…

C++17并行算法与HIPSTDPAR

C17 parallel algorithms and HIPSTDPAR — ROCm Blogs (amd.com) C17标准在原有的C标准库中引入了并行算法的概念。像std::transform这样的并行版本算法保持了与常规串行版本相同的签名&#xff0c;只是增加了一个额外的参数来指定使用的执行策略。这种灵活性使得已经使用C标准…

数据采集项目2-业务数据同步

全量同步 每天都将业务数据库中的全部数据同步一份到数据仓库 全量同步采用DataX datax datax使用 执行 python /opt/module/datax/bin/datax.py /opt/module/datax/job/job.json 更多job.json配置文件在&#xff1a; 生成的DataX配置文件 java -jar datax-config-genera…

【RabbitMQ】RabbitMQ 的 6 种工作模式

RabbitMQ 的 6 种工作模式 1.简单模式2.工作队列模式3.交换机模式4.Routing 转发模式5.主题转发模式6.RPC 模式6.1 消息属性6.2 关联标识6.3 工作流程 7.小结 1.简单模式 生产者把消息放入队列&#xff0c;消费者获得消息&#xff0c;如下图所示。这个模式只有 一个消费者、一…

【python】python指南(三):使用正则表达式re提取文本中的http链接

一、引言 对于算法工程师来说&#xff0c;语言从来都不是关键&#xff0c;关键是快速学习以及解决问题的能力。大学的时候参加ACM/ICPC一直使用的是C语言&#xff0c;实习的时候做一个算法策略后台用的是php&#xff0c;毕业后做策略算法开发&#xff0c;因为要用spark&#x…

LeetCode | 520.检测大写字母

这道题直接分3种情况讨论&#xff1a;1、全部都为大写&#xff1b;2、全部都为小写&#xff1b;3、首字母大写其余小写。这里我借用了一个全是大写字母的串和一个全为小写字母的串进行比较 class Solution(object):def detectCapitalUse(self, word):""":type …

Python基础教程(十五):面向对象编程

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

【机器学习】Dify:AI智能体开发平台版本升级

一、引言 关于dify&#xff0c;之前力推过&#xff0c;大家可以跳转 AI智能体研发之路-工程篇&#xff08;二&#xff09;&#xff1a;Dify智能体开发平台一键部署了解&#xff0c;今天主要以dify为例&#xff0c;分享一下如何进行版本升级。 二、版本升级 2.1 原方案 #首次…

超图制作栅格数据集专题图示例

之前写过一两篇专题图的博文&#xff0c;是制作的矢量数据集的专题图&#xff1b; 有一个栅格数据集如下&#xff0c;不知是干嘛的&#xff0c;可能是一个地形&#xff0c;或水系&#xff1b; 看一下对栅格数据集制作专题图&#xff1b;能制作的专题图类型少些&#xff0c; 先…

pytorch学习笔记7

getitem在进行索引取值的时候自动调用,也是一个魔法方法,就像列表索引取值那样,一个意思 import torchvision from torch.utils.data import DataLoaderdata_transformtorchvision.transforms.Compose([torchvision.transforms.ToTensor()] ) test_datatorchvision.datasets.C…

GraphQL(9):Spring Boot集成Graphql简单实例

1 安装插件 我这边使用的是IDEA&#xff0c;需要先按照Graphql插件&#xff0c;步骤如下&#xff1a; &#xff08;1&#xff09;打开插件管理 在IDEA中&#xff0c;打开主菜单&#xff0c;选择 "File" -> "Settings" (或者使用快捷键 Ctrl Alt S …

【测试】软件测试方案—实际项目直接套用(Word原件)

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.…

宝藏速成秘籍(5)插入排序法

一、前言 1.1、概念 插入排序&#xff08;Insertion Sort&#xff09;是一种简单直观的排序算法&#xff0c;其工作原理类似于人们整理一手扑克牌。插入排序通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入…

Javaweb03-Servlet技术1(Servlet,ServletConfig,ServletContext)

Servlet技术(Servlet,ServletConfig,ServletContext) 1.Servlet的概述 Servlet是运行在Web服务器端的Java应用程序&#xff0c;它使用Java语言编写。与Java程序的区别是&#xff0c;Servlet 对象主要封装了对HTTP请求的处理&#xff0c;并且它的运行需要Servlet容器(Tomcat)的…

MySQL与PostgreSQL关键对比四(关联查询性能)

引言&#xff1a;MySQL单表的数据规模一般建议在百万级别&#xff0c;而PostgreSQL的单表级别一般可以到亿级&#xff0c;如果是MPP版本就会更多。从基础数据建议上&#xff0c;不难看出&#xff0c;MySQL在Join的情况下也就是主要查询的情况下性能和PostgreSQL相差还是很大的。…

Navicat和SQLynx产品功能比较一(整体比较)

Navicat和SQLynx都是数据库管理工具&#xff0c;在过去的二十年中&#xff0c;国内用户主要是使用Navicat偏多&#xff0c;一般是个人简单开发需要&#xff0c;数据量一般不大&#xff0c;开发相对简单。SQLynx是最近几年的数据库管理工具&#xff0c;Web开发&#xff0c;桌面版…

【odoo】odoo中对子数据的独有操作[(0, 0, {‘name‘: ‘demo‘})]

概要 在Odoo中&#xff0c;有种写法用于操作 one2many 或 many2many 字段时&#xff0c;描述如何在数据库中创建、更新或删除相关记录。具体而言&#xff0c;这是一种命令格式&#xff0c;被称为 "commands" 或 "special command tuples"&#xff0c;用于 …

高考志愿填报,大学读什么专业比较好?

高考分数出炉后&#xff0c;选择什么样的专业&#xff0c;如何去选择专业&#xff1f;于毕业生而言是一个难题。因为&#xff0c;就读的专业前景不好&#xff0c;意味着就业情况不乐观&#xff0c;意味着毕业就是失业。 盲目选择专业的确会让自己就业时受挫&#xff0c;也因此…

服务器数据恢复—OceanStor存储中NAS卷数据丢失如何恢复数据?

服务器存储数据恢复环境&故障&#xff1a; 华为OceanStor某型号存储。工作人员在上传数据时发现该存储上一个NAS卷数据丢失&#xff0c;管理员随即关闭系统应用&#xff0c;停止上传数据。这个丢失数据的卷中主要数据类型为office文件、PDF文档、图片文件&#xff08;JPG、…