CESIUM例子学习(九)——Primitive(1)

本文详细介绍了如何使用Cesium中的Primitive进行三维地理信息的绘制,包括BoxGeometry、BoxOutlineGeometry和RectangleGeometry的创建方法及参数设置,帮助读者掌握更高级的Cesium绘图技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习Primitive前,首先感谢GISEarth大神的https://blog.youkuaiyun.com/happyduoduo1/article/details/51868042这篇博文。下面的Cesium支持的几何图形,是直接从他的博文中截图的,再次感谢。

cesium加载数据方式多种多样,一般用entity、dataSources和Primitive。其中entity是最高级的,基本上是统一的使用样式,比较容易上手。之前学习过程中都是用entity,今天学习一下Primitive加载。

在看CESIUM的materials例子时,看着看着就有点懵逼了,先看看下面代码:

 geometry: new Cesium.RectangleGeometry({
          rectangle: Cesium.Rectangle.fromDegrees(
            -120.0,
            20.0,
            -60.0,
            40.0
          ),
          vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
        }),
      })

上面的代码是RectangleGeometry创建一个矩形要素,问题来了:我怎么知道Cesium可以创建哪些要素啊?是不是有PointGeometry这个类呢?从哪里可以知道cesium支持什么要素呢?可以自定义要素吗?GISEarth大神早知道了小白我的心声。下面是Cesium支持的几何图形:

有了可以创建要素的接口,就放心多了。

一、Primitive参数

Primitive中常用参数可能有:

geometryInstances,它是Primitive最基本的要素之一,定义了绘制要素的几何形状;

appearance:几何要素显示出来的外观;

modelMatrix:几何形状的4元素变换矩阵。可提供绘制要素位置并对其进行旋转、平移、缩放等操作。

show:是否渲染。

二、绘制BoxGeometry(盒子)与BoxOutlineGeometry

BoxGeometry绘制代码如下:

var material = Cesium.Material.fromType('Color');
material.uniforms.color = new Cesium.Color(1.0, 1.0, 1.0, 0.3);//白色透明度0.3
var center = Cesium.Cartesian3.fromDegrees(107.941991, 26.917029, 18000)
var dimensions = new Cesium.Cartesian3(19000.0, 9000.0, 3000.0)//盒子的长、宽、高
function addBoxGeometry () {
    var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
    var hprRotation = Cesium.Matrix3.fromHeadingPitchRoll(
        new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(90), 0.0, 0.0)// 中心点水平旋转90度
    );
    var hpr = Cesium.Matrix4.fromRotationTranslation(
        hprRotation,
        new Cesium.Cartesian3(0.0, 0.0, 0.0)// 不平移
    );
    Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix);
    viewer.scene.primitives.add(
        new Cesium.Primitive({
            geometryInstances: new Cesium.GeometryInstance({
                geometry: Cesium.BoxGeometry.fromDimensions({
                    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
                    dimensions: dimensions,
                }),
                modelMatrix: modelMatrix,提供位置与姿态参数
                id: "BoxGeometry"
            }),
            appearance: new Cesium.EllipsoidSurfaceAppearance({
                aboveGround: false,
                material: material
            })
        })
    );
}

绘制结果如下图,其中红色盒子和中心点是entity加载。

绘制BoxOutlineGeometry只是把

// geometry: Cesium.BoxGeometry.fromDimensions //改成
 geometry: Cesium.BoxOutlineGeometry.fromDimensions

即可绘制盒子的边线。如下图:

三、绘制RectangleGeometry(矩形)

在用entity加载绘制的矩形时,可以设置矩形帖地或设置矩形离地高度,在用Primitive加载矩形同样需要设置。否则可能出现下面情况,如图:

RectangleGeometry绘制代码如下:

function addRectangleGeometry () {
    let rectangle = Cesium.Rectangle.fromDegrees(
        107.941991, 25.917029,
        118.941991, 28.917029,
    )
    console.log(rectangle.height)
    let geometryInstances = new Cesium.GeometryInstance({
        geometry: new Cesium.RectangleGeometry({
            rectangle: rectangle,
            vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
            height: 120000,矩形离椭球体的高度
        }),
    })
    viewer.scene.primitives.add(
        new Cesium.Primitive({
            geometryInstances: geometryInstances,
            appearance: new Cesium.EllipsoidSurfaceAppearance({
                aboveGround: false,
                material: material
            })
        })
    );
}

 

### 正确销毁 Cesium 资源或实例 在 Vue 开发单页应用 (SPA) 中,当使用 Cesium 进行地理空间数据可视化时,确保正确销毁资源对于防止内存泄漏至关重要。由于 `keep-alive` 组件的存在使得 `beforeDestroy` 生命周期钩子未能正常工作,这可能导致 Cesium 实例无法被适当清理[^1]。 为了有效管理 Cesium 的生命周期并避免潜在的渲染错误和性能问题,可以采取以下策略: #### 手动调用 destroy 方法 Cesium 提供了一个内置方法来释放其占用的 GPU 和 CPU 资源——即 `viewer.destroy()` 函数。此函数不仅会移除 DOM 元素中的 Canvas,还会清除所有关联的对象及其监听器,从而彻底终止 Cesium Viewer 的运行状态。 ```javascript // 假设 viewer 是已经创建好的 Cesium.Viewer 对象 if (typeof this.viewer !== 'undefined') { this.viewer.destroy(); } ``` 通过这种方式可以在不再需要 Cesium 地图视图的情况下主动触发销毁操作,比如导航离开当前页面之前执行上述代码片段即可实现预期效果。 #### 利用事件监听机制 考虑到 SPA 应用的特点,在路由变化时应当及时处理好各个模块之间的衔接关系。因此可以通过侦听 `$route` 变更事件来进行针对性的操作,如下面的例子所示: ```javascript watch: { '$route'() { // 当路径发生改变时尝试销毁旧的地图实例 if (this.viewer && !this.$route.meta.keepAlive) { this.viewer.destroy(); delete this.viewer; } } }, destroyed(){ // 额外的安全措施以确保组件完全卸载时也能够清理残留对象 if(this.viewer){ this.viewer.destroy(); delete this.viewer; } } ``` 以上方式能够在每次切换至非持久化页面(未设置 `meta.keepAlive=true` 属性)时自动回收不必要的图形资源,减少因重复初始化带来的额外开销以及可能引发的兼容性问题[^2]。 #### 初始化与销毁场景的最佳实践 除了简单的调用 `destroy()` 外,还应该注意按照官方文档推荐的方式去构建和配置 Cesium 环境。例如,在初始化阶段应尽可能早地引入必要的依赖项和服务;而在结束服务前,则要确认所有的异步请求都已经完成,并且没有任何活动的任务正在等待响应[^3]。 ```javascript mounted () { const container = document.getElementById('cesiumContainer'); // 创建一个新的Viewer实例... } beforeRouteLeave(to, from, next) { if (this.viewer) { this.viewer.entities.removeAll(); // 清理实体集合 this.viewer.scene.primitives.remove(primitive); // 移除原始几何体 this.viewer.imageryLayers.removeAll(true); // 删除影像图层 this.viewer.destroy(); // 销毁整个Viewer实例 next(); } else { next(); } } ``` 这种方法有助于维护良好的编程习惯,同时也提高了应用程序的整体稳定性和用户体验质量。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值