From e5e65bb50cbfb973f98191993ab559767eff7a53 Mon Sep 17 00:00:00 2001
From: suerprisePlus <15810472099@163.com>
Date: 星期二, 30 七月 2024 17:06:34 +0800
Subject: [PATCH] 页面添加(知识图谱,数据统计,数据分析,站点管理)

---
 src/views/visual/mapView/attributeInfo.vue   |  171 +++
 src/components/Tool/Popup.vue                |    2 
 src/views/visual/mapView/location.vue        |    2 
 src/utils/mapServer/kgServer.js              |    9 
 public/glb/LJX.glb                           |    0 
 src/assets/js/mapSdk/mapConfig.js            |   35 
 public/glb/SNG.glb                           |    0 
 public/glb/ZB.glb                            |    0 
 src/assets/js/mapSdk/index.js                |   29 
 src/views/visual/mapLayer/index.vue          |  460 +++++++++
 public/glb/GLKG.glb                          |    0 
 src/components/mapOl/index.vue               |  193 ++++
 public/glb/RDQ.glb                           |    0 
 public/glb/XB.glb                            |    0 
 src/api/mapView/map.js                       |   59 +
 public/config/config.js                      |   35 
 public/glb/GGG.glb                           |    0 
 src/store/modules/mapLayers.js               |   31 
 src/store/getters.js                         |    2 
 src/assets/js/configTools.js                 |   21 
 public/glb/BYQ.glb                           |    0 
 src/views/visual/mapView/lineRoaming.vue     |  118 ++
 public/glb/QT.glb                            |    0 
 src/assets/js/mapSdk/mapData.js              |  133 ++
 src/store/index.js                           |    5 
 src/views/visual/mapView/dataStatistics.vue  |  157 +++
 src/views/visual/atlas/index.vue             |  363 +++++++
 public/glb/DLQ.glb                           |    0 
 src/assets/js/mapSdk/mapServe.js             |  169 +++
 src/views/visual/mapView/layerManager.vue    |  105 ++
 src/views/visual/mapView/index.vue           |   67 +
 src/views/visual/analysis/index.vue          |  197 ++++
 package.json                                 |   12 
 src/views/visual/mapView/undergroundMode.vue |  116 ++
 public/glb/BDZ.glb                           |    0 
 src/views/visual/mapView/dataAnalysis.vue    |   44 
 public/glb/PDS.glb                           |    0 
 src/views/dataManager/siteInfo/index.vue     |  285 +++++
 src/assets/js/mapSdk/menuManager.js          |    3 
 39 files changed, 2,766 insertions(+), 57 deletions(-)

diff --git a/package.json b/package.json
index 485ab99..52ec330 100644
--- a/package.json
+++ b/package.json
@@ -36,14 +36,16 @@
     "url": "https://gitee.com/y_project/RuoYi-Vue.git"
   },
   "dependencies": {
+    "@antv/g6": "^4.8.19",
     "@easydarwin/easywasmplayer": "^4.0.7",
     "@jiaminghi/data-view": "^2.10.0",
     "@riophae/vue-treeselect": "0.4.0",
+    "@turf/turf": "^7.0.0",
     "axios": "0.24.0",
     "clipboard": "2.0.8",
     "codemirror": "^5.65.2",
-    "core-js": "3.25.3",
-    "echarts": "5.4.0",
+    "core-js": "^3.25.3",
+    "echarts": "^5.4.0",
     "element-china-area-data": "^4.1.1",
     "element-ui": "2.15.10",
     "file-saver": "2.0.5",
@@ -58,11 +60,14 @@
     "moment": "^2.29.4",
     "mqtt": "^4.3.3",
     "nprogress": "0.2.0",
+    "ol": "^6.15.1",
     "quill": "1.3.7",
+    "relation-graph": "^2.2.3",
     "screenfull": "5.0.2",
     "script-loader": "^0.7.2",
     "sortablejs": "1.10.2",
     "sql-formatter": "^4.0.2",
+    "terraformer-wkt-parser": "^1.2.1",
     "three": "^0.157.0",
     "vue": "2.6.12",
     "vue-clipboard2": "^0.3.3",
@@ -76,7 +81,8 @@
     "vue-router": "3.4.9",
     "vue-seamless-scroll": "^1.1.23",
     "vuedraggable": "2.24.3",
-    "vuex": "3.6.0"
+    "vuex": "3.6.0",
+    "xlsx": "^0.16.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "4.4.6",
diff --git a/public/config/config.js b/public/config/config.js
index e917262..0abac97 100644
--- a/public/config/config.js
+++ b/public/config/config.js
@@ -1,8 +1,39 @@
 console.log(location);
 const host = location.origin;
+const isWeb = false;
+var isUrl = isWeb ? "103.135.160.14" : "192.168.11.24";
+// api绔彛
+const apiHost = isWeb ? isUrl + "" : isUrl + ":12316";
+// 閰嶇綉绔彛
+const peiWangHost = isWeb ? isUrl + "" : isUrl + ":8101";
+// GeoServer绔彛
+const geoHost = isWeb ? isUrl + "" : isUrl + ":9055";
+// {host}鏇挎崲
+const iisHost = isWeb ? isUrl + ":9036" : "localhost:80";
+// 鐭ヨ瘑鍥捐氨绔彛
+const kgHost = isWeb ? isUrl + ":9036" : isUrl + ":8080";
+// 鏁版嵁鍒嗘瀽绔彛
+const pyHost = isWeb ? isUrl + ":9036" : isUrl + ":8000";
 
+//閰嶇疆
 const config = {
-  apiServices: "http://192.168.11.24:12316/server/",
+  // server鏈嶅姟
+  apiServices: "http://" + apiHost + "/server/",
+  // 鐭ヨ瘑鍥捐氨鏈嶅姟
+  kgServices: "http://" + kgHost,
+  // 閰嶇綉鏈嶅姟
+  peiWangServices: "http://" + peiWangHost + "/peiwang/",
+  //鏁版嵁鍒嗘瀽鎺ュ彛
+  pyServices: "http://" + pyHost + "/py",
   imageUrl: "",
-  sdkImg: host+"/visual/CimSDK/"
+  // sdk鏄剧ず
+  sdkImg: host + "/visual/CimSDK/",
+  // 澶╁湴鍥�
+  tdToken: "94a34772eb88317fcbf8428e10448561",
+  // geoServer鏈嶅姟
+  geoServer: {
+    url: "http://" + geoHost + "/geoserver/sxpw",
+    wms: "/wms",
+    wfs: ""
+  }
 };
diff --git a/public/glb/BDZ.glb b/public/glb/BDZ.glb
new file mode 100644
index 0000000..8034fe0
--- /dev/null
+++ b/public/glb/BDZ.glb
Binary files differ
diff --git a/public/glb/BYQ.glb b/public/glb/BYQ.glb
new file mode 100644
index 0000000..21f728e
--- /dev/null
+++ b/public/glb/BYQ.glb
Binary files differ
diff --git a/public/glb/DLQ.glb b/public/glb/DLQ.glb
new file mode 100644
index 0000000..604fca5
--- /dev/null
+++ b/public/glb/DLQ.glb
Binary files differ
diff --git a/public/glb/GGG.glb b/public/glb/GGG.glb
new file mode 100644
index 0000000..dac59dc
--- /dev/null
+++ b/public/glb/GGG.glb
Binary files differ
diff --git a/public/glb/GLKG.glb b/public/glb/GLKG.glb
new file mode 100644
index 0000000..0511799
--- /dev/null
+++ b/public/glb/GLKG.glb
Binary files differ
diff --git a/public/glb/LJX.glb b/public/glb/LJX.glb
new file mode 100644
index 0000000..5b8c4dc
--- /dev/null
+++ b/public/glb/LJX.glb
Binary files differ
diff --git a/public/glb/PDS.glb b/public/glb/PDS.glb
new file mode 100644
index 0000000..c70d5e6
--- /dev/null
+++ b/public/glb/PDS.glb
Binary files differ
diff --git a/public/glb/QT.glb b/public/glb/QT.glb
new file mode 100644
index 0000000..49138b2
--- /dev/null
+++ b/public/glb/QT.glb
Binary files differ
diff --git a/public/glb/RDQ.glb b/public/glb/RDQ.glb
new file mode 100644
index 0000000..988fd1a
--- /dev/null
+++ b/public/glb/RDQ.glb
Binary files differ
diff --git a/public/glb/SNG.glb b/public/glb/SNG.glb
new file mode 100644
index 0000000..4e911f4
--- /dev/null
+++ b/public/glb/SNG.glb
Binary files differ
diff --git a/public/glb/XB.glb b/public/glb/XB.glb
new file mode 100644
index 0000000..c10436e
--- /dev/null
+++ b/public/glb/XB.glb
Binary files differ
diff --git a/public/glb/ZB.glb b/public/glb/ZB.glb
new file mode 100644
index 0000000..c10436e
--- /dev/null
+++ b/public/glb/ZB.glb
Binary files differ
diff --git a/src/api/mapView/map.js b/src/api/mapView/map.js
index 72b9793..8125790 100644
--- a/src/api/mapView/map.js
+++ b/src/api/mapView/map.js
@@ -1,6 +1,63 @@
-import mapServer from '../../utils/mapServer/mapServer';
+import mapServer from '@/utils/mapServer/mapServer';
+import kgServer from '@/utils/mapServer/kgServer';
 
 //閰嶇綉鎺ュ彛 => 鏌ヨ鎵�鏈�
 export function zhangzitou_selectAllLine(params) {
     return mapServer.get('/zhangzitou/selectAllLine', { params: params });
 }
+//鍥惧眰绠$悊 => 鏌ヨ鎵�鏈�
+export function layer_selectAll(params) {
+    return mapServer.get('/layer/selectAll', { params: params });
+}
+//鍥惧眰绠$悊 => 鏂板鍥惧眰
+export function layer_insert(params) {
+    return mapServer.post('/layer/insert', params);
+}
+//鍥惧眰绠$悊=> 鍒犻櫎鍥惧眰
+export function layer_delete(params) {
+    return mapServer.get('/layer/delete', { params: params });
+}
+
+//鍥惧眰绠$悊=> 鍒犻櫎鍥惧眰
+export function layer_updates(params) {
+    return mapServer.post('/layer/updates', params);
+}
+//鍥惧眰绠$悊=> 鏇存柊涓�鏉�
+export function layer_update(params) {
+    return mapServer.post('/layer/update', params);
+}
+
+//閰嶇綉鎺ュ彛 => 鏌ヨ鎵�鏈�
+export function zhangzitou_selectAll(params) {
+    return mapServer.get('/zhangzitou/selectAll', { params: params });
+}
+//鍥捐氨鏌ヨ鎺ュ彛
+export function kg_getGraph(params) {
+    return kgServer.post('/kg/getGraph', params);
+}
+//鍥捐氨鏌ヨ鎺ュ彛
+export function kg_queryGraphResult(params) {
+    return kgServer.post('/kg/queryGraphResult', params);
+}
+
+//閰嶇綉鎺ュ彛 => 鏁版嵁缁熻
+export function zhangzitou_selectInfos(params) {
+    return mapServer.get('/zhangzitou/selectInfos', { params: params });
+}
+//閰嶇綉鎺ュ彛 => 鏁版嵁缁熻=>绾胯矾
+export function zhangzitou_deleteZhangzitouEntitys(params) {
+    return mapServer.get('/zhangzitou/deleteZhangzitouEntitys', { params: params });
+}
+
+//閰嶇綉鎺ュ彛 => 绔欑偣鏂板
+export function zhangzitou_insertZhangzitouEntity(params) {
+    return mapServer.post('/zhangzitou/insertZhangzitouEntity', params);
+}
+//閰嶇綉鎺ュ彛 => 淇敼绔欑偣
+export function zhangzitou_updateZhangzitouEntity(params) {
+    return mapServer.post('/zhangzitou/updateZhangzitouEntity', params);
+}
+// //閰嶇綉鎺ュ彛 => 鍒犻櫎绔欑偣
+// export function zhangzitou_deleteZhangzitouEntitys(params) {
+//     return mapServer.get('/zhangzitou/deleteZhangzitouEntitys', { params: params } );
+//   }
\ No newline at end of file
diff --git a/src/assets/js/configTools.js b/src/assets/js/configTools.js
index 37942cd..994795a 100644
--- a/src/assets/js/configTools.js
+++ b/src/assets/js/configTools.js
@@ -20,6 +20,25 @@
     },
     add0(m) {
         return m < 10 ? '0' + m : m;
-      },
+    },
+    //JSON鐢熸垚鐩綍鏍�
+    getTreeData(res) {
+        let cloneData = JSON.parse(JSON.stringify(res)); // 瀵规簮鏁版嵁娣卞害鍏嬮殕
+        return cloneData.filter((father) => {
+            // 寰幆鎵�鏈夐」
+            let branchArr = cloneData.filter((child) => father.id == child.pid);
+            if (branchArr.length > 0) {
+                branchArr.sort(function (a, b) {
+                    return a.orderNum - b.orderNum;
+                });
+            }
+
+            branchArr.length > 0 ? (father.children = branchArr) : ''; // 缁欑埗绾ф坊鍔犱竴涓猚hildren灞炴�э紝骞惰祴鍊�
+            // 灞炰簬鍚屼竴瀵硅薄闂锛屼緥濡傦細浠� a=b銆乧=1 锛岀劧鍚庡啀浠� b.c=c 锛� 閭d箞 a.c=b.c=c=1 锛涘悓鐞嗭紝鍚庣画浠� c.d=2 ,閭d箞 a.c.d 涔熸槸=2锛�
+            // 鐢辨寰幆澶氭鍚庯紝灏辫兘褰㈡垚鐩稿簲鐨勬爲褰㈡暟鎹粨鏋�
+            return father.pid == 0; // 杩斿洖涓�绾ц彍鍗�
+        });
+    },
+ 
 };
 export default configTools;
diff --git a/src/assets/js/mapSdk/index.js b/src/assets/js/mapSdk/index.js
index 6980051..bcb21b0 100644
--- a/src/assets/js/mapSdk/index.js
+++ b/src/assets/js/mapSdk/index.js
@@ -1,3 +1,7 @@
+import mapConfig from './mapConfig';
+import mapData from './mapData';
+import mapServer from './mapServe';
+
 const mapInit = {
     Init() {
         window.earthCtrl = new SmartEarth.EarthCtrl('sdkContainer', {
@@ -7,9 +11,32 @@
             printLog: false,
             // sceneMode: SmartEarth.Cesium.SceneMode.SCENE2D
         });
+        // 鍒濆鍖朇esium
         window.Cesium = SmartEarth.Cesium;
+        // 鍒濆鍖朧iewer
         window.Viewer = earthCtrl.viewer;
-        Viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString('#A9A9A9'); //璁剧疆鍦扮悆棰滆壊
+        //璁剧疆鍦扮悆棰滆壊
+        Viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString('#A9A9A9');
+        // 榛樿璁剧疆搴曞浘
+        this.addImageLayer();
+    },
+    addImageLayer() {
+        const baseLayer = mapData.baseLayer;
+        // 娣诲姞澶╁湴鍥惧簳鍥�
+        mapServer.addLayer({
+            serveType: 'tdMap',
+            url: baseLayer.sUrl + baseLayer.vecLayer + baseLayer.lUrl,
+        });
+        // 娣诲姞澶╁湴鍥炬爣娉�
+        mapServer.addLayer({
+            serveType: 'tdMap',
+            url: baseLayer.sUrl + baseLayer.cvaLayer + baseLayer.lUrl,
+        });
+        // 鍒濆鍖栬瑙�
+        this.setdefaultPerspective();
+    },
+    setdefaultPerspective() {
+        mapConfig.sertCameraTo(mapData.defaultPerspective);
     },
 };
 export default mapInit;
diff --git a/src/assets/js/mapSdk/mapConfig.js b/src/assets/js/mapSdk/mapConfig.js
new file mode 100644
index 0000000..b558605
--- /dev/null
+++ b/src/assets/js/mapSdk/mapConfig.js
@@ -0,0 +1,35 @@
+import WKT from 'terraformer-wkt-parser';
+const mapConfig = {
+    sertCameraTo(res) {
+        earthCtrl.camera.jumpTo({
+            destination: {
+                x: res.x,
+                y: res.y,
+                z: res.z,
+            },
+        });
+    },
+    userSceneFlyTo(res){
+        const options = {
+            duration: 2,
+            offset: new SmartEarth.Cesium.HeadingPitchRange(1.0, -0.3, 1000)
+        };
+        earthCtrl.userScene.flyTo(res,options);
+    },
+    getModelMatrix(res) {
+        var headingPitchRoll = new Cesium.HeadingPitchRoll(res.heading, res.pitch, res.roll);
+        var position = Cesium.Cartesian3.fromDegrees(res.longitude, res.latitude, res.altitude);
+        var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
+            position, headingPitchRoll, Cesium.Ellipsoid.WGS84,
+            Cesium.Transforms.eastNorthUpToFixedFrame,
+            new Cesium.Matrix4());
+        return modelMatrix;
+    },
+    getWKTParse(res){
+        return WKT.parse(res)
+    },
+    getWKTConvert(res){
+        return WKT.convert(res)
+    }
+};
+export default mapConfig;
\ No newline at end of file
diff --git a/src/assets/js/mapSdk/mapData.js b/src/assets/js/mapSdk/mapData.js
index 81e940f..2b2db2f 100644
--- a/src/assets/js/mapSdk/mapData.js
+++ b/src/assets/js/mapSdk/mapData.js
@@ -1,3 +1,5 @@
+// import { label } from 'three/examples/jsm/nodes/Nodes.js';
+
 const mapData = {
     menuData: [
         {
@@ -73,13 +75,13 @@
         {
             id: 's6',
             name: '瀹氫綅',
-            children:[
+            children: [
                 {
-                    id:'a1',
-                    name:'鍧愭爣瀹氫綅',
+                    id: 'a1',
+                    name: '鍧愭爣瀹氫綅',
                     pid: 's6',
-                }
-            ]
+                },
+            ],
         },
         {
             id: 's7',
@@ -147,7 +149,7 @@
                     pid: 's8',
                 },
                 {
-                    id: 'a6',
+                    id: 'a5',
                     name: '娓呴櫎',
                     pid: 's8',
                 },
@@ -159,7 +161,7 @@
             children: [
                 {
                     id: 'a1',
-                    name: '鍦颁笅妯″瀷',
+                    name: '鍦颁笅妯″紡',
                     pid: 's9',
                 },
                 {
@@ -170,5 +172,122 @@
             ],
         },
     ],
+    // 榛樿搴曞浘
+    baseLayer: {
+        sUrl: 'http://t0.tianditu.gov.cn/DataServer?T=',
+        lUrl: '&x={x}&y={y}&l={z}&tk=',
+        vecLayer: 'vec_w',
+        cvaLayer: 'cva_w',
+    },
+    // 榛樿瑙嗚
+    defaultPerspective: {
+        x: -1935239.1689147458,
+        y: 4653957.816261454,
+        z: 3900586.9686804516,
+    },
+    // 鍥惧眰绠$悊
+    layerData: {
+        layerOption: [
+            {
+                value: '1',
+                label: '鐩綍',
+            },
+            {
+                value: '2',
+                label: '鍥惧眰',
+            },
+        ],
+        sourceOption: [
+            {
+                value: 'Tileset',
+                label: 'Tileset',
+            },
+            {
+                value: 'WMS',
+                label: 'WMS',
+            },
+            {
+                value: 'TMS',
+                label: 'TMS',
+            },
+            {
+                value: 'GEOJSON',
+                label: 'GEOJSON',
+            },
+            {
+                value: 'WFS',
+                label: 'WFS',
+            },
+        ],
+        dataOption: [
+            { value: '鏉嗗', label: '鏉嗗' },
+            {
+                value: '閰嶇綉绠�',
+                label: '閰嶇綉绠�',
+            },
+            {
+                value: '鐜綉鏌�',
+                label: '鐜綉鏌�',
+            },
+            {
+                value: 'HW',
+                label: 'HW',
+            },
+            {
+                value: 'KG',
+                label: 'KG',
+            },
+            {
+                value: 'PD',
+                label: 'PD',
+            },
+            {
+                value: 'XB',
+                label: 'XB',
+            },
+            {
+                value: 'ZB',
+                label: 'ZB',
+            },
+            {
+                value: '鍙樺帇鍣�',
+                label: '鍙樺帇鍣�',
+            },
+            {
+                value: '鍙樼數绔�',
+                label: '鍙樼數绔�',
+            },
+            {
+                value: '鎸囩ず鍣�',
+                label: '鎸囩ず鍣�',
+            },
+            {
+                value: '鍏朵粬',
+                label: '鍏朵粬',
+            },
+        ],
+    },
+    // 鏁版嵁缁熻
+    dataStatistics: {
+        BDZ: '鍙樼數绔�',
+        BYQ: '鍙樺帇鍣�',
+        DLQ: '鏂矾鍣�',
+        GT: '鏉嗗',
+        GGG: '閽㈢鏉�',
+        GLKG: '闅旂寮�鍏�',
+        LJX: '杩炴帴绾�',
+        PD: '閰嶇數瀹�',
+        RDQ: '鐔旀柇鍣�',
+        SNG: '姘存偿鏉�',
+        XB: '绠卞彉',
+        HW: '鐜綉鏌�',
+        DLZJJT: '鐢电紗涓棿鎺ュご',
+        ZB: 'ZB',
+        KG: '寮�鍏�',
+        ZSQ: '鏁呴殰鎸囩ず鍣�',
+        PDS: 'PDS',
+
+    },
+    
 };
 export default mapData;
diff --git a/src/assets/js/mapSdk/mapServe.js b/src/assets/js/mapSdk/mapServe.js
new file mode 100644
index 0000000..541dd94
--- /dev/null
+++ b/src/assets/js/mapSdk/mapServe.js
@@ -0,0 +1,169 @@
+import mapConfig from './mapConfig';
+import { zhangzitou_selectAll } from '@/api/mapView/map.js';
+import WKT from 'terraformer-wkt-parser';
+// 鏈嶅姟鍔犺浇
+const mapServer = {
+    serveType: null,
+    layerList: [],
+    addLayer(res) {
+        const obj = this.getLayerChecked(res);
+        if (obj) return;
+        this.serveType = res.serveType;
+        switch (this.serveType) {
+            case 'tdMap':
+                this.addTdLayer(res);
+                break;
+            case 'WMS':
+                this.addWMSLayer(res);
+                break;
+            case 'Tileset':
+                this.addTilesetLayer(res);
+                break;
+            case 'WFS':
+                this.addWFSLayer(res);
+                break;
+        }
+    },
+    addWFSLayer(res) {
+        zhangzitou_selectAll({
+            limit: 1000000,
+            page: 1,
+        }).then((response) => {
+            if (response.data.code != 200) return;
+            const pois = response.data.result.pois;
+            const cnName = res.cnName + '_' + res.id;
+            const modelLayer = new Cesium.PrimitiveCollection();
+           modelLayer.name = cnName;
+            Viewer.scene.primitives.add(modelLayer);
+            pois.map((item) => {
+                var geom = WKT.parse(item.geom);
+                var style = {
+                    longitude: geom.coordinates[0],
+                    latitude: geom.coordinates[1],
+                    altitude: 0,
+                    heading: 0,
+                    pitch: 0,
+                    roll: 0,
+                };
+                const modelMatrix = mapConfig.getModelMatrix(style);
+                const url =  '/glb/' + item.type + '.glb';
+                modelLayer.add(
+                    Cesium.Model.fromGltf({
+                        id: item.id,
+                        url: url,
+                        scale: 1,
+                        minimumPixelSize: 20,
+                        maximumScale: 20,
+                        modelMatrix: modelMatrix,
+                        primitive: item,
+                    })
+                );
+            });
+            this.layerList.push({
+                id: res.id,
+                name: cnName,
+                layer: modelLayer,
+                serveType: this.serveType,
+            });
+        });
+    },
+
+    addTdLayer(res) {
+        const url = res.url + config.tdToken;
+        Viewer.imageryLayers.addImageryProvider(
+            new Cesium.UrlTemplateImageryProvider({
+                url: url,
+            })
+        );
+    },
+    getLayerChecked(res) {
+        const obj = this.layerList.filter((item) => {
+            if (item.id == res.id) {
+                return item;
+            }
+        });
+        const boolen = obj.length > 0 ? true : false;
+        return boolen;
+    },
+    addWMSLayer(res) {
+        const serverUrl = config.geoServer;
+        const that = this;
+        var getFeatureInfoFormat = new Cesium.GetFeatureInfoFormat('html', null, function (html) {
+            that.getFeatureInfo(html);
+        });
+
+        const layer = new Cesium.WebMapServiceImageryProvider({
+            url: serverUrl.url + serverUrl.wms,
+            layers: res.url,
+            getFeatureInfoParameters: { info_format: 'text/html' },
+            enablePickFeatures: true,
+            getFeatureInfoFormats: [getFeatureInfoFormat],
+            parameters: {
+                transparent: true,
+                format: 'image/png',
+                srs: 'EPSG:4490',
+                styles: '',
+                cql_filter: '',
+            },
+            tileWidth: 512,
+            tileHeight: 512,
+        });
+
+        const imageLayer = Viewer.imageryLayers.addImageryProvider(layer);
+        const cnName = res.cnName + '_' + res.id;
+        imageLayer.name = cnName;
+        imageLayer.id = res.id;
+        this.layerList.push({
+            id: res.id,
+            name: cnName,
+            layer: imageLayer,
+            serveType: this.serveType,
+        });
+    },
+    addTilesetLayer(res) {
+        let url = res.url.indexOf('{host}') > -1 ? res.url.replace('{host}', iisHost) : res.url;
+        var height = 0;
+        if (res.bak) {
+            height = JSON.parse(res.bak).height;
+        }
+        var model = earthCtrl.factory.create3DTilesets({
+            url: url,
+            option: {
+                height: height,
+                id: res.id,
+            },
+        });
+        const cnName = res.cnName + '_' + res.id;
+        model.item.readyPromise.then((item) => {
+            mapConfig.userSceneFlyTo(item);
+            this.layerList.push({
+                id: res.id,
+                name: cnName,
+                layer: model,
+                serveType: this.serveType,
+            });
+        });
+    },
+    setTilesetArgs() {},
+    removeLayer(res) {
+        const cnName = res.cnName + '_' + res.id;
+        this.layerList.map((item, index) => {
+            if (cnName == item.name && res.id == item.id) {
+                if (item.serveType == 'WMS') {
+                    Viewer.imageryLayers.remove(item.layer);
+                    this.layerList.splice(index, 1);
+                } else if (item.serveType == 'Tileset') {
+                    item.layer.deleteObject();
+                    this.layerList.splice(index, 1);
+                }else if (item.serveType == 'WFS') {
+                    Viewer.scene.primitives.remove(item.layer)
+                    this.layerList.splice(index, 1);
+                }
+            }
+        });
+    },
+    async getFeatureInfo(res) {
+        console.log(res);
+    },
+};
+export default mapServer;
diff --git a/src/assets/js/mapSdk/menuManager.js b/src/assets/js/mapSdk/menuManager.js
index caf3ce7..e2a46a0 100644
--- a/src/assets/js/mapSdk/menuManager.js
+++ b/src/assets/js/mapSdk/menuManager.js
@@ -1,3 +1,4 @@
+
 const menuManager = {
     pid: null,
     pointFly: null,
@@ -190,7 +191,7 @@
                 return res.name;
                 break;
             case 'a2':
-                return res.name;
+                earthCtrl.factory.createScreenshot();
                 break;
             default:
                 return null;
diff --git a/src/components/Tool/Popup.vue b/src/components/Tool/Popup.vue
index 0bdab40..cd7981b 100644
--- a/src/components/Tool/Popup.vue
+++ b/src/components/Tool/Popup.vue
@@ -43,7 +43,7 @@
             showBox: false,
             // 鏄惁鏄剧ず鍐呭
             showContainer: true,
-            defaultMaxHeight: '400px',
+            defaultMaxHeight: '700px',
         };
     },
     directives: {
diff --git a/src/components/mapOl/index.vue b/src/components/mapOl/index.vue
new file mode 100644
index 0000000..6537e15
--- /dev/null
+++ b/src/components/mapOl/index.vue
@@ -0,0 +1,193 @@
+<template>
+    <div id="mapView" class="olBox">
+        <div class="menuTool">
+            <el-form :inline="true" :model="formInline" class="demo-form-inline">
+                <el-form-item label="缁忓害:">
+                    {{ formInline.lon }}
+                </el-form-item>
+                <el-form-item label="绾害:">
+                    {{ formInline.lat }}
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="success" icon="el-icon-plus" @click="drowPoint"></el-button>
+                    <el-button type="danger" icon="el-icon-delete" @click="clearDrawPoint"></el-button>
+                </el-form-item>
+            </el-form>
+        </div>
+    </div>
+</template>
+
+<script>
+import TileLayer from 'ol/layer/Tile';
+import XYZ from 'ol/source/XYZ';
+import Map from 'ol/Map';
+import View from 'ol/View';
+import { transform } from 'ol/proj';
+import VectorSource from 'ol/source/Vector';
+import { Vector as VectorLayer, Tile } from 'ol/layer';
+import { Draw } from 'ol/interaction';
+import Feature from 'ol/Feature';
+import { Circle as CircleStyle, Style, Fill, Stroke, Icon, Text } from 'ol/style';
+import { Point } from 'ol/geom';
+import ImageWMS from "ol/source/ImageWMS";
+import Image from "ol/layer/Image";
+import mapData from '@/assets/js/mapSdk/mapData.js';
+import mapConfig from '../../assets/js/mapSdk/mapConfig';
+import * as turf from '@turf/turf'
+export default {
+    props: {
+        parentData: {
+            type: String,
+            default: '',
+
+        }
+    },
+    data() {
+        return {
+            mapol: null,
+            drawLayer: null,
+            formInline: {
+                lon: '',
+                lat: ''
+            }
+        }
+    },
+    mounted() {
+        this.initOlMap();
+    },
+    methods: {
+        initOlMap() {
+            const baseLayer = mapData.baseLayer;
+            const vecUrl = baseLayer.sUrl + baseLayer.vecLayer + baseLayer.lUrl
+            var vectorLayer = new TileLayer({
+                source: new XYZ({
+                    url: vecUrl + config.tdToken,
+                }),
+            });
+            const cvaUrl = baseLayer.sUrl + baseLayer.cvaLayer + baseLayer.lUrl
+            var vectorLayer1 = new TileLayer({
+                source: new XYZ({
+                    url: cvaUrl + config.tdToken,
+                }),
+            });
+            this.mapol = new Map({
+                target: 'mapView',
+                layers: [vectorLayer, vectorLayer1],
+                view: new View({
+                    center: transform([112.5545931210261, 37.86275646283009], 'EPSG:4326', 'EPSG:3857'),
+                    zoom: 12,
+                    projection: 'EPSG:3857',
+                }),
+            });
+
+
+            var layer2 = new Image({
+                name: "Wms_Layer",
+                source: new ImageWMS({
+                    crossOrigin: "anonymous",
+                    url: config.geoServer.url + config.geoServer.wms,
+                    params: {
+                        FORMAT: "image/png",
+                        VERSION: "1.1.1",
+                        LAYERS: 'sxpw:sxdwx',
+                    },
+                }),
+            });
+            this.mapol.addLayer(layer2);
+            if (this.parentData) {
+                const obj = mapConfig.getWKTParse(this.parentData)
+                this.formInline = {
+                    lon: obj.coordinates[0],
+                    lat: obj.coordinates[1],
+                }
+                this.addPointData(obj);
+            }
+        },
+        addPointData(res) {
+            const coord = res.coordinates;
+
+            const urlImg = config.sdkImg + 'Workers/image/mark.png';
+            var geom = transform(
+                [parseFloat(coord[0]), parseFloat(coord[1])],
+                'EPSG:4326',
+                'EPSG:3857'
+            );
+            var feature = new Feature({
+                geometry: new Point(geom),
+            });
+            feature.setStyle(
+                new Style({
+                    image: new Icon({
+                        scale: [0.8, 0.8],
+                        src: urlImg
+                    }),
+
+                })
+            );
+
+            const source = new VectorSource();
+            source.addFeature(feature);
+            this.drawLayer = new VectorLayer();
+            this.drawLayer.setSource(source);
+            this.mapol.addLayer(this.drawLayer);
+            this.setOlLocal(coord)
+        },
+        setOlLocal(geom) {
+            this.mapol.getView().animate({
+                center: transform(geom, 'EPSG:4326', 'EPSG:3857'), // 涓績鐐�
+                zoom: 18, // 缂╂斁绾у埆
+
+            });
+
+        },
+        drowPoint() {
+            const source = new VectorSource({ wrapX: false });
+            this.clearDrawPoint();
+            this.drawLayer = new VectorLayer({
+                source: source,
+            });
+            this.mapol.addLayer(this.drawLayer);
+            this.draw = new Draw({
+                source: source, // 鍜屽浘灞備娇鐢ㄥ悓涓�涓猻ource锛岀敾鐨勫浘褰㈠湪鍥惧眰涓婏紝鍥惧眰鍦ㄥ湴鍥句笂鍗冲彲灞曠ず
+                type: 'Point', // 鍙�夋嫨涓夎褰紝澶氳竟褰紝鍦嗗舰绛夊叿浣撹瀹樼綉demo
+                freehand: false, // 鐢婚�夎繕鏄偣閫�
+            });
+            // 娣诲姞浜や簰
+            this.mapol.addInteraction(this.draw);
+            this.draw.on('drawend', (e) => {
+                let feature = e.feature;
+                let geom = feature.getGeometry();
+                var extent = geom.flatCoordinates;
+                var a1 = transform([extent[0], extent[1]], 'EPSG:3857', 'EPSG:4326');
+                this.formInline.lon = parseFloat(a1[0]).toFixed(6);
+                this.formInline.lat = parseFloat(a1[1]).toFixed(6);
+                var point = turf.point([this.formInline.lon, this.formInline.lat]);
+                const gPoint= mapConfig.getWKTConvert(point.geometry)
+                this.$emit('childData', gPoint);
+                this.mapol.removeInteraction(this.draw);
+            });
+        },
+        clearDrawPoint() {
+            if (this.drawLayer) {
+                this.mapol.removeLayer(this.drawLayer);
+            }
+        },
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.olBox {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    margin: 0;
+    padding: 0;
+
+    ::v-deep.ol-control {
+        display: none;
+    }
+
+    .menuTool {}
+}
+</style>
\ No newline at end of file
diff --git a/src/store/getters.js b/src/store/getters.js
index 8adb1b6..2b2da34 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -15,5 +15,7 @@
   topbarRouters:state => state.permission.topbarRouters,
   defaultRoutes:state => state.permission.defaultRoutes,
   sidebarRouters:state => state.permission.sidebarRouters,
+  layerTree:state => state.mapLayers.layerTree,
+  defaultLayer:state => state.mapLayers.defaultLayer,
 }
 export default getters
diff --git a/src/store/index.js b/src/store/index.js
index 97aaef8..074c0c4 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -7,7 +7,7 @@
 import permission from './modules/permission'
 import settings from './modules/settings'
 import getters from './getters'
-
+import mapLayers from './modules/mapLayers'
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
@@ -17,7 +17,8 @@
     user,
     tagsView,
     permission,
-    settings
+    settings,
+    mapLayers
   },
   getters
 })
diff --git a/src/store/modules/mapLayers.js b/src/store/modules/mapLayers.js
new file mode 100644
index 0000000..aa0a339
--- /dev/null
+++ b/src/store/modules/mapLayers.js
@@ -0,0 +1,31 @@
+import Cookies from 'js-cookie';
+
+const state = {
+    layerTree: [],
+    defaultLayer: [],
+};
+
+const mutations = {
+    CHANGE_LAYERTREE: (state, res) => {
+        state.layerTree = res;
+    },
+    CHANGE_DEFAULTLAYER: (state,res) => {
+        state.defaultLayer = res;
+    },
+};
+
+const actions = {
+    changeLayerTree({ commit }, obj) {
+        commit('CHANGE_LAYERTREE', obj);
+    },
+    changeDefaultLayer({ commit }, obj) {
+        commit('CHANGE_DEFAULTLAYER', obj);
+    },
+};
+
+export default {
+    namespaced: true,
+    state,
+    mutations,
+    actions,
+};
diff --git a/src/utils/mapServer/kgServer.js b/src/utils/mapServer/kgServer.js
new file mode 100644
index 0000000..317db29
--- /dev/null
+++ b/src/utils/mapServer/kgServer.js
@@ -0,0 +1,9 @@
+import axios from "axios";
+const kgServer = axios.create({
+    // axios涓姹傞厤缃湁baseURL閫夐」锛岃〃绀鸿姹俇RL鍏叡閮ㄥ垎
+    baseURL: config.kgServices,
+    // 瓒呮椂
+    timeout: -1
+  });
+  export default kgServer;
+  
\ No newline at end of file
diff --git a/src/views/dataManager/siteInfo/index.vue b/src/views/dataManager/siteInfo/index.vue
new file mode 100644
index 0000000..0a97d27
--- /dev/null
+++ b/src/views/dataManager/siteInfo/index.vue
@@ -0,0 +1,285 @@
+<template>
+    <div class="siteInfo">
+        <el-card>
+            <div class="infoSearch">
+                <el-form :inline="true" :model="queryParams" class="demo-form-inline">
+                    <el-form-item label="鍚嶇О">
+                        <el-input size="small" v-model="queryParams.name" placeholder="璇疯緭鐐逛綅鍚嶇О..."></el-input>
+                    </el-form-item>
+                </el-form>
+                <div>
+                    <el-button size="small" plain type="primary" @click="setInfoQyery" icon="el-icon-search">鏌ヨ</el-button>
+                    <el-button size="small" plain type="info" @click="setInfoRefresh" icon="el-icon-refresh">閲嶇疆</el-button>
+                    <el-button size="small" plain type="success" @click="setInfoAdd" icon="el-icon-plus">娣诲姞</el-button>
+                    <el-button size="small" plain type="danger" @click="setInfoDel" icon="el-icon-delete">鍒犻櫎</el-button>
+                </div>
+            </div>
+        </el-card>
+
+        <el-card class="infoConTent">
+            <div class="infoTable">
+                <el-table :data="tableData" style="width: 100%" border height="calc(100% - 65px)" @selection-change="handleSelectionChange">
+                    <el-table-column type="selection" width="55" />
+                    <el-table-column align="center" type="index" label="搴忓彿" width="70px" />
+                    <el-table-column align="center" prop="id" v-if="false" />
+                    <el-table-column align="center" prop="name" label="鍚嶇О" />
+
+                    <el-table-column align="center" prop="line" label="鐜嚎" />
+                    <el-table-column align="center" prop="type" label="绫诲瀷" :formatter="setInFoType" />
+                    <el-table-column align="center" prop="geom" label="浣嶇疆" />
+                    <el-table-column min-width="100" label="鎿嶄綔">
+                        <template slot-scope="scope">
+                            <el-button @click="setInfoEdit(scope.$index, scope.row)" type="warning" plain size="small">缂栬緫</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageIndex" :limit.sync="queryParams.pageSize" @pagination="setInfoSearch" />
+            </div>
+        </el-card>
+        <el-dialog width="30%" :title="dialogTitle" :before-close="outerClose" :visible.sync="dialogFlag">
+            <el-form :model="editData">
+                <el-form-item label="鍚嶇О" :label-width="formLabelWidth">
+                    <el-input v-model="editData.name" style="width: 100%" placeholder=""></el-input>
+                </el-form-item>
+                <el-form-item label="鐜嚎" :label-width="formLabelWidth">
+                    <el-input v-model="editData.line" style="width: 100%" placeholder=""></el-input>
+                </el-form-item>
+                <el-form-item label="绫诲瀷" :label-width="formLabelWidth">
+                    <el-select v-model="editData.type" style="width: 100%" placeholder="">
+                        <el-option v-for="item in siteOption" :key="item.value" :label="item.name" :value="item.val"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="浣嶇疆" :label-width="formLabelWidth">
+                    <div style="width: 100%">
+                        <el-input v-model="editData.geom" style="width: 92%" placeholder="" disabled=""></el-input>
+                        <el-link style="float: right" @click="setInnerDialog"><i class="el-icon-plus"></i></el-link>
+                    </div>
+                </el-form-item>
+            </el-form>
+            <el-dialog width="50%" title="鐐逛綅" :visible.sync="innerVisible" :before-close="innerClose" append-to-body>
+                <div style="height: 540px">
+                    <olMap v-if="innerVisible" @childData="childData" :parentData="parentData"></olMap>
+                </div>
+            </el-dialog>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click="outerClose">鍙� 娑�</el-button>
+                <el-button @click="submitOuter" type="primary">纭� 璁�</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { zhangzitou_selectAll, zhangzitou_insertZhangzitouEntity, zhangzitou_updateZhangzitouEntity, zhangzitou_deleteZhangzitouEntitys } from '@/api/mapView/map.js';
+import mapData from '@/assets/js/mapSdk/mapData';
+import olMap from '@/components/mapOl/index.vue';
+export default {
+    components: {
+        olMap,
+    },
+    data() {
+        return {
+            total: 0,
+            queryParams: {
+                pageIndex: 1,
+                pageSize: 10,
+                name: '',
+                srid: 4326,
+            },
+            formLabelWidth: '80px',
+            multipleSelection: [],
+            tableData: [],
+            editData: {
+                type: '',
+            },
+            dialogTitle: null,
+            dialogFlag: false,
+            siteOption: [],
+            infoOption: null,
+            innerVisible: false,
+            parentData: null,
+        };
+    },
+    mounted() {
+        this.setInfoSearch();
+        this.getInfoOption();
+    },
+    methods: {
+        setInFoType(row, column) {
+            var obj = row.type;
+            if (this.infoOption[obj]) {
+                return this.infoOption[obj];
+            }
+            return obj;
+        },
+        getInfoOption() {
+            this.infoOption = mapData.dataStatistics;
+            const option = [];
+            for (var key in this.infoOption) {
+                option.push({
+                    name: this.infoOption[key],
+                    val: key,
+                });
+            }
+            this.siteOption = option;
+        },
+        setInfoQyery() {
+            this.queryParams.pageIndex = 1;
+            this.queryParams.pageSize = 10;
+            this.setInfoSearch();
+        },
+        setInfoSearch() {
+            zhangzitou_selectAll({
+                limit: this.queryParams.pageSize,
+                page: this.queryParams.pageIndex,
+                name: this.queryParams.name,
+            }).then((response) => {
+                if (response.data.code != 200) return;
+                const valData = response.data.result;
+                this.tableData = valData.pois;
+                this.total = valData.total;
+            });
+        },
+        setInfoRefresh() {
+            this.queryParams = {
+                pageIndex: 1,
+                pageSize: 10,
+                name: '',
+                srid: 4326,
+            };
+            this.setInfoSearch();
+        },
+        setInfoAdd() {
+            this.dialogTitle = '鏂板';
+            this.editData.type = this.siteOption[0].val;
+            this.dialogFlag = true;
+        },
+        setInfoDel() {
+            if (this.multipleSelection.length < 0) return;
+            const std = [];
+            for (var i in this.multipleSelection) {
+                std.push(this.multipleSelection[i].id);
+            }
+            zhangzitou_deleteZhangzitouEntitys({ ids: std.toString() }).then((response) => {
+                if (response.data.code != 200) {
+                    return this.$message('鍒犻櫎澶辫触');
+                }
+                this.$message({
+                    message: '鍒犻櫎鎴愬姛',
+                    type: 'success',
+                });
+
+                this.setInfoQyery();
+            });
+        },
+        setInfoEdit(index, row) {
+            this.dialogTitle = '淇敼';
+            this.editData = { ...row };
+            this.parentData = this.editData.geom;
+            this.dialogFlag = true;
+        },
+        handleSelectionChange(res) {
+            this.multipleSelection = res;
+        },
+        setInnerDialog() {
+            this.innerVisible = true;
+        },
+        outerClose() {
+            this.dialogFlag = false;
+            this.parentData = null;
+            this.editData = {
+                type: '',
+            };
+        },
+        innerClose() {
+            this.innerVisible = false;
+            this.parentData = null;
+        },
+        submitOuter() {
+            if (this.dialogTitle == '鏂板') {
+                this.outerInsert();
+            } else {
+                this.outerEdit();
+            }
+            this.dialogFlag = false;
+        },
+        childData(res) {
+            this.editData.geom = res;
+        },
+        outerInsert() {
+            const obj = { ...this.editData };
+            zhangzitou_insertZhangzitouEntity(obj).then((response) => {
+                if (response.data.code != 200) {
+                    return this.$message('鏂板澶辫触');
+                }
+                this.$message({
+                    message: '鏂板鎴愬姛',
+                    type: 'success',
+                });
+                this.outerClose();
+                this.setInfoRefresh();
+            });
+        },
+        outerEdit() {
+            const obj = { ...this.editData };
+            console.log(obj);
+            zhangzitou_updateZhangzitouEntity(obj).then((response) => {
+                if (response.data.code != 200) {
+                    return this.$message('淇敼澶辫触');
+                }
+                this.$message({
+                    message: '淇敼鎴愬姛',
+                    type: 'success',
+                });
+                this.outerClose();
+                this.setInfoSearch();
+            });
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.siteInfo {
+    width: calc(100% - 20px);
+    height: calc(100% - 20px);
+    position: absolute;
+    margin: 10px;
+    border-radius: 5px;
+    display: flex;
+    flex-direction: column;
+
+    .infoSearch {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        ::v-deep.el-form-item {
+            margin: 0px;
+        }
+    }
+
+    .infoConTent {
+        margin-top: 10px;
+        flex: 1;
+        position: relative;
+
+        .infoTable {
+            width: calc(100% - 30px);
+            height: calc(100% - 36px);
+            position: absolute;
+            display: flex;
+            flex-direction: column;
+        }
+    }
+
+    ::v-deep.el-divider--horizontal {
+        margin: 0px;
+        margin-bottom: 10px;
+    }
+
+    ::v-deep.el-card__body {
+        padding: 15px;
+    }
+}
+</style>
diff --git a/src/views/visual/analysis/index.vue b/src/views/visual/analysis/index.vue
index 456942e..b6560cf 100644
--- a/src/views/visual/analysis/index.vue
+++ b/src/views/visual/analysis/index.vue
@@ -1,9 +1,160 @@
 <template>
-    <div class="atlasBox"></div>
+    <div class="atlasBox" v-loading="gLoading">
+        <el-form :inline="true" :model="formInline" class="demo-form-inline">
+            <el-form-item label="涓婁紶鏁版嵁">
+                <el-input :placeholder="placeholder" v-model="formInline.file">
+
+                    <i slot="suffix" @click="onClickInputFile" class="el-input__icon el-icon-upload2"></i>
+                </el-input>
+            </el-form-item>
+
+            <el-form-item>
+                <el-button type="primary" size="small" plain icon="el-icon-setting" @click="onSubmit">鍒� 鏋�</el-button>
+                <el-button type="info" size="small" plain icon="el-icon-refresh" @click="onRefresh">閲� 缃�</el-button>
+            </el-form-item>
+        </el-form>
+
+        <input size="small" id="fromFile" type="file" style="display: none;" accept=".xlsx,.xls"
+            @change="onFileInputChange"></input>
+        <el-divider />
+        <div class="atlasContnt">
+            <el-table v-show="showTable" height=" calc(100% - 1px)" style="  width:100%" :data="tableData">
+                <el-table-column v-for="(item, index) in tableDataHeader" :key="index" align="center" :prop="item.name
+                    " :label="item.name"></el-table-column>
+            </el-table>
+
+            <el-carousel v-show="!showTable" style="height: 100%;" :interval="5000" arrow="always">
+                <el-carousel-item v-for="(item, key) in carouseList" :key="key">
+                    <el-image class="image" :src="item.src" :preview-src-list="[item.src]">
+                    </el-image>
+                </el-carousel-item>
+            </el-carousel>
+
+        </div>
+    </div>
 </template>
 
 <script>
-export default {};
+import XLSX from 'xlsx'
+import $ from "jquery";
+export default {
+    data() {
+        return {
+            formInline: {
+                file: ''
+            },
+            placeholder: "璇烽�夋嫨瑕佷笂浼犵殑鏁版嵁",
+            selectFileType: ".xlsx,.xls",
+            tableData: [],
+            tableDataHeader: [],
+            gLoading: false,
+            showTable: true,
+            carouseList: [],
+        }
+    },
+    methods: {
+        onSubmit() {
+            var fs = document.getElementById("fromFile");
+            if (fs.files.length == 0) {
+                this.$store.state.setLoading = false;
+                return this.$message("璇烽�夋嫨闇�瑕佷笂浼犵殑鏁版嵁鏂囦欢");
+            }
+            this.gLoading = true;
+            var formFile = new FormData();
+            var fileObj = fs.files[0]
+            formFile.append("file", fileObj); //鍔犲叆鏂囦欢瀵硅薄
+            document.getElementById('fromFile').vlaue = "";
+            this.formInline.file = ''
+            const that = this;
+            $.ajax(
+                config.pyServices + "/scatterplot",
+                {
+                    type: 'POST',
+                    data: formFile,
+                    async: true,
+                    cache: false,
+                    contentType: false,
+                    processData: false,
+                    success: (rs) => {
+                        that.showTable = false;
+                        that.setShowImage(rs);
+                        that.gLoading = false
+
+                    },
+                    error: (rs) => {
+                        that.gLoading = false
+                    },
+                })
+        },
+        onRefresh() {
+            this.gLoading = false;
+            this.showTable = true;
+            this.carouseList = [];
+            this.tableData = [];
+            this.tableDataHeader = [];
+            document.getElementById('fromFile').vlaue = "";
+            this.formInline.file = ''
+        },
+        setShowImage(response) {
+
+            const std = [];
+            for (var key in response) {
+                std.push({
+                    src: config.pyServices + '/image?file_name=' + response[key]
+                })
+            }
+            this.carouseList = std
+        },
+        onClickInputFile() {
+            document.getElementById('fromFile').click();
+        },
+        onFileInputChange(event) {
+
+            var that = this
+            // 鎷垮彇鏂囦欢瀵硅薄
+            let f = event.currentTarget.files[0]
+
+            this.formInline.file = f.name
+            // 鐢‵ileReader鏉ヨ鍙�
+            let reader = new FileReader()
+            // 閲嶅啓FileReader涓婄殑readAsBinaryString鏂规硶
+            FileReader.prototype.readAsBinaryString = (f) => {
+                let binary = ''
+                let wb // 璇诲彇瀹屾垚鐨勬暟鎹�
+                let outdata // 浣犻渶瑕佺殑鏁版嵁
+                let reader = new FileReader()
+
+                reader.onload = (e) => {
+                    // 璇诲彇鎴怳int8Array锛屽啀杞崲涓篣nicode缂栫爜锛圲nicode鍗犱袱涓瓧鑺傦級
+                    let bytes = new Uint8Array(reader.result)
+                    let length = bytes.byteLength
+                    for (let i = 0; i < length; i++) {
+                        binary += String.fromCharCode(bytes[i])
+                    }
+
+                    // 鎺ヤ笅鏉ュ氨鏄痻lsx浜嗭紝鍏蜂綋鍙湅api
+                    wb = XLSX.read(binary, {
+                        type: 'binary'
+                    })
+                    outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
+                    var str = outdata[0];
+                    var std = [];
+                    for (var key in str) {
+
+                        std.push({ name: key })
+
+                    }
+                    that.tableDataHeader = std
+                    that.tableData = outdata
+                }
+
+                reader.readAsArrayBuffer(f)
+            }
+            reader.readAsBinaryString(f)
+
+        }
+    }
+};
 </script>
 
 <style lang="scss" scoped>
@@ -13,6 +164,46 @@
     position: absolute;
     margin: 10px;
     border-radius: 5px;
-    background: yellowgreen;
+    display: flex;
+    flex-direction: column;
+
+    // background: yellowgreen;
+    ::v-deep.el-divider--horizontal {
+        margin: 0px;
+        margin-bottom: 10px;
+    }
+
+    ::v-deep.el-form-item {
+        margin-bottom: 15px;
+        margin-top: 10px;
+    }
+
+    .atlasContnt {
+        flex: 1;
+
+        .image {
+            width: 100%;
+            height: 95%;
+        }
+
+        ::v-deep.el-carousel__container {
+            height: 100%;
+
+        }
+
+        ::v-deep.el-carousel__button {
+            background: #409EFF !important
+        }
+
+        // background: skyblue;
+        // ::v-deep.el-carousel__container {
+        //     height: 100%;
+
+        // }
+
+        // ::v-deep.el-carousel__button {
+        //     background: #409EFF !important
+        // }
+    }
 }
 </style>
diff --git a/src/views/visual/atlas/index.vue b/src/views/visual/atlas/index.vue
index a0e89d6..d890e9f 100644
--- a/src/views/visual/atlas/index.vue
+++ b/src/views/visual/atlas/index.vue
@@ -1,10 +1,335 @@
 <template>
-    <div class="atlasBox"></div>
+    <div class="atlasBox">
+        <div id="container" class="container" v-show="!showEcharts">
+            <svg class="keywords" @mousemove="listener($event)">
+                <a href="javascript:void(0)" v-for="(tag, index) in tags" :key="index"
+                    @contextmenu="removeClick($event, tag)" @click="nodeClick(tag)">
+                    <text class="text" :x="tag.x" :y="tag.y" :font-size="20 * (600 / (600 - tag.z))"
+                        :fill-opacity="(400 + tag.z) / 600" :fill="tag.color">{{ tag.text }}</text>
+                </a>
+            </svg>
+        </div>
+        <div class="graphicBox" v-show="showEcharts">
+            <div class="konwReturn fl">
+                <el-link @click="showEcharts = false">
+                    <i class="el-icon-d-arrow-left"></i>
+                </el-link>
+                褰撳墠棰嗗煙:{{ targetName }}
+            </div>
+            <div id="graphicContent" v-loading="g_loading" class="graphicContent">
+                <RelationGraph ref="graphRef" :options="graphOptions" :on-node-expand="onNodeExpand"
+                    :on-node-collapse="onNodeCollapse">
+                </RelationGraph>
+            </div>
+        </div>
+    </div>
 </template>
 
 <script>
+import G6 from '@antv/g6';
+import { kg_getGraph, kg_queryGraphResult } from '@/api/mapView/map.js';
+import RelationGraph from 'relation-graph'
 export default {
-    
+    components: { RelationGraph },
+    data() {
+        return {
+            width: null,
+            height: null,
+            tags: [],
+            showEcharts: false,
+            speedX: Math.PI / 360,
+            speedY: Math.PI / 360,
+            CX: 600,
+            CY: 300,
+            RADIUS: 200,
+            ZRADIUS: 200,
+            targetName: null,
+            // 鍥捐氨
+            g_loading: true,
+            demoname: '---',
+            graphOptions: {
+                layout:
+                {
+                    label: '涓績',
+                    layoutName: 'tree',
+                    layoutClassName: 'seeks-layout-center',
+                    defaultJunctionPoint: 'border',
+                    defaultNodeShape: 0,
+                    defaultLineShape: 1,
+                    from: 'left',
+                    max_per_width: 300,
+                    min_per_height: 40
+                },
+                defaultLineMarker: {
+                    markerWidth: 12,
+                    markerHeight: 12,
+                    refX: 6,
+                    refY: 6,
+                    data: 'M2,2 L10,6 L2,10 L6,6 L2,2'
+                },
+                moveToCenterWhenRefresh: false,
+                defaultExpandHolderPosition: 'right',
+                defaultNodeShape: 1,
+                defaultNodeWidth: 100,
+                defaultLineShape: 4,
+                defaultJunctionPoint: 'lr',
+                defaultNodeBorderWidth: 0,
+                defaultLineColor: 'rgba(0, 186, 189, 1)',
+                defaultNodeColor: 'rgba(0, 206, 209, 1)'
+            }
+        }
+    },
+
+    mounted() {
+
+        // ;
+        this.setResizeStart();
+    },
+    methods: {
+        nodeClick(tag) {
+            this.showEcharts = true;
+            this.targetName = tag.text
+            this.g_loading = true
+            this.getGraphData(tag.text)
+
+        },
+
+        getGraphData(name) {
+
+
+
+            this.graphOptions.layout.max_per_width = this.width
+            kg_queryGraphResult(
+                { domain: name }
+            ).then(response => {
+                if (response.data.code != 200) return
+                this.g_loading = false;
+                const data = response.data.data
+                if (!this.width) {
+                    this.width = document.getElementById('container').innerWidth;
+                }
+                const obj = data.node.filter(item => {
+                    if (item.name == name) {
+                        return item
+                    }
+                })
+                this.getGraphicNodes(data.node, data.relationship, obj)
+            })
+        },
+        onNodeCollapse(node, e) {
+            // const graphInstance = this.$refs.graphRef.getInstance();
+            // graphInstance.doLayout();
+        },
+        // 閫氳繃onNodeExpand浜嬩欢鐩戝惉鑺傜偣鐨勫睍寮�浜嬩欢锛屽湪琚睍寮�鐨勬椂鍊欐湁閫夋嫨鐨勫幓浠庡悗鍙拌幏鍙栨暟鎹紝濡傛灉宸茬粡浠庡悗鍙板姞杞借繃鏁版嵁锛屽垯璁╁綋鍓嶅浘璋辨牴鎹綋鍓嶇殑鑺傜偣閲嶆柊甯冨眬
+        onNodeExpand(node, e) {
+            const graphInstance = this.$refs.graphRef.getInstance();
+            // 鏍规嵁鍏蜂綋鐨勪笟鍔¢渶瑕佸喅瀹氭槸鍚﹂渶瑕佷粠鍚庡彴鍔犺浇鏁版嵁
+            if (!node.data.isNeedLoadDataFromRemoteServer) {
+                console.log('杩欎釜鑺傜偣鐨勫瓙鑺傜偣宸茬粡鍔犺浇杩囦簡');
+                graphInstance.doLayout();
+                return;
+            }
+            // 鍒ゆ柇鏄惁宸茬粡鍔ㄦ�佸姞杞芥暟鎹簡
+            if (node.data.childrenLoaded) {
+                console.log('杩欎釜鑺傜偣鐨勫瓙鑺傜偣宸茬粡鍔犺浇杩囦簡');
+                graphInstance.doLayout();
+                return;
+            }
+            // this.g_loading = true;
+            node.data.childrenLoaded = true;
+            this.loadChildNodesFromRemoteServer(node);
+        },
+        loadChildNodesFromRemoteServer(node) {
+            var graphInstance = this.$refs.graphRef.getInstance();
+            graphInstance.doLayout();
+        },
+        getGraphicNodes(res, lines, obj) {
+            const std = [];
+            const ids = [];
+           
+            lines.filter(item => {
+             
+                if (ids.indexOf(item.sourceId) < 0) {
+                    ids.push(item.sourceId)
+                }
+                if (obj && obj.length > 0) {
+                    if (item.targetId == obj[0].uuid) {
+                        ids.push(item.targetId)
+                    }
+                }
+
+            })
+
+            res.filter(item => {
+                var poi = false;
+                if (item.poi && item.poi == 1) {
+                    poi = true;
+                }
+               
+                const expand = ids.indexOf(item.uuid) > -1 ? false : true
+                if (!expand) {
+
+                    std.push({
+                        // 'uuid': item.id ? item.id : new Date().getTime(),
+                        'id': item.uuid,
+                        'text': item.name,
+                        // expandHolderPosition: 'right',
+                        // expanded: true,
+                        // data: { isNeedLoadDataFromRemoteServer: true, childrenLoaded: false },
+                    })
+                } else {
+                    std.push({
+                        // 'uuid': item.id ? item.id : new Date().getTime(),
+                        'id': item.uuid,
+                        'text': item.name,
+                        // expandHolderPosition: 'right',
+                        // expanded: false,
+                        // data: { isNeedLoadDataFromRemoteServer: true, childrenLoaded: false },
+                    })
+                }
+
+            })
+            this.getGraphicLines(std, lines)
+        },
+        getGraphicLines(nodes, res) {
+            const std = [];
+            res.filter(item => {
+                std.push({
+                    "from": "" + item.sourceId + "",
+                    "to": "" + item.targetId + "",
+                    "text": "鍖呭惈",
+                })
+
+            })
+            const json_data = {
+                'rootId': 'a',
+                'nodes': nodes,
+                'lines': std
+            };
+            this.setGraphic(json_data)
+        },
+        setGraphic(res) {
+
+
+
+            setTimeout(() => {
+
+                this.$refs.graphRef.setJsonData(res, (graphInstance) => {
+                    // 杩欎簺鍐欎笂褰撳浘璋卞垵濮嬪寲瀹屾垚鍚庨渶瑕佹墽琛岀殑浠g爜
+                    graphInstance.doLayout();
+                });
+
+            }, 1000);
+
+
+            setTimeout(() => {
+
+                var graphInstance = this.$refs.graphRef.getInstance();
+
+            }, 2000);
+        },
+        removeClick() { },
+        rotateX(speedX) {
+            var cos = Math.cos(speedX);
+            var sin = Math.sin(speedX);
+            for (let tag of this.tags) {
+                var y1 = (tag.y - this.CY) * cos - tag.z * sin + this.CY;
+                var z1 = tag.z * cos + (tag.y - this.CY) * sin;
+                tag.y = y1;
+                tag.z = z1;
+            }
+        },
+        rotateY(speedY) {
+            var cos = Math.cos(speedY);
+            var sin = Math.sin(speedY);
+            for (let tag of this.tags) {
+                var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
+                var z1 = tag.z * cos + (tag.x - this.CX) * sin;
+                tag.x = x1;
+                tag.z = z1;
+            }
+        },
+        resizeWindow() {
+            if (this.showEcharts) return;
+            let height = document.getElementById('container').clientHeight;
+            let width = document.getElementById('container').clientWidth;
+            width = width * 0.85;
+            if (width > 1200) {
+                this.CX = width / 2;
+            }
+            height = height - 150;
+            this.CY = height / 2;
+            let radius = Math.min(this.CY, this.CX) / 2;
+            if (radius > 200) {
+                this.RADIUS = radius;
+            }
+            this.setCreateGraph();
+        },
+        setResizeStart() {
+            this.resizeWindow();
+            window.addEventListener('resize', this.resizeWindow);
+            this.setCreateGraph();
+            //浣跨悆寮�濮嬫棆杞�
+            const interval = setInterval(() => {
+                this.rotateX(this.speedX);
+                this.rotateY(this.speedY);
+            }, 17);
+            this.$once('hook:beforedestroy', () => {
+                interval && clearInterval(interval);
+                window.removeEventListener('resize', this.resizeWindow);
+            });
+        },
+        //鍥捐氨鍒濆鍖�
+        setCreateGraph() {
+            kg_getGraph({
+                command: 0,
+                pageIndex: 1,
+                pageSize: 5000,
+            }).then((response) => {
+                if (response.data.code != 200) return;
+
+                this.setGraphStart(response.data.data.nodeList);
+            });
+        },
+        listener(event) {
+            var x = event.clientX - this.CX;
+            var y = event.clientY - this.CY;
+            if (event.target.tagName == 'text') {
+                this.speedX = 0;
+                this.speedY = 0;
+            } else {
+                this.speedX = x * 0.00001 > 0 ? Math.min(this.RADIUS * 0.00002, x * 0.0001) : Math.max(-this.RADIUS * 0.00002, x * 0.0001);
+                this.speedY = y * 0.00001 > 0 ? Math.min(this.RADIUS * 0.00002, y * 0.0001) : Math.max(-this.RADIUS * 0.00002, y * 0.0001);
+            }
+
+            // var val = document.getElementById("removeLabel").style.display;
+            // if (val == "none") {
+            //     document.getElementById("removeLabel").style.top = event.clientY - 20 + 'px';
+            //     document.getElementById("removeLabel").style.left = event.clientX + 10 + 'px';
+            // }
+        },
+        setGraphStart(arr) {
+            const field = 'label';
+            const obj = arr.filter((item, index) => {
+                return arr.findIndex((i) => i[field] === item[field]) === index;
+            });
+            let tags = [];
+            const length = obj.length;
+            for (let i = 0; i < length; i++) {
+                let tag = {};
+                let k = -1 + (2 * (i + 1) - 1) / length;
+                let a = Math.acos(k);
+                let b = a * Math.sqrt(length * Math.PI);
+                tag.text = obj[i].label;
+                (tag.id = obj[i].id), (tag.label = obj[i].label), (tag.x = this.CX + this.RADIUS * Math.sin(a) * Math.cos(b));
+                tag.y = this.CY + this.RADIUS * Math.sin(a) * Math.sin(b);
+                tag.z = this.ZRADIUS * Math.cos(a);
+                tag.color = 'rgb(' + parseInt(Math.random() * 255) + ',' + parseInt(Math.random() * 255) + ',' + parseInt(Math.random() * 255) + ')';
+                tags.push(tag);
+            }
+            this.tags = [].concat(tags);
+        },
+    },
 };
 </script>
 
@@ -15,6 +340,38 @@
     position: absolute;
     margin: 10px;
     border-radius: 5px;
-    background: skyblue;
+
+    // background: skyblue;
+    .container {
+        width: 100%;
+        height: 100%;
+    }
+
+    .keywords {
+        width: 100%;
+        height: 100%;
+    }
+
+    .keywords .text:hover {
+        font-size: 200%;
+    }
+
+    .SVGBox {
+        width: 100%;
+        height: 100%;
+    }
+
+    .graphicBox {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+
+        .graphicContent {
+            padding: 10px;
+            flex: 1;
+
+        }
+    }
 }
 </style>
diff --git a/src/views/visual/mapLayer/index.vue b/src/views/visual/mapLayer/index.vue
new file mode 100644
index 0000000..f604cc4
--- /dev/null
+++ b/src/views/visual/mapLayer/index.vue
@@ -0,0 +1,460 @@
+<template>
+    <div class="layerBox">
+        <div class="leftTree">
+            <el-card class="treeCard">
+                <div>
+                    <el-input :placeholder="placeholderData" suffix-icon="el-icon-search" v-model="searchData">
+                    </el-input>
+                </div>
+                <div class="treeBox">
+                    <el-tree :data="treeData" node-key="id" :default-checked-keys="activeNodeId"
+                        :default-expanded-keys="activeNodeId" :filter-node-method="filterNode" highlight-current
+                        ref="tree" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
+                </div>
+            </el-card>
+        </div>
+        <div class="rightContent">
+            <el-card style="height: 100%;">
+                <div class="contentMenu">
+                    <el-button icon="el-icon-plus" @click="setAddNode(true)">鏂板鍚岀骇</el-button>
+                    <el-button icon="el-icon-plusde" :disabled="activeNode && activeNode.type != '1'"
+                        @click="setAddNode(false)">鏂板瀛愮骇</el-button>
+                    <el-button icon="el-icon-delete" @click="setDelNode">鍒犻櫎</el-button>
+                    <el-button icon="el-icon-top" @click="setMoveUp">鍚戜笂绉诲姩</el-button>
+                    <el-button icon="el-icon-bottom" @click="setMoveDown">鍚戜笅绉诲姩</el-button>
+                </div>
+                <el-divider />
+                <el-form ref="formInline" :model="formInline" label-width="80px">
+                    <el-form-item label="鍥惧眰鍚嶇О : ">
+                        <el-input v-model="formInline.cnName"></el-input>
+                    </el-form-item>
+                    <el-form-item label="鍥惧眰绫诲瀷 : ">
+                        <el-select v-model="formInline.type" style="width: 100%;">
+                            <el-option v-for="item in layerOption" :key="item.value" :label="item.label"
+                                :value="item.value">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="鏈嶅姟绫诲瀷 : " v-show="formInline.type == '2'">
+                        <el-select v-model="formInline.serveType" style="width: 100%;">
+                            <el-option v-for="item in sourceOption" :key="item.value" :label="item.label"
+                                :value="item.value">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="鏈嶅姟鍦板潃 : " v-show="formInline.type == '2'">
+                        <el-input v-model="formInline.url"></el-input>
+                    </el-form-item>
+                    <el-form-item label="鏁版嵁绫诲瀷 : " v-show="formInline.type == '2'">
+                        <el-select v-model="formInline.dataType" style="width: 100%;">
+                            <el-option v-for="item in dataOption" :key="item.value" :label="item.label"
+                                :value="item.value">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="鏄惁鏄剧ず : " v-show="formInline.type == '2'">
+                        <el-radio v-model="formInline.isShow" label="0">鍚�</el-radio>
+                        <el-radio v-model="formInline.isShow" label="1">鏄�</el-radio>
+                    </el-form-item>
+                    <el-form-item label="澶囨敞 : ">
+                        <el-input v-model="formInline.bak"></el-input>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button type="primary" @click="onSubEdit">淇敼</el-button>
+                        <el-button @click="onCanelEdit">閲嶇疆</el-button>
+                    </el-form-item>
+                </el-form>
+            </el-card>
+        </div>
+        <el-dialog :title="appendTitle" :visible.sync="appendActive" width="30%">
+            <el-form ref="appendFrom" :model="appendFrom" label-width="80px">
+                <el-form-item label="鍥惧眰鍚嶇О : ">
+                    <el-input v-model="appendFrom.cnName"></el-input>
+                </el-form-item>
+                <el-form-item label="鍥惧眰绫诲瀷 : ">
+                    <el-select v-model="appendFrom.type" style="width: 100%;">
+                        <el-option v-for="item in layerOption" :key="item.value" :label="item.label"
+                            :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="鏈嶅姟绫诲瀷 : " v-show="appendFrom.type == '2'">
+                    <el-select v-model="appendFrom.serveType" style="width: 100%;">
+                        <el-option v-for="item in sourceOption" :key="item.value" :label="item.label"
+                            :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="鏈嶅姟鍦板潃 : " v-show="appendFrom.type == '2'">
+                    <el-input v-model="appendFrom.url"></el-input>
+                </el-form-item>
+                <el-form-item label="鏁版嵁绫诲瀷 : " v-show="appendFrom.type == '2'">
+                    <el-select v-model="appendFrom.dataType" style="width: 100%;">
+                        <el-option v-for="item in dataOption" :key="item.value" :label="item.label" :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="鏄惁鏄剧ず : " v-show="appendFrom.type == '2'">
+                    <el-radio v-model="appendFrom.isShow" label="0">鍚�</el-radio>
+                    <el-radio v-model="appendFrom.isShow" label="1">鏄�</el-radio>
+                </el-form-item>
+                <el-form-item label="澶囨敞 : ">
+                    <el-input v-model="appendFrom.bak"></el-input>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="handleSubmitClose">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleSubmit">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import mapData from '@/assets/js/mapSdk/mapData.js';
+import { layer_selectAll, layer_insert, layer_delete, layer_updates, layer_update } from "@/api/mapView/map.js"
+import configTools from '@/assets/js/configTools.js';
+
+export default {
+    name: 'mapLayer',
+    components: {},
+    data() {
+        return {
+            searchData: '',
+            placeholderData: '璇疯緭鍏ヨ鏌ヨ鐨勫浘灞傚悕绉�',
+            formInline: {},
+            layerOption: [],
+            sourceOption: [],
+            dataOption: [],
+            treeData: [],
+            defaultProps: {
+                children: 'children',
+                label: 'cnName'
+            },
+            activeNode: null,
+            activeNodeId: [],
+            formData: {},
+            appendData: {},
+            appendActive: false,
+            appendTitle: "",
+            appendFlag: null,
+            appendFrom: {},
+            insertData: {},
+            treeList: [],
+        };
+    },
+    created() {
+        this.setFormInlineStart();
+    },
+    watch: {
+        searchData(val) {
+            this.$refs.tree.filter(val);
+        },
+    },
+    mounted() {
+        this.setlayerStart();
+    },
+    methods: {
+        //鍥惧眰妯$硦鏌ヨ
+        filterNode(value, data) {
+            if (!value) return true;
+            return data.cnName.indexOf(value) !== -1;
+        },
+        // 鏁版嵁鍒濆鍖�
+        setFormInlineStart() {
+            const layerData = mapData.layerData;
+            this.layerOption = layerData.layerOption;
+            this.sourceOption = layerData.sourceOption;
+            this.dataOption = layerData.dataOption;
+            this.formData = {
+                cnName: '',
+                type: this.layerOption[0].value,
+                serveType: this.sourceOption[0].value,
+                url: '',
+                dataType: this.dataOption[0].value,
+                isShow: '0',
+                bak: ''
+            }
+            this.formInline = { ... this.formData }
+        },
+        // 鍥惧眰鏍戣幏鍙栨暟鎹�
+        setlayerStart() {
+            layer_selectAll().then(response => {
+                if (response.data && response.data.result && response.data.result.length > 0) {
+                    const val = response.data.result;
+                    this.treeList = val;
+                    this.treeData = configTools.getTreeData(val)
+                    this.$nextTick(() => {
+
+                        if (this.insertData && this.insertData.name) {
+                            const obj = val.filter(item => {
+                                if (item.pid == this.insertData.id && item.cnName == this.insertData.name) {
+                                    return item;
+                                }
+                            })
+                            if (obj && obj.length > 0) {
+                                this.handleNodeClick(obj[0])
+
+                                this.insertData = {}
+                            }
+                        } else if (!this.activeNode) {
+                            if (this.treeData.length > 0) {
+                                this.handleNodeClick(this.treeData[0])
+                            }
+                        } else if (this.activeNode) {
+                            this.handleNodeClick(this.activeNode)
+                        }
+                    })
+                }
+            })
+        },
+        setLayerFormInline(res) {
+            res.type = res.type.toString();
+            res.isShow = res.isShow.toString();
+            res.isProject = res.isProject.toString();
+            this.formInline = res
+        },
+        //淇敼鎻愪氦
+        onSubEdit() {
+            layer_update(this.formInline).then(response => {
+                if (response.data.code != 200) {
+                    return this.$message({
+                        showClose: true,
+                        message: '淇敼澶辫触',
+                        type: 'error'
+                    });
+                }
+                this.$message({
+                    showClose: true,
+                    message: '淇敼鎴愬姛',
+                    type: 'success'
+                });
+                this.setlayerStart();
+            })
+        },
+        // 鍥惧眰鏍戠偣鍑�
+        handleNodeClick(res) {
+            const lid = res.id;
+            this.activeNodeId = [lid];
+            this.$refs.tree.setCurrentKey(lid);
+            this.activeNode = this.$refs.tree.getNode(lid).data;
+            this.onCanelEdit();
+        },
+        // 閲嶇疆
+        onCanelEdit() {
+            const val = { ... this.activeNode }
+            this.setLayerFormInline(val)
+        },
+        //娣诲姞鑺傜偣
+        setAddNode(res) {
+            this.appendTitle = res ? '鏂板鍚岀骇' : '鏂板瀛愮骇'
+            this.appendActive = true;
+            this.appendFrom = { ... this.formData }
+        },
+        // 鍙栨秷娣诲姞
+        handleSubmitClose() {
+            this.appendActive = false;
+            this.appendTitle = "";
+            this.appendFrom = {};
+        },
+        setDelNode() {
+            layer_delete({ id: this.formInline.id }).then(response => {
+                if (response.data.code == 200) {
+                    this.activeNode = null;
+                    this.activeNodeId = null;
+                    this.setlayerStart();
+                    this.$message({
+                        showClose: true,
+                        message: '鍒犻櫎鎴愬姛',
+                        type: 'success'
+                    });
+                } else {
+                    this.$message({
+                        showClose: true,
+                        message: '鍒犻櫎澶辫触',
+                        type: 'error'
+                    });
+                }
+            })
+        },
+        getMaxOrderNum(res) {
+            var val = null;
+            for (var i in res) {
+                if (val) {
+                    val = res[i].data.orderNum
+                } else {
+                    if (res[i].data.orderNum > val) {
+                        val = res[i].data.orderNum;
+                    }
+                }
+            }
+            return val + 1;
+        },
+        //娣诲姞鎻愪氦
+        async handleSubmit() {
+            const isAddParent = this.appendTitle == "鏂板鍚岀骇" ? true : false;
+            const val = { ... this.appendFrom };
+            val.isShow = parseInt(val.isShow);
+            val.isProject = parseInt(val.isProject);
+            val.level = isAddParent ? this.activeNode.level : this.activeNode.level + 1;
+            val.pid = isAddParent ? this.activeNode.pid : this.activeNode.id;
+            const pchildNodes = isAddParent ? this.$refs.tree.getNode(this.activeNode.id).parent.childNodes : this.$refs.tree.getNode(this.activeNode.id).childNodes
+            val.orderNum = this.getMaxOrderNum(pchildNodes);
+            if (this.treeData.length <= 0) {
+                val.pid = 0;
+                val.orderNum = 1;
+                val.lever = 1;
+            }
+            this.insertData = {
+                name: val.cnName,
+                id: val.pid
+            }
+            const response = await layer_insert(val);
+            if (response.data.code == 200) {
+                this.$message({
+                    showClose: true,
+                    message: '娣诲姞鎴愬姛',
+                    type: 'success'
+                });
+                this.handleSubmitClose();
+                this.setlayerStart();
+            } else {
+                this.$message({
+                    showClose: true,
+                    message: '娣诲姞澶辫触',
+                    type: 'error'
+                });
+            }
+        },
+        // 鍚戜笂绉诲姩
+        setMoveUp() {
+            let node = this.$refs.tree.getCurrentNode();
+            let pchildNodes = this.$refs.tree.getNode(node.id).parent.childNodes;
+            let currentId = null;
+            for (let i = 0; i < pchildNodes.length; i++) {
+                if (pchildNodes[i].data.id == node.id) {
+                    currentId = i;
+                }
+            }
+            if (currentId == 0) {
+                return this.$message({
+                    message: "澶勪簬椤剁锛屼笉鑳界户缁笂绉�",
+                    type: "warning",
+                });
+            }
+            const tempChildrenNodex1 = pchildNodes[currentId - 1];
+            const tempChildrenNodex2 = pchildNodes[currentId];
+            var arr = [];
+            this.treeList.filter((res) => {
+                if (res.id == tempChildrenNodex2.data.id) {
+                    arr.push(res);
+                } else if (res.id == tempChildrenNodex1.data.id) {
+                    arr.push(res);
+                }
+            });
+            const orderNum = arr[1].orderNum
+            arr[1].orderNum = arr[0].orderNum
+            arr[0].orderNum = orderNum
+            this.sendChange(arr)
+        },
+        // 鍚戜笅绉诲姩
+        setMoveDown() {
+            let node = this.$refs.tree.getCurrentNode();
+            let pchildNodes = this.$refs.tree.getNode(node.id).parent.childNodes;
+            let currentId = null;
+            for (let i = 0; i < pchildNodes.length; i++) {
+                if (pchildNodes[i].data.id == node.id) {
+                    currentId = i;
+                }
+            }
+            if (currentId > pchildNodes.length - 1) {
+                return this.$message({
+                    message: "澶勪簬搴曠锛屼笉鑳界户缁笂绉�",
+                    type: "warning",
+                });
+            }
+            const tempChildrenNodex1 = pchildNodes[currentId + 1];
+            const tempChildrenNodex2 = pchildNodes[currentId];
+            var arr = [];
+            this.treeList.filter((res) => {
+                if (res.id == tempChildrenNodex2.data.id) {
+                    arr.push(res);
+                } else if (res.id == tempChildrenNodex1.data.id) {
+                    arr.push(res);
+                }
+            });
+            const orderNum = arr[1].orderNum
+            arr[1].orderNum = arr[0].orderNum
+            arr[0].orderNum = orderNum;
+            this.sendChange(arr)
+        },
+        sendChange(res) {
+            layer_updates(res).then(response => {
+                if (response.data.code != 200) {
+                    return this.$message({
+                        showClose: true,
+                        message: '绉诲姩澶辫触',
+                        type: 'error'
+                    });
+                }
+                this.setlayerStart();
+            })
+        }
+
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.layerBox {
+    width: calc(100% - 20px);
+    height: calc(100% - 20px);
+    position: absolute;
+    margin: 10px;
+    border-radius: 5px;
+    display: flex;
+
+    .leftTree {
+        width: 20%;
+        height: 100%;
+        margin-right: 10px;
+
+        .treeCard {
+            height: 100%;
+
+
+            ::v-deep.el-card__body {
+                height: 100%;
+                display: flex;
+                flex-direction: column;
+            }
+
+            .treeBox {
+                margin-top: 10px;
+                flex: 1;
+                overflow: auto;
+            }
+        }
+
+        ::v-deep .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
+            color: #409EFF;
+        }
+    }
+
+    .rightContent {
+        flex: 1;
+
+        .contentMenu {
+            display: flex;
+            justify-content: flex-end;
+        }
+
+        ::v-deep .el-divider--horizontal {
+            margin: 15px 0px;
+        }
+    }
+}
+</style>
+
+
+</style>
diff --git a/src/views/visual/mapView/attributeInfo.vue b/src/views/visual/mapView/attributeInfo.vue
new file mode 100644
index 0000000..89f9f95
--- /dev/null
+++ b/src/views/visual/mapView/attributeInfo.vue
@@ -0,0 +1,171 @@
+<template>
+    <Popup ref="pop" top="20px" :title="title" @close="close(true)" width="1000px" :maxHeight="'700px'"
+        @cancel="close(false)">
+        <div class="menuBox">
+            <div class="serachContent">
+                <el-form :inline="true" :model="formInline" class="demo-form-inline">
+                    <el-form-item label="鍚嶇О">
+                        <el-input size="small" v-model="formInline.name" placeholder="璇疯緭鍏ュ畾浣嶅悕绉�..."></el-input>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button size="small" plain type="primary" @click="setInfoSearch"
+                            icon="el-icon-search">鏌ヨ</el-button>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button size="small" plain type="info" @click="setInfoRefresh"
+                            icon="el-icon-refresh">閲嶇疆</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+            <div class="tableContent">
+                <div class="tableBox">
+                    <el-table :data="tableData" border height="calc(100% - 2px)" ref="filterTable" style="width: 100%">
+                        <el-table-column label="瀹氫綅" width="100" align="center">
+                            <template slot-scope="scope">
+                                <el-button icon="el-icon-map-location" size="small"
+                                    @click="spaceLocation(scope.$index, scope.row)"></el-button>
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="鍚嶇О" prop="name" align="center"></el-table-column>
+                        <el-table-column label="鐜嚎" prop="line" align="center"></el-table-column>
+                        <el-table-column label="绫诲瀷" prop="type" align="center"></el-table-column>
+                        <el-table-column label="浣嶇疆" prop="geom" align="center"></el-table-column>
+                    </el-table>
+                </div>
+
+                <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageIndex"
+                    :limit.sync="queryParams.pageSize" @pagination="getAttributeInfo" />
+            </div>
+        </div>
+    </Popup>
+</template>
+
+<script>
+import Popup from '@/components/Tool/Popup.vue';
+import { zhangzitou_selectAll } from "@/api/mapView/map.js"
+import mapConfig from '../../../assets/js/mapSdk/mapConfig';
+
+
+export default {
+    name: 'attributeInfo',
+    components: { Popup },
+    data() {
+        return {
+            title: '灞炴�т俊鎭�',
+            total: 0,
+            queryParams: {
+                pageIndex: 1,
+                pageSize: 10,
+                name: "",
+                srid: 4326,
+            },
+            billboardEntity: null,
+            formInline: {
+                name: ''
+            }
+        };
+    },
+    methods: {
+        // 鍏抽棴寮圭獥
+        close(isCloseBtn, removeLayer = true) {
+            //   removeLayer && this.removeImageLayer();
+            this.delBillboard();
+            // 閲嶇疆data鍊�
+            Object.assign(this.$data, this.$options.data());
+            !isCloseBtn && this.$refs.pop.close();
+        },
+
+        // 鎵撳紑寮圭獥
+        open() {
+            this.close(true);
+            this.$refs.pop.open();
+            this.getAttributeInfo();
+        },
+        setInfoSearch() {
+            this.queryParams.name = this.formInline.name;
+            this.getAttributeInfo();
+        },
+        setInfoRefresh() {
+            this.formInline.name = "";
+            this.queryParams.pageIndex = 1;
+            this.queryParams.pageSize = 10;
+            this.setInfoSearch();
+        },
+        getAttributeInfo() {
+            zhangzitou_selectAll({
+                name: this.queryParams.name,
+                page: this.queryParams.pageIndex,
+                limit: this.queryParams.pageSize,
+                srid: this.queryParams.srid
+            }).then(response => {
+                if (response.data.code != 200) return;
+                const valDta = response.data.result;
+                this.total = valDta.total;
+                this.tableData = valDta.pois
+            })
+        },
+        delBillboard() {
+            if (this.billboardEntity) {
+                this.billboardEntity.removeFromMap();
+                this.billboardEntity = null;
+                return
+            }
+        },
+        spaceLocation(index, row) {
+            var wkt = mapConfig.getWKTParse(row.geom);
+            this.delBillboard();
+            const url = config.sdkImg + 'Workers/image/mark.png';
+            this.billboardEntity = earthCtrl.factory.createBillboard({
+                name: "鏍囩鐐�",
+                image: url,
+                width: 16,
+                height: 22,
+                lon: wkt.coordinates[0],
+                lat: wkt.coordinates[1],
+                alt: 10,
+                scale: 1.5,
+            });
+            earthCtrl.userScene.flyTo(this.billboardEntity)
+
+        },
+
+
+
+
+
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.menuBox {
+    position: relative;
+    height: 660px;
+    width: calc(100% - 0px);
+    padding: 10px;
+    display: flex;
+    flex-direction: column;
+
+    .serachContent {
+        display: flex;
+    }
+
+    .tableContent {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        background: #ffffff;
+
+        .tableBox {
+            flex: 1;
+
+        }
+
+        .pagination-container {
+            padding: 0px 10px !important;
+        }
+
+    }
+
+}
+</style>
diff --git a/src/views/visual/mapView/dataAnalysis.vue b/src/views/visual/mapView/dataAnalysis.vue
new file mode 100644
index 0000000..b86ef29
--- /dev/null
+++ b/src/views/visual/mapView/dataAnalysis.vue
@@ -0,0 +1,44 @@
+<template>
+    <Popup ref="pop" top="20px" :title="title" @close="close(true)" width="1400px" :maxHeight="'700px'"
+        @cancel="close(false)">
+        <div class="menuBox">
+          <analysis></analysis>
+        </div>
+    </Popup>
+</template>
+
+<script>
+import Popup from '@/components/Tool/Popup.vue';
+import analysis from '../analysis/index.vue'
+export default {
+    name: 'dataAnalysis',
+    components: { Popup, analysis },
+    data() {
+        return {
+            title: '鏁版嵁鍒嗘瀽',
+        };
+    },
+    methods: {
+        // 鍏抽棴寮圭獥
+        close(isCloseBtn, removeLayer = true) {
+            //   removeLayer && this.removeImageLayer();
+            // 閲嶇疆data鍊�
+            Object.assign(this.$data, this.$options.data());
+            !isCloseBtn && this.$refs.pop.close();
+        },
+        // 鎵撳紑寮圭獥
+        open() {
+            this.close(true);
+            this.$refs.pop.open();
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.menuBox {
+    position: relative;
+    height: 680px;
+    width: 100%;
+}
+</style>
diff --git a/src/views/visual/mapView/dataStatistics.vue b/src/views/visual/mapView/dataStatistics.vue
new file mode 100644
index 0000000..7d6735f
--- /dev/null
+++ b/src/views/visual/mapView/dataStatistics.vue
@@ -0,0 +1,157 @@
+<template>
+    <Popup ref="pop" top="20px" :title="title" @close="close(true)" width="1000px" :maxHeight="'700px'"
+        @cancel="close(false)">
+        <div class="menuBox">
+            <div class="serachContent">
+                <el-select v-model="linesName" @change="setEchartChange" placeholder="璇烽�夋嫨">
+                    <el-option v-for="(item, key) in linesOption" :key="key" :label="item.line" :value="item.line">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="echartContent">
+                <div id="myEchart" class="myChart"> </div>
+            </div>
+        </div>
+    </Popup>
+</template>
+
+<script>
+import Popup from '@/components/Tool/Popup.vue';
+import { zhangzitou_selectInfos } from "@/api/mapView/map.js"
+import mapData from '@/assets/js/mapSdk/mapData';
+import * as echarts from 'echarts';
+export default {
+    name: 'dataAnalysis',
+    components: { Popup },
+    data() {
+        return {
+            title: '鏁版嵁缁熻',
+            allLines: [],
+            linesOption: [],
+            linesName: '',
+            myChart: null,
+        };
+    },
+    methods: {
+        // 鍏抽棴寮圭獥
+        close(isCloseBtn, removeLayer = true) {
+            //   removeLayer && this.removeImageLayer();
+            // 閲嶇疆data鍊�
+            Object.assign(this.$data, this.$options.data());
+            !isCloseBtn && this.$refs.pop.close();
+        },
+        // 鎵撳紑寮圭獥
+        open() {
+            this.close(true);
+            this.$refs.pop.open();
+            this.getAllLines();
+        },
+        getAllLines() {
+            zhangzitou_selectInfos().then(response => {
+                if (response.data.code != 200) {
+                    return this.close();
+                }
+                this.setAllLinses(response.data.result)
+            })
+        },
+        setAllLinses(res) {
+            this.allLines = res;
+            this.linesOption = this.allLines.filter((item, index, self) =>
+                index === self.findIndex((t) => t.line === item.line)
+            );
+            this.linesName = this.linesOption[0].line;
+            this.setEchartChange();
+        },
+        setEchartChange() {
+            zhangzitou_selectInfos({
+                line: this.linesName
+            }).then(response => {
+                if (response.data.code != 200) return
+                const result = response.data.result;
+
+                const objData = []
+                result.filter(item => {
+                    const type = mapData.dataStatistics[item.type];
+                    if (type) {
+                        item.type = type
+                    }
+                    objData.push({
+                        value: item.count, name: item.type
+                    })
+                })
+                this.setEchartShow(objData)
+            })
+
+        },
+
+        setEchartShow(res) {
+
+            let option = {
+                title: {
+
+                    left: 'center'
+                },
+                tooltip: {
+                    trigger: 'item'
+                },
+                legend: {
+                    orient: 'vertical',
+                    left: 'left'
+                },
+                series: [
+                    {
+                        name: this.linesName,
+                        type: 'pie',
+                        radius: '50%',
+                        data: res,
+                        emphasis: {
+                            itemStyle: {
+                                shadowBlur: 10,
+                                shadowOffsetX: 0,
+                                shadowColor: 'rgba(0, 0, 0, 0.5)'
+                            }
+                        }
+                    }
+                ]
+            };
+            if (!this.myChart) {
+
+                this.myChart = echarts.init(document.getElementById("myEchart"));
+            }
+
+
+            this.myChart.setOption(option);
+            window.addEventListener("resize", () => {
+                this.myChart.resize();
+            });
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.menuBox {
+    position: relative;
+    height: 660px;
+    width: calc(100% - 0px);
+    padding: 10px;
+    display: flex;
+    flex-direction: column;
+
+    .serachContent {
+        display: flex;
+    }
+
+    .echartContent {
+        flex: 1;
+
+
+        .myChart {
+            margin-top: 10px;
+            width: 100%;
+            height: calc(100% - 10px);
+        }
+    }
+
+}
+</style>
diff --git a/src/views/visual/mapView/index.vue b/src/views/visual/mapView/index.vue
index a1378c1..539c4f3 100644
--- a/src/views/visual/mapView/index.vue
+++ b/src/views/visual/mapView/index.vue
@@ -13,7 +13,8 @@
                             </span>
                             <div v-if="item.children">
                                 <el-dropdown-menu v-show="item.children" slot="dropdown">
-                                    <el-dropdown-item style="text-align: center" :command="res" v-for="(res, key) in item.children" :key="key">{{ res.name }}</el-dropdown-item>
+                                    <el-dropdown-item style="text-align: center" :command="res"
+                                        v-for="(res, key) in item.children" :key="key">{{ res.name }}</el-dropdown-item>
                                 </el-dropdown-menu>
                             </div>
                         </el-dropdown>
@@ -28,10 +29,22 @@
                     <i :size="20" class="el-icon-d-arrow-left"></i>
                 </div>
             </div>
+            <!-- 鍥惧眰绠$悊 -->
             <layer-manager ref="layerManager"></layer-manager>
+            <!-- 鍧愭爣瀹氫綅 -->
             <location ref="location"></location>
+            <!-- 鐭ヨ瘑鍥捐氨 -->
             <knowledge ref="knowledge"></knowledge>
+            <!-- 绾胯矾婕父 -->
             <lineRoaming ref="lineRoaming"></lineRoaming>
+            <!-- 鍦颁笅妯″紡 -->
+            <undergroundMode ref="undergroundMode"></undergroundMode>
+            <!-- 鏁版嵁鍒嗘瀽 -->
+            <dataAnalysis ref="dataAnalysis"></dataAnalysis>
+            <!-- 鏁版嵁缁熻 -->
+            <dataStatistics ref="dataStatistics"></dataStatistics>
+            <!-- 灞炴�т俊鎭� -->
+            <attributeInfo ref="attributeInfo"></attributeInfo>
         </div>
     </div>
 </template>
@@ -44,10 +57,17 @@
 import location from './location.vue';
 import knowledge from './knowledge.vue';
 import lineRoaming from './lineRoaming.vue';
-
+import { layer_selectAll } from "@/api/mapView/map.js";
+import configTools from '@/assets/js/configTools';
+import store from "@/store";
+import mapServer from '@/assets/js/mapSdk/mapServe';
+import undergroundMode from './undergroundMode.vue';
+import dataAnalysis from './dataAnalysis.vue';
+import dataStatistics from './dataStatistics.vue'
+import attributeInfo from './attributeInfo.vue';
 export default {
     name: 'mapView',
-    components: { layerManager, location, knowledge, lineRoaming },
+    components: { layerManager, location, knowledge, lineRoaming, undergroundMode, dataAnalysis, dataStatistics, attributeInfo },
     data() {
         return {
             menuIsShow: false,
@@ -58,13 +78,37 @@
     },
     mounted() {
         this.mapViewStart();
+
+    },
+    beforeDestroy() {
+        this.$store.dispatch('mapLayers/changeLayerTree', [])
+        this.$store.dispatch('mapLayers/changeDefaultLayer', [])
     },
     methods: {
         mapViewStart() {
             this.menuOption = mapData.menuData;
             this.$nextTick(() => {
                 mapInit.Init();
+                this.getSelectLayers();
             });
+        },
+        getSelectLayers() {
+            layer_selectAll().then(response => {
+                if (response.data.code != 200) return
+                const defaultLayer = [];
+                const val = response.data.result.filter(item => {
+                    item.checked = false;
+                    if (item.type == 2 && item.isShow == 1) {
+                        item.checked = true;
+                        mapServer.addLayer(item)
+                        defaultLayer.push(item.id)
+                    }
+                    return item;
+                })
+                this.$store.dispatch('mapLayers/changeDefaultLayer', defaultLayer)
+                var obj = configTools.getTreeData(val)
+                this.$store.dispatch('mapLayers/changeLayerTree', obj)
+            })
         },
         setMenuClose() {
             this.menuIsShow = !this.menuIsShowx;
@@ -86,6 +130,7 @@
             this.$refs && this.$refs.knowledge && this.$refs.knowledge.close();
         },
         setPopShow(response) {
+            console.log(response);
             switch (response) {
                 case '鍥惧眰绠$悊':
                     this.$refs && this.$refs.layerManager && this.$refs.layerManager.open();
@@ -98,6 +143,18 @@
                     break;
                 case '绾胯矾婕父':
                     this.$refs && this.$refs.lineRoaming && this.$refs.lineRoaming.open();
+                    break;
+                case '鍦颁笅妯″紡':
+                    this.$refs && this.$refs.undergroundMode && this.$refs.undergroundMode.open();
+                    break;
+                case '鏁版嵁鍒嗘瀽':
+                    this.$refs && this.$refs.dataAnalysis && this.$refs.dataAnalysis.open();
+                    break;
+                case '灞炴�т俊鎭�':
+                    this.$refs && this.$refs.attributeInfo && this.$refs.attributeInfo.open();
+                    break;
+                case '鏁版嵁缁熻':
+                    this.$refs && this.$refs.dataStatistics && this.$refs.dataStatistics.open();
                     break;
                 default:
                     break;
@@ -151,7 +208,7 @@
         .closeMenu {
             width: 30px;
             height: 100%;
-            background: rgba(245, 245, 245, 1);
+            background: rgb(255, 255, 255);
             color: #4ab1fc;
             display: flex;
             position: relative;
@@ -161,7 +218,7 @@
 
         .menuItemBox {
             color: #7a7a7a;
-            background: rgba(245, 245, 245, 1);
+            background: rgb(255, 255, 255);
             line-height: 40px;
             padding: 0px 10px;
             font-size: 14px;
diff --git a/src/views/visual/mapView/layerManager.vue b/src/views/visual/mapView/layerManager.vue
index 2da6706..5ce9395 100644
--- a/src/views/visual/mapView/layerManager.vue
+++ b/src/views/visual/mapView/layerManager.vue
@@ -1,23 +1,42 @@
 <template>
-    <Popup ref="pop" top="20px" left="calc(100% - 600px)"  :title="title" @close="close(true)" width="300px"   @cancel="close(false)">
-        <el-tree></el-tree>
+    <Popup ref="pop" top="20px" left="calc(100% - 600px)" :title="title" @close="close(true)" width="300px"
+        @cancel="close(false)">
+
+        <div class="layerBox">
+            <el-tree show-checkbox :data="treeData" ref="tree" node-key="id" :default-checked-keys="defaultLayer"
+                @check-change="handleCheckChange" :props="defaultProps"></el-tree>
+        </div>
     </Popup>
 </template>
 
 <script>
 import Popup from '@/components/Tool/Popup.vue';
+import store from "@/store";
+import mapServer from '@/assets/js/mapSdk/mapServe';
+
 export default {
     name: 'layerManager',
     components: { Popup },
+    computed: {
+        getlayerTree() {
+            return store.getters.getlayerTree
+        }
+    },
     data() {
         return {
             title: '鍥惧眰绠$悊',
+            defaultProps: {
+                children: 'children',
+                label: 'cnName'
+            },
+            treeData: [],
+            defaultLayer: [],
+            ids: [],
         };
     },
     methods: {
         // 鍏抽棴寮圭獥
         close(isCloseBtn, removeLayer = true) {
-            //   removeLayer && this.removeImageLayer();
             // 閲嶇疆data鍊�
             Object.assign(this.$data, this.$options.data());
             !isCloseBtn && this.$refs.pop.close();
@@ -26,9 +45,87 @@
         open() {
             this.close(true);
             this.$refs.pop.open();
+            this.$nextTick(() => {
+                this.setLayerStart();
+            })
+        },
+        setLayerStart() {
+            if (store.getters && store.getters.layerTree) {
+                this.defaultLayer = store.getters.defaultLayer;
+                this.ids = this.defaultLayer;
+                this.treeData = store.getters.layerTree
+            }
+
+        },
+        handleCheckChange(data, checked, indeterminate) {
+            const checkIds = this.$refs.tree.getCheckedKeys()
+            if (this.ids === checkIds) return
+            this.ids.map(o => {
+                if (checkIds.indexOf(o) < 0) {
+                    const obj = this.$refs.tree.getNode(o);
+                    console.log(obj.checked);
+                    if (obj.checked) {
+                        mapServer.addLayer(obj.data)
+                    } else {
+                        mapServer.removeLayer(obj.data)
+                    }
+                }
+            })
+
+            checkIds.map(n => {
+                if (this.ids.indexOf(n) < 0) {
+                    const obj = this.$refs.tree.getNode(n);
+                    if (obj.checked) {
+                        mapServer.addLayer(obj.data)
+                    } else {
+                        mapServer.removeLayer(obj.data)
+                    }
+                }
+            })
+
+
+
+            this.$store.dispatch('mapLayers/changeLayerTree', this.treeData)
+            const ids = this.$refs.tree.getCheckedKeys()
+            this.ids = ids;
+            this.$store.dispatch('mapLayers/changeDefaultLayer', ids)
+        },
+        setServerLayerChange(data, checked) {
+            if (checked) {
+                mapServer.addLayer(data)
+            } else {
+                mapServer.removeLayer(data)
+            }
+
+        },
+        getNodeList(list, checked) {
+            list.map(item => {
+                if (item.type == 1) {
+                    if (item.children && item.children.length > 0) {
+                        this.getNodeList(item.children)
+                    }
+                } else {
+                    this.setServerLayerChange(item, checked)
+                }
+            })
         },
     },
+
+
 };
 </script>
 
-<style></style>
+<style lang="scss" scoped>
+.layerBox {
+    height: 680px;
+
+    ::v-deep.el-tree {
+        background: transparent !important;
+
+        .el-tree-node__content:hover {
+            color: #409EFF;
+        }
+    }
+
+}
+</style>
diff --git a/src/views/visual/mapView/lineRoaming.vue b/src/views/visual/mapView/lineRoaming.vue
index 8ba57cd..5fb625a 100644
--- a/src/views/visual/mapView/lineRoaming.vue
+++ b/src/views/visual/mapView/lineRoaming.vue
@@ -1,19 +1,26 @@
 <template>
-    <Popup ref="pop" top="20px" left="calc(100% - 600px)" :title="title" @close="close(true)" width="300px" :maxHeight="'700px'" @cancel="close(false)">
-         <div class="menuBox">
-            <el-form ref="form"   label-width="80px">
-              <el-form-item label="绾胯矾:">
-               
-              </el-form-item>
-              <el-form-item label="绾胯矾:">
-          
-              </el-form-item>
-              <el-form-item>
-                <el-button size="mini" >寮�濮嬫极娓�</el-button>
-                <el-button size="mini" >缁撴潫婕父</el-button>
-              </el-form-item>
+    <Popup ref="pop" top="20px" left="calc(100% - 600px)" :title="title" @close="close(true)" width="300px"
+        :maxHeight="'700px'" @cancel="close(false)">
+        <div class="menuBox">
+            <el-form ref="form" label-width="80px">
+                <el-form-item label="绾胯矾:">
+                    <el-select v-model="value" @chagne="setLineOptionChagne" placeholder="璇烽�夋嫨">
+                        <el-option v-for="item in lineOption" :key="item.value" :label="item.name" :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="绾胯矾:">
+                    <el-select v-model="value1" placeholder="璇烽�夋嫨">
+                        <el-option v-for="item in lineOption1" :key="item.value" :label="item.name" :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                    <el-button size="mini" @click="setRoamStart">寮�濮嬫极娓�</el-button>
+                    <el-button size="mini" @click="setRoamStop">缁撴潫婕父</el-button>
+                </el-form-item>
             </el-form>
-         </div>
+        </div>
     </Popup>
 </template>
 
@@ -22,20 +29,26 @@
 import {
     zhangzitou_selectAllLine
 } from '@/api/mapView/map.js'
+import WKT from 'terraformer-wkt-parser';
 export default {
     name: 'location',
     components: { Popup },
     data() {
         return {
             title: '绾胯矾婕父',
+            lineOption: [],
+            lineOption1: [],
+            lineObj: null,
+            value: '',
+            value1: '',
+            roamLine: null,
         };
     },
-   
- 
+
+
     methods: {
         // 鍏抽棴寮圭獥
         close(isCloseBtn, removeLayer = true) {
-            //   removeLayer && this.removeImageLayer();
             // 閲嶇疆data鍊�
             Object.assign(this.$data, this.$options.data());
             !isCloseBtn && this.$refs.pop.close();
@@ -46,14 +59,77 @@
             this.$refs.pop.open();
             this.romaLineStart();
         },
-        romaLineStart(){
-            zhangzitou_selectAllLine({  
+        romaLineStart() {
+            zhangzitou_selectAllLine({
                 limit: 100000,
                 page: 1
-            }).then((response)=>{
-                console.log(response);
+            }).then((response) => {
+                if (response.data.code != 200) return
+                this.lineOption = [];
+                this.lineObj = response.data.result.pois;
+                this.lineObj.map(item => {
+                    if (this.lineOption.length == 0) {
+                        this.lineOption.push({
+                            name: item.line,
+                            value: item.line
+                        })
+                    } else {
+                        const n = this.lineOption.filter(r => {
+                            if (r.name == item.line) {
+                                return r
+                            }
+
+                        })
+                        if (n.length == 0) {
+                            this.lineOption.push({
+                                name: item.line,
+                                value: item.line
+                            })
+                        }
+                    }
+                })
+                this.value = this.lineOption[0].value
+                this.setLineOptionChagne();
             })
         },
+        setLineOptionChagne() {
+            const a = this.value
+            this.lineOption1 = [];
+            this.lineObj.map(item => {
+                if (item.line == a) {
+                    this.lineOption1.push({
+                        name: item.name,
+                        value: item.geom,
+                    })
+                }
+            })
+            this.value1 = this.lineOption1[0].value;
+            this.setLineOption1Chagne();
+
+        },
+        setLineOption1Chagne() {
+            this.roamLine = this.value1;
+        },
+        setRoamStart() {
+            if (!this.roamLine) return;
+            const obj = WKT.parse(this.roamLine).coordinates[0]
+            var degreesArr = obj.reduce((combined, current) => combined.concat(current), []);
+            earthCtrl.factory.getFlyData(degreesArr, data => {
+                data.showPoint = false;
+                data.showLine = true;
+                data.mode = 1;
+
+            })
+        },
+        setRoamStop(){
+
+        },
+
+
+
+
+
+
     },
 };
 </script>
diff --git a/src/views/visual/mapView/location.vue b/src/views/visual/mapView/location.vue
index 85f2da4..a6aa5b5 100644
--- a/src/views/visual/mapView/location.vue
+++ b/src/views/visual/mapView/location.vue
@@ -84,9 +84,7 @@
             this.$refs[formName].validate((valid) => {
                 if (valid) {
                     this.setRemoveBillboard();
-
                     const url = config.sdkImg + 'Workers/image/mark.png';
-                    console.log(url);
                     this.billboard = Viewer.entities.add({
                         position: Cesium.Cartesian3.fromDegrees(this.modelFrom.lon, this.modelFrom.lat), // 璁剧疆瀹炰綋鍦ㄥ湴鐞冧笂鐨勪綅缃�
                         billboard: {
diff --git a/src/views/visual/mapView/undergroundMode.vue b/src/views/visual/mapView/undergroundMode.vue
new file mode 100644
index 0000000..12dbcb6
--- /dev/null
+++ b/src/views/visual/mapView/undergroundMode.vue
@@ -0,0 +1,116 @@
+<template>
+    <Popup ref="pop" top="20px" left="calc(100% - 600px)" :maxHeight="'700px'" :title="title" @close="close(true)"
+        width="300px" @cancel="close(false)">
+        <div style="padding: 10px;">
+            <div class="underGroundBox">
+                <el-switch class="elSwitch" @change="setUnderGroundCheck" v-model="value1" active-text="鍦颁笅妯″紡">
+                </el-switch>
+
+                <!-- <div class="contentRight">
+                    <el-switch class="elSwitch" v-model="value2" active-text="鍦颁笅缃戞牸">
+                    </el-switch>
+                </div> -->
+            </div>
+            <div class="underGroundBox">
+                <span>
+                    閫忔槑搴� :
+                </span>
+                <div class="contentRight">
+                    <el-slider v-model="value3" @change="setAlphaChange" :format-tooltip="formatTooltip"></el-slider>
+                </div>
+
+            </div>
+        </div>
+
+
+    </Popup>
+</template>
+
+<script>
+import Popup from '@/components/Tool/Popup.vue';
+export default {
+    name: 'location',
+    components: { Popup },
+    data() {
+        return {
+            title: '鍦颁笅妯″紡',
+            value1: true,
+            value2: false,
+            value3: 50,
+
+        };
+    },
+    methods: {
+        // 鍏抽棴寮圭獥
+        close(isCloseBtn, removeLayer = true) {
+            //   removeLayer && this.removeImageLayer();
+            // 閲嶇疆data鍊�
+            this.value1 = false;
+            this.value3 = 50;
+            this.setUnderGroundCheck();
+            this.setAlphaChange()
+            Object.assign(this.$data, this.$options.data());
+            !isCloseBtn && this.$refs.pop.close();
+
+        },
+        setUnderGroundCheck() {
+            earthCtrl.camera.undergroundMode = this.value1
+            earthCtrl.camera.imageryLayerAlpha = this.value3 / 100
+        },
+        // 鎵撳紑寮圭獥
+        open() {
+            this.close(true);
+            this.$refs.pop.open();
+
+            this.setUnderGroundCheck();
+        },
+        formatTooltip(val) {
+            return val + '%'
+        },
+        setAlphaChange() {
+            earthCtrl.camera.imageryLayerAlpha = this.value3 / 100
+        }
+
+
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+.elSwitch {
+    ::v-deep.el-switch__core {
+        border-radius: 10px !important;
+        width: 40px !important;
+        height: 20px;
+    }
+
+    ::v-deep.el-switch__core:after {
+        width: 16px;
+        height: 16px;
+        border-radius: 100%;
+
+    }
+
+
+}
+
+.underGroundBox {
+    display: flex;
+    margin-bottom: 10px;
+    align-items: center;
+
+    span {
+        font-size: 14px;
+    }
+
+    .contentRight {
+        flex: 1;
+        margin-left: 10px;
+    }
+}
+
+::v-deep .el-switch.is-checked .el-switch__core:after {
+    margin-left: -17px;
+
+}
+</style>

--
Gitblit v1.9.3