Bladeren bron

场景想定

wuxiang 2 jaren geleden
bovenliggende
commit
0774a87453
4 gewijzigde bestanden met toevoegingen van 1187 en 582 verwijderingen
  1. 658 577
      package-lock.json
  2. 3 0
      package.json
  3. 424 0
      src/views/situation/index.vue
  4. 102 5
      vue.config.js

File diff suppressed because it is too large
+ 658 - 577
package-lock.json


+ 3 - 0
package.json

@@ -12,6 +12,8 @@
   "dependencies": {
     "axios": "^0.18.0",
     "bpmn-js-token-simulation": "^0.10.0",
+    "cesium": "1.93",
+    "copy-webpack-plugin": "^5.0.0",
     "core-js": "^3.6.4",
     "echarts": "^4.2.1",
     "element-ui": "^2.13.0",
@@ -24,6 +26,7 @@
     "lodash": "^4.17.5",
     "min-dash": "^3.5.2",
     "register-service-worker": "^1.6.2",
+    "screenfull": "^5.1.0",
     "sortablejs": "^1.7.0",
     "v-charts": "^1.19.0",
     "vue": "^2.6.11",

+ 424 - 0
src/views/situation/index.vue

@@ -0,0 +1,424 @@
+<template>
+    <div class="container">
+      <el-row style="height:50px;">
+        <div class="header" >
+          <el-button :type="(this.dimension==2?'success':'danger')" @click="dimensionswitch(2)" round>二维</el-button>
+          <el-button :type="(this.dimension==3?'success':'danger')" @click="dimensionswitch(3)" round>三维</el-button>
+          <el-button :type="(this.dimension==5?'success':'danger')" @click="dimensionswitch(5)" round>一体化</el-button>
+        </div>
+      </el-row>
+      <el-row style="height:calc(100% - 50px);display:flex;position: relative;">
+        <el-col style="height:100%;position: relative;" :span="this.leftwidth"  >
+          <div class="main-layout" v-on:mouseover="changeActive('3D')">
+            <div id="3DcesiumContainer" class="map"></div>
+          </div>
+        </el-col>
+        <el-col style="height:100%;position: relative;" :span="(24-this.leftwidth)" >
+          <div class="main-layout" v-on:mouseover="changeActive('2D')">
+            <div id="2DcesiumContainer" class="map"></div>
+          </div>
+        </el-col>
+        <el-tabs type="border-card" v-model="activeName" tab-position="left" class="menu" :stretch="true" @tab-click="legendClick">
+        <el-tab-pane name="first">
+          <span slot="label">
+          <el-tooltip class="item" effect="dark" content="标绘" placement="left">
+            <i class="el-icon-wind-power"></i>
+          </el-tooltip>
+          </span>
+        </el-tab-pane>
+        <el-tab-pane name="second">
+          <span slot="label">
+          <el-tooltip class="item" effect="dark" content="模型" placement="left">
+            <i class="el-icon-receiving"></i>
+          </el-tooltip>
+          </span>
+        </el-tab-pane>
+        </el-tabs>
+        <div class="buttons">
+          <el-button icon="el-icon-full-screen" circle @click="ismax()"></el-button>
+          <el-button icon="el-icon-coin" circle></el-button>
+          <el-button icon="el-icon-bangzhu" @click="Fly()" circle></el-button>
+          <el-button icon="el-icon-house" circle @click="home()"></el-button>
+          <el-button icon="el-icon-plus" circle  @click="big()"></el-button>
+          <el-button icon="el-icon-minus" circle  @click="small()"></el-button>
+        </div>
+      </el-row>
+      
+    </div>
+  </template>
+  <script>
+  import screenfull from "screenfull";
+  export default ({
+    computed: {
+  
+    },
+    
+    data() {
+      return {
+        viewer2D: null,
+        viewer3D: null,
+        dimension: 3,
+        leftwidth: 0,
+        mousevalue: null,
+        shouldAnimate: false,
+        activeName: 'first',
+        currentLab: {
+        index: -1,
+        isActive: false
+      }
+  
+  
+  
+      }
+  
+    },
+    mounted() {
+      
+      this.cesiumInit();
+      
+    },
+  
+    methods: {
+      
+      cesiumInit() {
+        this.viewer2D = new this.Cesium.Viewer("2DcesiumContainer", {
+            sceneMode: this.Cesium.SceneMode.SCENE2D,
+            animation: false, // 是否显示时间轴动画
+            baseLayerPicker: false,
+            homeButton: false,
+            geocoder: false,
+            timeline: false,
+            fullscreenButton: false,
+            sceneModePicker: false,
+            navigationHelpButton: false,
+            selectionIndicator: false,
+            imageryProvider: new this.Cesium.UrlTemplateImageryProvider({
+              url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
+              layer: "tdtVecBasicLayer",
+              style: "default",
+              format: "image/png",
+              tileMatrixSetID: "GoogleMapsCompatible",
+              show: false
+                  })
+               
+      
+        });
+  
+        this.viewer3D = new this.Cesium.Viewer('3DcesiumContainer', {
+          animation: false, // 是否显示时间轴动画
+          baseLayerPicker: false,
+          homeButton: false,
+          geocoder: false,
+          timeline: false,
+          fullscreenButton: false,
+          sceneModePicker: false,
+          navigationHelpButton: false,
+          selectionIndicator: false,
+          // imageryProvider:  new this.Cesium.WebMapServiceImageryProvider({
+          //   url: '/geoserver/map/wms',
+          //     // 这里是自定义的图层名称
+          //     layers: 'map',
+          //     parameters: {
+          //         service: 'WMS',
+          //         format: 'image/png',
+          //         transparent: true
+          //     }
+          // }),
+  
+        imageryProvider:  
+        // new this.Cesium.WebMapTileServiceImageryProvider({
+        //     url: "http://10.170.16.95:8080/geoserver/gwc/service/wmts/rest/map:map/{style}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png",
+        //     layer: 'map:map',
+        //     style: 'raster',
+        //     format: 'image/png',
+        //     tileMatrixSetID: 'EPSG:900913',      //一般使用EPSG:3857坐标系
+          
+        //   }),
+        new this.Cesium.UrlTemplateImageryProvider({
+                  url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
+                  layer: "tdtVecBasicLayer",
+                  style: "default",
+                  format: "image/png",
+                  tileMatrixSetID: "GoogleMapsCompatible",
+                  show: false
+              })
+              });
+  
+        this.viewer3D._cesiumWidget._creditContainer.style.display = "none";
+        this.viewer2D._cesiumWidget._creditContainer.style.display = "none";
+        this.viewer3D.camera.setView({
+          destination: new this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000),
+          // 方向,俯视和仰视的视角
+          // orientation:{
+          //   heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
+          //   pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
+          // }
+        })
+        this.viewer2D.camera.setView({
+          destination: new this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000),
+          // 方向,俯视和仰视的视角
+          // orientation:{
+          //   heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
+          //   pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
+          // }
+        })
+        // this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 1500000;  //相机高度的最大值
+        this.viewer2D.camera.percentageChanged = 0.01;
+        this.viewer2D.camera.changed.addEventListener(this.sync);
+        this.viewer3D.camera.percentageChanged = 0.01;
+        this.viewer3D.camera.changed.addEventListener(this.sync);
+      },
+      removeAllModel(){
+        this.viewer.entities.removeAll(); // 移除全部模型
+      },
+      sync() {
+        
+        if(this.mousevalue=='3D'){
+            // 三维地图中心点
+            let center = new this.Cesium.Cartesian2(
+                Math.floor(this.viewer3D.canvas.clientWidth / 2),
+                Math.floor(this.viewer3D.canvas.clientHeight / 2)
+            );
+          
+          
+  
+            // 转为世界坐标系
+            let position = this.viewer3D.scene.camera.pickEllipsoid(center);
+            console.log(position);
+            // 判断中心点是否在椭球体上
+            if (this.Cesium.defined(position)) {
+  
+                // 获取三维地图中心点与相机之间的距离
+                let distance = this.Cesium.Cartesian3.distance(
+                    position,
+                    this.viewer3D.scene.camera.positionWC
+                );
+                position = this.convertWorldToCartographic(position)
+                // 更新二维地图
+                this.viewer2D.scene.camera.setView({
+                destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude,position.latitude,distance),
+        })
+                console.log(distance);
+            }
+          }
+      if(this.mousevalue=='2D'){
+          // 二维地图中心点
+        let center = new this.Cesium.Cartesian2(
+            Math.floor(this.viewer2D.canvas.clientWidth / 2),
+            Math.floor(this.viewer2D.canvas.clientHeight / 2)
+        );
+        // 转为世界坐标系
+        let position = this.viewer2D.scene.camera.pickEllipsoid(center);
+        console.log(position);
+        // 判断中心点是否在椭球体上
+        if (this.Cesium.defined(position)) {
+  
+            // 获取三维地图中心点与相机之间的距离
+            let distance =  this.viewer2D.scene.camera.positionCartographic.height;
+  
+            position = this.convertWorldToCartographic(position)
+            // 更新三维地图
+            this.viewer3D.scene.camera.setView({
+                destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude,position.latitude,distance),
+        })
+            console.log(this.viewer2D.scene.camera.positionWC)
+        }
+      }},
+            // 将世界坐标系转换为经纬度坐标系
+        convertWorldToCartographic(worldPosition) {
+          const ellipsoid = this.viewer2D.scene.globe.ellipsoid;
+          const cartographic = ellipsoid.cartesianToCartographic(worldPosition);
+          const longitude = this.Cesium.Math.toDegrees(cartographic.longitude);
+          const latitude = this.Cesium.Math.toDegrees(cartographic.latitude);
+          const height = cartographic.height;
+          return { longitude, latitude, height };
+        },
+        // 监听地图变化
+        changeActive(value){
+          this.mousevalue = value 
+          console.log(value)
+      },
+      dimensionswitch(value){
+        this.dimension = value
+        if(value == 3) {
+          this.leftwidth = 24;
+        }else if(value == 2){
+          this.leftwidth = 0;
+  
+        }else{
+          this.leftwidth = 12;
+        }
+      },
+      //全屏缩小
+      ismax(){
+        if(screenfull.isEnabled && screenfull.isFullscreen){
+          screenfull.exit();
+        }else{
+          screenfull.request();
+        }
+      },
+       /* 获取camera中心点坐标 */
+       getCenterPosition () {
+        var result = this.viewer2D.camera.pickEllipsoid(new this.Cesium.Cartesian2(this.viewer2D.canvas.clientWidth / 2, this.viewer2D.canvas
+          .clientHeight / 2))
+        var curPosition = this.Cesium.Ellipsoid.WGS84.cartesianToCartographic(result)
+        var lon = curPosition.longitude * 180 / Math.PI
+        var lat = curPosition.latitude * 180 / Math.PI
+        var height = this.viewer2D.camera.positionCartographic.height
+        return {
+          lon: lon,
+          lat: lat,
+          height: height
+        }
+      },
+  
+      /* 地图放大 */
+      big () {
+        // 镜头拉进
+        this.viewer2D.camera.flyTo({
+          destination: this.Cesium.Cartesian3.fromDegrees(this.getCenterPosition().lon, this.getCenterPosition().lat, this.getCenterPosition().height / 1.8),
+          duration: 1.0
+        })
+      },
+      /* 地图缩小 */
+      small () {
+        // 镜头远离
+        this.viewer2D.camera.flyTo({
+          destination: this.Cesium.Cartesian3.fromDegrees(this.getCenterPosition().lon, this.getCenterPosition().lat, this.getCenterPosition().height * 1.2),
+          duration: 1.0
+        })
+      },
+      home () {
+          this.viewer2D.camera.flyTo({
+                  destination: this.Cesium.Cartesian3.fromDegrees(117.918977,25.0,1500000)
+              });
+      },
+      Fly() {
+        this.shouldAnimate = !this.shouldAnimate
+        this.viewer2D.clock.shouldAnimate = true
+        this.viewer3D.clock.shouldAnimate = true
+        if(this.shouldAnimate == true){
+          this.startRun({ multiplier: 2000 })
+        }else{
+          this.stopRun()
+        }
+      },
+      startRun (option = { multiplier: 1 }) {
+         // 监听每次渲染前执行矩阵求解
+        this.viewer3D.scene.postUpdate.addEventListener(this.rotateSetting) 
+        // 根据option修改一些参数
+        if (this.viewer3D.clock) {
+          const keys = Object.keys(option)
+          for (let k of keys) {
+            this.viewer3D.clock[k] = option[k]
+          }
+        }
+      },
+      stopRun () {
+        let viewer = this.viewer3D
+        viewer.clock.multiplier = 1
+        viewer.scene.postUpdate.removeEventListener(this.rotateSetting)
+      },
+      rotateSetting () {
+            let Cesium = this.Cesium
+            let viewer = this.viewer3D
+            if (!viewer || viewer.scene.mode !== Cesium.SceneMode.SCENE3D) {
+              return
+            }
+            const icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(
+              viewer.clock.currentTime
+            )
+            // icrfToFixed 在上面的方法中,若没加载好所需的计算资源会返回undefined,判断下
+            if (Cesium.defined(icrfToFixed)) {
+              const camera = viewer.camera
+              const offset = Cesium.Cartesian3.clone(camera.position)
+              const transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed)
+              camera.lookAtTransform(transform, offset)
+            }
+      },
+       //// tabs 切换点击 
+    legendClick(tab, event) {
+  
+      var tab_content = document.querySelectorAll(".menu .el-tabs__content");
+      if (this.currentLab.index == tab.index) {
+        tab_content[0].style.display == 'none'|| ''? tab_content[0].style.display = 'block' : tab_content[0].style.display = 'none';
+      }
+      if (this.currentLab.index != tab.index) {
+        this.currentLab.index = tab.index;
+        tab_content[0].style.display = 'block';
+      }
+    }
+  
+  }
+  
+  })
+  </script>
+  <style scoped>
+  .header{
+    background-color: #1c222b;
+    color: #fff;
+    height: 100%;
+    display: flex;
+    flex-direction: row;
+    align-items:center;/*由于flex-direction: column,因此align-items代表的是水平方向*/
+    justify-content: center;/*由于flex-direction: column,因此justify-content代表的是垂直方向*/
+  }
+  .header .el-button{
+    width: 150px;
+    margin: 0 10px;
+    height:30px;
+    padding: 1px 23px;
+  } 
+  
+  .box-card {
+    min-height: 100%;
+    height: 100%;
+  }
+  
+  /deep/ .el-card__body {
+    height: 100% !important;
+    padding: 0px !important;
+  }
+  
+  
+  .main-layout {
+    height: 100%;
+    width: 100%;
+  }
+  
+  .container {
+    height: 100%;
+   
+  }
+  
+  .map {
+    width: 100%;
+    height: 100%;
+  }
+  
+  .menu{
+    position: absolute;
+    height: 400px;
+    z-index: 999;
+    left: 20px;
+    top: 20px;
+  }
+  
+  /deep/.el-tabs--left .el-tabs__header.is-left {
+      margin-right: unset !important;
+  }
+  
+  .buttons{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-items: center;
+    position: absolute;
+    z-index: 999;
+    right: 20px;
+    top: 20px;
+  }
+  .el-button{
+    margin: 5px !important;
+  }
+  </style>  

+ 102 - 5
vue.config.js

@@ -1,6 +1,103 @@
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const webpack = require('webpack') 
+const cesiumSource = 'node_modules/cesium/Source'
+const cesiumWorkers = '../Build/Cesium/Workers'
+const path = require("path");
+function resolve(dir) {
+  return path.join(__dirname, dir);
+}
 module.exports = {
-  lintOnSave: false,
-  devServer: {
-    port: 8085
-  }
-};
+    publicPath: './',  // 基本路径
+    outputDir: 'dist', // 构建时的输出目录
+    assetsDir: 'static', // 放置静态资源的目录
+    indexPath: 'index.html', // html 的输出路径
+    filenameHashing: true, // 文件名哈希值
+    lintOnSave: false, // 是否在保存的时候使用 `eslint-loader` 进行检查。
+  
+    // 组件是如何被渲染到页面中的? (ast:抽象语法树;vDom:虚拟DOM)
+    // template ---> ast ---> render ---> vDom ---> 真实的Dom ---> 页面
+    // runtime-only:将template在打包的时候,就已经编译为render函数
+    // runtime-compiler:在运行的时候才去编译template
+    runtimeCompiler: false,
+  
+    transpileDependencies: [], // babel-loader 默认会跳过 node_modules 依赖。
+    productionSourceMap: false, // 是否为生产环境构建生成 source map
+  
+    configureWebpack: {
+      plugins: [
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }]),
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }]),
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }]),
+        new CopyWebpackPlugin([{ from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers' }]),
+   
+        new webpack.DefinePlugin({
+          CESIUM_BASE_URL: JSON.stringify('./')
+        })
+      ],
+      module: {
+        unknownContextCritical: false,
+        unknownContextRegExp: /\/cesium\/cesium\/Source\/Core\/buildModuleUrl\.js/
+      },
+      // 配置cesium----开始
+      amd: {
+        toUrlUndefined: true
+      },
+      output: {
+        sourcePrefix: ' '
+      }
+     },
+    devServer: {
+      proxy: {
+        '/socket.io':{
+          target: 'http://192.168.1.6:1234', // target host
+          changeOrigin: true, // needed for virtual hosted sites
+          logLevel: 'debug'
+        },
+        '/sockjs-node': {
+          target: 'http://192.168.1.6:1234',
+          ws: true,
+          changeOrigin: true
+        },
+        '/geoserver': {
+          target: 'http://localhost:8080',
+          ws: true,
+          changeOrigin: true,
+          // pathRewrite:{
+          //   "^/geoserver":""
+          // } 
+        }
+          
+      }
+    },
+
+    chainWebpack: config => {
+      config.resolve.alias
+        .set("@", resolve("src"))
+        .set("assets", resolve("src/assets"))
+        .set("components", resolve("src/components"))
+        .set("public", resolve("public"))
+        .set("cesium",path.resolve(__dirname, cesiumSource))
+    // set svg-sprite-loader
+    config.module
+      .rule('svg')
+      .exclude.add(resolve('src/assets'))  // 存放 svg 目录的目录
+      .end()
+    config.module
+      .rule('assets')
+      .test(/\.svg$/)
+      .include.add(resolve('src/assets'))  // 存放 svg 目录的目录
+      .end()
+      .use('svg-sprite-loader')
+      .loader('svg-sprite-loader')
+      .options({
+        symbolId: 'icon-[name]'
+      })
+      .end()
+    config.module
+      .rule('glb')
+      .test(/\.glb$/)
+      .use('url-loader')
+      .loader('url-loader')
+      .end();
+    }
+  }

Some files were not shown because too many files changed in this diff