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

article/2025/6/15 5:35:25

基于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.hkcw.cn/article/eLPyRsxFmu.shtml

相关文章

Ubuntu 系统部署 MySQL 入门篇

一、安装 MySQL 1.1 更新软件包 在终端中执行以下命令&#xff0c;更新系统软件包列表&#xff0c;确保安装的是最新版本的软件&#xff1a; sudo apt update 1.2 安装 MySQL 执行以下命令安装 MySQL 服务端&#xff1a; sudo apt install mysql-server 在安装过程中&…

机器学习——主成分分析PCA

主成分分析—PCA 一、主成分分析简介1. PCA概述2. 降维 & PCA3. PCA的优缺点 二、PCA的数学基础1. 方差2. 协方差矩阵3. 特征值和特征向量 三、PCA的算法流程1. 标准化数据2. 计算协方差矩阵3.计算特征值和特征向量4. 选择主成分5. 数据投影 四、代码分析&#xff08;人脸识…

连接关键点:使用 ES|QL 联接实现更丰富的可观测性洞察

作者&#xff1a;来自 Elastic Luca Wintergerst ES|QL 的 LOOKUP JOIN 现已进入技术预览阶段&#xff0c;它允许你在查询时对日志、指标和追踪进行丰富处理&#xff0c;无需在摄取时进行非规范化。动态添加部署、基础设施或业务上下文&#xff0c;减少存储占用&#xff0c;加速…

专家:乌军“蛛网”行动影响深远 无人机开启新战局

乌克兰在大规模使用无人机发动特种攻击方面再次震惊了世界。6月1日,乌克兰国家安全局对俄罗斯境内多地的军用机场发动大规模无人机攻击,声称摧毁了“多达41架战略轰炸机”。俄罗斯方面承认乌军无人机成功袭击的事实,但表示损失没有那么大。西方媒体认为,乌方使用的这种无人…

西北华北华南大片区域高温来袭 多地将迎35℃以上高温

今明两天(6月3日至4日),我国降雨主要出现在云南和华南沿海、东北地区等地,局地还可能伴有强对流天气。随着高压脊东移,北方大部气温逐渐升高,华北、黄淮等地高温天气将发展增多,南方多地5日起也将加入高温行列。昨天,冷空气南下导致南方强降雨区域南压至华南和云南一带…

美拆解首艘核动力航母要花多少钱 5亿多美元启动拆解

美国《星条旗报》网站报道,世界上第一艘核动力航母“企业”号将在亚拉巴马州拆解。佛蒙特州的一家公司获得了超过5亿美元的资金,用于拆除停放在亚拉巴马州莫比尔市的这艘历史悠久的航母。五角大楼发布的采购公告显示,位于佛蒙特州弗农的北极星海事拆卸服务有限责任公司获得了…

基于AI的6个学术搜索工具推荐:功能特点与适用场景分析

和传统的学术搜索平台pubmed、google scholar相比&#xff0c;AI驱动的学术搜索引擎不再依赖简单的关键词匹配&#xff0c;而是通过理解用户意图和语境&#xff0c;实现更精准、更具上下文关联的检索结果&#xff0c;并能够将搜索内容总结为完整答案。 除了Perplexity和秘塔AI搜…

scrapy练习笔记

scrapy练习 文章目录 scrapy练习一、scrapy安装二、scrapy基本流程2.1 学习目标2.2 创建一个新项目2.3 创建Item2.4 解析 Response2.5 使用 Item2.6 开始爬取 三、爬取多页3.1 练习3.2 输出格式3.3 使用 Item Pipeline 暂时到这 一、scrapy安装 官网&#xff1a;https://www.s…

cmake学习1

基本起点 本笔记的主要参考文献是cmake文档&#xff0c;对文档的二次提炼和补充学习。 1. cmake_minimum_required() 任何项目的最顶层CMakeLists.txt都必须首先使用 cmake_minimum_required() 命令指定最低 CMake 版本。这建立策略设置并确保以下 CMake 函数以兼容的 CMake…

基与OpenCV实现单目相机实时追踪对物体的测量算法(Android版)

本人原创转载请注明出处 前言 本算法是基于摄像头到测量物体的已知距离和摄像头像素焦距的前提下测量物体的宽高&#xff0c;并根据参照物的实际尺寸测量其他物体。 效果图 准备环境 1.首先硬件你要有一个摄像头&#xff0c;最好是USB即插即用免驱的 2.我使用的是12寸的安…

【计算机视觉】单目深度估计模型-Depth Anything-V2

概述 本篇将简单介绍Depth Anything V2单目深度估计模型&#xff0c;该模型旨在解决现有的深度估计模型在处理复杂场景、透明或反射物体时的性能限制。与前一代模型相比&#xff0c;V2版本通过采用合成图像训练、增加教师模型容量&#xff0c;并利用大规模伪标签现实数据进行学…

常见离线语音识别模块功能说明——天问ASR;机芯智能;海凌科;轻语音

本文章从开发方式及功能等方面上进行说明&#xff0c;便于开发者进行选择与开发。 本文章依据截至2024年8月1日各网站资料进行整理编写。 总结&#xff1a; 开发方式上&#xff1a; 天文ASR 有着最灵活的开发方式&#xff0c;可完全按照程序员意愿进行开发&#xff0c;同时有…

Whisper.cpp + GPU 加速全攻略:Mac M 芯片高效转录音频教程

内容预告 本文将手把手教你如何利用 GPU 加速&#xff0c;在 Mac M 芯片上使用 Whisper 进行音频转文字&#xff0c;大幅提升转录效率。 本教程涵盖&#xff1a; Whisper.cpp 简介&#xff1a;为什么它适用于本地语音转写&#xff1f;Mac M 芯片的 GPU 加速&#xff1a;如何…

ROS2 与机器人视觉入门教程(ROS2 OpenCV)

系列文章目录 目录 系列文章目录 前言 一、 1.1 先决条件 1.1.1 安装 0. 安装要求 1. 安装 ROS2&#xff1a; 2. cv_bridge 1.2 获取机器人视觉库简介&#xff1a; 1.2.1 克隆该资源库 1.2.2 下载附加数据 1.2.3 编译代码 1.3 测试代码 二、ROS2 中的图像发布者…

计算机视觉:扩散模型(Diffusion Models)在图像生成中的突破

计算机视觉:扩散模型(Diffusion Models)在图像生成中的突破 一、前言二、扩散模型基础概念​2.1 马尔可夫链(Markov Chain)​2.2 扩散过程(Diffusion Process)​2.3 逆扩散过程(Reverse Diffusion Process)​三、扩散模型在图像生成中的原理​3.1 训练阶段​3.2 推理阶…

深入了解视频质量诊断的关键技术要点

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;视频质量诊断是IT行业中的关键任务&#xff0c;它包括多个领域的专业知识&#xff0c;用于确保视频内容的高质量呈现。本文将详细解析与视频质量诊断相关的各个技术要点&#xff0c;包括视频编码技术、分辨率和…

高效降噪不求人!精选6款音频降噪免费软件助你一键消噪

你是否也常常被音频中的噪音困扰&#xff1f;环境杂音、设备电流声、甚至呼吸声&#xff0c;都可能让精心录制的内容大打折扣。 本文从百款工具中实测筛选出6款还不错的会议录音降噪处理工具。无论你是剪辑小白还是职业后期&#xff0c;3分钟快速匹配你的降噪刚需&#xff01;…

深度学习目标检测构建基于YOLOv8的人体动作识别系统,如何使系统能够通过GUI界面支持图片、视频和摄像头输入,来识别人体动作站立,行走,摔倒,弯腰,坐立进行检测

深度学习目标检测构建基于YOLOv8的人体动作识别系统&#xff0c;如何使系统能够通过GUI界面支持图片、视频和摄像头输入&#xff0c;来识别人体动作站立&#xff0c;行走&#xff0c;摔倒&#xff0c;弯腰&#xff0c;坐立进行检测 文章目录 1. 环境配置2. 数据准备与模型训练…

猫粮哪个牌子质量好性价比高?安全猫粮选购推荐

从开始养猫到现在也算是有10年的铲屎年龄了&#xff0c;先后经历了膨化粮、烘焙猫粮以及猫罐头的喂养时期。结果这么多年过去了&#xff0c;现在喂的最多的还是烘焙猫粮&#xff0c;低温工艺留住大部分营养&#xff0c;不会让猫咪黑下巴&#xff0c;适口性也更好&#xff0c;性…

重塑在线软件开发新纪元:集成高效安全特性,深度解析与评估会员与促销管理系统的系统架构设计

案例 阅读以下关于软件架构设计与评估的叙述&#xff0c;回答问题1和问题2。 【题目】 某电子商务公司拟升级其会员与促销管理系统&#xff0c;向用户提供个性化服务&#xff0c;提高用户的粘性。在项目立项之初&#xff0c;公司领导层一致认为本次升级的主要目标是提升会员管…