【WebGis开发 - Cesium】三维可视化项目教程---图层管理拓展图层透明度控制

目录

  • 引言
  • 一、为什么要开发图层透明度控制功能
  • 二、开发思路整理
    • 1. cesium图层api查询
      • 1.1 imageryLayer 透明度
      • 1.2 primitive 透明度
  • 三、代码编写
    • 1. 修改原有图层管理代码
    • 2. 新增页面结构
    • 3. 编写图层透明度控制方法
  • 四、总结

引言

本教程主要是围绕Cesium这一开源三维框架开展的可视化项目教程。总结一下相关从业经验,如果有什么疑问或更好的见解,欢迎评论、私聊探讨,共同进步。教程依托于vue3前端框架,参考初始化内容:【WebGis开发 - Cesium】三维可视化项目教程—初始化场景

在【WebGis开发 - Cesium】三维可视化项目教程—图层管理基础 文中我们已经搭建了图层管理的基础框架代码。在本篇中我们将拓展图层透明度控制功能。

先看效果:

在这里插入图片描述


一、为什么要开发图层透明度控制功能

cesium三维场景不可避免地会存在遮挡关系,二维图层因为添加顺序问题存在层级遮挡,三维图层因为物理长宽高相互遮挡。在实际应用场景中,我们常常需要两个图层之间互作对比,通过将其中一个图层半透明来突出与另一个图层的位置关系。根据现有图层管理的图层类型,我们大致可以将图层分为 imageryLayerprimitiveLayer 这两种(后者是不存在的,只是做分类起名字)。

  • 二维图层例如:wmtswmsmapserver 等都会以 imageryLayer 形式存储在cesium实例中。
  • 三维图层例如:3dtiles 会以 primitive 形式存储在cesium实例中。

大致上图层会以imageryLayerprimitive 这两种形式存在,所以在考虑设置透明度时,可以针对这两种类型分别编写对应方法。


二、开发思路整理

首先整理一下要实现这个功能需要准备哪些东西:

  • 一个直观的滑动条组件,将滑动选择的透明度值输入给图层材质。本文中使用 element-plusslider 组件。
  • 查询cesium针对imageryLayerprimitive 这两种形式的透明材质如何设置。

1. cesium图层api查询

1.1 imageryLayer 透明度

文档地址:imageryLayer图层文档
在这里插入图片描述
通过传递[0.0 , 1.0]区间内的浮点数设置图层透明度。

有一个测试用的小技巧,当你在初始化cesium场景时设置了window.viewer。那么你可以通过控制台输入 viewer.imageryLayers._layers 得到imageryLayer 数组。打开其中一个,找到 alpha 属性,双击属性值可以动态输入一个新值用来测试。回车键确定输入值,场景中如果该图层在最上层,那么将能看到它的透明度变为原来的一半(临时修改,刷新页面效果即消失)。
在这里插入图片描述

1.2 primitive 透明度

primitive 三维图层设置透明度和 imageryLayer 略有不同,它没有显式的提供一个 alpha 属性属性用来修改透明度。我们需要从3dtiles实例对象中设置style属性。
通过查询 viewer.scene.primitives._primitives 可以获取到当前已经加载的3dtiles图层有哪些。查询指定图层的style属性发现是 undefined,此时我们需要自定义一个 Cesium3DTileStyle 示例赋予指定图层的style属性。参考:Cesium3DTileStyle参考文档
在这里插入图片描述


三、代码编写

1. 修改原有图层管理代码

为了适应图层透明度调整的功能需求,我们仍需在原有的图层管理代码中做少许微调。

调整hooks/useLayerManager.js文件内容:

// 修改 addWmtsLayer 方法const addWmtsLayer = (data) => {// 其他代码保持原样// 向全局状态输入图层数据,新增默认不透明度为1layerStore.addImageryLayer({...data,show: true,opacity: 1,layerId: layer.layerId,});};
// 修改 add3dtilesLayer 方法const add3dtilesLayer = async (data) => {// 其他代码保持原样// 向全局状态输入图层数据,新增默认不透明度为1layerStore.addPrimitiveLayer({...data,show: true,opacity: 1,layerId: tileset.layerId,});viewer.flyTo(tileset);};

这里添加opacity字段是为了与已选图层中的slider组件做双向绑定。

2. 新增页面结构

在原有图层管理的页面中已选图层拖拽组件上继续修改页面结构:

  • 改造dragItem,将其分为上下两层,上层为标题和删除按钮,下层为透明度控制slider。
  • 在slider中我使用了 change 方法,在拖拽结束鼠标松开时触发透明度更新。如果你的场景不复杂且电脑配置足够高,可以替换为 input 方法,鼠标拖动slider实时控制图层透明度变化。
  • 在图层树添加 ref="layerTree" 配合删除按钮做勾选框与图层删除联动效果。
      <el-treeref="layerTree"style="max-width: 300px":data="dataSource"show-checkboxnode-key="id"default-expand-allcheck-on-click-node@check="onCheck"@check-change="checkChange":expand-on-click-node="false"></el-tree><div>已选图层</div><draggablev-model="layerStore.imageryLayers"@change="dragChange"item-key="id"ghostClass="ghost"><template #item="{ element }"><div class="dragItem"><div class="dragItem_title"><span>{{ element.label }}</span><imgsrc="@/assets/icons/delete.svg"alt="delete"@click="deleteLayer(element)"/></div><el-slider:min="0":max="1":step="0.1"v-model="element.opacity"@change="changeOpacity(element)"/></div></template></draggable>

新增js方法完成页面部分

  • useLayerManager.js文件中新引入 setLayerOpacity 通用方法,用于设置图层透明度。
  • 配合 el-treeref 属性,定义组件dom的引用。利用 setChecked 方法将删除图层手动去掉勾选,完成树结构勾选框与已选列表同步效果。
import { useLayerManager } from "@/hooks/useLayerManager.js";
const { removeLayer, setLayerOpacity} = useLayerManager();
const changeOpacity = (data) => {console.log("changeOpacity", data);setLayerOpacity(data);
};const layerTree = ref(null);
const deleteLayer = (data) => {removeLayer(data);layerTree.value.setChecked(data.id, false, true);
};

3. 编写图层透明度控制方法

在hooks/useLayerManager.js文件中继续添加方法,注意最后将方法导出:

对外暴露设置图层不透明度通用方法,根据类型选择具体方法。

  /*** @description: 设置图层不透明度通用方法* @param {*} data* @return {*}*/const setLayerOpacity = (data) => {return setLayerOpacityFunctions[data.type](data);};return {setLayerOpacity }

创建不透明度方法调度对象,存储具体方法

  /*** @description:  设置图层不透明度方法map,用于存储不同图层设置不透明度方法* @return {*}*/const setLayerOpacityFunctions = {"wmts": setImageryLayerOpacity,"3dtiles": setPrimitiveLayerOpacity,};

创建具体不同类型图层不透明度设置方法

  /*** @description: 设置ImageryLayer图层不透明度* @param {*} data* @return {*}*/const setImageryLayerOpacity = (data) => {const layerData = layerStore.getImageryLayer(data.id);if (layerData) {const layer = viewer.imageryLayers._layers.find((item) => item.layerId === layerData.layerId);layer.alpha = data.opacity;}};/*** @description: 设置PrimitiveLayer图层不透明度* @param {*} data* @return {*}*/const setPrimitiveLayerOpacity = (data) => {const layerData = layerStore.getPrimitiveLayer(data.id);if (layerData) {const layer = viewer.scene.primitives._primitives.find((item) => item.layerId === layerData.layerId);layer.style = new Cesium.Cesium3DTileStyle({color: `color('rgba(255,255,255,${data.opacity})')`,});}};

至此就完成了已选图层透明度控制,以及图层手动删除的功能拓展。


四、总结

本篇主要是利用 element-plusslider 组件配合 pinia 存储的数据列表做双向绑定,完成图层透明度控制功能。利用 tree 组件的 setChecked 方法,完成已选图层与图层树的删除联动效果。根据功能拓展的需求,将原有图层管理操作逻辑进行修改完善以适应新功能的接入。重点在于根据业务的需求逻辑,封装cesium提供的原始api方法,形成维度更高的项目级api方法。

再接再厉~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/458937.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何通过sip信令以及抓包文件分析媒体发到哪个地方

前言 问题描述&#xff1a;A的媒体没转发到B&#xff0c;B只能听到回铃音&#xff0c;没有A的说话声音&#xff0c;并且fs这边按正常的信令发送了. 分析流程 分析早期媒体发送到哪一个IP 10.19.0.1发送了一个请求给10.19.0.157这个IP&#xff0c;然而这里的SDP媒体地址&am…

react 总结+复习+应用加深

文章目录 一、React生命周期1. 挂载阶段&#xff08;Mounting&#xff09;补充2. 更新阶段&#xff08;Updating&#xff09;补充 static getDerivedStateFromProps 更新阶段应用补充 getSnapshotBeforeUpdate3. 卸载阶段&#xff08;Unmounting&#xff09; 二、React组件间的…

搭建 mongodb 副本集,很详细

搭建 mongodb 副本集&#xff0c;很详细 一、前言二、创建用户1、创建 root 用户2、创建测试用户3、修改用户密码 三、修改配置文件&#xff08;主节点&#xff09;1、开启登录认证2、加上副本集3、最终配置文件 四、副本节点1、创建副本节点目录2、编辑配置文件3、启动副本节点…

2024年四川省大学生程序设计竞赛 补题记录

文章目录 Problem A. 逆序对染色&#xff08;思维树状数组&#xff09;Problem B. 连接召唤&#xff08;贪心&#xff09;Problem E. L 型覆盖检查器&#xff08;模拟&#xff09;Problem F. 小球进洞&#xff1a;平面版&#xff08;几何&#xff09;Problem G. 函数查询Proble…

关于传输线电感

要理解自感、互感、回路电感&#xff0c;PCB表层单位长度电感约为7.5纳亨每英寸&#xff0c;内层约为9纳亨每英寸 磁力线 电流周围会产生磁场&#xff0c;可以认为磁场是由许多“力线”构成。 电流穿过与其垂直的某一平面时&#xff0c;在该平面内激起一个“磁漩涡” 形成许多…

JavaSet集合

无序&#xff08;指的是添加顺序和获取出的数据顺序不一致&#xff0c;不重复&#xff0c;无索引 既然Set没有索引&#xff0c;因此功能同上一篇Connection的功能&#xff0c;几乎没有额外的功能 HashSet的原理 为什么是无序&#xff08;要构建红黑树&#xff09;&#xff0…

【Linux学习】(9)调试器gdb

前言 Linux基础工具&#xff1a;安装软件我们用的是yum&#xff0c;写代码用的是vim&#xff0c;编译代码用gcc/g&#xff0c;调试代码用gdb&#xff0c;自动化构建用make/Makefile&#xff0c;多人协作上传代码到远端用的是git。 在前面我们把yum、vim、gcc、make、git都已经学…

逆向工程基本概念

引言 逆向工程&#xff08;Reverse Engineering&#xff09;是指从已经存在的产品或系统中提取信息&#xff0c;并理解其设计原理的过程。在软件开发中&#xff0c;逆向工程通常用于理解一个已有软件系统的内部工作原理&#xff0c;可能是为了兼容性、安全分析、修复或者改进等…

Pyhton自动化测试持续集成和Jenkins

持续集成 官方术语&#xff1a; 持续集成&#xff08;Continuous Integration&#xff09;&#xff0c;也就是我们经常说的 CI 持续集成&#xff08;CI&#xff09;是一种实践&#xff0c;可以让团队在持续的基础上收到反馈并进行改进&#xff0c;不必等到开发周期后期才寻找…

二十四、Python基础语法(变量进阶)

一、引用 在定义变量的时候, 解释器会给变量和数据分别在内存中分配内存&#xff0c;变量中保存的是数据的地址, 称为引用&#xff0c;Python 中数据的传递,传递的都是引用&#xff0c;可以使用 id(变量) 函数,获取变量中引用地址。 # 将数字1在内存中的地址储存到变量a中 a …

人工智能岗位英语面试 - 如何确保模型的可靠性和性能

确保模型的可靠性和性能 1. Precision Precision is a metric that measures how accurate the model’s positive predictions are. It calculates the ratio of true positives (correctly predicted positive cases) to the total number of predicted positives (both tr…

时间比较日期

现在需要一个获取当前时间然后对比一个月后的时间的java方法&#xff0c;比如&#xff1a;当前时间获取到是2024-10-28&#xff0c;然后我写定一个时间2024-10-29&#xff0c;这两个比大小&#xff0c;获取的当前时间要小于我写定的时间返回true否则返回false import java.time…

从头学PHP之数组输出基本函数

上期我们讲到了数组&#xff0c;数组是个特殊的变量&#xff0c;在程序中的重要程度很高&#xff0c;大部分数据处理的时候会用到这种特殊的变量&#xff0c;那么现在让我们继续深入一下吧。 上期我们打印出了数组的值&#xff0c;用print_r()或者var_dump()这俩函数&#xff0…

paddleocr使用FastDeploy 部署工具部署 rknn 模型

在 PC 端转换 pdmodel 模型为 rknn 模型和在板端使用百度飞浆开发的 FastDeploy 部署工具部署 rknn 模型 以下内容是在 PC 端系统为 Ubuntu20.04&#xff0c;板端系统为ubuntu20.04 的环境下实现的 描述&#xff1a; 官网地址 rknn_zoo RKNPU2_SDK …

【Linux】进程调度 | 进程切换上下文数据

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;青果大战linux 总有光环在陨落&#xff0c;总有新星在闪烁 小感慨&#xff1a; …

区块链系统控制台Console的安装与运维

【要求】 登陆Linux 服务器&#xff0c;安装、部署区块链系统控制台 Console&#xff0c;并完成节点的运维。同 时&#xff0c;检查控制台是否能够正常运行。 【任务】 1. 登陆 linux 服务器&#xff0c;进入指定操作目录按下列要求完成控制的安装与部 署&#xff0c;并将安装过…

Rust语言的优缺点以及学习建议

在编程世界的不断演变中&#xff0c;Rust 作为一种重要的语言脱颖而出。它以安全性和性能为核心&#xff0c;正在获得开发者们的广泛关注。但究竟什么是 Rust&#xff1f;它为何如此受欢迎&#xff1f;在这篇博客中&#xff0c;我们将深入探讨 Rust 的世界&#xff0c;探索它的…

【三十七】【QT开发应用】使用QVideoWidget播放视频,QT模块缺失时更新安装模块步骤(利用虚拟网址打开应用加速)

效果展示 下面有一个按钮打开视频&#xff0c;点击按钮之后会出现一个弹窗选择文件&#xff0c;默认打开的是D盘&#xff0c;并且选择的文件的类型有.mp4 .flv或者所有文件。选择正确的视频文件之后可以正常播放视频。 widget.h 主窗口头文件 #pragma once#include <QtWid…

【设计模式系列】适配器模式(九)

目录 一、什么是适配器模式 二、适配器模式的角色 三、适配器模式的典型应用 四、适配器模式在InputStreamReader中的应用 一、什么是适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将不兼容的接口转换为一个客户端…

【Vue】word / excel / ppt / pdf / 视频(mp4,mov) 预览

文件预览 Vue3一. word二. excel三. ppt四. pdf4.1 vue-pdf-embed4.2 iframe 五. 视频六&#xff1a;扩展——kkFileView Vue3 一. word 安装&#xff1a;npm install docx-preview父页面 <template><div><DocPreviewv-if"filePath.includes(docx)"…