在 Cesium 中,如果你想在实体(Entity)上实现鼠标右击(右键点击)的处理,你需要使用 Cesium 的事件系统来监听鼠标事件,并结合一些逻辑来判断点击是否发生在实体上。由于 Cesium 没有直接提供"点击实体"的事件,你需要自己实现这个逻辑。
以下是一个基本的步骤和示例代码,用于在 Cesium 中实现鼠标右击实体时的处理:
- 监听全局的鼠标右击事件 :使用 Cesium 的
ScreenSpaceEventHandler
来监听鼠标右击事件。 - 判断点击位置是否位于实体上 :这通常涉及到射线投射(ray-casting)或其他形式的拾取(picking)技术。Cesium 提供了
Scene.pick
方法,它可以用于获取在指定位置上的对象。 - 执行处理逻辑:如果点击位置上有实体,执行相应的处理逻辑。
示例代码:
javascript
var viewer = new Cesium.Viewer('cesiumContainer');
// 创建一个 ScreenSpaceEventHandler 实例来监听鼠标事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 监听右键点击事件
handler.setInputAction(function(click) {
// 使用 pick 方法获取点击位置上的对象
var pickedObject = viewer.scene.pick(click.position);
// 检查 pickedObject 是否是 Entity 或与 Entity 相关的对象(如 Primitive)
// 注意:直接 pick 可能不会直接返回 Entity,而可能是与 Entity 相关的其他对象
// 你可能需要遍历 EntityCollection 或使用其他方法来确认点击的 Entity
if (pickedObject && /* 这里添加你的逻辑来判断 pickedObject 是否是你关心的 Entity */) {
// 执行你的处理逻辑
console.log('Right-clicked on an entity!');
// 例如:显示一个提示框、改变实体的颜色等
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
注意:
- 直接使用
pick
方法可能不会直接返回 Entity 对象。它可能会返回与 Entity 相关的其他对象,如 Primitive、Geometry 等。你可能需要遍历你的 EntityCollection 或使用其他方法来确认点击的 Entity。 - 如果你的 Entity 使用了 Billboard、Label 或其他不直接参与射线投射的可视化元素,那么你可能需要使用其他方法来检测点击,如检查鼠标位置是否在 Billboard 的边界框内。
- 你可以使用 Cesium 的其他事件(如鼠标移动、左键点击等)来增强你的交互体验。
例:要在Cesium三维地图上点击某个点,在该点加一个自定义图标的实体,并且鼠标右击这个实体时,我要做一些操作。添加一个自定义图标的实体,并为该实体添加一个myData自定义数据,后面根据这个数据做是否点击该实体的判断。
javascript
// 点击地图,添加一个自定义实体
function clickCesiumMapAddEntities() {
let ellipsoid = window.viewer.scene.globe.ellipsoid;
dropHandler = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
dropHandler.setInputAction((move) => {
let cartesian = window.viewer.camera.pickEllipsoid(move.position, ellipsoid);
if (cartesian) {
// 苗卡尔椭球体的三维坐标 转 地图坐标(弧度)
let cartographic = window.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
// 地图坐标(弧度) 转 十进制度数 toFixed保留小数点后几位
let lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);//拿到经度
let lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(8);//拿到纬度
//自动获取模型高度
let position = window.viewer.scene.pickPosition(move.position);
//如果对象已定义,将度转为经纬度
let lableHeight = Cesium.Cartographic.fromCartesian(position);
let height = lableHeight.height.toFixed(2);//模型高度
addBillboardEntities(lon,lat,height)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
function addBillboardEntities(lon,lat,height){
let myEntities = window.viewer.entities.add({
name: 'myEntities',
//给初始点位设置一定的离地高度,否者会被压盖
position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
billboard: {
image: baseUrlIcon, // 图片服务器完整的图片地址 如:static/images/mybaseUrlIcon.img
width: 60,
height: 60,
},
myData: {
name: 'myEntities',
lon: lon,
lat: lat,
},
})
// 添加完实体,左键监听事件,判断点击的实体
let handler = new Cesium.ScreenSpaceEventHandler(window.viewer.scene.canvas);
handler.setInputAction(function (movement) {
var picked = window.viewer.scene.pick(movement.position)
if (Cesium.defined(picked) && picked.id.id) {
if (!picked.id.myData) return;
// myData就是我们在添加实体时,自己添加的自定义标识,在这里我们就可以做自己的事情了
console.log('我当前点击的是那个实体:',picked.id.myData)
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
删除某个实体 window.viewer.entities.remove(entitys[i]);
删除所有实体:window.viewer.entities.removeAll();
拿到当前已添加所有的实体window.viewer.entities._entities._array;