浏览代码

Merge branch 'onemap_zmg'

mork 4 周之前
父节点
当前提交
2b5e57c3b2

+ 47 - 68
package-lock.json

@@ -9,15 +9,16 @@
       "version": "0.1.0",
       "dependencies": {
         "@element-plus/icons-vue": "^2.0.10",
+        "@vue-office/excel": "^1.7.14",
         "axios": "^0.27.2",
         "echarts": "^5.6.0",
         "element-plus": "^2.2.15",
         "moment": "^2.30.1",
         "vue": "^3.2.13",
+        "vue-demi": "^0.14.10",
         "vue-json-editor": "^1.4.3",
         "vue-json-viewer": "^3.0.4",
         "vue-router": "^4.0.3",
-        "vue3-lottie": "^3.3.1",
         "vuex": "^4.0.0"
       },
       "devDependencies": {
@@ -557,6 +558,23 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@vue-office/excel": {
+      "version": "1.7.14",
+      "resolved": "https://registry.npmjs.org/@vue-office/excel/-/excel-1.7.14.tgz",
+      "integrity": "sha512-pVUgt+emDQUnW7q22CfnQ+jl43mM/7IFwYzOg7lwOwPEbiVB4K4qEQf+y/bc4xGXz75w1/e3Kz3G6wAafmFBFg==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "peerDependencies": {
+        "@vue/composition-api": "^1.7.1",
+        "vue": "^2.0.0 || >=3.0.0",
+        "vue-demi": "^0.14.6"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@vue/cli-overlay": {
       "version": "5.0.9",
       "dev": true,
@@ -945,30 +963,6 @@
         "url": "https://github.com/sponsors/antfu"
       }
     },
-    "node_modules/@vueuse/core/node_modules/vue-demi": {
-      "version": "0.14.10",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "vue-demi-fix": "bin/vue-demi-fix.js",
-        "vue-demi-switch": "bin/vue-demi-switch.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.0.0-rc.1",
-        "vue": "^3.0.0-0 || ^2.6.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/@vueuse/metadata": {
       "version": "9.13.0",
       "license": "MIT",
@@ -986,30 +980,6 @@
         "url": "https://github.com/sponsors/antfu"
       }
     },
-    "node_modules/@vueuse/shared/node_modules/vue-demi": {
-      "version": "0.14.10",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "vue-demi-fix": "bin/vue-demi-fix.js",
-        "vue-demi-switch": "bin/vue-demi-switch.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/antfu"
-      },
-      "peerDependencies": {
-        "@vue/composition-api": "^1.0.0-rc.1",
-        "vue": "^3.0.0-0 || ^2.6.0"
-      },
-      "peerDependenciesMeta": {
-        "@vue/composition-api": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/@webassemblyjs/ast": {
       "version": "1.14.1",
       "dev": true,
@@ -3064,6 +3034,7 @@
     },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
+      "dev": true,
       "license": "MIT"
     },
     "node_modules/fast-glob": {
@@ -4079,6 +4050,7 @@
     },
     "node_modules/klona": {
       "version": "2.0.6",
+      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 8"
@@ -4367,10 +4339,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/lottie-web": {
-      "version": "5.12.2",
-      "license": "MIT"
-    },
     "node_modules/lower-case": {
       "version": "2.0.2",
       "dev": true,
@@ -7043,6 +7011,32 @@
         }
       }
     },
+    "node_modules/vue-demi": {
+      "version": "0.14.10",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+      "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/vue-hot-reload-api": {
       "version": "2.3.4",
       "dev": true,
@@ -7163,21 +7157,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/vue3-lottie": {
-      "version": "3.3.1",
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "klona": "^2.0.6",
-        "lottie-web": "5.12.2"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "peerDependencies": {
-        "vue": "^3.2"
-      }
-    },
     "node_modules/vuex": {
       "version": "4.1.0",
       "license": "MIT",

+ 2 - 1
package.json

@@ -8,15 +8,16 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.0.10",
+    "@vue-office/excel": "^1.7.14",
     "axios": "^0.27.2",
     "echarts": "^5.6.0",
     "element-plus": "^2.2.15",
     "moment": "^2.30.1",
     "vue": "^3.2.13",
+    "vue-demi": "^0.14.10",
     "vue-json-editor": "^1.4.3",
     "vue-json-viewer": "^3.0.4",
     "vue-router": "^4.0.3",
-    "vue3-lottie": "^3.3.1",
     "vuex": "^4.0.0"
   },
   "devDependencies": {

+ 2 - 2
src/components/AppVue/Header.vue

@@ -19,7 +19,7 @@ export default {
       menuList: [
         { index: 1, label: "首页", isActive: true },
         { index: 2, label: "时空数据管理", isActive: false },
-        { index: 3, label: "二维GIS引擎", isActive: false },
+        // { index: 3, label: "二维GIS引擎", isActive: false },
         { index: 4, label: "时空门户", isActive: false },
         { index: 5, label: "微功能", isActive: false },
         { index: 6, label: "应用管理", isActive: false },
@@ -47,7 +47,7 @@ export default {
           break;
         case 3:
           // this.$router.push("/application");
-          this.$router.push("/skmh/scene");
+          // this.$router.push("/skmh/scene");
           break;
         case 4:
           // this.$router.push("/function");

+ 389 - 0
src/components/filePreview/viewPreview.vue

@@ -0,0 +1,389 @@
+<template>
+    <div class="container">
+        <div class="map-container" v-if="isShow == 1">
+            <div id="skysceneryContainer"></div>
+            <div class="infoDialog" v-show="infoDialogShow">
+                <div class="close" @click="closeWin">×</div>
+                <div class="content" v-if="nowPoint != null">
+                    <el-scrollbar>
+                        <div class="item" v-for="info in nowPointInfo" :key="info">{{info.key}}: {{ info.value }}</div>
+                    </el-scrollbar>
+                </div>
+            </div>
+        </div>
+        <div class="page-content" v-if="isShow == 2">
+            <vue-office-excel
+                :src="excelUrl"
+                @rendered="onRendered"
+                @error="onError"
+                />
+        </div>
+         <div class="page-content" v-if="isShow == 3">
+            <div style="height: 100%; display: flex; align-items: center; justify-content: center;">
+                <el-empty class="custom-empty" description="不支持的文件类型" />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { ElMessage } from 'element-plus'
+import VueOfficeExcel from '@vue-office/excel'
+import '@vue-office/excel/lib/index.css'
+import { toRaw } from "vue";
+export default {
+    name: "",
+    components: {
+       VueOfficeExcel
+    },
+    data() {
+        return {
+            dataJson:[],
+            pointImg:require('@static/images/point.png'),
+            geometryArr:[],
+            mapHandle:null,
+            infoDialogShow:false,
+            nowPoint: null,
+            nowPointInfo:null,
+            excelUrl:'',
+            loading:false,
+            error:'',
+            isShow:1,
+        };
+    },
+    created() {
+        
+    },
+    mounted() {
+        const queryParams = new URLSearchParams(window.location.search);
+        let url = queryParams.get('url');
+        console.log(queryParams.get('url')); // 输出: value1
+        if(url){
+            let arr = url.split('.');
+            let type = arr[arr.length-1];
+            if(type == 'json' || type == 'geojson'){
+                let param = {url:url}
+                this.isShow = 1
+                window.SkySceneryConfig = {};
+                window.loadScripts([systemConfig.scriptMain]).then(() => {
+                    this.creatMap();
+                    setTimeout(() => {
+                        this.getVectorData(param);
+                    }, 1000)
+                    
+                });
+            }else if(type == 'xlsx' || type == 'xls'){
+                this.isShow = 2
+                this.excelUrl = url
+                this.loadExcel();
+            }else{
+                this.isShow = 3
+                // ElMessage.error('不支持的文件类型')
+            }
+        }
+    },
+   
+    methods: {
+        onRendered() {
+            // ElMessage.success('Excel文件渲染完成')
+        },
+        loadExcel() {
+            if (!this.excelUrl) {
+                // this.error = '请输入Excel文件在线地址'
+                return
+            }
+            this.loading = true
+            this.error = ''
+            // 加载Excel文件,实际加载由VueOfficeExcel组件处理
+            setTimeout(() => {
+                this.loading = false
+            }, 1000)
+        },
+        onError(err) {
+            ElMessage.error('Excel文件加载失败:', err)
+            // this.error = 'Excel文件加载失败,请检查文件地址是否正确'
+            this.loading = false
+        },
+         creatMap() {
+            window.viewer = new SkyScenery.Viewer("skysceneryContainer", {
+                animation: false, //是否创建动画小器件,左下角仪表
+                baseLayerPicker: false, //是否显示图层选择器
+                imageryProvider: new SkyScenery.SingleTileImageryProvider({
+                url: (function createColorCanvas(color) {
+                    var width = 1,
+                    height = 1;
+                    var canvas = document.createElement("canvas");
+                    canvas.width = width;
+                    canvas.height = height;
+                    var ctx = canvas.getContext("2d");
+                    ctx.fillStyle = color;
+                    ctx.fillRect(0, 0, width, height);
+                    return canvas.toDataURL();
+                })("#ffffff00"),
+                rectangle: SkyScenery.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
+                }),
+                fullscreenButton: false, //是否显示全屏按钮
+                geocoder: false, //是否显示geocoder小器件,右上角查询按钮
+                homeButton: false, //是否显示Home按钮
+                infoBox: false, //是否显示信息框
+                sceneModePicker: false, //是否显示3D/2D选择器
+                selectionIndicator: false, //是否显示选取指示器组件
+                timeline: false, //是否显示时间轴
+                navigationHelpButton: false, //是否显示右上角的帮助按钮
+                scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
+                shouldAnimate: false, //是否自动播放
+                // 性能优化配置
+                requestRenderMode: true,
+                maximumRenderTimeChange: Infinity,
+                preserveDrawingBuffer: false,
+                useBrowserRecommendedResolution: true,
+            });
+
+            // 添加地图服务
+            viewer.imageryLayers.addImageryProvider(
+                new SkyScenery.ArcGisMapServerImageryProvider({
+                url:
+                    "https://szlszxdt.qpservice.org.cn/internal_map/?servertype=shmap_blue_web&proxyToken=" +
+                    SkySceneryConfig.token,
+                enablePickFeatures: false, // 禁用要素拾取功能以提高性能
+                })
+            );
+
+            // 定位
+            viewer.camera.setView({
+                destination: SkyScenery.Cartesian3.fromDegrees(121.1158994,31.15205574, 30000.0), // 设置位置
+                orientation: {
+                    heading: SkyScenery.Math.toRadians(0.0), // 方向
+                    pitch: SkyScenery.Math.toRadians(-90.0), // 倾斜角度
+                    roll: 0,
+                },
+            });
+            
+        },
+        closeWin() {
+            this.infoDialogShow = false;
+            this.nowPoint = null;
+            this.nowPointInfo = null;
+        },
+        dwanMap(){
+            let that = this;
+            if(that.geometryArr.length>0){
+                that.geometryArr.map(function (info) {
+                    viewer.entities.remove(info)
+                })
+            }
+            that.geometryArr = that.dataJson.features.map(function (info) {
+                if(info.geometry.type == "Point"){
+                    return that.addPoint(info)
+                }else if(info.geometry.type == "LineString"){
+                    return that.addLine(info)
+                }else{
+                    return that.addPolygon(info)
+                }
+                
+            })
+            that.pointTCHandle();
+        },
+        addPolygon(param){
+            let arr = [];
+            param.geometry.coordinates.forEach(element => {
+                element.forEach(e => {
+                    arr.push(e[0]);
+                    arr.push(e[1]);
+                })
+            });
+            return viewer.entities.add(new SkyScenery.Entity({
+                name: " polygon",
+                polygon: {
+                    hierarchy: {
+                        positions: SkyScenery.Cartesian3.fromDegreesArray(arr)
+                    },
+                    heightReference: SkyScenery.HeightReference.CLAMP_TO_GROUND,
+                    material: SkyScenery.Color.CYAN.withAlpha(0.5)
+                },
+                info: {
+                    coor: [arr[0], arr[1]],
+                    properties: param.properties
+                },
+            }));
+        },
+        addLine(param){
+            return viewer.entities.add({
+                name: "line",
+                polyline: {
+                    //经纬度数组转世界坐标,带高度的话是fromDegreesArrayHeights
+                    positions: SkyScenery.Cartesian3.fromDegreesArray(param.geometry.coordinates),
+                    width: 2,
+                    material: SkyScenery.Color.CYAN,
+                    info: {
+                        properties: param.properties
+                    },
+                }
+            });
+        },
+        addPoint(param){
+            let that = this;
+            return viewer.entities.add(new SkyScenery.Entity({
+                name:"point",
+                position: SkyScenery.Cartesian3.fromDegrees(param.geometry.coordinates[0], param.geometry.coordinates[1]),
+                type: "point",
+                info: {
+                  coor: [param.geometry.coordinates[0], param.geometry.coordinates[1]],
+                  properties: param.properties
+                },
+                billboard: {
+                  image: that.pointImg,
+                  disableDepthTestDistance: Number.POSITIVE_INFINITY,
+                  scale: 0.3,
+                  horizontalOrigin: SkyScenery.HorizontalOrigin.CENTER,
+                  verticalOrigin: SkyScenery.VerticalOrigin.BOTTOM,
+                }
+              }));
+        },
+        // 点击事件绑定
+        pointTCHandle() {
+            let that = this;
+            if (!this.mapHandle) {
+                this.mapHandle = new SkyScenery.ScreenSpaceEventHandler(viewer.canvas, this);
+                this.mapHandle.setInputAction(function (movement) {
+                    that.infoDialogShow = false
+                    const pickedObject = viewer.scene.pick(movement.position);
+
+                    let cartesian = viewer.camera.pickEllipsoid(
+                        movement.position,
+                        viewer.scene.globe.ellipsoid
+                    );
+                    // 空间坐标转世界坐标(弧度)
+                    let cartographic = SkyScenery.Cartographic.fromCartesian(cartesian);
+                    // 弧度转为角度(经纬度)
+                    let lon = SkyScenery.Math.toDegrees(cartographic.longitude); // 经度值
+                    let lat = SkyScenery.Math.toDegrees(cartographic.latitude); // 纬度值
+                    let center = [lon,lat]
+                    if (SkyScenery.defined(pickedObject) && SkyScenery.defined(pickedObject.id)) {
+                        const entity = pickedObject.id;
+                        that.infoDialogShow = true
+                        that.nowPoint = entity.info;
+                        that.nowPointInfo =  Object.keys(that.nowPoint.properties).map(key => ({ key, value: that.nowPoint.properties[key] }));
+                        that.nowPoint["type"] = "info";
+                        // let xy = that.lonlatConvertToScreenXY(entity.info.coor)
+                        let xy = that.lonlatConvertToScreenXY(center)
+                        document.querySelector(".infoDialog").style.top = (xy.y - 230) + "px";
+                        document.querySelector(".infoDialog").style.left = (xy.x - 100) + "px";
+                    } else {
+                        // console.log('未拾取到实体');
+                    }
+                }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
+                viewer.scene.postRender.addEventListener(that.updatePosition, this);
+            } else {
+                toRaw(this.mapHandle).destroy();
+                this.mapHandle = null
+                that.nowPointInfo = null
+                viewer.scene.postRender.removeEventListener(that.updatePosition, this);
+            }
+        },
+        // 经纬度转屏幕坐标
+        lonlatConvertToScreenXY(lonlat) {
+            // 定义经纬度
+            var longitude = SkyScenery.Math.toRadians(lonlat[0]); // 例如:东经116.391度
+            var latitude = SkyScenery.Math.toRadians(lonlat[1]); // 例如:北纬39.907度
+            var height = 0; // 高度,通常在地表为0
+            // 将经纬度转换为笛卡尔坐标
+            // var cartographic = SkyScenery.Cartographic.fromDegrees(longitude, latitude, height);
+            var cartesian = SkyScenery.Cartesian3.fromRadians(longitude, latitude, height, viewer.scene.globe.ellipsoid);
+            // 将笛卡尔坐标转换为窗口坐标
+            var canvasCoordinates = viewer.scene.cartesianToCanvasCoordinates(cartesian);
+            return canvasCoordinates
+        },
+        // 位置更新
+        updatePosition() {
+            try {
+                if (this.nowPoint != null) {
+                    const obj = toRaw(this.nowPoint);
+                    let xy = this.lonlatConvertToScreenXY(obj.coor)
+                    if (!xy) {
+                        document.querySelector(".infoDialog").style.top = "-9999px";
+                        document.querySelector(".infoDialog").style.left = "-9999px";
+                    } else {
+                        document.querySelector(".infoDialog").style.top = (xy.y - 230) + "px";
+                        document.querySelector(".infoDialog").style.left = (xy.x - 100) + "px";
+                    }
+                }
+            } catch (error) {
+                // debugger
+            }
+        },
+        
+        getVectorData(param){
+            let that = this;
+            fetch(param.url, {
+                method: 'GET',
+            }).then(response => response.json()) // 假设服务器返回 JSON 数据
+                .then(data => {
+                    console.log('[ eee ] >')
+                    that.dataJson = data;
+                    that.closeWin()
+                    that.dwanMap()
+                })
+        },
+    },
+    beforeDestroy() {
+        viewer = undefined
+    }
+};
+</script>
+<style lang="less" scoped>
+.container {
+    width: 100%;
+    height: 100%;
+    padding: 0px;
+    margin: 0 auto;
+    overflow: hidden;
+}
+.map-container {
+    width: 100%;
+    height: 100%;
+}
+.page-content {
+    width: 100%;
+    height: 100%;
+    background-color: #fff;
+    border-radius: 4px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    overflow: hidden;
+  }
+.infoDialog {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    max-width: 500px;
+    height: 200px;
+    // background: #01346f99;
+    background: #ffffff;
+    border-radius: 10px;
+
+    .close {
+      font-size: 24px;
+      position: absolute;
+      top: 6px;
+      right: 8px;
+      line-height: 24px;
+      width: 24px;
+      height: 24px;
+      cursor: pointer;
+      // color: #ffffff;
+      color: #000000;
+    }
+
+    .content {
+      height: 160px;
+      // color: #ffffff;
+      color: #000000;
+      margin: 30px 0px 10px 20px;
+      overflow: auto;
+      .item {
+        line-height: 30px;
+        margin-right: 20px;
+      }
+    }
+  }
+</style>

+ 1 - 0
src/main.js

@@ -10,6 +10,7 @@ import ElementPlus from 'element-plus'
 import zhCn from 'element-plus/es/locale/lang/zh-cn'
 import 'element-plus/dist/index.css' // 引入默认主题样式
 import 'element-plus/theme-chalk/dark/css-vars.css' // 引入暗色主题样式
+
 initApp.use(ElementPlus, {
     locale: zhCn,
 })

+ 9 - 1
src/router/index.js

@@ -70,7 +70,7 @@ const routes = [
         component: function () {
           return import('../views/yygl/appCenter.vue')
         }
-      },
+      }
     ],
   },
   // {
@@ -134,6 +134,14 @@ const routes = [
     component: function () {
       return import('../views/wgn/Example.vue')
     },
+  },
+   // 文件预览功能
+  {
+    path: '/fileView',
+    name: 'fileView',
+    component: function () {
+      return import('../components/filePreview/viewPreview.vue')
+    },
   },
   // 应用管理
   // {

+ 1 - 1
src/views/example/Map.vue

@@ -60,7 +60,7 @@ export default {
             );
             // 定位
             viewer.camera.setView({
-                destination: SkyScenery.Cartesian3.fromDegrees(121.1, 31, 30000.0), // 设置位置
+                destination: SkyScenery.Cartesian3.fromDegrees(121.1158994,31.15205574, 30000.0), // 设置位置
                 orientation: {
                     heading: SkyScenery.Math.toRadians(0.0), // 方向
                     pitch: SkyScenery.Math.toRadians(-90.0), // 倾斜角度

+ 1 - 1
src/views/yygl/manage/index.vue

@@ -45,7 +45,7 @@
       <!-- 搜索栏区域 -->
       <div class="search-section">
         <el-input 
-          placeholder="请输入应用名称模块相关关键字" 
+          placeholder="请输入应用名称关键字" 
           v-model="searchKeyword" 
           class="search-input" 
           clearable

+ 6 - 1
src/views/yygl/overview/index.vue

@@ -48,7 +48,7 @@
               <p class="app-description">{{ app.content }}</p>
               <div class="app-footer">
                 <span class="app-date">{{ app.createTime }}</span>
-                <el-button type="primary" size="small" class="visit-button">访问</el-button>
+                <el-button type="primary" size="small" class="visit-button" @click="handleVisit">访问</el-button>
               </div>
             </div>
           </div>
@@ -94,6 +94,11 @@ export default {
       this.getDmsTagSName();
       this.getDmsDataList();
     },
+    handleVisit() {
+      // http://localhost:2027/fileView?url=/proxy_dms/static/1_青浦大数据中心一张图功能表20240531.xlsx
+      // http://localhost:2027/fileView?url=/proxy_dms/static/test.geojson
+      window.open('fileView?url='+this.curUrl+'/static/1_青浦大数据中心一张图功能表20240531.xlsx', '_blank');
+    },
     getDmsTagSName(){
       let requestParams = {
         sName: 'tag',