原生cesium 实现楼栋抽离效果

server/2024/11/19 15:45:18/

这里写自定义目录标题

  • 需求背景
  • 解决思路
  • 解决效果
  • index.vue

需求背景

需要实现整栋楼的展开,合上,单层抽离的预览效果

解决思路

由于3dtiles格式分成选中的元素太多,做模型抽离较麻烦
采用把模型按每层分成小模型用model的方式交互加载

解决效果

index.vue

/**
* @author: liuk
* @date: 2024-11-18
* @describe:楼层叠加
*/
<template><div class="floorsStacking-wrap"><p>楼层叠加</p><p>当前楼层:{{ curFloor || 20 }}</p><el-button type="primary" style="width:100px;margin-left: 0" @click='spreadFloor'>展开楼层</el-button><el-button type="primary" style="width:100px;margin-left: 0" @click='closeFloor'>合上楼层</el-button><el-button type="warning" style="width:100px;margin-left: 0" @click="reset">重置</el-button><el-button type="primary" style="width:100px;margin-left: 0" @click="mapResetCamera">视角</el-button><Tdt_img_d/></div>
</template><script lang="ts" setup>
import {usemapStore} from "@/store/modules/cesiumMap";
import {onMounted, onUnmounted, reactive, toRefs} from "vue"
import {cartesianToWgs84} from "@/utils/dictionary";
// Component
import Tdt_img_d from "@/views/cesium/component/controlPanel/layerManagement/basicMap/tdt_img_d.vue"
import {ElMessage} from "element-plus";const mapStore = usemapStore()
const model = reactive({curFloor: ""
})
const {curFloor} = toRefs(model)onMounted(() => {viewer.dataSources.add(floorsStackingDatasource);addEntity()mapResetCamera()handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction(onMouseClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
})onUnmounted(() => {handler.destroy()floorsStackingDatasource?.entities?.removeAll()viewer.dataSources.remove(floorsStackingDatasource);
})// 地图逻辑
const viewer = mapStore.getCesiumViewer();
const floorsStackingDatasource = new Cesium.CustomDataSource("floorsStacking");
let handlerconst addEntity = () => {new Array(20).fill("").forEach((_, index) => {floorsStackingDatasource.entities.add({customType: "floorsStacking",floor: index + 1,position: Cesium.Cartesian3.fromDegrees(113.136103, 25.720441, 673 + index * 3 - (index && 2.3)),model: {uri: getGlbUrl(index + 1),},});})
}const spreadFloor = () => {floorsStackingDatasource.entities.values.forEach((entity, index) => {const pos = cartesianToWgs84(entity.position.getValue())entity.position = Cesium.Cartesian3.fromDegrees(pos[0], pos[1], pos[2] + 4 * entity.floor)})
}const closeFloor = () => {floorsStackingDatasource.entities.values.forEach((entity, index) => {const pos = cartesianToWgs84(entity.position.getValue())entity.position = Cesium.Cartesian3.fromDegrees(pos[0], pos[1], pos[2] - 4 * entity.floor)})
}const onMouseClick = (movement) => {const pickedObject = viewer.scene.pick(movement.position);if (!Cesium.defined(pickedObject) || !Cesium.defined(pickedObject.id)) returnconst entity = pickedObject.id;if (entity instanceof Cesium.Entity && entity.customType === "floorsStacking") {model.curFloor = entity.floorElMessage.success(`点击了${entity.floor}`)floorsStackingDatasource.entities.values.forEach(entity => {if (entity.floor > model.curFloor) entity.show = false})}
}const reset = () => {model.curFloor = ""floorsStackingDatasource.entities.values.forEach(entity => entity.show = true)
}const getGlbUrl = (i) => {switch (true) {case i === 1:return `${import.meta.env.VITE_APP_MODELDATA}/floorsStackGlb/1.glb`case i < 7:return `${import.meta.env.VITE_APP_MODELDATA}/floorsStackGlb/${i}.glb`case i < 16:return `${import.meta.env.VITE_APP_MODELDATA}/floorsStackGlb/6.glb`case i === 16:return `${import.meta.env.VITE_APP_MODELDATA}/floorsStackGlb/16.glb`case i < 19:return `${import.meta.env.VITE_APP_MODELDATA}/floorsStackGlb/17.glb`default:return `${import.meta.env.VITE_APP_MODELDATA}/floorsStackGlb/${i}.glb`}
}const mapResetCamera = () => {viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(113.139392, 25.720645, 792.29),orientation: {heading: Cesium.Math.toRadians(275),pitch: Cesium.Math.toRadians(-17.7),roll: 0.0}});
}
</script><style lang="scss" scoped>
.floorsStacking-wrap {display: flex;flex-direction: column;justify-content: space-evenly;align-items: center;position: absolute;top: 100px;left: 280px;width: 120px;height: 240px;border-radius: 5px;background: rgba(0, 0, 0, 0.6);pointer-events: auto;}
</style>

http://www.ppmy.cn/server/143226.html

相关文章

nginx证书流式响应配置

要配置 Nginx 支持流式响应的反向代理&#xff0c;你需要进行一些特定的设置&#xff0c;以确保 Nginx 不会缓冲响应并正确地将数据转发到后端服务器。以下是一个简单的配置示例&#xff0c;假设你的后端服务器运行在 http://backend-server:port&#xff1a; server {listen …

lua脚本语言基本原理

Lua是一种轻量级、高效的脚本语言&#xff0c;其原理主要包括以下几个方面&#xff1a; 词法分析 原理&#xff1a;词法分析器按从左到右的顺序对 Lua 脚本的源程序字符流进行扫描&#xff0c;依据词法规则将其识别为一个个单词&#xff0c;如关键字、标识符、常量、运算符等…

Python学习27天

字典 dict{one:1,two:2,three:3} # 遍历1&#xff1a; # 先取出Key for key in dict:# 取出Key对应的valueprint(f"key:{key}---value:{dict[key]}")#遍历2&#xff0c;依次取出value for value in dict.values():print(value)# 遍历3&#xff1a;依次取出key,value …

【网络安全】SSL(二):Keyless SSL技术细节

未经许可,不得转载。 文章目录 TLS双重目标握手过程是什么?TLS 中的握手类型TLS 术语表RSA 握手协议临时 Diffie-Hellman 握手Diffie-Hellman 握手过程保护密钥服务器其他安全考虑性能提升场景分析持久连接精简握手会话恢复的问题Keyless SSL 的会话恢复功能会话票据恢复会话…

深入理解 Java 阻塞队列:使用场景、原理与性能优化

在并发编程中&#xff0c;线程安全的队列是解决线程间任务传递和调度的关键工具之一。阻塞队列&#xff08;BlockingQueue&#xff09;作为一种线程安全的队列&#xff0c;实现了在并发环境下对共享数据的安全访问&#xff0c;广泛应用于生产者-消费者模型、任务调度和多线程计…

推荐一款好用的ios传输设备管理工具:AnyTrans for iOS

AnyTrans for iOS是一款好用的ios传输设备管理工具&#xff0c;可以方便用户对iphone、ipad、ipod中的文件进行管理操作&#xff0c;可以方便用户在电脑上进行各类文件的管理操作&#xff0c;支持联系人、视频、音频、短信、图片等文件的导入&#xff0c;软件支持双向传输和浏览…

阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_作战无人机和察打无人机图鉴

文献基本信息 题名作者来源发表时间2020年国外先进军用无人机技术发展综述 袁成;董晓琳;朱超磊 飞航导弹 2021-01-14 2021年国外军用无人机装备技术发展综述 朱超磊 ;袁成;杨佳会;飞航导弹 战术导弹技术2022-02-112022年国外军用无人机装备技术发展综述 朱超磊;金钰;王靖…

生日主题的烟花特效HTML,CSS,JS

目录 图片展示 完整代码 关键点解释 图片展示 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><t…