乐于分享
好东西不私藏

vue+cesium示例:坡向分析(附源码下载)

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>  <divid="cesiumContainer"class="cesium-container">  </div></template><scriptsetup>import { onMounted, onUnmounted, ref } from 'vue';import * as Cesium from 'cesium';Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxZjhjYjhkYS1jMzA1LTQ1MTEtYWE1Mi0zODc5NDljOGVkMDYiLCJpZCI6MTAzNjEsInNjb3BlcyI6WyJhc2wiLCJhc3IiLCJhc3ciLCJnYyJdLCJpYXQiOjE1NzA2MDY5ODV9.X7tj92tunUvx6PkDpj3LFsMVBs_SBYyKbIL_G9xKESA';// 声明Cesium Viewer实例let viewer = null;// 组件挂载后初始化CesiumonMounted(async () => {  initMap();});const initMap = async () => {  // 初始化Cesium Viewer  viewer = new Cesium.Viewer('cesiumContainer', {    // 基础配置    animationfalse// 动画小部件    baseLayerPickerfalse// 底图选择器    fullscreenButtonfalse// 全屏按钮    vrButtonfalse// VR按钮    geocoderfalse// 地理编码搜索框    homeButtonfalse// 主页按钮    infoBoxfalse// 信息框 - 禁用点击弹窗    sceneModePickerfalse// 场景模式选择器    selectionIndicatorfalse// 选择指示器    timelinefalse// 时间轴    navigationHelpButtonfalse// 导航帮助按钮    navigationInstructionsInitiallyVisiblefalse// 导航说明初始可见性    scene3DOnlyfalse// 仅3D场景    // terrain: Cesium.Terrain.fromWorldTerrain(), // 使用世界地形  });  // 隐藏logo  viewer.cesiumWidget.creditContainer.style.display = "none";  viewer.scene.globe.enableLighting = false;  // 禁用大气层和太阳  viewer.scene.skyAtmosphere.show = false;  //前提先把场景上的图层全部移除或者隐藏   // viewer.scene.globe.baseColor = Cesium.Color.BLACK; //修改地图蓝色背景  viewer.scene.globe.baseColor = new Cesium.Color(0.00.10.21.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.scene.debugShowFramesPerSecond = true;  viewer.scene.globe.depthTestAgainstTerrain = true;  // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({  //   url: '//data.mars3d.cn/terrain'  // });  const terrainProvider = await Cesium.CesiumTerrainProvider.fromIonAssetId(3956);  viewer.terrainProvider = terrainProvider;  viewer.camera.flyTo({    destinationCesium.Cartesian3.fromDegrees(      114.20597076416016,      31.15141366186558      , 5000.0)  });  //坡向分析  class falling {    constructor(viewer, config) {      this.viewer = viewer;      this.config = config;      this.loadResult();    }    loadResult() {      let _this = this;      const startx1 = _this.config.positons[0];      const starty1 = _this.config.positons[1];      const startx2 = _this.config.positons[2];      const starty2 = _this.config.positons[3];      const startx3 = _this.config.positons[4];      const starty3 = _this.config.positons[5];      const startx4 = _this.config.positons[6];      const starty4 = _this.config.positons[7];      //坡向显示      function analysis(startx1, starty1, startz1, startx2, starty2, startz2, startx3, starty3, startz3, startx4, starty4, startz4) {        //高度z全为0        const count = 100;        let slopelineposition = [];        let hireacys = [];        let hireacysdistance = []        for (let j = 0; j < 100; j++) {          for (let i = 0; i < 100; i++) {            let hireacy = [];            //分割成小面,切分经纬度            hireacy.push(new Cesium.Cartesian3(startx1 + (startx2 - startx1) / count * i + (startx4 + (startx3 - startx4) / count * (i) - startx1 - (startx2 - startx1) / count * i) / count * j,              starty1 + (starty2 - starty1) / count * i + (starty4 + (starty3 - starty4) / count * (i) - starty1 - (starty2 - starty1) / count * i) / count * j,              startz1 + (startz2 - startz1) / count * i + (startz4 + (startz3 - startz4) / count * (i) - startz1 - (startz2 - startz1) / count * i) / count * j))            hireacy.push(new Cesium.Cartesian3(startx1 + (startx2 - startx1) / count * (i + 1) + (startx4 + (startx3 - startx4) / count * (i + 1) - startx1 - (startx2 - startx1) / count * (i + 1)) / count * j,              starty1 + (starty2 - starty1) / count * (i + 1) + (starty4 + (starty3 - starty4) / count * (i + 1) - starty1 - (starty2 - starty1) / count * (i + 1)) / count * j,              startz1 + (startz2 - startz1) / count * (i + 1) + (startz4 + (startz3 - startz4) / count * (i + 1) - startz1 - (startz2 - startz1) / count * (i + 1)) / count * j))            hireacy.push(new Cesium.Cartesian3(startx4 + (startx3 - startx4) / count * (i + 1) - (startx4 + (startx3 - startx4) / count * (i + 1) - startx1 - (startx2 - startx1) / count * (i + 1)) / count * (count - 1 - j),              starty4 + (starty3 - starty4) / count * (i + 1) - (starty4 + (starty3 - starty4) / count * (i + 1) - starty1 - (starty2 - starty1) / count * (i + 1)) / count * (count - 1 - j),              startz4 + (startz3 - startz4) / count * (i + 1) - (startz4 + (startz3 - startz4) / count * (i + 1) - startz1 - (startz2 - startz1) / count * (i + 1)) / count * (count - 1 - j)))            hireacy.push(new Cesium.Cartesian3(startx4 + (startx3 - startx4) / count * i - (startx4 + (startx3 - startx4) / count * (i) - startx1 - (startx2 - startx1) / count * i) / count * (count - 1 - j),              starty4 + (starty3 - starty4) / count * i - (starty4 + (starty3 - starty4) / count * (i) - starty1 - (starty2 - starty1) / count * i) / count * (count - 1 - j),              startz4 + (startz3 - startz4) / count * i - (startz4 + (startz3 - startz4) / count * (i) - startz1 - (startz2 - startz1) / count * i) / count * (count - 1 - j)))            hireacys.push(hireacy);            //取出面的8个点坐标,拿点坐标去求高度值            slopelineposition.push(Cesium.Cartographic.fromDegrees(hireacy[0].x, hireacy[0].y));            slopelineposition.push(Cesium.Cartographic.fromDegrees((hireacy[0].x + hireacy[1].x) / 2, (hireacy[0].y + hireacy[1].y) / 2));            slopelineposition.push(Cesium.Cartographic.fromDegrees(hireacy[1].x, hireacy[1].y));            slopelineposition.push(Cesium.Cartographic.fromDegrees((hireacy[1].x + hireacy[2].x) / 2, (hireacy[1].y + hireacy[2].y) / 2));            slopelineposition.push(Cesium.Cartographic.fromDegrees(hireacy[2].x, hireacy[2].y));            slopelineposition.push(Cesium.Cartographic.fromDegrees((hireacy[2].x + hireacy[3].x) / 2, (hireacy[2].y + hireacy[3].y) / 2));            slopelineposition.push(Cesium.Cartographic.fromDegrees(hireacy[3].x, hireacy[3].y));            slopelineposition.push(Cesium.Cartographic.fromDegrees((hireacy[3].x + hireacy[0].x) / 2, (hireacy[3].y + hireacy[0].y) / 2));          }        }        const promise = Cesium.sampleTerrainMostDetailed(_this.config.terrainProvider, slopelineposition);        promise.then(function (updatedPositions) {          //拿到所有的高度数据          let heighmm = [];          let m = 0          //计算坡度比的次数          let countcolor1 = 0;          let countcolor2 = 0;          let countcolor3 = 0;          let countcolor4 = 0;          let countcolor5 = 0;          let countcolor6 = 0;          let countcolor7 = 0;          for (let k = 0; k < updatedPositions.length / 8; k++) {            //第一个点与第五个点的坡度            let slope1 = (updatedPositions[m].height - updatedPositions[m + 4].height) / (Cesium.Cartesian3.distance(              Cesium.Cartesian3.fromDegrees(updatedPositions[m].latitude, updatedPositions[m].longitude, updatedPositions[m].height),              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 4].latitude, updatedPositions[m + 4].longitude, updatedPositions[m + 4].height)))            //第二个点与第六个点的坡度            let slope2 = (updatedPositions[m + 1].height - updatedPositions[m + 5].height) / (Cesium.Cartesian3.distance(              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 1].latitude, updatedPositions[m + 1].longitude, updatedPositions[m + 1].height),              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 5].latitude, updatedPositions[m + 5].longitude, updatedPositions[m + 5].height)))            //第三个点与第七个点的坡度            let slope3 = (updatedPositions[m + 2].height - updatedPositions[m + 6].height) / (Cesium.Cartesian3.distance(              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 2].latitude, updatedPositions[m + 2].longitude, updatedPositions[m + 2].height),              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 6].latitude, updatedPositions[m + 6].longitude, updatedPositions[m + 6].height)))            //第四个点与第八个点的坡度            let slope4 = (updatedPositions[m + 3].height - updatedPositions[m + 7].height) / (Cesium.Cartesian3.distance(              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 3].latitude, updatedPositions[m + 3].longitude, updatedPositions[m + 3].height),              Cesium.Cartesian3.fromDegrees(updatedPositions[m + 7].latitude, updatedPositions[m + 7].longitude, updatedPositions[m + 7].height)))            // console.log("slope1:"+slope1+";slope2:"+slope2+";slope3:"+slope3+";slope4:"+slope4);            let arrposition = [Math.abs(slope1), Math.abs(slope2), Math.abs(slope3), Math.abs(slope4)];//取绝对值            arrposition.sort();            let slope = arrposition[3]; // 拿到最大的坡度值              let lineposition = [];//画方向线的坐标            if (slope == Math.abs(slope1)) {              if (slope1 > 0) {                lineposition.push(Cesium.Math.toDegrees(updatedPositions[m].longitude), Cesium.Math.toDegrees(updatedPositions[m].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 4].longitude), Cesium.Math.toDegrees(updatedPositions[m + 4].latitude));              } else {                lineposition.push(                  Cesium.Math.toDegrees(updatedPositions[m + 4].longitude), Cesium.Math.toDegrees(updatedPositions[m + 4].latitude),                  Cesium.Math.toDegrees(updatedPositions[m].longitude), Cesium.Math.toDegrees(updatedPositions[m].latitude));              }            } else if (slope == Math.abs(slope2)) {              if (slope2 > 0) {                lineposition.push(Cesium.Math.toDegrees(updatedPositions[m + 1].longitude), Cesium.Math.toDegrees(updatedPositions[m + 1].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 5].longitude), Cesium.Math.toDegrees(updatedPositions[m + 5].latitude));              } else {                lineposition.push(                  Cesium.Math.toDegrees(updatedPositions[m + 5].longitude), Cesium.Math.toDegrees(updatedPositions[m + 5].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 1].longitude), Cesium.Math.toDegrees(updatedPositions[m + 1].latitude));              }            } else if (slope == Math.abs(slope3)) {              if (slope3 > 0) {                lineposition.push(Cesium.Math.toDegrees(updatedPositions[m + 2].longitude), Cesium.Math.toDegrees(updatedPositions[m + 2].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 6].longitude), Cesium.Math.toDegrees(updatedPositions[m + 6].latitude));              } else {                lineposition.push(                  Cesium.Math.toDegrees(updatedPositions[m + 6].longitude), Cesium.Math.toDegrees(updatedPositions[m + 6].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 2].longitude), Cesium.Math.toDegrees(updatedPositions[m + 2].latitude));              }            } else if (slope == Math.abs(slope4)) {              if (slope4 > 0) {                lineposition.push(Cesium.Math.toDegrees(updatedPositions[m + 3].longitude), Cesium.Math.toDegrees(updatedPositions[m + 3].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 7].longitude), Cesium.Math.toDegrees(updatedPositions[m + 7].latitude));              } else {                lineposition.push(                  Cesium.Math.toDegrees(updatedPositions[m + 7].longitude), Cesium.Math.toDegrees(updatedPositions[m + 7].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 3].longitude), Cesium.Math.toDegrees(updatedPositions[m + 3].latitude));              }            }            slope = (Math.abs(slope1) + Math.abs(slope2) + Math.abs(slope3) + Math.abs(slope4)) / 4//四个坡度值大小有的差值特别大,这里取的平均值用来配置颜色            //console.log(slope);            let slopecolor;            if (0 <= slope && slope < 0.29) {              slopecolor = '#ff9090'              countcolor1++;            } else if (0.29 <= slope && slope < 0.5) {              slopecolor = '#ff8080'              countcolor2++;            } else if (0.5 <= slope && slope < Math.sqrt(2) / 2) {              slopecolor = '#ff7070'              countcolor3++;            } else if (Math.sqrt(2) / 2 <= slope && slope < 0.87) {              slopecolor = '#ff6060'              countcolor4++;            } else if (0.87 <= slope && slope < 0.91) {              slopecolor = '#ff5050'              countcolor5++;            } else if (0.91 <= slope && slope < 0.95) {              slopecolor = '#ff4040'              countcolor6++;            } else {              slopecolor = '#ff3030'              countcolor7++;            }            _this.viewer.entities.add({              //type: 'drawSloperectange',              rectangle: {                coordinatesCesium.Rectangle.fromDegrees(                  Cesium.Math.toDegrees(updatedPositions[m].longitude), Cesium.Math.toDegrees(updatedPositions[m].latitude),                  Cesium.Math.toDegrees(updatedPositions[m + 4].longitude), Cesium.Math.toDegrees(updatedPositions[m + 4].latitude))                ,                materialCesium.Color.fromCssColorString(slopecolor)              },            }            );            ……          }        });      }    }  }</script>

源码下载

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » vue+cesium示例:坡向分析(附源码下载)

评论 抢沙发

5 + 9 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮