cesium解决画点只显示一半的问题


Cesium实战系列文章总目录传送门

1.背景

在鼠标拾取点击位置坐标,并添加到图上显示的时候,发现点只能显示一半,另一半被压盖,如下图:
在这里插入图片描述
此时的核心函数代码为:

/**
 * @description: 获取当前鼠标点击位置坐标,并添加到图上显示
 * @param {*} _viewer
 * @return {*}
 */
function getClickPointAdd(_viewer) {
    // 注册屏幕点击事件
    let handler = new Cesium.ScreenSpaceEventHandler(_viewer.scene.canvas);
    handler.setInputAction(function(event) {
        // 转换为不包含地形的笛卡尔坐标
        let clickPosition = _viewer.scene.camera.pickEllipsoid(event.position);
        // 转经纬度(弧度)坐标
        let radiansPos = Cesium.Cartographic.fromCartesian(clickPosition);
        // 转角度
        console.log("经度:" + Cesium.Math.toDegrees(radiansPos.longitude) + ", 纬度:" + Cesium.Math.toDegrees(radiansPos.latitude));

        // 添加点
        _viewer.entities.add({
            position: clickPosition,
            point: {
                color: Cesium.Color.YELLOW,
                pixelSize: 30,
            }
        })
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}

2.解决方法

2.1设置圆点深度检测阈值

Cesium的PointGraphics中提供了disableDepthTestDistance方法来设置圆的深度检测阈值:传送门
在这里插入图片描述即需要通过设置相机到圆要素的距离阈值来判断是否开启深度检测,这里设置为1000.0米。

disableDepthTestDistance: 1000.0,

当相机与要素距离小于阈值是,此时结果为:
在这里插入图片描述但是当相机距离超过阈值时,就会开启深度检测,圆还是会只显示一半

将阈值设置为无穷大时:

disableDepthTestDistance: Number.POSITIVE_INFINITY,

虽然无论相机距离远近,圆都可以正常显示,但是没有圆的深度检测,不同要素之间的遮挡无法得到有效判断,有的在建筑物后的点会在建筑物前显示,造成视觉误差与干扰。

2.2设置圆点的高度

为圆要素设置一定的高度,抬伸显示。拉伸的高度与圆符号的大小有关,才能避免被遮挡只显示一半。

position:Cesium.Cartesian3.fromDegrees(lon, lat, height);

但是此时点具有高度,飘在空中,无法准确表达地面坐标,存在一定的视觉干扰;且当相机距离较远时,还是会出现只显示一半的情况。

2.3关闭viewer的深度检测

默认状态下深度检测是关闭的,需要手动开启。

// 关闭深度检测
viewer.scene.globe.depthTestAgainstTerrain = false;

虽然可以用,但是关闭深度检测,会无法有效判断物体的前后关系,而判断是否被遮挡

3.总结

添加圆只能显示一半是因为深度检测过程,物体因为前后位置关系产生的遮挡所导致的。

但直接关闭深度检测,会影响遮挡判断,这里本人使用的方法是将圆拉伸至一定高度显示。

4.参考

参考1:传送门

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用Cesium画点并添加弹框的步骤如下: 1. 首先,您需要在Vue项目中安装Cesium和vite-plugin-cesium插件。在vite.config.ts文件中,配置插件和别名,以便正确加载Cesium库。 2. 在Vue组件中,引入Cesium并创建一个Viewer实例。您可以使用Cesium.CesiumWidget构造函数来创建一个具有默认属性的Viewer。 3. 创建一个Entity实例,并设置其位置以及其他属性。您可以使用Cesium.Cartesian3来定义点的位置。 4. 为Entity添加描述信息,可以使用Entity.description属性。您可以在描述中使用HTML标签和CSS样式来自定义弹框的内容。 5. 监听鼠标单击事件,获取点击屏幕位置,使用Cesium.SceneTransforms.wgs84ToWindowCoordinates将Cartesian坐标转换为屏幕坐标。 6. 动态设置弹出框的位置,通过计算弹出框的宽高和实时位置来确定其在屏幕上的位置。 下面是一个示例代码片段,展示了使用Cesium画点并添加弹框的过程: ```javascript // 在Vue组件中 import * as Cesium from 'cesium'; export default { mounted() { // 创建Cesium Viewer实例 const viewer = new Cesium.Viewer(this.$refs.cesiumContainer, { // 设置其他属性 }); // 创建Entity实例 const entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(经度, 纬度), // 设置点的位置 point: { pixelSize: 10, color: Cesium.Color.YELLOW, }, description: '<div>弹框的内容</div>', // 设置弹框的内容 }); // 监听鼠标单击事件 viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(event) { const position = event.position; const cartesian = viewer.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid); const windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian); // 根据windowPosition设置弹出框的位置 }, Cesium.ScreenSpaceEventType.LEFT_CLICK); }, }; ``` 请根据您的具体需求和项目设置,进行适当的调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

右弦GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值