vue+cesium示例:地形开挖(附源码下载)

基于cesium和vue绘制多边形实现地形开挖效果,适合学习Cesium与前端框架结合开发3D可视化项目。

demo源码运行环境以及配置

运行环境:依赖Node安装环境,demo本地Node版本:推荐v18+。

运行工具:vscode或者其他工具。

配置方式:下载demo源码,vscode打开,然后顺序执行以下命令:
(1)下载demo环境依赖包命令:npm install
(2)启动demo命令:npm run dev
(3)打包demo命令: npm run build

技术栈

Vue 3.5.13

Vite 6.2.0

Cesium 1.128.0

示例效果
在这里插入图片描述
核心源码

<template><div id="cesiumContainer" class="cesium-container"><!-- 模型调整控制面板 --><div class="control-panel"><div class="panel-header"><h3>地形开挖</h3></div><div class="panel-body"><div class="control-group"><button @click="startDrawPolygon">绘制多边形</button></div><div class="control-group"><button @click="clearDrawing">清除绘制</button></div><div class="control-group" v-if="drawingInstructions"><span>{{ drawingInstructions }}</span></div></div></div></div>
</template><script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import * as Cesium from 'cesium';Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxZjhjYjhkYS1jMzA1LTQ1MTEtYWE1Mi0zODc5NDljOGVkMDYiLCJpZCI6MTAzNjEsInNjb3BlcyI6WyJhc2wiLCJhc3IiLCJhc3ciLCJnYyJdLCJpYXQiOjE1NzA2MDY5ODV9.X7tj92tunUvx6PkDpj3LFsMVBs_SBYyKbIL_G9xKESA';
// 声明Cesium Viewer实例
let viewer = null;
// 声明变量用于存储事件处理器和绘制状态
let handler = null;
let activeShapePoints = [];
let activeShape = null;
let floatingPoint = null;
let excavateInstance = null;// 绘制状态提示
const drawingInstructions = ref('');// 组件挂载后初始化Cesium
onMounted(async () => {const files = ["./excavateTerrain/excavateTerrain.js"];loadScripts(files, function () {console.log("All scripts loaded");initMap();});
});
const loadScripts = (files, callback) => {// Make Cesium available globally for the scriptswindow.Cesium = Cesium;if (files.length === 0) {callback();return;}const file = files.shift();const script = document.createElement("script");script.onload = function () {loadScripts(files, callback);};script.src = file;document.head.appendChild(script);
};
const initMap = async () => {// 初始化Cesium Viewerviewer = new Cesium.Viewer('cesiumContainer', {// 基础配置animation: false, // 动画小部件baseLayerPicker: false, // 底图选择器fullscreenButton: false, // 全屏按钮vrButton: false, // VR按钮geocoder: false, // 地理编码搜索框homeButton: false, // 主页按钮infoBox: false, // 信息框 - 禁用点击弹窗sceneModePicker: false, // 场景模式选择器selectionIndicator: false, // 选择指示器timeline: false, // 时间轴navigationHelpButton: false, // 导航帮助按钮navigationInstructionsInitiallyVisible: false, // 导航说明初始可见性scene3DOnly: false, // 仅3D场景terrain: Cesium.Terrain.fromWorldTerrain(), // 使用世界地形});// 隐藏logoviewer.cesiumWidget.creditContainer.style.display = "none";viewer.scene.globe.enableLighting = true;// 禁用大气层和太阳viewer.scene.skyAtmosphere.show = false;//前提先把场景上的图层全部移除或者隐藏 // viewer.scene.globe.baseColor = Cesium.Color.BLACK; //修改地图蓝色背景viewer.scene.globe.baseColor = new Cesium.Color(0.0, 0.1, 0.2, 1.0); //修改地图为暗蓝色背景// 设置抗锯齿viewer.scene.postProcessStages.fxaa.enabled = true;// 清除默认底图viewer.imageryLayers.remove(viewer.imageryLayers.get(0));// 加载底图 - 使用更暗的地图服务const imageryProvider = await Cesium.ArcGisMapServerImageryProvider.fromUrl("https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer");viewer.imageryLayers.addImageryProvider(imageryProvider);// 设置默认视图位置 - 默认显示全球视图viewer.camera.setView({destination: Cesium.Cartesian3.fromDegrees(104.0, 30.0, 10000000.0), // 中国中部上空orientation: {heading: 0.0,pitch: -Cesium.Math.PI_OVER_TWO,roll: 0.0}});// 启用地形深度测试,确保地形正确渲染viewer.scene.globe.depthTestAgainstTerrain = true;// 清除默认地形// viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider({});// 开启帧率viewer.scene.debugShowFramesPerSecond = true;
}
// 开始绘制多边形
const startDrawPolygon = () => {// 清除之前的绘制clearDrawing();// 设置绘制提示drawingInstructions.value = '左键点击添加顶点,右键完成绘制';// 创建新的事件处理器handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);// 监听左键点击事件 - 添加顶点handler.setInputAction((click) => {// 获取点击位置的笛卡尔坐标const cartesian = viewer.scene.pickPosition(click.position);if (!Cesium.defined(cartesian)) {return;}// 将点添加到活动形状点数组activeShapePoints.push(cartesian);// 如果是第一个点,创建浮动点if (activeShapePoints.length === 1) {floatingPoint = createPoint(cartesian);// 创建动态多边形activeShape = createPolygon(activeShapePoints);}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);// 监听鼠标移动事件 - 更新动态多边形handler.setInputAction((movement) => {if (activeShapePoints.length >= 1) {const cartesian = viewer.scene.pickPosition(movement.endPosition);if (!Cesium.defined(cartesian)) {return;}// 更新浮动点位置if (floatingPoint) {floatingPoint.position.setValue(cartesian);}// 更新动态多边形if (activeShape) {const positions = activeShapePoints.concat([cartesian]);activeShape.polygon.hierarchy = new Cesium.PolygonHierarchy(positions);}}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);// 监听右键点击事件 - 完成绘制handler.setInputAction(() => {if (activeShapePoints.length < 3) {// 至少需要3个点才能形成多边形drawingInstructions.value = '至少需要3个点才能形成多边形,请继续绘制';return;}// 完成绘制terminateShape();// 执行地形开挖performExcavation(activeShapePoints);// 清除绘制状态drawingInstructions.value = '绘制完成,地形已开挖';// 清除事件处理器handler.destroy();handler = null;}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};// 创建点实体
const createPoint = (position) => {return viewer.entities.add({position: position,point: {color: Cesium.Color.WHITE,pixelSize: 10,heightReference: Cesium.HeightReference.CLAMP_TO_GROUND}});
};// 创建多边形实体
const createPolygon = (positions) => {return viewer.entities.add({polygon: {hierarchy: new Cesium.PolygonHierarchy(positions),material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.3)),outline: true,outlineColor: Cesium.Color.WHITE,// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND// 关键属性:贴地模式clampToGround: true,// 禁用挤压高度// height: 0,// height: 0,// perPositionHeight: false,// classificationType: Cesium.ClassificationType.BOTH,// zIndex: 100}});
};// 完成绘制形状
const terminateShape = () => {// 移除动态实体if (floatingPoint) {viewer.entities.remove(floatingPoint);floatingPoint = null;}if (activeShape) {viewer.entities.remove(activeShape);activeShape = null;}// 创建最终的多边形// if (activeShapePoints.length >= 3) {//   const finalPolygon = viewer.entities.add({//     polygon: {//       hierarchy: new Cesium.PolygonHierarchy(activeShapePoints),//       material: new Cesium.ColorMaterialProperty(Cesium.Color.GREEN.withAlpha(0.3)),//       outline: true,//       outlineColor: Cesium.Color.GREEN,//       height: 0,//       perPositionHeight: false,//       classificationType: Cesium.ClassificationType.BOTH,//       zIndex: 100//     }//   });// }
};// 执行地形开挖
const performExcavation = (positions) => {// 如果已有开挖实例,先尝试清除if (excavateInstance) {try {// 重置地形开挖viewer.scene.globe.clippingPlanes = undefined;viewer.entities.removeById("entityDM");viewer.entities.removeById("entityDMBJ");} catch (error) {console.error("清除之前的开挖失败", error);}}// 创建新的地形开挖实例excavateInstance = new excavateTerrain(viewer, {positions: positions,height: 50,bottom: "./excavateTerrain/excavationregion_side.jpg",side: "./excavateTerrain/excavationregion_top.jpg",});
};// 清除绘制
const clearDrawing = () => {// 清除事件处理器if (handler) {handler.destroy();handler = null;}// 清除动态实体if (floatingPoint) {viewer.entities.remove(floatingPoint);floatingPoint = null;}if (activeShape) {viewer.entities.remove(activeShape);activeShape = null;}// 清空点数组activeShapePoints = [];viewer.entities.removeAll();// 清除绘制提示drawingInstructions.value = '';// 重置地形开挖if (excavateInstance) {try {viewer.scene.globe.clippingPlanes = undefined;viewer.entities.removeById("entityDM");viewer.entities.removeById("entityDMBJ");excavateInstance = null;} catch (error) {console.error("清除地形开挖失败", error);}}
};// 组件卸载前清理资源
onUnmounted(() => {clearDrawing();if (viewer) {viewer.destroy();viewer = null;}
});
</script><style scoped>
.cesium-container {width: 100%;height: 100vh;margin: 0;padding: 0;overflow: hidden;position: relative;
}.control-panel {position: absolute;top: 20px;left: 20px;width: 300px;background-color: rgba(38, 38, 38, 0.85);border-radius: 8px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);color: white;z-index: 1000;overflow: hidden;transition: all 0.3s ease;
}.panel-header {background-color: rgba(0, 0, 0, 0.5);padding: 10px 15px;border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}.panel-header h3 {margin: 0;font-size: 16px;font-weight: 500;
}.panel-body {padding: 15px;
}.control-group {margin-bottom: 15px;
}.control-group label {display: block;margin-bottom: 5px;font-size: 14px;
}.control-group input[type="range"] {width: 100%;margin-bottom: 5px;background-color: rgba(255, 255, 255, 0.2);border-radius: 4px;
}.control-group span {font-size: 12px;color: rgba(255, 255, 255, 0.7);display: block;margin-top: 5px;line-height: 1.4;
}.control-group span {font-size: 12px;color: rgba(255, 255, 255, 0.7);
}.control-group button {background-color: #4285f4;color: white;border: none;padding: 8px 15px;border-radius: 4px;cursor: pointer;font-size: 14px;width: 100%;transition: background-color 0.3s ease;
}.control-group button:hover {background-color: #3367d6;
}
</style>

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

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

相关文章

qwen大模型在进行词嵌入向量时,针对的词表中的唯一数字还是其他的?

qwen大模型在进行词嵌入向量时,针对的词表中的唯一数字还是其他的? Qwen大模型进行词嵌入向量时,针对的是词表中每个 Token 对应的唯一数字(Token ID) ,核心逻辑结合词表构建、嵌入过程展开 一、Qwen 词表与 Token ID Qwen 用 BPE 分词器(基于 tiktoken,以 cl100k 为…

动态规划-1143.最长公共子序列-力扣(LeetCode)

一、题目解析 对于给定了两个字符串中&#xff0c;需要找到最长的公共子序列&#xff0c;也就是两个字符串所共同拥有的子序列。 二、算法原理 1、状态表示 dp[i][j]&#xff1a;表示s1的[0,i]和s2的[0,j]区间内所有子序列&#xff0c;最长子序列的长度 2、状态转移方程 根…

互联网c++开发岗位偏少,测开怎么样?

通过这标题&#xff0c;不难看出问这个问题的&#xff0c;就是没工作过的。如果工作过&#xff0c;那就是不断往深的钻研&#xff0c;路越走越窄&#xff0c;找工作一般就是找原来方向的。没工作过的&#xff0c;那一般就是学生。 学生找什么方向的工作比较好&#xff1f; 学生…

推荐算法八股

跑路了&#xff0c;暑期0offer&#xff0c;华为主管面挂了&#xff0c;真幽默&#xff0c;性格测评就挂了居然给我一路放到主管面&#xff0c;科大迅飞太嚣张&#xff0c;直接跟人说后面要面华为&#xff0c;元戎启行&#xff0c;学了C后python完全忘了怎么写&#xff0c;挺尴尬…

Spring Boot微服务架构(九):设计哲学是什么?

一、Spring Boot设计哲学是什么&#xff1f; Spring Boot 的设计哲学可以概括为 ​​“约定优于配置”​​ 和 ​​“开箱即用”​​&#xff0c;其核心目标是​​极大地简化基于 Spring 框架的生产级应用的初始搭建和开发过程​​&#xff0c;让开发者能够快速启动并运行项目…

前端导入Excel表格

前端如何在 Vue 3 中导入 Excel 文件&#xff08;.xls 和 .xlsx&#xff09;&#xff1f; 在日常开发中&#xff0c;我们经常需要处理 Excel 文件&#xff0c;比如导入数据表格、分析数据等。文章将在 Vue 3 中实现导入 .xls 和 .xlsx 格式的文件&#xff0c;并解析其中的数据…

C++和C#界面开发方式的全面对比

文章目录 C界面开发方式1. **MFC&#xff08;Microsoft Foundation Classes&#xff09;**2. **Qt**3. **WTL&#xff08;Windows Template Library&#xff09;**4. **wxWidgets**5. **DirectUI** C#界面开发方式1. **WPF&#xff08;Windows Presentation Foundation&#xf…

刷leetcode hot100返航必胜版--链表6/3

链表初始知识 链表种类&#xff1a;单链表&#xff0c;双链表&#xff0c;循环链表 链表初始化 struct ListNode{ int val; ListNode* next; ListNode(int x): val&#xff08;x&#xff09;,next(nullptr) {} }; //初始化 ListNode* head new ListNode(5); 删除节点、添加…

软考 系统架构设计师系列知识点之杂项集萃(78)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;77&#xff09; 第139题 以下关于软件测试工具的叙述&#xff0c;错误的是&#xff08;&#xff09;。 A. 静态测试工具可用于对软件需求、结构设计、详细设计和代码进行评审、走查和审查 B. 静…

【Unity】云渲染

1 前言 最近在搞Unity云渲染的东西&#xff0c;所以研究了下官方提供的云渲染方案Unity Renderstreaming。注&#xff1a;本文使用的Unity渲染管线是URP。 2 文档 本文也只是介绍基本的使用方法&#xff0c;更详细内容参阅官方文档。官方文档&#xff1a;Unity Renderstreamin…

组相对策略优化(GRPO):原理及源码解析

文章目录 PPO vs GRPOPPO的目标函数GRPO的目标函数KL散度约束与估计ORM监督RL的结果PRM监督RL的过程迭代RL算法流程 GRPO损失的不同版本GRPO源码解析 DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models PPO vs GRPO PPO的目标函数 J P P O…

Linux或者Windows下PHP版本查看方法总结

确定当前服务器或本地环境中 PHP 的版本,可以通过以下几种方法进行操作: 1. 通过命令行检查 这是最直接且常用的方法,适用于本地开发环境或有 SSH 访问权限的服务器。 方法一:php -v 命令 php -v输出示例:PHP 8.1.12 (cli) (built: Oct 12 2023 12:34:56) (NTS) Copyri…

[Linux] MySQL源码编译安装

目录 环境包安装 创建程序用户 解压源码包 配置cmake ​编辑编译 安装 配置修改属性 属主和属组替换成mysql用户管理 系统环境变量配置 初始化数据库 服务管理 启动 环境包安装 yum -y install ncurses ncurses-devel bison cmake gcc gcc-c 重点强调&#xff1a;采…

【C++项目】负载均衡在线OJ系统-1

文章目录 前言项目结果演示技术栈&#xff1a;结构与总体思路compiler编译功能-common/util.hpp 拼接编译临时文件-common/log.hpp 开放式日志-common/util.hpp 获取时间戳方法-秒级-common/util.hpp 文件是否存在-compile_server/compiler.hpp 编译功能编写&#xff08;重要&a…

转战海外 Web3 远程工作指南

目录 一、明确职业目标和技能 二、准备常用软件 &#xff08;一&#xff09;通讯聊天工具 &#xff08;二&#xff09;媒体类平台 &#xff08;三&#xff09;线上会议软件 &#xff08;四&#xff09;办公协作工具 &#xff08;五&#xff09;云存储工具 &#xff08;六…

MongoDB账号密码笔记

先连接数据库&#xff0c;新增用户密码 admin用户密码 use admin db.createUser({ user: "admin", pwd: "yourStrongPassword", roles: [ { role: "root", db: "admin" } ] })用户数据库用户密码 use myappdb db.createUser({ user: &…

CSS强制div单行显示不换行

在CSS中&#xff0c;要让<div>的内容强制单行显示且不换行&#xff0c;可通过以下属性组合实现&#xff1a; 核心解决方案&#xff1a; css 复制 下载 div {white-space: nowrap; /* 禁止文本换行 */overflow: hidden; /* 隐藏溢出内容 */text-overflow: e…

RK3568-快速部署codesys runtime

前期准备 PC-win10系统 RK3568-debian系统,内核已打入实时补丁,开启ssh服务。PC下载安装CODESYS Development System V3.5.17.0 https://store.codesys.com/en/codesys.html#product.attributes.wrapperPC下载安装 CODESYS Control for Linux ARM64 SL 4.1.0.0.package ht…

中英混合编码解码全解析

qwen模型分词器怎么映射的:中英混合编码解码全解析 中英文混合编码与解码的过程,本质是 字符编码标准(如 UTF-8)对多语言字符的统一处理 ,核心逻辑围绕“字节序列 ↔ 字符映射”展开 北京智源人工智能研究院中文tokenID qwen模型分词器文件 一、编码阶段:统一转为字节序…

React 事件处理与合成事件机制揭秘

引言 在现代前端开发的技术生态中&#xff0c;React凭借其高效的组件化设计和声明式编程范式&#xff0c;已成为构建交互式用户界面的首选框架之一。除了虚拟DOM和单向数据流等核心概念&#xff0c;React的事件处理系统也是其成功的关键因素。 这套系统通过"合成事件&qu…