【Cesium】十、Cesium画点只有一半的问题,亲测有用

一、前言

上一篇文章 【Cesium】九、Cesium点击地图获取点击位置的坐标,虽然在地图上添加了图标,但是只有一半,本片文章 学习如何解决。

本文参考文章:
cesium解决画点只显示一半的问题
cesium 点只显示一半

在这里插入图片描述

二、解决方法

参考的文章中共提到三种方法,我这边只实现了两种,第二种方法不知道加在哪里。

第一种:关闭深度检测(圆点自身的)

使用disableDepthTestDistance: Number.POSITIVE_INFINITY,

圆点完全都在地上了

存在问题:

图中间的小圆点实际在建筑的后面,但是,还是却显示在建筑的前面

这是关闭深度检测的必然结果!

在这里插入图片描述

参考代码:

添加代码:disableDepthTestDistance: Number.POSITIVE_INFINITY,

添加后代码:

viewer.entities.add({
    
    
  position: clickPosition,
  point: {
    
    
    disableDepthTestDistance: Number.POSITIVE_INFINITY,
    color: Cesium.Color.YELLOW,
    pixelSize: 30
  }

第二种:抬升高度 (该方法 我没有实现)

下述语句中输入高度值

let position = Cesium.Cartesian3.fromDegrees(x, y, 10);

相关解释:

position中的10,代表圆点的高度,单位是“米”(从圆点的中心抬高10米)

pixelSize中的5,代表圆点的像素大小,单位是“像素”(5代表直径?)

圆不被遮挡的条件:只有position中的高度,比pixelSize换算成米的数值大

在不同的camera高度下,一个像素代表的实际高度(单位为米),是不一样的

camera越高,一个像素换算成米,就越大

camera越低,一个像素换算成米,就越小

存在问题:

position中的height比较小:camera高的时候,小圆点还是有可能有一部分在地球下面

在这里插入图片描述

position中的height比较大:camera低的时候,点会显得离地面很远

在这里插入图片描述

第三种:关闭深度检测(系统整体的)

执行下述代码,关闭深度检测

viewer.scene.globe.depthTestAgainstTerrain = false;

这个完美解决了,那么关闭系统整体的深度检测会导致哪些问题呢?

请教别人,他说会导致一个问题:地下的物体会被看到。

App.vue

App.vue 完整代码仅供参考:

<template>
  <div id="cesiumContainer"></div>
</template>
<script setup>
import {
    
     onMounted, reactive, ref } from "vue";
import * as Cesium from "cesium";
const initFn = async () => {
    
    
  const viewer = new Cesium.Viewer("cesiumContainer", {
    
    
    infoBox: false,
    geocoder: false,
    homeButton: false,
    sceneModePicker: false,
    baseLayerPicker: true,
    navigationHelpButton: false,
    animation: false,
    timeline: false,
    fullscreenButton: false,
    vrButton: false,
  });

  // 将 viewer 暴露到全局
  window.viewer = viewer;

  viewer._cesiumWidget._creditContainer.style.display = "none"; //取消版权信息


  viewer.scene.globe.depthTestAgainstTerrain = true;
  // 创建一个事件处理器来处理屏幕空间事件
  var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
  // 监听鼠标点击事件
  handler.setInputAction(function (click) {
    
    
    // 使用pick函数获取点击位置的实际位置
    var cartesian = viewer.scene.pickPosition(click.position);
    if (Cesium.defined(cartesian)) {
    
    
      // 将笛卡尔坐标转换为经纬度坐标
      var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      var longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
      var latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
      var heightString = cartographic.height.toFixed(2);
      console.log('经度:' + longitudeString + ',纬度:' + latitudeString + ',高度:' + heightString)

      // 添加点
      let clickPosition = viewer.scene.camera.pickEllipsoid(click.position);
      viewer.entities.add({
    
    
        position: clickPosition,
        point: {
    
    
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          color: Cesium.Color.YELLOW,
          pixelSize: 30
        }
      })
    }
    // 使用Scene.pick来获取3D Tiles的实际高度
    var pickedObject = viewer.scene.pick(click.position);
    if (Cesium.defined(pickedObject)) {
    
    
      // 获取到3D Tiles的高度
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      const height = cartographic.height;

      const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
      const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
      console.log('点击位置的经度是: ' + lon);
      console.log('点击位置的纬度是: ' + lat);
      console.log('点击位置的高度是: ' + height);
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

};



onMounted(() => {
    
    
  // Cesium 初始化
  initFn();
});
</script>
<style>
#app {
      
      
  width: 100%;
  height: 100%;
  font-family: sans-serif;
  text-align: center;
}

html,
body,
#cesiumContainer {
      
      
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
</style>

后面我还会更新更多关于cesium知识,敬请关注。