【开源】Cesium场景效果大全(cesium+vue3+vite+vuex)

Hello大家好,我是日拱一卒的攻城师不浪,专注前端、后端、AI学习、二三维可视化、GIS等学习沉淀,这是2024年输出的第11/100篇文章,欢迎志同道合的朋友一起学习交流;
公众号:攻城师不浪

绿泡泡:brown_7778

视频效果

前言

今天再一次带来我的开源项目Cesium-test,这个项目主要收集了cesium在日常业务开发中常用到的一些场景效果的开发。

项目地址

我用我的廉价服务器给它搭了一个窝,感兴趣的可以点击查看(服务器带宽很低,带这种3D肯定很慢,嫌慢的可以直接看上方视频效果,还有动感的音药噢~)

Cesium-test网址:www.brown77.cn:3389

Cesium

首先,我先来简单介绍一下cesium,可能有的同学还不太了解,毕竟业务可能没有涉及到这块领域。

Cesiumjs

一个开源的JavaScript库,用于在Web浏览器中创建三维地球仪和二维地图。它利用了 WebGL 技术,可以在不需要插件的情况下,为用户提供丰富的交互式三维地理信息可视化体验。

应用领域

通过介绍我们不难看出,这个框架主要应用于二三维可视化以及GIS领域,可以说非常强大。

Cesium-test

cesium-test是我近期开源的一个项目,里面集结了一些常用的业务场景效果,包括:

  1. 粒子效果
  • 下雨
  • 下雪
  • 雾天
  • 火焰
  1. POI点位
  • 基础打点
  • 聚合
  • primitive底层打点(性能佳)
  • primitive聚合(性能佳)
  • 点位动态弹窗
  1. 第三方服务加载
  • xyz瓦片
  • 3D Tiles
  1. 材质
  • 道路闪烁
  • 道路流光效果
  • 辐射圈
  • 圆扩散
  • 四色图
  • 流动的水面
  • 天空盒
  1. 几何
  • 量测
  • 点线面绘制
  • 态势图、箭头
  1. 场景
  • 水淹模拟
  • 热力图
  • 时间轴
  • 遮罩反选(边界)
  1. 分析
  • 天际线分析
  • 高程(限高)分析

其中primitive聚合这个解决方案还被知名开源项目vue-cesium所收纳!

这个开源我目前还没用过,因为我用Cesium比较少,不过看项目里场景效果覆盖的已经很全了,用需要的小伙伴可以用用试试,也欢迎给我反馈。

项目中还封装了一些公共的类以及方法,例如:绘制测量天气类聚合类等等,方便重复使用。

项目初始化

几个关键点:

  • cesium token:必须要有,到cesium官网申请,项目跑起来需要用到的
  • viewer:视角,3D场景中必备
  • 根元素:初始化canvas要用到的根元素
js 复制代码
import { onMounted } from "vue";
import store from "@/store/store.js";
import * as Cesium from "cesium";

// cesium的token,可自行申请
Cesium.Ion.defaultAccessToken =
  "xxx";

onMounted(() => {
  init();
});
const init = () => {
  const viewer = new Cesium.Viewer("cesiumContainer", {
    infoBox: false,
    timeline: false, // 是否显示时间线控件
    // 图层插件
    imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
      url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
    }),
    // 地形插件
    terrainProvider: new Cesium.CesiumTerrainProvider({
      url: "http://data.marsgis.cn/terrain",
    }),
  });

相机

3D场景中必备的相机,当你在上一步初始化成功viewer之后,就可以在viewer中拿到相机实例了。

js 复制代码
const store = useStore()
const { viewer } = store.state


viewer.camera.flyTo({
  // 从以度为单位的经度和纬度值返回笛卡尔3位置。
  destination: Cesium.Cartesian3.fromDegrees(120.36, 36.09, 40000),
  orientation: {
    // heading:默认方向为正北,正角度为向东旋转,即水平旋转,也叫偏航角。
    // pitch:默认角度为-90,即朝向地面,正角度在平面之上,负角度为平面下,即上下旋转,也叫俯仰角。
    // roll:默认旋转角度为0,左右旋转,正角度向右,负角度向左,也叫翻滚角
    heading: Cesium.Math.toRadians(0.0), // 正东,默认北
    pitch: Cesium.Math.toRadians(-90), // 向正下方看
    roll: 0.0, // 左右
  },
  duration: 3, // 飞行时间(s)
})

几何图形

在3D场景中,每一个元素小品实例都是由几何元素所构成渲染的,例如:线等。

聚合打点

这个需求其实应该在大部分业务项目中都会遇到,属于一个高频知识点,但是在碰到上万甚至是上十万的点位进行聚合的时候,我发现极大一部分人都会遇到性能上的问题,官方貌似并没有出手解决这个问题,而且我之前在网上找解决方案也很难找到。

后来我就自己倒腾了好几天,终于研发出一个还不错的解决方案。

其实官方是有现成的entity聚合类的:EntityCluster,但是这个类在碰到大批量点位的时候,性能卡的一批,因为entity是基于primitive的一个封装,而primitive才是底层的几何类,它的性能才是最优的。

因此我就按照这个思路,心想能不能仿照EntityCluster的源码以及它的算法:KDBush,去构建一个primitiveCluster大类呢,功夫不负有心人,最终还真让我实现了,在项目的src\utils\cesiumCtrl\primitiveCluster.js里。

但是我发现虽然封装好了这个类,但是还是有很多人不会用,所以怎么用也是个技术活哈哈。

js 复制代码
const billboardsCollection = viewer.scene.primitives.add(
  new Cesium.BillboardCollection()
);
let billboardsCollectionCombine = new Cesium.BillboardCollection();

let primitivesCollection = null;
let primitives = null;

const formatClusterPoint = (features) => {
  primitivesCollection = new Cesium.PrimitiveCollection();
  billboardsCollectionCombine = new Cesium.BillboardCollection();
  var scene = viewer.scene;
  let primitivecluster = null;
  primitivecluster = new PrimitiveCluster();

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

  //后面设置聚合的距离及聚合后的图标颜色显示与官方案例一样
  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],
      2000
    );

    // 带图片的点
    billboardsCollectionCombine.add({
      image: "/images/mark-icon.png",
      width: 32,
      height: 32,
      position,
    });
  }
  primitivecluster._billboardCollection = billboardsCollectionCombine;
  // 同时在赋值时调用_initialize方法
  primitivecluster._initialize(scene);

  primitivesCollection.add(primitivecluster);
  primitives = viewer.scene.primitives.add(primitivesCollection);

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

有了这个类,就再也不怕大批量点位渲染卡顿的烦恼啦!

项目思考

其实别看cesium也是一个js框架,但是说实话,对一个没接触过三维的或者GIS方向的前端(比如我)来说,上手还是有一定难度的,因为它里面包含了太多的专业知识需要我们去一一攻坚。

并且,cesium封装了大量的类,毛估大概有几百个!一开始看到密密麻麻的API的时候,头瞬间就大了一圈。

而且,如果想要更好地运用 CesiumJS,不止要会一些三维的知识,学习一定的地理信息系统(GIS)知识也是有一定必要的。例如:

  1. 地理坐标系统:了解地理坐标系统(如 WGS 84、GCS、PCS 等)的基本概念和区别,以及如何在 CesiumJS 中正确设置和转换坐标系统。

  2. 地图投影:理解地图投影的原理和不同类型的地图投影(如墨卡托投影、Web墨卡托投影等),以及它们如何在 CesiumJS 中应用。

  3. 地理数据格式:熟悉常见的地理数据格式,如 GeoJSON、KML、GPX、Shapefile 等,以及如何在 CesiumJS 中加载和处理这些数据格式。

  4. 矢量数据和栅格数据:了解矢量数据(如点、线、面)和栅格数据(如卫星图像、地形数据)的区别及其在 CesiumJS 中的应用方式。

  5. 空间分析:掌握基本的空间分析概念,如缓冲区分析、叠加分析、网络分析等,这有助于你在 CesiumJS 中进行更复杂的地理信息处理。

  6. 地图符号化:理解如何在 CesiumJS 中对地图元素进行符号化,包括设置样式、颜色、图标等,以提高地图的可读性和美观性。

  7. 图层管理:了解如何在 CesiumJS 中管理和操作图层,包括添加、移除、显示和隐藏图层,以及调整图层顺序和透明度。

  8. API 和 SDK 使用:熟悉 CesiumJS 提供的 API 和 SDK,了解如何使用它们来定制地图功能和创建交互式应用。

  9. 性能优化:掌握一些性能优化的技巧,如数据简化、级别细节(LOD)、视锥体剔除等,以确保 CesiumJS 应用在不同设备上都能流畅运行。

  10. 三维建模和动画:了解基本的三维建模和动画原理,这可以帮助你在 CesiumJS 中创建更丰富的三维场景和动画效果。

  11. 实时数据集成:了解如何将实时数据(如传感器数据、社交媒体信息等)集成到 CesiumJS 应用中,以提供动态更新的地理信息服务。

最后

这个项目我已开源,也欢迎感兴趣的小伙伴能够加入进来,一起参与共建(目前还是有一定的star基础的🤭)

开源地址:github.com/tingyuxuan2...

如果觉得项目对你有帮助,希望可以随手点一个star,激励我去开源更多优秀的代码。

如果有在做数字孪生或者GIS方面的同学也可以加我交流:brown_7778,我拉你进交流群。

如果觉得文章对你有帮助,也欢迎一键三连👏👏👏,你的鼓励是支持我持续原创下去的动力~

相关推荐
SafePloy安策6 小时前
ES信息防泄漏:策略与实践
大数据·elasticsearch·开源
学编程的小程7 小时前
【安全通信】告别信息泄露:搭建你的开源视频聊天系统briefing
安全·开源·音视频
问道飞鱼7 小时前
【微服务知识】开源RPC框架Dubbo入门介绍
微服务·rpc·开源·dubbo
customer0812 小时前
【开源免费】基于SpringBoot+Vue.JS课程答疑系统(JAVA毕业设计)
java·jvm·vue.js·spring boot·spring cloud·kafka·开源
多客软件佳佳13 小时前
校园交友系统的设计与实现(开源版+三端交付+搭建+售后)
小程序·前端框架·uni-app·开源·php·交友
智方科技13 小时前
3DTiles之使用customShader调整风格
3d·智慧城市·cesium
山海鲸可视化15 小时前
GIS融合之路(八)-如何用Cesium直接加载OSGB文件(不用转换成3dtiles)
3d·gis·数字孪生·cesium·倾斜摄影·osgb
OpenTiny社区15 小时前
重磅更新!Fluent Editor 开源富文本支持 LaTeX 可编辑公式啦~
前端·ui·开源·opentiny
小牛itbull16 小时前
ReactPress 安装指南:从 MySQL 安装到项目启动
前端·javascript·数据库·mysql·react.js·开源·reactpress
蜜桃小阿雯17 小时前
JAVA开源项目 微服务在线教育系统 计算机毕业设计
java·开发语言·spring boot·微服务·java-ee·开源·maven