目录
viewer.scene.pick(e.position)?
viewer.scene.pickPosition(e.position)??场景坐标
viewer.scene.globe.pick(viewer.camera.getPickRay(e.position), viewer.scene))??地表坐标
?viewer.camera.pickEllipsoid(e.position)??世界坐标
鼠标点击点位置,有以下情形:
- 获取点击处屏幕坐标?
- 获取鼠标点的对应椭球面位置
- 获取加载地形后对应的经纬度和高程
- 获取倾斜摄影或模型点击处的坐标
<template>
<div id="cesiumContainer"></div>
</template>
<script setup>
import * as Cesium from "cesium";
import { onMounted } from "vue";
onMounted(() => {
const viewer = new Cesium.Viewer("cesiumContainer", {
infoBox: false, // 禁用沙箱,解决控制台报错
selectionIndicator: false, //选择指示器
});
viewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏logo版权
viewer.entities.add({
name: "点",
position: Cesium.Cartesian3.fromDegrees(-75.0, 30.0), //经纬度转世界坐标
point: {
show: true,
color: Cesium.Color.GREEN,
pixelSize: 20,
outlineColor: Cesium.Color.YELLOW,
outlineWidth: 3,
},
})
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((e) => {
console.log("e:", e);
// 通过屏幕坐标获取当前位置的实体信息
console.log("viewer.scene.pick(e.position):", viewer.scene.pick(e.position));//只有点击entity才不为undefined,否则就算点击地球也会是undefined
console.log("viewer.scene.pickPosition(e.position):", viewer.scene.pickPosition(e.position));
console.log("viewer.camera.pickEllipsoid(e.position):", viewer.camera.pickEllipsoid(e.position));
console.log("viewer.scene.globe.pick(viewer.camera.getPickRay(e.position), viewer.scene)):", viewer.scene.globe.pick(viewer.camera.getPickRay(e.position), viewer.scene));
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});
</script>
<style scoped>
#cesiumContainer {
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
其中,e.position中的x,y为屏幕坐标,屏幕左上角为原点
?
viewer.scene.pick(e.position)?
viewer.scene.pick (windowPosition,width , height ) →0bject?
拾取cesium场景中的空间对象,且返回最前面的一个空间对象,可以拾取entity实体,primitive图元,数据源datasource,3dtiles瓦片数据。
只有点击entity等实体才不为undefined,否则就算点击地球也会是undefined
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((e) => {
console.log("e:", e);
let pickedObject = viewer.scene.pick(e.position)
// 通过屏幕坐标获取当前位置的实体信息
console.log("viewer.scene.pick(e.position):", viewer.scene.pick(e.position));//只有点击entity才不为undefined,否则就算点击地球也会是undefined
if (!Cesium.defined(pickedObject)) {
console.log("没有拾取到空间对象")
return;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
viewer.scene.pickPosition(e.position)??场景坐标
- ? ? 获取场景里的点的经纬度(模型上的点)。相机看过去第一个被挡住的模型(如entity)上的坐标
- ? ? 可以采集entity,primitive,3dtile的坐标
- ? ? 当拾取区域无entity,primitive,3dtile时,将返回一个无法预料的坐标(标准椭球面以下,无法使用,无法预料)
- 只有在开启深度测试且不使用默认地形的情况下才是准确的,在未开启“地形深度检测”的情况下只能在3DTile上准确获取空间坐标
viewer.scene.pickPosition (windowPosition,result)→Cartesian3?
注意:获取到笛卡尔坐标存在不准确性:
1.在无地形的情况下,不开启深度测试,在地球上拾取是准确的;
2.在有地形的情况下,不开启深度测试,在地球上拾取是不准确的;因为存在深度问题,必须开启深度测试,即 viewer.scene.globe.depthTestAgainstTerrain = true。
总结:
pickPosition在depthTestAgainstTerrain=false 时只能在3DTile上获取准确位置
当depthTestAgainstTerrain=true 时,在3DTile和底图上均能获取准确位置
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((e) => {
console.log("e:", e);
let cartesian = viewer.scene.pickPosition(e.position);
console.log("cartesian:", cartesian);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
console.log("cartographic:", cartographic);
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
let alt = cartographic.height; // 高度
let coordinate = {
longitude: Number(lng.toFixed(6)),
latitude: Number(lat.toFixed(6)),
altitude: Number(alt.toFixed(2)),
};
console.log("coordinate:", coordinate);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
viewer.scene.globe.pick(viewer.camera.getPickRay(e.position), viewer.scene))??地表坐标
- 此方法无论是否存在地形,无论是否开启地形深度检测,获取与地形的笛卡尔坐标都是准确的,因为此方法只是与地形的求交,不包括模型、倾斜摄影表面?
- ? ? 获取地表面的点的经纬度(地形上的点)
- ? ? 将无视entity、3dtile,不能拾取其表面坐标
- ? ? 获取当前点击视线与地球表面相交的坐标(有无地形时候均可用,无地形时高程几乎为0)
?let ray = viewer.camera.getPickRay(e.position);
viewer.scene.globe.pick (ray,scene,result )?→Cartesian3
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((e) => {
console.log("e:", e);
let ray = viewer.camera.getPickRay(e.position);
console.log("ray:", ray);
let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
console.log("cartesian:", cartesian);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
console.log("cartographic:", cartographic);
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
let alt = cartographic.height; // 高度
let coordinate = {
longitude: Number(lng.toFixed(6)),
latitude: Number(lat.toFixed(6)),
altitude: Number(alt.toFixed(2)),
};
console.log("coordinate:", coordinate);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
viewer.camera.pickEllipsoid(e.position)??世界坐标
- ? ? 获取椭球上的点的经纬度(数学模型上的椭球)
- ? ? 获取当前点击视线与标准椭球面相交处的坐标,无高程(恒为0)
viewer.scene.camera.pickEllipsoid (windowPosition,ellipsoid , result ) →Cartesian3
pickEllipsoid 只用于无地形椭球面的获取坐标,不可用于加载地形场景。在加载地形的场景上获取的坐标不准确
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((e) => {
console.log("e:", e);
let cartesian = viewer.camera.pickEllipsoid(e.position);
console.log("cartesian:", cartesian);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
console.log("cartographic:", cartographic);
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
let alt = cartographic.height; // 高度,椭球面height永远等于0
let coordinate = {
longitude: Number(lng.toFixed(6)),
latitude: Number(lat.toFixed(6)),
altitude: Number(alt.toFixed(2)),
};
console.log("coordinate:", coordinate);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|