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

news2025/1/16 1:59:47

 作者: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)
			return
			positions = 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.coloradmin.cn/o/998432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PYTHON学习-文件管理,打工人必备~

🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…

秒杀场景下用Redis分布式锁解决超卖问题

前言 超卖问题通常出现在多用户并发操作的情况下,即多个用户尝试购买同一件商品,导致商品库存不足或者超卖。解决超卖问题的方法有很多:乐观锁、Redis分布式锁、消息队列等。 分布式锁是一种多节点共享的同步机制,通过在多个节点…

《TCP/IP网络编程》阅读笔记--getsockopt和setsockopt的使用

目录 1--Socket的多种可选项 2--getsocketopt() 3--setsockopt() 4--代码实例 1--Socket的多种可选项 Socket 拥有多种可选项,其可分为 SOL_SOCKET 层,IPPROTO_IP 层和IPPROTO_TCP 层等,一般通过 getsocketopt() 和 setsockopt() 函数进行…

【Cpolar内网穿透】公网SSH远程连接Termux – 电脑使用安卓Termux

目录 前言 1.安装ssh 2.安装cpolar内网穿透 3.远程ssh连接配置 4.公网远程连接 5.固定远程连接地址 前言 使用安卓机跑东西的时候,屏幕太小,有时候操作不习惯。不过我们可以开启ssh,使用电脑PC端SSH远程连接手机termux。 本次教程主要…

C#,《小白学程序》第二十课:大数(BigInteger)的四则运算之一,加法

大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算。 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法。 重复了部分 19 课的代码。 1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary>…

软件架构设计(十一) 软件产品线

1、基本概念 软件产品线是从DSSA(特定领域架构)扩展而来的,我们从事软件开发,当您有了多年的经验之后,往往会沉淀到某一个特定领域,然后做这个领域的行业软件。 此时,您会把一些共性的东西开发出来,稳定下来。如果以后再开发同类型的系统时,做一些小修小改或者应用层…

《Python趣味工具》——自制emoji(1)绘制爱心应援牌❤️

项目目标&#xff1a; 本项目旨在学习如何自制emoji&#xff0c;学习内容主要分为3个方面&#xff0c;分3次来讲&#xff0c;根本在于了解了turtle的使用&#xff01; 1.完成一个爱心应援牌 2.完成静态的emoji 3.让emoji动起来&#xff01; 今天我们来学习第一个部分。 文章目录…

推荐一个图像生成开源项目——Fooocus

目录 什么是Fooocus&#xff1f; 项目地址 性能消耗 如何安装 效果对比 总结 什么是Fooocus&#xff1f; Fooocus是一款图像生成软件&#xff0c;但它不同寻常&#xff0c;是对稳定扩散&#xff08;Stable Diffusion&#xff09;和Midjourney的设计理念的巧妙重新思考。本…

C语言经典100例题(42)--学习使用auto定义变量的用法

目录 题目 问题分析 代码 运行结果 题目 学习使用auto定义变量的用法 问题分析 auto存储类型只对属于块的变量有效。auto变量具有自动存储期限、块作用域&#xff0c;并且无连接。auto存储类型几乎从来不用明确地指明&#xff0c;因为对于在块内部声明的变量&#xff0c;…

超经典 Linux 运维巡检脚本及示例

inux 系统日常巡检脚本&#xff0c;巡检内容包含了&#xff1a;磁盘、内存、CPU、进程、文件更改、用户登录等一系列的操作&#xff0c;直接用就行了。 报告以邮件发送到邮箱&#xff0c;在 log 下生成巡检报告。 一、巡检脚本 #!/bin/bash # Author: HanWei # Date: 2020-…

Nginx__高级进阶篇之LNMP动态网站环境部署

动态网站和LNMP&#xff08;LinuxNginxMySQLPHP&#xff09;都是用于建立和运行 web 应用程序的技术。 动态网站是通过服务器端脚本语言&#xff08;如 PHP、Python、Ruby等&#xff09;动态生成网页内容的网站。通过这种方式&#xff0c;动态网站可以根据用户的不同请求生成不…

Sentinel-限流降级

0.目录 初识Sentinel 流量控制 隔离和降级 授权规则 规则持久化 1.初识Sentinel 1.0目录 雪崩问题及解决方案 服务保护技术对比 Sentinel介绍和安装 微服务整合Sentinel 1.1 雪崩问题 1.1.1 引起雪崩的原本 如果服务D出现了问题&#xff0c;那么当服务A调用服务D时&…

Jetpack Compose 1.5 发布:全新 Modifier 系统带来性能大幅提升

不久前 Compose 1.5.0 稳定版发布&#xff0c;在组合的性能方面得到明显改善&#xff0c;这主要归功于对 Modifier API 的持续重构。 Modifier 是 Compose 中的重要概念&#xff0c;为 Composition 中的 LayoutNode 配置各种样式信息以用于后续渲染。在 1.3.0 之前的 Modifier …

【教师节特辑】做个教师节快乐照片墙吧

写作原因&#xff1a; 教师节到了&#xff0c;身边或多或少都有很多不少的老师&#xff0c;基本以前认识的老师都不记得了&#xff0c;以后总也会认识一些日本老师的。程序员&#xff0c;就应该以自己的方式来庆祝教师节。想了下&#xff0c;要不还是做个照片墙把。 项目链接 …

2024年java面试--mysql(2)

系列文章目录 2024年java面试&#xff08;一&#xff09;–spring篇2024年java面试&#xff08;二&#xff09;–spring篇2024年java面试&#xff08;三&#xff09;–spring篇2024年java面试&#xff08;四&#xff09;–spring篇2024年java面试–集合篇2024年java面试–redi…

电商API与电商数据经济的产生【电商平台-淘宝/京东/拼多多下的API数据经济】

计算机连接了互联网后&#xff0c;释放出了巨大的创新力和价值&#xff0c;同样地&#xff0c;智能合约一旦连接到快速增长的链下数据和API经济&#xff0c;也将变得无比强大。如果智能合约可以连接至链下数据提供商、web API、企业系统、云服务商、物联网设备、支付系统以及其…

高分三号1米分辨率飞机检测识别数据集

二、背景介绍 合成孔径雷达(Synthetic Aperture Radar, SAR) 是一种主动式的微波成像系统&#xff0c;它不受光照、云雾 和气候等自然条件影响&#xff0c;具备全天时、全天候对地 观测的能力&#xff0c;已成为遥感领域重要的信息获取平 台。近年来&#xff0c;随着遥感成像技…

Redis主从复制集群的介绍及搭建

在现代的软件开发中&#xff0c;数据的可靠性和可用性是至关重要的。Redis&#xff0c;作为一个开源的、内存中的数据结构存储系统&#xff0c;以其出色的性能和灵活的数据结构&#xff0c;赢得了开发者们的广泛喜爱。而 Redis 的主从复制功能&#xff0c;更是为我们提供了一种…

基于AHP模型指标权重分析python整理

一 背景介绍 日常会有很多定量分析的场景&#xff0c;然而也会有一些定性分析的场景针对定性分析的场景&#xff0c;预测者只能通过主观判断分析能力来推断事物的性质和发展趋势然而针对个人的直觉和虽然能够有一定的协助判断效果&#xff0c;但是很难量化到指标做后期的复用 …

Mybatis学习笔记2 增删改查及核心配置文件详解

Mybatis学习笔记1 Mybatis入门_biubiubiu0706的博客-CSDN博客 将Mybatis进行封装 SqlSessionUtil工具类 package com.example.util;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFacto…