news 2026/9/11 9:20:23

CesiumJS 地下场景可视化:管线展示、切剖查看与点击查询

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CesiumJS 地下场景可视化:管线展示、切剖查看与点击查询

CesiumJS 地下场景可视化:管线展示、切剖查看与点击查询

【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium

当管线数据需要在地面以下呈现时,核心矛盾只有一条深度线:哪些像素在前、哪些在后。CesiumJS 是基于 WebGL 的三维地球引擎,提供地形、3D Tiles 与深度测试控制,用于搭建 Cesium 地下场景并完成管线三维展示。本文用三个子任务走通一条地下管网的完整流程。

能力边界:地下可视化能做什么、不能做什么

CesiumJS 的渲染走 WebGL 光栅化管线,场景里所有图层共用一张深度缓冲。这意味着地下物体与地表地形的遮挡关系不是"贴"上去的特效,而是由深度值自动裁决的。具体能力:

  • 地形按高程瓦片加载,地表会正确遮挡地面以下的几何体,这是深度测试的默认行为;
  • 3D Tiles 支持显式开启depthTestAgainstTerrain,让地下对象参与地形深度测试,切剖后的管线不会浮在切面上;
  • 实体支持HeightReference.BELOW_GROUND,点、标注可以直接沉到地表之下;
  • 裁剪区域与裁剪平面可切掉部分地表或模型,露出地下结构;
  • 拾取与元数据查询可以定位到单个管线特征。

局限同样直白:它是光栅化引擎,不是 BIM 内核。十万级管线、带完整材质的大体量城市模型会撞上帧率上限;地层剖面、地质建模它一概不管,属于数据生产侧的工作,引擎只负责把已经算好的几何画出来。

任务实战:搭出一个地下管网场景

先建场景,并把相机行为调到适合地下的参数。

const viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider: Cesium.createWorldTerrain(), baseLayerPicker: false, geocoder: false, sceneModePicker: false, homeButton: false }); // 关掉碰撞检测,相机才能穿过地表进入地下 viewer.scene.screenSpaceCameraController.enableCollisionDetection = false; viewer.scene.globe.depthTestAgainstTerrain = true;

enableCollisionDetection = false让鼠标拖动不再被地形顶住,相机能直接穿到地表之下;globe.depthTestAgainstTerrain = true让地表参与深度测试,地面正确挡住地下的物体。

加载管线与地质数据:用 3D Tiles 让引擎管 LOD。

const tileset = viewer.scene.primitives.add( new Cesium.Cesium3DTileset({ url: 'data/pipeline-network/tileset.json', depthTest: true, depthTestAgainstTerrain: true }) ); // 地质剖面用实体画在地面以下 viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(116.4, 39.9, -15), box: { dimensions: Cesium.Cartesian3.fromElements(300, 4, 300) }, heightReference: Cesium.HeightReference.BELOW_GROUND, material: Cesium.Color.rgb(255, 180, 0).withAlpha(0.35) });

depthTestAgainstTerrain: true是关键:地形被切剖后,切面下方的管线会被切面正确遮挡,而不是整条管线"浮"在剖面上。此时深度测试已经在替你处理"谁在前谁在后",不需要任何手工排序。3D Tiles 还按距离和视锥自动切换瓦片细节等级,远处瓦片降精度、近处瓦片高细节,这一层 LOD 引擎内置,不用自己写。

加点击查询:选中一条管线就查它。

viewer.screenSpaceEventHandler.setInputAction(function (movement) { const picked = viewer.scene.pick(movement.position); if (!Cesium.defined(picked) || !picked.id) { return; } const entity = picked.id; console.log('选中对象:', entity.name, '材质:', entity.propertyBag?.material ?? '未标注'); viewer.zoomTo(entity); }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

scene.pick返回深度最靠前的对象,propertyBag里放管线台账字段(材质、管径、埋深),命中后直接打印或回填到查询面板。如果管线特征带元数据,可以用tileset.metadata的属性表达式做条件着色与筛选,比全量实体拾取省内存。

性能技巧:问题、手段与效果

问题手段效果
城市级管线一次全量加载数据切成 3D Tiles 瓦片,交给引擎按距离、视锥调度只有视口附近的瓦片驻留显存,内存随视角伸缩
阀门、井盖等大量重复小构件用 3D Tiles 实例化或合并几何,减少 draw call绘制调用显著减少,帧率更稳
多层管线同深度叠加、画面闪烁用裁剪区域切剖展示,代替同层叠加避免深度冲突,画面稳定
二进打开场景加载慢依赖瓦片 HTTP 缓存,首访后走缓存二次打开明显变快

常见误区

  • 以为地下不可见是材质问题。实际是浮点深度精度有限:地形面与管线在同一深度带时,深度缓冲区分不了两者,表现为闪烁。处理上不要用同层叠加,改用裁剪区域切掉一块地表做剖视,或者让不同埋深的管线各占一个深度带。
  • 把所有管线塞进一个数据源全量加载。内存膨胀、渲染线程卡死。按 3D Tiles 切瓦片,引擎自动管理细节等级;自建几何也要按区域分块,进入视口才加入场景。
  • 对碰撞检测一刀切。开着它,相机贴着地形时根本进不去地下;关掉后相机又能穿到球体内部出不来。地下场景通常关掉它,再用scene.maximumCameraHeight之类参数把上界收住。
  • tileset.show做筛选。全量开关不解决"选中哪几根管线"的问题。正确做法是用元数据属性表达式过滤和着色,或者把常变的管线状态放到独立的轻量数据源里。

下一步

官方 API 文档见 Documentation/,其中裁剪、3D Tiles 元数据等条目与本文流程直接对应。可运行的同类示例在 Sandcastle 示例库 里,重点看 clipping-regions(裁剪地表切剖)、splitdirection(分屏对比视角)与 3d-tiles 系列(元数据筛选、深度测试)。数据侧再往深走,可以把管线台账接入 3D Tiles 的 metadata 字段,让筛选、统计和着色都走元数据表达式,而不是维护大量实体。

【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 9:20:21

InfluxDB数据同步到Doris:基于SeaTunnel的完整落地实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 9:20:03

Linux内存管理:kswapd原理与性能优化实战

1. Linux内存管理基础与kswapd角色定位在Linux系统中,内存管理是内核最核心的功能之一。当物理内存不足时,系统需要通过页面回收机制释放内存,这就是kswapd守护进程的核心职责。与直接内存回收(direct reclaim)不同&am…

作者头像 李华
网站建设 2026/9/11 9:14:07

如何查找空白符号、查看Unicode编码

适用情况示例: 游戏(如王者荣耀)中ID被占用,可以添加一个空白符号无痛重名 让微信朋友圈的分隔符显得更高级(? 网上找的符号太容易重复、看不懂、复制别人的不知道到底复制了个什么东西? 这篇文…

作者头像 李华
网站建设 2026/9/11 9:13:36

UART传输时间精确计算:从7N1到115200波特率的实操指南

1. 这不是“背公式”问题,而是搞懂UART时序本质的实操门槛你手头正调试一块STM32开发板,串口打印突然卡顿;或者用FT231X转USB调试ESP32,发现发出去的JSON字符串总在第7个字节后被截断;又或者在Linux下用stty配置串口&a…

作者头像 李华