赞
踩
上一篇学习了创建实体的一些基础知识,但有时还需要我们使用鼠标进行手动绘制,这一篇就来进行鼠标绘制实体的实现(点,线,矩形,圆,多边形)。
(这里需要掌握三个知识点,一是上一篇中的创建实体、二是鼠标事件、三是回调函数)
既然是鼠标绘制,自然离不开鼠标事件,我们需要先简单了解一下cesium的鼠标事件。
这是Cesium中用于处理鼠标和触摸事件的主要类。需要创建一个此类的实例来开始事件监听。
let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(event => {
略
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
上述代码示例为Cesium的canvas创建了一个新的事件处理器。
LEFT_CLICK: 左键点击
RIGHT_CLICK: 右键点击
LEFT_DOUBLE_CLICK: 左键双击
RIGHT_DOUBLE_CLICK: 右键双击
MIDDLE_CLICK: 中键点击
MOUSE_MOVE: 鼠标移动
WHEEL: 鼠标滚轮滚动
使用 setInputAction 方法可以为特定的事件类型设置回调函数。
在回调函数中的 event 对象,包含与事件相关的数据。例如,对于鼠标点击事件,可以访问 event.position 来获取鼠标点击的屏幕坐标。
handler.setInputAction(function(event) {
console.log('鼠标左键点击位置::', event.position);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.destroy(); //永久性销毁事件处理器,之后它不能再被使用。
handler.removeInputAction(eventType); //仅移除特定事件类型的监听(如:handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);)
我们通过鼠标事件来获取位置信息,再通过回调函数进行属性值修改。
Cesium.CallbackProperty 是 Cesium.js 库中的一个特性,允许用户为属性提供一个回调函数,该函数描述了属性值如何随时间变化。这在需要动态或根据特定逻辑更改属性值的情况下特别有用,例如为实体的位置、颜色或其他属性设置动画效果。其实我们这里画线,画圆、画多边形等都是先创建不同的实体,然后根据鼠标事件获取位置坐标,动态改变其属性值,从而显示鼠标绘制的效果。
以下是 Cesium.CallbackProperty 的主要特点:
与其他静态属性不同,使用 CallbackProperty 创建的属性是动态的,它可以随时间或其它条件变化。
当需要获取属性值时,会调用提供的回调函数。这意味着每次 Cesium 请求属性值时,它都会执行这个函数。因此,你可以基于各种条件(例如当前时间)来计算和返回不同的值。
callback
:一个回调函数,当需要属性值时会被调用。这个函数通常接收两个参数:time 和 result。time 是一个 JulianDate 对象,表示当前时间;而 result 是一个可选的参数,用于存储结果,以避免不必要的对象创建。
isConstant
:一个布尔值,表示该属性是否是常数。即使属性是由回调函数定义的,也有可能总是返回相同的值。在这种情况下,可以将 isConstant 设置为 true。
请见“五、鼠标绘制圆”中绘制圆的代码说明。
允许用户点击地球的某个位置,然后在那个位置上添加一个红色的点,用户鼠标右击,结束绘制,并返回点位置。
/** * 绘制点 */ DrawPoints() { return new Promise((resolve, reject) => { let viewer = this.viewer; let drawnPoints = []; // 创建一个事件处理器 let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); // 注册鼠标左键点击事件,用于绘制点 handler.setInputAction(event => { // 获取鼠标点击的笛卡尔坐标(鼠标点击位置->笛卡尔坐标) var cartesian = this.getCatesian3FromPX(event.position); // 确保坐标有效 if (cartesian) { // 添加点实体 viewer.entities.add({ position: cartesian, point: { color: Cesium.Color.RED, pixelSize: 10 } }); // 获取地理坐标(经纬度) let cartographic = Cesium.Cartographic.fromCartesian(cartesian); let longitude = Cesium.Math.toDegrees(cartographic.longitude); let latitude = Cesium.Math.toDegrees(cartographic.latitude); let height=Cesium.Math.toDegrees(cartographic.height); // 将绘制的点添加到数组中 drawnPoints.push({ lng: longitude, lat: latitude,height:height }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 注册鼠标右键点击事件,用于结束绘制 handler.setInputAction(() => { // 销毁事件处理器 handler.destroy(); // 返回所有绘制的点 resolve(drawnPoints); }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); }); },
/** * 拾取位置点 * @param {Object} px 屏幕坐标 * @return {Object} Cartesian3 三维坐标 */ getCatesian3FromPX: function(px) { if (this.viewer && px) { var picks = this.viewer.scene.drillPick(px); var cartesian = null; var isOn3dtiles = false, isOnTerrain = false; // drillPick for (let i in picks) { let pick = picks[i]; if ( (pick && pick.primitive instanceof Cesium.Cesium3DTileFeature) || (pick && pick.primitive instanceof Cesium.Cesium3DTileset) || (pick && pick.primitive instanceof Cesium.Model) ) { //模型上拾取 isOn3dtiles = true; } // 3dtilset if (isOn3dtiles) { this.viewer.scene.pick(px); // pick cartesian = this.viewer.scene.pickPosition(px); if (cartesian) { let cartographic = Cesium.Cartographic.fromCartesian(cartesian); if (cartographic.height < 0) cartographic.height = 0; let lon = Cesium.Math.toDegrees(cartographic.longitude), lat = Cesium.Math.toDegrees(cartographic.latitude), height = cartographic.height; cartesian = this.transformWGS84ToCartesian({ lng: lon, lat: lat, alt: height }); } } } // 地形 let boolTerrain = this.viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider; // Terrain if (!isOn3dtiles && !boolTerrain) { var ray = this.viewer.scene.camera.getPickRay(px); if (!ray) return null; cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene); isOnTerrain = true; } // 地球 if (!isOn3dtiles && !isOnTerrain && boolTerrain) { cartesian = this.viewer.scene.camera.pickEllipsoid( px, this.viewer.scene.globe.ellipsoid ); } if (cartesian) { let position = this.transformCartesianToWGS84(cartesian); if (position.alt < 0) { cartesian = this.transformWGS84ToCartesian(position, 0.1); } return cartesian; } return false; } }, /*** * 坐标转换 84转笛卡尔 * @param {Object} {lng,lat,alt} 地理坐标 * @return {Object} Cartesian3 三维位置坐标 */ transformWGS84ToCartesian: function(position, alt) { if (this.viewer) { return position ? Cesium.Cartesian3.fromDegrees( position.lng || position.lon, position.lat, (position.alt = alt || position.alt), Cesium.Ellipsoid.WGS84 ) : Cesium.Cartesian3.ZERO; } }, /*** * 坐标转换 笛卡尔转84 * @param {Object} Cartesian3 三维位置坐标 * @return {Object} {lng,lat,alt} 地理坐标 */ transformCartesianToWGS84: function(cartesian) { if (this.viewer && cartesian) { var ellipsoid = Cesium.Ellipsoid.WGS84; var cartographic = ellipsoid.cartesianToCartographic(cartesian); return { lng: Cesium.Math.toDegrees(cartographic.longitude), lat: Cesium.Math.toDegrees(cartographic.latitude), alt: cartographic.height }; } },
该方法根据给定的屏幕坐标px,计算出对应的三维世界坐标。该三维世界坐标可以代表一个具体的点在地图上的位置。
使用drillPick方法来获取屏幕坐标点上所有的对象。如果该点上有一个或多个对象,方法会尝试从3D模型上拾取坐标。
如果拾取不在3D模型上,并且地形存在,则从地形上拾取坐标。
如果既不在3D模型上也不在地形上,则从地球椭球体上拾取坐标。
最后返回这个点的三维世界坐标,或者在无法确定时返回false。
该方法根据给定的地理坐标(WGS84格式)计算出相应的三维世界坐标(笛卡尔坐标)。
使用Cesium的Cartesian3.fromDegrees方法从给定的经纬度和高度计算出三维坐标。
该方法根据给定的三维世界坐标(笛卡尔坐标)计算出相应的地理坐标(WGS84格式)。
使用Cesium的Ellipsoid.WGS84和cartesianToCartographic方法将三维世界坐标转换为地理坐标。
使用左键点击事件来添加点,创建一个折线实体来表示用户点击确定的所有点之间的线段。同时每当用户移动鼠标时,显示从最后一个点击位置到当前鼠标位置的一个动态线段。
/** * 绘制折线 */ DrawPolyline() { return new Promise((resolve, reject) => { let viewer = this.viewer; let polylinePoints = []; // 临时折线实体 let polylineEntity = viewer.entities.add({ Id:"drawingPolyline", name:"画线", polyline: { //使用CallbackProperty允许我们在用户点击时动态更新线段的位置 positions: new Cesium.CallbackProperty(() => { return polylinePoints; }, false), width: 2, material: Cesium.Color.RED } }); // 临时动态线实体 let dynamicLineEntity = viewer.entities.add({ polyline: { positions: new Cesium.CallbackProperty(() => { if (lastPoint && currentMousePoint) { return [lastPoint, currentMousePoint]; } else { return []; } }, false), width: 2, material: Cesium.Color.RED.withAlpha(0.5) // 使用半透明红色,与主线区分 } }); let lastPoint = null; let currentMousePoint = null; // 创建事件处理器 let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); // 注册鼠标左键点击事件,用于添加点和显示点 handler.setInputAction(event => { let cartesian = this.getCatesian3FromPX(event.position); if (cartesian) { polylinePoints.push(cartesian); lastPoint = cartesian; viewer.entities.add({ position: cartesian, point: { color: Cesium.Color.BLUE, pixelSize: 10 } }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 鼠标移动事件,更新当前鼠标位置并重绘临时线 handler.setInputAction(event => { currentMousePoint = this.getCatesian3FromPX(event.endPosition); }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 注册鼠标左键双击点击事件,用于结束绘制 handler.setInputAction(() => { handler.destroy(); viewer.entities.remove(dynamicLineEntity); // 移除临时线 resolve(polylinePoints); }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); }); },
用户首先通过单击选择圆的中心,然后通过移动鼠标选择半径。当用户双击时,绘制将完成。
/** * 绘制圆形 */ DrawCircle() { return new Promise((resolve, reject) => { let viewer = this.viewer; let centerPoint = null; let centerPointEntity = null; // 用于存储中点实体的引用 let radius = 10; viewer.scene.globe.depthTestAgainstTerrain = false; let drawingCircle = viewer.entities.add({ id: "drawingCircle", name: "画圆", ellipse: { semiMinorAxis: new Cesium.CallbackProperty(() => { return radius; }, false), semiMajorAxis: new Cesium.CallbackProperty(() => { return radius; }, false), material: Cesium.Color.BLUE.withAlpha(0.2), outline: true, outlineColor: Cesium.Color.RED, outlineWidth:2, fill: true, //为true时只显示轮廓线 } }); let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); handler.setInputAction(event => { var cartesian = this.getCatesian3FromPX(event.position); if (cartesian && centerPoint === null) { centerPoint = cartesian; drawingCircle.position = centerPoint; // 添加中点实体并保存其引用 centerPointEntity = viewer.entities.add({ position: cartesian, point: { color: Cesium.Color.RED, pixelSize: 10 } }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); handler.setInputAction(event => { if (centerPoint) { let cartesian = this.getCatesian3FromPX(event.endPosition); if (cartesian) { let distance = Cesium.Cartesian3.distance(centerPoint, cartesian); radius = distance; } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); handler.setInputAction(() => { if (centerPoint !== null && radius > 0) { handler.destroy(); // 关闭鼠标事件监听,结束绘制 let circleCenter = Cesium.Cartographic.fromCartesian(centerPoint); let lng = Cesium.Math.toDegrees(circleCenter.longitude); let lat = Cesium.Math.toDegrees(circleCenter.latitude); resolve({ center: { lng: lng, lat: lat }, radius: radius }); } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); }); },
我们可以看到鼠标绘制圆是如何实现的呢?首先,创建一个圆实体,即 let drawingCircle = viewer.entities.add({......})
,其中在
ellipse: {
semiMinorAxis: new Cesium.CallbackProperty(() => {
return radius;
}, false),
semiMajorAxis: new Cesium.CallbackProperty(() => {
return radius;
}, false),
...
这里使用了回调函数CallbackProperty
,将semiMinorAxis
和 semiMajorAxis
绑定上了radius
,也就是说圆的半径将根据radius
值的变化而变化。看到这里相信你已经明白了,后面我们要做的就是根据鼠标移动来改变radius
的值,从而改变圆的大小。即鼠标移动监听里的 radius = distance;
。
首次单击选择左上角,移动鼠标调整矩形的大小,然后双击来结束绘制并保存矩形的点。通过捕获用户在地图上的鼠标操作来确定矩形的两个对角点,然后使用这两个点来定义矩形。
/** * 绘制矩形 */ DrawRectangle() { var allPoints = []; // 设置返回值 return new Promise((resolve, reject) => { let viewer = this.viewer; let topLeftPoint = null; let bottomRightPoint = null; let drawingRectangle = viewer.entities.add({ id: "drawingRectangle", name: "画矩形", rectangle: { coordinates: new Cesium.CallbackProperty(() => { if (topLeftPoint === null || bottomRightPoint === null) { return; } let west = topLeftPoint.longitude; let north = topLeftPoint.latitude; let east = bottomRightPoint.longitude; let south = bottomRightPoint.latitude; return new Cesium.Rectangle(west, south, east, north); }, false), material: Cesium.Color.BLUE.withAlpha(0.2), closeTop: true, closeBottom: false } }); let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); handler.setInputAction(event => { var cartesian = this.getCatesian3FromPX(event.position); if (cartesian) { if (topLeftPoint === null) { topLeftPoint = Cesium.Cartographic.fromCartesian(cartesian); } viewer.entities.add({ position: cartesian, point: { color: Cesium.Color.RED, pixelSize: 10 } }); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); handler.setInputAction(event => { if (topLeftPoint) { bottomRightPoint = Cesium.Cartographic.fromCartesian(this.getCatesian3FromPX(event.endPosition)); } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); handler.setInputAction(() => { if (topLeftPoint !== null && bottomRightPoint !== null) { handler.destroy(); // 关闭鼠标事件监听,结束绘制 let west = Cesium.Math.toDegrees(topLeftPoint.longitude); let north = Cesium.Math.toDegrees(topLeftPoint.latitude); let east = Cesium.Math.toDegrees(bottomRightPoint.longitude); let south = Cesium.Math.toDegrees(bottomRightPoint.latitude); allPoints.push({ lng: west, lat: north }); allPoints.push({ lng: east, lat: north }); allPoints.push({ lng: east, lat: south }); allPoints.push({ lng: west, lat: south }); allPoints.push(allPoints[0]); // 闭合 resolve(allPoints); } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); }); },
贴地:
不贴地:
点击地图以定义多边形的顶点,可以随着鼠标移动看到多边形的形状实时更新,通过双击结束多边形绘制,并返回所有的顶点。
/** * 绘制多边形 * @param {Object} option * @param {Boolean} option.ground 是否贴地 */ DrawPolygon(option) { var allPoints=[] // 设置返回值 return new Promise((resolve, reject) => { // 1. 获取Cesium Viewer let viewer = this.viewer; // 2. 创建一个用于存储多边形顶点的数组 let polygonPoints = []; // 3. 创建一个用于显示当前绘制中的多边形的实体 let drawingPolygon = viewer.entities.add({ id: "drawingPolygon", name: "画多边形", polygon: { hierarchy: new Cesium.CallbackProperty(() => { return new Cesium.PolygonHierarchy(polygonPoints); }, false), material: Cesium.Color.BLUE.withAlpha(0.2), perPositionHeight: (option&&option.ground)||false // true:不贴地/false:贴地 }, }); // 4. 创建一个用于显示当前绘制中的线的实体 let drawingLine = viewer.entities.add({ id: "drawingLine", name: "画线", polyline: { positions: new Cesium.CallbackProperty(() => { return polygonPoints; }, false), width: 3, material: Cesium.Color.GREEN } }); // 5. 监听鼠标点击事件,将点击的点添加到顶点数组中,并添加点实体 let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); handler.setInputAction(event => { var cartesian = this.getCatesian3FromPX(event.position); if (cartesian) { // 将点坐标添加到数组中 polygonPoints.push(cartesian.clone()); // 在第一次点击时,添加一个克隆的点到数组中,用于动态更新 if (polygonPoints.length === 1) { polygonPoints.push(cartesian.clone()); } // 添加点实体 viewer.entities.add({ position: cartesian, point: { color: Cesium.Color.RED, pixelSize: 10 } }); //将三维笛卡尔坐标系点转为经纬度坐标点,并保存到点数组中 let cartesian3 = cartesian.clone() // 使用Cesium.Cartographic.fromCartesian将Cartesian3对象转换为Cartographic对象 let cartographic = Cesium.Cartographic.fromCartesian(cartesian3); allPoints.push([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height]); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 6. 监听鼠标移动事件,动态更新多边形和线的形状 handler.setInputAction(event => { var cartesian = this.getCatesian3FromPX(event.endPosition); if (polygonPoints.length >= 2) { if (cartesian && cartesian.x) { polygonPoints.pop(); polygonPoints.push(cartesian); } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 7. 监听鼠标右键点击事件,结束绘制 handler.setInputAction(() => { var cartesian=polygonPoints[polygonPoints.length-1] // 添加点实体 viewer.entities.add({ position: cartesian, point: { color: Cesium.Color.RED, pixelSize: 10 } }); polygonPoints.push(polygonPoints[0]); handler.destroy(); // 关闭鼠标事件监听,结束绘制 resolve(allPoints); }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); }) },
let option = {
ground: true //true:不贴地/false:贴地
};
DrawPolygon(option).then(allPoints => {
// 在这里,allPoints是结束绘制后的点坐标数组
var resultPoints=allPoints
})
var allPoints=[]
return new Promise((resolve, reject) => {
......
}
在这个方法开始时,定义了一个allPoints数组,用于存储绘制的多边形的所有顶点,并且返回一个Promise,允许在绘制结束后将这些点的坐标返回。
let viewer = this.viewer;
获取Cesium的Viewer实例
let drawingPolygon = viewer.entities.add({ ... });
这段代码通过Cesium的entities.add方法创建一个新的实体,并将它添加到地图上。这个实体用于实时显示用户绘制的多边形。
let drawingLine = viewer.entities.add({ ... });
创建一个实体来实时显示用户绘制的线。
let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(event => { ... }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
这段代码创建一个新的ScreenSpaceEventHandler实例来监听鼠标和触摸事件。然后设置一个函数来监听左键点击事件。每当用户点击鼠标左键时,这个函数就会被调用,并将点击的位置添加到polygonPoints数组(即多边形的顶点)和allPoints数组。
需要说明的是这一段代码:
//将三维笛卡尔坐标系点转为经纬度坐标点,并保存到点数组中
let cartesian3 = cartesian.clone()
// 使用Cesium.Cartographic.fromCartesian将Cartesian3对象转换为Cartographic对象
let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
allPoints.push([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height]);
加上这一段只是因为,如果要对获取的点数组进行进一步使用,我更习惯使用经纬度坐标
handler.setInputAction(event => { ... }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
当用户移动鼠标时,这个函数会被调用。它用于实时更新正在绘制的多边形和线的形状。
handler.setInputAction(() => { ... }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
这个函数监听鼠标左键双击事件。当用户双击鼠标左键时,这个函数会被调用,表示用户完成了多边形的绘制。此时,它会添加最后一个点实体,关闭鼠标事件监听,结束绘制,并通过resolve(allPoints)将绘制的点坐标返回。
这个方法允许用户通过点击和移动鼠标在Cesium地图上绘制一个多边形。在用户完成绘制(通过双击鼠标左键)后,这个方法通过Promise的resolve函数将绘制的点坐标数组allPoints返回,供其他部分的代码使用。
(比如进行填挖方的计算,将上面的点数组传到地形填挖方计算的方法,用来生成三角网)
绘制完成:
拖拽点:
思路:
在完成绘制后(即在双击事件结束后),初始化一个新的鼠标事件处理器专门用于拖拽操作。在新的事件处理器中,设置监听左键按下、左键抬起和鼠标移动的事件,用于实现拖拽交互。为了在拖动点时停止地图的默认移动事件,需要在开始拖动事件时暂时禁用默认的摄像机控制,并在拖动结束后再次启用它。(保证点数组长度不变,修改拖拽点的位置)
代码:
let handler = this.globalHandler; handler.setInputAction(event => { var cartesian = this.getCatesian3FromPX(event.position); if (cartesian) { // 将点坐标添加到数组中 polygonPoints.push(cartesian.clone()); // 在第一次点击时,添加一个克隆的点到数组中,用于动态更新 if (polygonPoints.length === 1) { polygonPoints.push(cartesian.clone()); } // 添加点实体 var pointEntity = viewer.entities.add({ id: "point" + polygonPoints.length, position: cartesian, point: { color: Cesium.Color.RED, pixelSize: 10 } }); pointEntities.push(pointEntity); //添加到多边形数组中 let cartesian3 = cartesian.clone(); // 使用Cesium.Cartographic.fromCartesian将Cartesian3对象转换为Cartographic对象 let cartographic = Cesium.Cartographic.fromCartesian(cartesian3); allPoints.push([ Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height ]); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); // 6. 监听鼠标移动事件,动态更新多边形和线的形状 handler.setInputAction(event => { var cartesian = this.getCatesian3FromPX(event.endPosition); if (polygonPoints.length >= 2) { if (cartesian && cartesian.x) { polygonPoints.pop(); polygonPoints.push(cartesian); } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 7. 监听鼠标双击事件,结束绘制 handler.setInputAction(() => { var cartesian = polygonPoints[polygonPoints.length - 1]; handler.destroy(); // 关闭鼠标事件监听,结束绘制 // 移除因单击事件产生的最后一个点 if (polygonPoints.length > 1) { // 去除数组中最后一个点 polygonPoints.pop(); // 返回值 allPoints.pop(); allPoints.push(allPoints[0]); // 闭合 var endPoint = viewer.entities.getById( "point" + (polygonPoints.length + 1) ); if (endPoint) { viewer.entities.remove(endPoint); } var startPoint = viewer.entities.getById("point1"); if (startPoint) { viewer.entities.remove(startPoint); } } resolve(allPoints); // 移除用于绘制的动态线实体 viewer.entities.remove(drawingLine); // 以下为拖拽点改变多边形形状代码 let selectedPointEntity = null; let selectedIndex = -1; var dragHandler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); //鼠标按下 dragHandler.setInputAction(event => { const pickedObject = viewer.scene.pick(event.position); if ( Cesium.defined(pickedObject) && pointEntities.includes(pickedObject.id) ) { selectedPointEntity = pickedObject.id; selectedIndex = pointEntities.indexOf(selectedPointEntity); // 禁用摄像机控制 viewer.scene.screenSpaceCameraController.enableRotate = false; viewer.scene.screenSpaceCameraController.enableTranslate = false; viewer.scene.screenSpaceCameraController.enableZoom = false; viewer.scene.screenSpaceCameraController.enableTilt = false; viewer.scene.screenSpaceCameraController.enableLook = false; } }, Cesium.ScreenSpaceEventType.LEFT_DOWN); // 当鼠标移动时 dragHandler.setInputAction(event => { if (selectedPointEntity) { const cartesian = this.getCatesian3FromPX(event.endPosition); if (cartesian && selectedIndex !== -1) { selectedPointEntity.position = cartesian; polygonPoints[selectedIndex] = cartesian; // 如果当前拖动的是第一个点或是最后一个点 if (selectedIndex === 0||selectedIndex===polygonPoints.length - 2) { polygonPoints[polygonPoints.length - 1] = cartesian; pointEntities[polygonPoints.length - 1].position.setValue( cartesian ); } } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 当鼠标左键抬起时 dragHandler.setInputAction(() => { selectedPointEntity = null; selectedIndex = -1; // 启用摄像机控制 viewer.scene.screenSpaceCameraController.enableRotate = true; viewer.scene.screenSpaceCameraController.enableTranslate = true; viewer.scene.screenSpaceCameraController.enableZoom = true; viewer.scene.screenSpaceCameraController.enableTilt = true; viewer.scene.screenSpaceCameraController.enableLook = true; }, Cesium.ScreenSpaceEventType.LEFT_UP); }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。