当前位置: 首页 > news >正文

SuperMap iClient3D 11i (2023) SP1 for Cesium之移动实体对象

 作者:nannan

目录

前言

一、代码思路

1.1 绘制面实体对象

1.2 鼠标左键按下事件

1.3 鼠标移动事件

1.4 鼠标左键抬起事件

二、运行效果

三、注意事项


前言

       SuperMap 官网三维前端范例 编辑线面,可以对面实体对象的节点进行增加、删除以及修改位置。那可不可以整个线/面对象选中后鼠标拖动,使该面对象的整体位置随着鼠标的移动而移动呢?目前客户这种需求是为了项目上可以实时调整面的区域,方便后端出图。下面和小编一起来看看该功能实现的过程及效果。

一、代码思路

1.1 绘制面实体对象

var polygon = viewer.entities.add({polygon: {hierarchy: {positions: [new Cesium.Cartesian3(290254.5148736448, 5637924.074937166, 2971777.4768239637),new Cesium.Cartesian3(286432.14053509803, 5640804.651089405, 2966391.9275969476),new Cesium.Cartesian3(283512.2666752818, 5640502.494127799, 2969385.3689191523),new Cesium.Cartesian3(287036.36797237827, 5636827.146248645, 2974105.8904601005)]},material: Cesium.Color.BLUE.withAlpha(0.5),//面颜色outline: true,//边框是否显示outlineWidth: 5,//边框线宽度outlineColor: Cesium.Color.YELLOW,//面边框线颜色perPositionHeight:true//是否使用每个位置的高度}
});
viewer.zoomTo(polygon);//定位

1.2 鼠标左键按下事件

       鼠标左键按下接口为 Cesium.ScreenSpaceEventType.LEFT_DOWN,具体代码如下:

viewer.screenSpaceEventHandler.setInputAction(function(e) {leftDownAction(e, viewer)
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

       鼠标左键按下需要获取选中的实体对象,选择(单击选择一个对象)是我们需要与基本API进行短暂交互的领域之一。使用 scene.pick 和 scene.drillpick 检索实体。小编这里采用scene.drillPick。那 scene.drillPick 和 scene.pick 的区别是什么呢?

       如果把 scene.drillPick(click.position) 中 drillPick 改成 pick,那么当鼠标点击或滑过时该位置存在多个 entity,哪怕点线面不在同一高度,面 entity 都可能会盖住点线 entity,从而使得被遮盖的点或线无法响应点击和滑过事件。

let entity = ''
let positions = null // 记录选中实体的位置信息
let newPosition = null // 记录鼠标移动的位置
let diff = [] // 记录选中实体与鼠标位置信息的差异
// 拖拽实体对象-左键按下
function leftDownAction(e, viewer) {entity = viewer.scene.drillPick(e.position, 1)[0];var position = changeToThree(e.position, viewer);if(entity) {// 锁定相机if(entity.id.polygon) {if(!entity.id.polygon.hierarchy._value) {return ''}positions = entity.id.polygon.hierarchy._value.positions;} else if(entity.id.polyline) {if(!entity.id.polyline.positions._value)returnpositions = entity.id.polyline.positions._value;};// 记录选中实体与鼠标位置信息的差异positions.forEach(function(item) {diff.push({x: item.x - position.x,y: item.y - position.y,z: item.z - position.z})});viewer.scene.screenSpaceCameraController.enableRotate = false;}
}

定义一个将经纬度格式转为世界坐标格式的方法

// 定义一个将经纬度格式转为世界坐标格式的方法
function changeToThree(position, viewer) {if(!position) return [];return viewer.scene.globe.pick(viewer.camera.getPickRay(position), viewer.scene);
}

1.3 鼠标移动事件

viewer.screenSpaceEventHandler.setInputAction(function(e) {mouseMoveAction(e, viewer)
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 拖拽实体对象-鼠标移动
function mouseMoveAction(e, viewer) {if(entity) {// 获取移动点的位置,且将格式转为世界坐标const movePosition = changeToThree(e.endPosition, viewer);// 根据鼠标位置以及选中实体与鼠标位置信息的差异计算出移动后的实体位置newPosition = diff.map(item => ({x: item.x + movePosition.x,y: item.y + movePosition.y,z: item.z + movePosition.z}));if(entity.id.polygon) {// 动态改变面的位置信息entity.id.polygon.hierarchy = new Cesium.CallbackProperty(function() {return new Cesium.PolygonHierarchy(newPosition)}, false);entity.id.polygon.positions = new Cesium.CallbackProperty(function() {return newPosition}, false);} else {entity.id.polyline.positions = new Cesium.CallbackProperty(function() {return newPosition}, false);};};
}

1.4 鼠标左键抬起事件

viewer.screenSpaceEventHandler.setInputAction(function(e) {leftUpAction(e, viewer)
}, Cesium.ScreenSpaceEventType.LEFT_UP);
// 拖拽实体对象-左键抬起
function leftUpAction(e, viewer) {if(entity.id.polygon) {entity.id.polygon.hierarchy = newPosition;entity.id.polygon.positions = newPosition;} else {entity.id.polyline.positions = newPosition;};positions = null; // 记录选中实体的位置信息newPosition = null; // 记录鼠标移动的位置diff = []; // 记录选中实体与鼠标位置信息的差异entity = null;// 解除相机锁定viewer.scene.screenSpaceCameraController.enableRotate = true;
}

二、运行效果

三、注意事项

       构建面实体对象需要用到 perPositionHeight参数,该参数用于指定是否使用每个位置的高度。这里需要设置为 true,否则默认 false 贴地,面边框不会和面一起跟随鼠标移动而移动,会是以下图 3.1 的效果。

图3.1 面边框不会和面一起跟随鼠标移动而移动

http://www.lryc.cn/news/166695.html

相关文章:

  • 【深度学习 AIGC】stablediffusion-infinity 在无界限画布中输出绘画 Outpainting
  • Flutter插件之阿里百川
  • ✔ ★ 算法基础笔记(Acwing)(三)—— 搜索与图论(17道题)【java版本】
  • 初试占比70%,计算机招生近200人,安徽理工大学考情分析
  • LeetCode题解:1720. 解码异或后的数组,异或,JavaScript,详细注释
  • 【C刷题】day2
  • Apollo源码安装的问题及解决方法
  • Flutter 挖孔屏的状态栏占用问题怎么解决,横屏后去掉了状态栏,还是会有一块黑色的竖条
  • Layui快速入门之第九节 表格事件的使用
  • [2023.09.14]: Rust的条件编译
  • 数据清洗:数据挖掘的前期准备工作
  • 基于FPGA的图像sobel锐化实现,包括tb测试文件和MATLAB辅助验证
  • HDMI 直通 ILA 调试实验
  • 基于Qt4开发曲线绘制交互软件Plotter
  • 数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病...
  • 【深度学习】 Python 和 NumPy 系列教程(十五):Matplotlib详解:2、3d绘图类型(1):线框图(Wireframe Plot)
  • 阿里云CDN缓存配置及优化-oss绑定CDN缓存自动刷新功能
  • 气象站有什么用?有哪些类型
  • 【深度学习】卷积神经网络(LeNet)
  • 什么是数据仓库,解释数据仓库的结构和ETL过程
  • 无线通信网络
  • 使用ElementPlus实现内嵌表格和内嵌分页
  • flex弹性盒模型与阿里图标的使用
  • linux 应用中offsetof ()是个啥?
  • ununtu中vim的使用
  • SqlServer在尝试加载程序集 ID 65917 时 Microsoft .NET Framework 出错。服务器可能资源不足,或者不信任该程序集
  • Discourse 如何下载备份并恢复本地数据库
  • 激光焊接汽车PP塑料配件透光率测试仪
  • Android面试题汇总(二)
  • 最新模块化设计小程序系统源码完整版:开源可二开,支持DIY