cesium实现大批量POI点位聚合渲染优化方案

这篇具有很好参考价值的文章主要介绍了cesium实现大批量POI点位聚合渲染优化方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

cesium primitive聚合,Cesium,javascript,前端

前言

cesium目前只提供了entityCluster这个聚合类,使打点聚合更方便快捷的实现,但是一般在真正做项目的时候,大家会经常碰到成千上万个甚至几十万个点位需要聚合打点,那这时候你如果还是用entity去实现的话,怕是要被用户按在地上疯狂摩擦,摩擦。。。😅

思考

我们可以通过模拟entityCluster这个类的实现方式,利用源码中的算法,改成primitive的实现方式;

开发

拉下cesium的源码,搜EntityCluster关键字,我们可以找到EntityCluster.js这个文件,那么这个代码就是实现聚合的核心逻辑,接下来我们可以复制一份出来,将EntityCluster全部改为PrimitiveCluster,接着getScreenSpacePositions这个方法里将entity的逻辑删除,否则会因为item.id为entity对象为空导致报错

function getScreenSpacePositions(
  collection,
  points,
  scene,
  occluder,
  entityCluster
) {
  if (!defined(collection)) {
    return;
  }

  const length = collection.length;
  for (let i = 0; i < length; ++i) {
    const item = collection.get(i);
    item.clusterShow = false;

    if (
      !item.show ||
      (entityCluster._scene.mode === SceneMode.SCENE3D &&
        !occluder.isPointVisible(item.position))
    ) {
      continue;
    }

    // const canClusterLabels =
    //   entityCluster._clusterLabels && defined(item._labelCollection);
    // const canClusterBillboards =
    //   entityCluster._clusterBillboards && defined(item.id._billboard);
    // const canClusterPoints =
    //   entityCluster._clusterPoints && defined(item.id._point);
    // if (canClusterLabels && (canClusterPoints || canClusterBillboards)) {
    //   continue;
    // }

    const coord = item.computeScreenSpacePosition(scene);
    if (!defined(coord)) {
      continue;
    }

    points.push({
      index: i,
      collection: collection,
      clustered: false,
      coord: coord,
    });
  }
}

好了,源码大体就是改这么多了,接下来就是怎么用;

使用

import PrimitiveCluster from "@/utils/cesiumCtrl/primitiveCluster";

// 初始化标签实例
const billboardsCollectionCombine = new Cesium.BillboardCollection();
// 初始化实体
const primitives = viewer.scene.primitives.add(
  new Cesium.PrimitiveCollection()
);

getGeojson("/json/schools.geojson").then(({ res }) => {
    // 先获取点位数据
    console.log(res);
    const { features } = res;
    formatClusterPoint(features);
  });
// 整理聚合数据
const formatClusterPoint = (features) => {
  var scene = viewer.scene;
  var primitivecluster = new PrimitiveCluster();

  //与entitycluster相同设置其是否聚合 以及最大最小值
  primitivecluster.enabled = true;
  primitivecluster.pixelRange = 60;
  primitivecluster.minimumClusterSize = 2;
  // primitivecluster._pointCollection = pointCollection;
  // primitivecluster._labelCollection = labelCollection;

  for (let i = 0; i < features.length; i++) {
    const feature = features[i];
    const coordinates = feature.geometry.coordinates;
    const position = Cesium.Cartesian3.fromDegrees(
      coordinates[0],
      coordinates[1]
    );

    // 带图片的点
    billboardsCollectionCombine.add({
      image: "/images/mark-icon.png",
      width: 32,
      height: 32,
      position,
    });
  }
  // 将数据传给primitivecluster的标签属性
  primitivecluster._billboardCollection = billboardsCollectionCombine;
  // 初始化
  primitivecluster._initialize(scene);
  // 将标签数据添加到实体中
  primitives.add(primitivecluster);

  // 监听相机缩放
  primitivecluster.clusterEvent.addEventListener(
    (clusteredEntities, cluster) => {
      // 关闭自带的显示聚合数量的标签
      cluster.label.show = false;
      cluster.billboard.show = true;
      cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;

      // 根据聚合数量的多少设置不同层级的图片以及大小
      cluster.billboard.image = combineIconAndLabel(
        "/images/school-icon.png",
        clusteredEntities.length,
        64
      );
      // cluster.billboard.image = "/images/school-icon.png";
      cluster.billboard._imageHeight = 60;
      cluster.billboard._imageWidth = 60;
      cluster.billboard._dirty = false;
      cluster.billboard.width = 40;
      cluster.billboard.height = 40;
    }
  );
  return primitivecluster;
};
/**
 * @description: 将图片和文字合成新图标使用(参考Cesium源码)
 * @param {*} url:图片地址
 * @param {*} label:文字
 * @param {*} size:画布大小
 * @return {*} 返回canvas
 */
function combineIconAndLabel(url, label, size) {
  // 创建画布对象
  let canvas = document.createElement("canvas");
  canvas.width = size;
  canvas.height = size;
  let ctx = canvas.getContext("2d");

  let promise = new Cesium.Resource.fetchImage(url).then((image) => {
    // 异常判断
    try {
      ctx.drawImage(image, 0, 0);
    } catch (e) {
      console.log(e);
    }

    // 渲染字体
    // font属性设置顺序:font-style, font-variant, font-weight, font-size, line-height, font-family
    ctx.fillStyle = Cesium.Color.BLACK.toCssColorString();
    ctx.font = "bold 20px Microsoft YaHei";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(label, size / 2, size / 2);

    return canvas;
  });
  return promise;
}

ok,以上就是完整的使用方法,主要是如何使用,不然会造成canvas相关方面的报错等等;

开源

详细源码细节可以查看:链接: primitive实现聚合源码 ,此开源项目集合了目前常用的一些三维动画场景,还在不断更新中;文章来源地址https://www.toymoban.com/news/detail-706003.html

到了这里,关于cesium实现大批量POI点位聚合渲染优化方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 多线程处理大批量数据操作

     @Autowired private DataSourceTransactionManager dataSourceTransactionManager; @Autowired private TransactionDefinition transactionDefinition; @Autowired private StudentService studentService; /**  * 对用户而言,27s 任是一个较长的时间,我们尝试用多线程的方式来经行修改操作看能否加快处理速度  * 预计创建10个线程

    2024年02月09日
    浏览(46)
  • Python 大批量写入数据 百万级别

    方案二 方案一

    2024年02月11日
    浏览(80)
  • MySQL---使用索引优化、大批量插入数据优化

    1. 使用索引优化 索引是数据库优化最常用也是最重要的手段之一 , 通过索引通常可以帮助用户解决大多数的 MySQL 的性能优化问题: 1.1 避免索引失效应用-全值匹配 该情况下,索引生效,执行效率高。 1.2 避免索引失效应用-最左前缀法则 1.3 避免索引失效应用-其他匹配原则

    2024年02月07日
    浏览(53)
  • Jmeter(三十一):制造大批量的用户数据数据

    需求:因测试需要,要造100w用户数据,通过用户名、手机号、密码可新增用户,其中用户名和电话号码要求100w用户不能重复 要点: 1、通过Bean shell Sampler实现用户名和手机号的足够随机。 符合我们常用规则的手机号:第一位为1,第二位为3-9,后面的9位为0-9即可。 phone=${_

    2024年02月10日
    浏览(43)
  • 如何使用python快速将大批量图片合成为视频?

    由于CSDN大批量导入图片容易出现乱序,本程序将支撑图片转为视频,便于用视频的方式展示文件内容。 由于图片名称复杂多样,为便于统一化处理,增强程序的通用性,使用改名程序可以降低手动调整的复杂度。 改名之后的效果: 注意此部分的图片大小仍需要手动修改或输

    2024年02月04日
    浏览(48)
  • 远程运维大批量IT设备?向日葵批量部署、分组授权与安全功能解析

    数字化转型的不断推进,给予了企业全方位的赋能,但任何发展都伴随着成本与代价,比如在数字化转型过程中企业内部办公与外部业务所需的不断增加的IT设备数量,就为日常的运维工作提出了更大的挑战。 针对企业面对海量IT设备时的运维难、效率低、容易出错等问题,

    2024年02月14日
    浏览(47)
  • 使用postman做接口测试传入大批量动态参数的方法

    postman是一个非常好用的接口测试工具,而且功能也很强大,今天只简单说一下使用postman如何对一个接口传入大批量参数进行测试的方法。 以我测试的平台为例,我们的平台是做在线教育平台的,我模拟的场景是老师有一门课叫ABC,现在需要有1000个学生加入ABC这门课。我们不

    2024年01月23日
    浏览(64)
  • redis 无占用 两种方式 清除大批量数据 lua脚本

    redis存储了很多无用的key,占用了大量内存,需要清除 第一种 (颗粒度较大) lua脚本,删除某些规则的key,输入删除的key,返回删除的符合规则的key的数量 弊端:颗粒度比较大,发送一个lua脚本去执行,会占用较多时间,堵塞其他redis命令 java代码 这样直接删除,因为规则有很

    2024年04月28日
    浏览(37)
  • Python 自动获取大批量excel数据并填写到网页表单(pandas;selenium)

    自动获取大批量excel数据并填写到网页表单 部分网页获取下拉列表点击的方式有所差异 这个请根据网页源码自做选择 一定要学会使用IPDB调试工具 太好用了!!!! 可能需要pip update一下 看提示 很好解决 没有报错最好啦 Python真是太好用了 办公利器啊!!!!

    2024年02月12日
    浏览(50)
  • 大批量数据导出csv,平替导出excel性能优化解决方案封装工具类

            有些业务逻辑需要在导出非常大量的数据,几百甚至几千万的数据这个时候再导出excel来对于性能都不是很友好,这个时候就需要替换实现思路来解决这个问题。         本文章提供了两种解决的方案,也是两种从数据库中拿取数据的方式一种是原生的jdbc一种是使用

    2024年01月16日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包