wanger 8 luni în urmă
comite
5634c7f7a5
100 a modificat fișierele cu 28096 adăugiri și 0 ștergeri
  1. 4 0
      .env
  2. 2 0
      .env.development
  3. 3 0
      .env.production
  4. 3 0
      .env.production-55
  5. 24 0
      .gitignore
  6. 7 0
      README.md
  7. BIN
      dist.rar
  8. 17 0
      index.html
  9. 3067 0
      package-lock.json
  10. 53 0
      package.json
  11. 0 0
      public/js/140000.geojson
  12. 27 0
      public/js/config.js
  13. 0 0
      public/js/xzqds.geojson
  14. 0 0
      public/js/xzqxs.geojson
  15. 16 0
      src/App.vue
  16. 90 0
      src/api/gdal/index.js
  17. 74 0
      src/api/main/index.js
  18. 84 0
      src/api/main/request.js
  19. 50 0
      src/api/main/request9289.js
  20. 12 0
      src/api/map/mapApi.js
  21. 211 0
      src/api/metadata/index.js
  22. 51 0
      src/api/metadata/request.js
  23. 45 0
      src/api/yxsj/yxsjApi.js
  24. BIN
      src/assets/401_images/401.gif
  25. BIN
      src/assets/404_images/404.png
  26. BIN
      src/assets/404_images/404_cloud.png
  27. 65 0
      src/assets/common.scss
  28. 539 0
      src/assets/icon/demo.css
  29. 1909 0
      src/assets/icon/demo_index.html
  30. 313 0
      src/assets/icon/iconfont.css
  31. 0 0
      src/assets/icon/iconfont.js
  32. 534 0
      src/assets/icon/iconfont.json
  33. BIN
      src/assets/icon/iconfont.ttf
  34. BIN
      src/assets/images/m-cesium.png
  35. BIN
      src/assets/images/m-cityLine.png
  36. BIN
      src/assets/images/m-earth.png
  37. BIN
      src/assets/images/m-normal.png
  38. BIN
      src/assets/images/maptype.png
  39. BIN
      src/assets/images/shadow_6bf0ecd.png
  40. 127 0
      src/assets/less/_variables.less
  41. 35 0
      src/assets/less/map.less
  42. 754 0
      src/assets/less/style.less
  43. 70 0
      src/assets/styles/index.scss
  44. 221 0
      src/assets/styles/public.css
  45. 4 0
      src/assets/styles/reset-elemenet-plus-style.scss
  46. 274 0
      src/assets/styles/scss-suger.scss
  47. 44 0
      src/assets/styles/transition.scss
  48. 1 0
      src/assets/vue.svg
  49. 206 0
      src/components/mapview/basemap.vue
  50. 220 0
      src/components/mapview/fastnav.vue
  51. 69 0
      src/components/mapview/index.js
  52. 599 0
      src/components/mapview/range/range.vue
  53. 87 0
      src/components/mapview/transparency.vue
  54. 255 0
      src/components/mapview/vectorTileAttrtable.vue
  55. 719 0
      src/components/mapview/vectorTileTool.vue
  56. 48 0
      src/main.js
  57. 165 0
      src/permission.js
  58. 18 0
      src/plugins/index.js
  59. 82 0
      src/plugins/modal.js
  60. 165 0
      src/router/index.js
  61. 96 0
      src/style.css
  62. 223 0
      src/utils/CoordTransformate.js
  63. 187 0
      src/utils/Export2Excel.js
  64. 587 0
      src/utils/Projection.json
  65. 1381 0
      src/utils/arcMap.js
  66. 18 0
      src/utils/auth.js
  67. 100 0
      src/utils/baseLayer.js
  68. 259 0
      src/utils/common.js
  69. 283 0
      src/utils/echartsoption.js
  70. 1178 0
      src/utils/map.js
  71. 1996 0
      src/utils/map/drawPlugin/DrawHelper.js
  72. 608 0
      src/utils/map/drawPlugin/GlobeBufferLineDrawer.js
  73. 577 0
      src/utils/map/drawPlugin/GlobeCircleDrawer.js
  74. 279 0
      src/utils/map/drawPlugin/GlobePointDrawer.js
  75. 302 0
      src/utils/map/drawPlugin/GlobePointMeasure.js
  76. 574 0
      src/utils/map/drawPlugin/GlobePolygonDrawer.js
  77. 693 0
      src/utils/map/drawPlugin/GlobePolygonMeasure.js
  78. 580 0
      src/utils/map/drawPlugin/GlobePolylineDrawer.js
  79. 575 0
      src/utils/map/drawPlugin/GlobePolylineSpaceMeasure.js
  80. 622 0
      src/utils/map/drawPlugin/GlobePolylineStickMeasure.js
  81. 404 0
      src/utils/map/drawPlugin/GlobeRectangleDrawer.js
  82. 57 0
      src/utils/map/drawPlugin/GlobeTooltip.js
  83. 211 0
      src/utils/map/drawPlugin/GlobeTracker.js
  84. 505 0
      src/utils/map/drawPlugin/PlotAttackArrowDrawer.js
  85. 537 0
      src/utils/map/drawPlugin/PlotPincerArrowDrawer.js
  86. 484 0
      src/utils/map/drawPlugin/PlotStraightArrowDrawer.js
  87. 89 0
      src/utils/map/fly/fly.js
  88. 182 0
      src/utils/map/fun/ViewShed.js
  89. 413 0
      src/utils/map/fun/layerDraw.js
  90. 131 0
      src/utils/map/fun/layerManager.js
  91. 107 0
      src/utils/map/fun/layerOverlay.js
  92. 195 0
      src/utils/map/fun/layerPosition.js
  93. 715 0
      src/utils/map/fun/layerQuery.js
  94. 285 0
      src/utils/map/fun/layerScreenshots.js
  95. 504 0
      src/utils/map/layerHelper.js
  96. 38 0
      src/utils/map/mapRequest.js
  97. 626 0
      src/utils/map/mapUtils.js
  98. 43 0
      src/utils/map/provider/ArcgisService.js
  99. 62 0
      src/utils/map/provider/BaiduMapService.js
  100. 27 0
      src/utils/map/provider/GaodeMapService.js

+ 4 - 0
.env

@@ -0,0 +1,4 @@
+VITE_portaluserno = 'admin'
+VITE_portalusername = '系统管理员'
+VITE_portalusermanager = '2'
+VITE_portaluserdept = '101010'

+ 2 - 0
.env.development

@@ -0,0 +1,2 @@
+VITE_BASE_API=/api
+VITE_DZZ_API=/dzzapi

+ 3 - 0
.env.production

@@ -0,0 +1,3 @@
+VITE_BASE_API=http://192.168.60.42:8080
+VITE_DZZ_API=http://192.168.60.42:8080
+

+ 3 - 0
.env.production-55

@@ -0,0 +1,3 @@
+VITE_BASE_API=http://192.168.100.30:8080
+VITE_DZZ_API=http://192.168.100.30:8080
+

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)

BIN
dist.rar


+ 17 - 0
index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta name="renderer" content="webkit" />
+		<meta charset="UTF-8" />
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
+		<!-- <link rel="icon" type="image/svg+xml" href="/favicon.png" /> -->
+		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+		<title>数据管理系统</title>
+		<script src="/js/config.js"></script>
+	</head>
+
+	<body>
+		<div id="app"></div>
+		<script type="module" src="/src/main.js"></script>
+	</body>
+</html>

+ 3067 - 0
package-lock.json

@@ -0,0 +1,3067 @@
+{
+  "name": "calligraphy-learning-system",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "calligraphy-learning-system",
+      "version": "0.0.0",
+      "dependencies": {
+        "@amap/amap-jsapi-loader": "^1.0.1",
+        "@element-plus/icons-vue": "^2.1.0",
+        "@icon-park/vue-next": "^1.4.2",
+        "@mapbox/togeojson": "^0.16.0",
+        "axios": "0.24.0",
+        "circle-to-polygon": "^2.2.0",
+        "coordtransform": "^2.1.2",
+        "driver.js": "^0.9.8",
+        "echarts": "^5.4.2",
+        "element-plus": "^2.3.3",
+        "file-saver": "^2.0.5",
+        "highlight.js": "^11.8.0",
+        "html2canvas": "^1.4.1",
+        "jquery": "^3.6.1",
+        "js-base64": "^3.7.5",
+        "js-cookie": "^3.0.1",
+        "less": "^4.1.3",
+        "less-loader": "^11.1.3",
+        "nprogress": "0.2.0",
+        "ol": "^6.5.0",
+        "pinia": "^2.0.33",
+        "proj4": "^2.8.0",
+        "qs": "^6.11.2",
+        "swiper": "^9.0.2",
+        "terser": "^5.17.6",
+        "vkbeautify": "^0.99.3",
+        "vue": "^3.2.41",
+        "vue-moment": "^4.1.0",
+        "x2js": "^3.4.4",
+        "xlsx": "^0.18.5"
+      },
+      "devDependencies": {
+        "@types/file-saver": "^2.0.5",
+        "@vitejs/plugin-vue": "^3.2.0",
+        "sass": "^1.56.2",
+        "sass-loader": "^13.2.0",
+        "script-loader": "^0.7.2",
+        "vite": "^3.2.3",
+        "vue-router": "^4.1.6"
+      }
+    },
+    "node_modules/@amap/amap-jsapi-loader": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
+      "integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw=="
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.5.tgz",
+      "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==",
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@ctrl/tinycolor": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.5.0.tgz",
+      "integrity": "sha512-tlJpwF40DEQcfR/QF+wNMVyGMaO9FQp6Z1Wahj4Gk3CJQYHwA2xVG7iKDFdW6zuxZY9XWOpGcfNCTsX4McOsOg==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@element-plus/icons-vue": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
+      "integrity": "sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==",
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+      "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+      "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@floating-ui/core": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.3.0.tgz",
+      "integrity": "sha512-vX1WVAdPjZg9DkDkC+zEx/tKtnST6/qcNpwcjeBgco3XRNHz5PUA+ivi/yr6G3o0kMR60uKBJcfOdfzOFI7PMQ=="
+    },
+    "node_modules/@floating-ui/dom": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.2.0.tgz",
+      "integrity": "sha512-QXzg57o1cjLz3cGETzKXjI3kx1xyS49DW9l7kV2jw2c8Yftd434t2hllX0sVGn2Q8MtcW/4pNm8bfE1/4n6mng==",
+      "dependencies": {
+        "@floating-ui/core": "^1.2.0"
+      }
+    },
+    "node_modules/@icon-park/vue-next": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/@icon-park/vue-next/-/vue-next-1.4.2.tgz",
+      "integrity": "sha512-+QklF255wkfBOabY+xw6FAI0Bwln/RhdwCunNy/9sKdKuChtaU67QZqU67KGAvZUTeeBgsL+yaHHxqfQeGZXEQ==",
+      "engines": {
+        "node": ">= 8.0.0",
+        "npm": ">= 5.0.0"
+      },
+      "peerDependencies": {
+        "vue": "3.x"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+      "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/source-map": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.3.tgz",
+      "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.18",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
+      "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
+      }
+    },
+    "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.14",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+    },
+    "node_modules/@mapbox/jsonlint-lines-primitives": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
+      "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/@mapbox/mapbox-gl-style-spec": {
+      "version": "13.28.0",
+      "resolved": "https://registry.npmmirror.com/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.28.0.tgz",
+      "integrity": "sha512-B8xM7Fp1nh5kejfIl4SWeY0gtIeewbuRencqO3cJDrCHZpaPg7uY+V8abuR+esMeuOjRl5cLhVTP40v+1ywxbg==",
+      "dependencies": {
+        "@mapbox/jsonlint-lines-primitives": "~2.0.2",
+        "@mapbox/point-geometry": "^0.1.0",
+        "@mapbox/unitbezier": "^0.0.0",
+        "csscolorparser": "~1.0.2",
+        "json-stringify-pretty-compact": "^2.0.0",
+        "minimist": "^1.2.6",
+        "rw": "^1.3.3",
+        "sort-object": "^0.3.2"
+      },
+      "bin": {
+        "gl-style-composite": "bin/gl-style-composite.js",
+        "gl-style-format": "bin/gl-style-format.js",
+        "gl-style-migrate": "bin/gl-style-migrate.js",
+        "gl-style-validate": "bin/gl-style-validate.js"
+      }
+    },
+    "node_modules/@mapbox/mapbox-gl-style-spec/node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/@mapbox/point-geometry": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmmirror.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
+      "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="
+    },
+    "node_modules/@mapbox/togeojson": {
+      "version": "0.16.0",
+      "resolved": "https://registry.npmmirror.com/@mapbox/togeojson/-/togeojson-0.16.0.tgz",
+      "integrity": "sha512-PeBrRQ+kuVP5j3lqa5JtnYBd9E7eQdWnsmOmUq8aWs0caNzLbCqnXSkKxrIGURukf7lZ82aOxjustLRX3f9GOA==",
+      "dependencies": {
+        "concat-stream": "~1.5.1",
+        "minimist": "1.2.0",
+        "xmldom": "~0.1.19"
+      },
+      "bin": {
+        "togeojson": "togeojson"
+      }
+    },
+    "node_modules/@mapbox/unitbezier": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmmirror.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz",
+      "integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA=="
+    },
+    "node_modules/@petamoriken/float16": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/@petamoriken/float16/-/float16-3.8.1.tgz",
+      "integrity": "sha512-oj3dU9kuMy8AqrreIboVh3KCJGSQO5T+dJ8JQFl369961jTWvPLP1GIlLy0FVoWehXLoI9BXygu/yzuNiIHBlg=="
+    },
+    "node_modules/@popperjs/core": {
+      "version": "2.11.7",
+      "resolved": "https://registry.npmmirror.com/@popperjs/core/-/core-2.11.7.tgz",
+      "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
+    "node_modules/@types/eslint": {
+      "version": "8.40.2",
+      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz",
+      "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==",
+      "peer": true,
+      "dependencies": {
+        "@types/estree": "*",
+        "@types/json-schema": "*"
+      }
+    },
+    "node_modules/@types/eslint-scope": {
+      "version": "3.7.4",
+      "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
+      "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+      "peer": true,
+      "dependencies": {
+        "@types/eslint": "*",
+        "@types/estree": "*"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+      "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
+      "peer": true
+    },
+    "node_modules/@types/file-saver": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz",
+      "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==",
+      "dev": true
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.12",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
+      "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
+      "peer": true
+    },
+    "node_modules/@types/lodash": {
+      "version": "4.14.191",
+      "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz",
+      "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+    },
+    "node_modules/@types/lodash-es": {
+      "version": "4.17.6",
+      "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.6.tgz",
+      "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==",
+      "dependencies": {
+        "@types/lodash": "*"
+      }
+    },
+    "node_modules/@types/node": {
+      "version": "20.3.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz",
+      "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==",
+      "peer": true
+    },
+    "node_modules/@types/web-bluetooth": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
+      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+    },
+    "node_modules/@vitejs/plugin-vue": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz",
+      "integrity": "sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==",
+      "dev": true,
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^3.0.0",
+        "vue": "^3.2.25"
+      }
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
+      "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz",
+      "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==",
+      "dependencies": {
+        "@vue/compiler-core": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz",
+      "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.47",
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/compiler-ssr": "3.2.47",
+        "@vue/reactivity-transform": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7",
+        "postcss": "^8.1.10",
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz",
+      "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/devtools-api": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
+      "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.47.tgz",
+      "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==",
+      "dependencies": {
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/reactivity-transform": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz",
+      "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==",
+      "dependencies": {
+        "@babel/parser": "^7.16.4",
+        "@vue/compiler-core": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.25.7"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.47.tgz",
+      "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==",
+      "dependencies": {
+        "@vue/reactivity": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz",
+      "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==",
+      "dependencies": {
+        "@vue/runtime-core": "3.2.47",
+        "@vue/shared": "3.2.47",
+        "csstype": "^2.6.8"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.47.tgz",
+      "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.2.47",
+        "@vue/shared": "3.2.47"
+      },
+      "peerDependencies": {
+        "vue": "3.2.47"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.47.tgz",
+      "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
+    },
+    "node_modules/@vueuse/core": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.12.0.tgz",
+      "integrity": "sha512-h/Di8Bvf6xRcvS/PvUVheiMYYz3U0tH3X25YxONSaAUBa841ayMwxkuzx/DGUMCW/wHWzD8tRy2zYmOC36r4sg==",
+      "dependencies": {
+        "@types/web-bluetooth": "^0.0.16",
+        "@vueuse/metadata": "9.12.0",
+        "@vueuse/shared": "9.12.0",
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/metadata": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.12.0.tgz",
+      "integrity": "sha512-9oJ9MM9lFLlmvxXUqsR1wLt1uF7EVbP5iYaHJYqk+G2PbMjY6EXvZeTjbdO89HgoF5cI6z49o2zT/jD9SVoNpQ==",
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/shared": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.12.0.tgz",
+      "integrity": "sha512-TWuJLACQ0BVithVTRbex4Wf1a1VaRuSpVeyEd4vMUWl54PzlE0ciFUshKCXnlLuD0lxIaLK4Ypj3NXYzZh4+SQ==",
+      "dependencies": {
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@webassemblyjs/ast": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+      "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/helper-numbers": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+      "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+      "peer": true
+    },
+    "node_modules/@webassemblyjs/helper-api-error": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+      "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+      "peer": true
+    },
+    "node_modules/@webassemblyjs/helper-buffer": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+      "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+      "peer": true
+    },
+    "node_modules/@webassemblyjs/helper-numbers": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+      "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+        "@webassemblyjs/helper-api-error": "1.11.6",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+      "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+      "peer": true
+    },
+    "node_modules/@webassemblyjs/helper-wasm-section": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+      "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/wasm-gen": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/ieee754": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+      "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+      "peer": true,
+      "dependencies": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "node_modules/@webassemblyjs/leb128": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+      "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+      "peer": true,
+      "dependencies": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/utf8": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+      "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+      "peer": true
+    },
+    "node_modules/@webassemblyjs/wasm-edit": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+      "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/helper-wasm-section": "1.11.6",
+        "@webassemblyjs/wasm-gen": "1.11.6",
+        "@webassemblyjs/wasm-opt": "1.11.6",
+        "@webassemblyjs/wasm-parser": "1.11.6",
+        "@webassemblyjs/wast-printer": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-gen": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+      "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/ieee754": "1.11.6",
+        "@webassemblyjs/leb128": "1.11.6",
+        "@webassemblyjs/utf8": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-opt": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+      "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/wasm-gen": "1.11.6",
+        "@webassemblyjs/wasm-parser": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-parser": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+      "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-api-error": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/ieee754": "1.11.6",
+        "@webassemblyjs/leb128": "1.11.6",
+        "@webassemblyjs/utf8": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wast-printer": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+      "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+      "peer": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@xmldom/xmldom": {
+      "version": "0.8.8",
+      "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.8.tgz",
+      "integrity": "sha512-0LNz4EY8B/8xXY86wMrQ4tz6zEHZv9ehFMJPm8u2gq5lQ71cfRKdaKyxfJAx5aUoyzx0qzgURblTisPGgz3d+Q==",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "peer": true
+    },
+    "node_modules/@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "peer": true
+    },
+    "node_modules/acorn": {
+      "version": "8.8.2",
+      "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/acorn-import-assertions": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+      "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+      "peer": true,
+      "peerDependencies": {
+        "acorn": "^8"
+      }
+    },
+    "node_modules/adler-32": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "peer": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "peer": true,
+      "peerDependencies": {
+        "ajv": "^6.9.1"
+      }
+    },
+    "node_modules/async-validator": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
+      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+    },
+    "node_modules/axios": {
+      "version": "0.24.0",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-0.24.0.tgz",
+      "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
+      "dependencies": {
+        "follow-redirects": "^1.14.4"
+      }
+    },
+    "node_modules/base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.21.9",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
+      "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "peer": true,
+      "dependencies": {
+        "caniuse-lite": "^1.0.30001503",
+        "electron-to-chromium": "^1.4.431",
+        "node-releases": "^2.0.12",
+        "update-browserslist-db": "^1.0.11"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001512",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz",
+      "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "peer": true
+    },
+    "node_modules/cfb": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
+      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+      "dependencies": {
+        "adler-32": "~1.3.0",
+        "crc-32": "~1.2.0"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chokidar/node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/chokidar/node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/chokidar/node_modules/fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/chokidar/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/chokidar/node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/chokidar/node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/chrome-trace-event": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+      "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+      "peer": true,
+      "engines": {
+        "node": ">=6.0"
+      }
+    },
+    "node_modules/circle-to-polygon": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/circle-to-polygon/-/circle-to-polygon-2.2.0.tgz",
+      "integrity": "sha512-yC9/bw6P0YmV2/oxm4DLrSgrzHhbz9H+vgUScmSFN5KilR/KFGVRbUi9a0mIYPsXK44HvnysVVi/iIysRJVvNw=="
+    },
+    "node_modules/codepage": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
+      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+    },
+    "node_modules/concat-stream": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmmirror.com/concat-stream/-/concat-stream-1.5.2.tgz",
+      "integrity": "sha512-H6xsIBfQ94aESBG8jGHXQ7i5AEpy5ZeVaLDOisDICiTCKpqEfr34/KmTrspKQNoLKNu9gTkovlpQcUi630AKiQ==",
+      "engines": [
+        "node >= 0.8"
+      ],
+      "dependencies": {
+        "inherits": "~2.0.1",
+        "readable-stream": "~2.0.0",
+        "typedarray": "~0.0.5"
+      }
+    },
+    "node_modules/concat-stream/node_modules/process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw=="
+    },
+    "node_modules/concat-stream/node_modules/readable-stream": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.0.6.tgz",
+      "integrity": "sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~1.0.6",
+        "string_decoder": "~0.10.x",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/coordtransform": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/coordtransform/-/coordtransform-2.1.2.tgz",
+      "integrity": "sha512-0xLJApBlrUP+clyLJWIaqg4GXE5JTbAJb5d/CDMqebIksAMMze8eAyO6YfHEIxWJ+c42mXoMHBzWTeUrG7RFhw=="
+    },
+    "node_modules/copy-anything": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
+      "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+      "dependencies": {
+        "is-what": "^3.14.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mesqueeb"
+      }
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+    },
+    "node_modules/crc-32": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
+      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
+      "bin": {
+        "crc32": "bin/crc32.njs"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
+    "node_modules/csscolorparser": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/csscolorparser/-/csscolorparser-1.0.3.tgz",
+      "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w=="
+    },
+    "node_modules/csstype": {
+      "version": "2.6.21",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
+      "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
+    },
+    "node_modules/dayjs": {
+      "version": "1.11.7",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz",
+      "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
+    },
+    "node_modules/driver.js": {
+      "version": "0.9.8",
+      "resolved": "https://registry.npmmirror.com/driver.js/-/driver.js-0.9.8.tgz",
+      "integrity": "sha512-bczjyKdX6XmFyCDkwtRmlaORDwfBk1xXmRO0CAe5VwNQTM98aWaG2LAIiIdTe53iV/B7W5lXlIy2xYtf0JRb7Q=="
+    },
+    "node_modules/echarts": {
+      "version": "5.4.2",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz",
+      "integrity": "sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA==",
+      "dependencies": {
+        "tslib": "2.3.0",
+        "zrender": "5.4.3"
+      }
+    },
+    "node_modules/echarts/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.4.450",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz",
+      "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==",
+      "peer": true
+    },
+    "node_modules/element-plus": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.3.4.tgz",
+      "integrity": "sha512-SQr0J9z7N4z48WYk/l9NE2tizl8Q7j2OhqlpTc42k4pGncry3+rVX6dsmcsglFynn6vt3NzYxWJqmLFyDKQq+g==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.4.1",
+        "@element-plus/icons-vue": "^2.0.6",
+        "@floating-ui/dom": "^1.0.1",
+        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+        "@types/lodash": "^4.14.182",
+        "@types/lodash-es": "^4.17.6",
+        "@vueuse/core": "^9.1.0",
+        "async-validator": "^4.2.5",
+        "dayjs": "^1.11.3",
+        "escape-html": "^1.0.3",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.21",
+        "lodash-unified": "^1.0.2",
+        "memoize-one": "^6.0.0",
+        "normalize-wheel-es": "^1.2.0"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/element-plus/node_modules/@element-plus/icons-vue": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.0.10.tgz",
+      "integrity": "sha512-ygEZ1mwPjcPo/OulhzLE7mtDrQBWI8vZzEWSNB2W/RNCRjoQGwbaK4N8lV4rid7Ts4qvySU3njMN7YCiSlSaTQ==",
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/enhanced-resolve": {
+      "version": "5.15.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+      "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+      "peer": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/errno": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+      "optional": true,
+      "dependencies": {
+        "prr": "~1.0.1"
+      },
+      "bin": {
+        "errno": "cli.js"
+      }
+    },
+    "node_modules/es-module-lexer": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
+      "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==",
+      "peer": true
+    },
+    "node_modules/esbuild": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.15.18.tgz",
+      "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.15.18",
+        "@esbuild/linux-loong64": "0.15.18",
+        "esbuild-android-64": "0.15.18",
+        "esbuild-android-arm64": "0.15.18",
+        "esbuild-darwin-64": "0.15.18",
+        "esbuild-darwin-arm64": "0.15.18",
+        "esbuild-freebsd-64": "0.15.18",
+        "esbuild-freebsd-arm64": "0.15.18",
+        "esbuild-linux-32": "0.15.18",
+        "esbuild-linux-64": "0.15.18",
+        "esbuild-linux-arm": "0.15.18",
+        "esbuild-linux-arm64": "0.15.18",
+        "esbuild-linux-mips64le": "0.15.18",
+        "esbuild-linux-ppc64le": "0.15.18",
+        "esbuild-linux-riscv64": "0.15.18",
+        "esbuild-linux-s390x": "0.15.18",
+        "esbuild-netbsd-64": "0.15.18",
+        "esbuild-openbsd-64": "0.15.18",
+        "esbuild-sunos-64": "0.15.18",
+        "esbuild-windows-32": "0.15.18",
+        "esbuild-windows-64": "0.15.18",
+        "esbuild-windows-arm64": "0.15.18"
+      }
+    },
+    "node_modules/esbuild-android-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+      "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-android-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+      "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+      "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+      "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+      "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+      "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-32": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+      "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+      "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+      "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+      "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-mips64le": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+      "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-ppc64le": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+      "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-riscv64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+      "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-s390x": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+      "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-netbsd-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+      "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-openbsd-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+      "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-sunos-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+      "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-32": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+      "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+      "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+      "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "peer": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "peer": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "peer": true,
+      "dependencies": {
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esrecurse/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "peer": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "peer": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+    },
+    "node_modules/events": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "peer": true,
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "peer": true
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "peer": true
+    },
+    "node_modules/file-saver": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+      "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "node_modules/geotiff": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/geotiff/-/geotiff-2.0.4.tgz",
+      "integrity": "sha512-aG8h9bJccGusioPsEWsEqx8qdXpZN71A20WCvRKGxcnHSOWLKmC5ZmsAmodfxb9TRQvs+89KikGuPzxchhA+Uw==",
+      "dependencies": {
+        "@petamoriken/float16": "^3.4.7",
+        "lerc": "^3.0.0",
+        "lru-cache": "^6.0.0",
+        "pako": "^2.0.4",
+        "parse-headers": "^2.0.2",
+        "web-worker": "^1.2.0",
+        "xml-utils": "^1.0.2"
+      },
+      "engines": {
+        "browsers": "defaults",
+        "node": ">=10.19"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+      "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/glob-to-regexp": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+      "peer": true
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/highlight.js": {
+      "version": "11.8.0",
+      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz",
+      "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==",
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "dependencies": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+      "optional": true,
+      "bin": {
+        "image-size": "bin/image-size.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/immutable": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.2.4.tgz",
+      "integrity": "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==",
+      "dev": true
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.12.1.tgz",
+      "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-what": {
+      "version": "3.14.1",
+      "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
+      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
+    },
+    "node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+    },
+    "node_modules/jest-worker": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+      "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+      "peer": true,
+      "dependencies": {
+        "@types/node": "*",
+        "merge-stream": "^2.0.0",
+        "supports-color": "^8.0.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      }
+    },
+    "node_modules/jquery": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmmirror.com/jquery/-/jquery-3.6.3.tgz",
+      "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
+    },
+    "node_modules/js-base64": {
+      "version": "3.7.5",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz",
+      "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA=="
+    },
+    "node_modules/js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+      "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "peer": true
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "peer": true
+    },
+    "node_modules/json-stringify-pretty-compact": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz",
+      "integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ=="
+    },
+    "node_modules/klona": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",
+      "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/lerc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/lerc/-/lerc-3.0.0.tgz",
+      "integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww=="
+    },
+    "node_modules/less": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz",
+      "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==",
+      "dependencies": {
+        "copy-anything": "^2.0.1",
+        "parse-node-version": "^1.0.1",
+        "tslib": "^2.3.0"
+      },
+      "bin": {
+        "lessc": "bin/lessc"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "optionalDependencies": {
+        "errno": "^0.1.1",
+        "graceful-fs": "^4.1.2",
+        "image-size": "~0.5.0",
+        "make-dir": "^2.1.0",
+        "mime": "^1.4.1",
+        "needle": "^3.1.0",
+        "source-map": "~0.6.0"
+      }
+    },
+    "node_modules/less-loader": {
+      "version": "11.1.3",
+      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.3.tgz",
+      "integrity": "sha512-A5b7O8dH9xpxvkosNrP0dFp2i/dISOJa9WwGF3WJflfqIERE2ybxh1BFDj5CovC2+jCE4M354mk90hN6ziXlVw==",
+      "engines": {
+        "node": ">= 14.15.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "less": "^3.5.0 || ^4.0.0",
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/loader-runner": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+      "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+      "peer": true,
+      "engines": {
+        "node": ">=6.11.5"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
+    "node_modules/lodash-unified": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz",
+      "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+      "peerDependencies": {
+        "@types/lodash-es": "*",
+        "lodash": "*",
+        "lodash-es": "*"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.25.9",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz",
+      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+      "dependencies": {
+        "sourcemap-codec": "^1.4.8"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "optional": true,
+      "dependencies": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/make-dir/node_modules/pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mapbox-to-css-font": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmmirror.com/mapbox-to-css-font/-/mapbox-to-css-font-2.4.2.tgz",
+      "integrity": "sha512-f+NBjJJY4T3dHtlEz1wCG7YFlkODEjFIYlxDdLIDMNpkSksqTt+l/d4rjuwItxuzkuMFvPyrjzV2lxRM4ePcIA=="
+    },
+    "node_modules/memoize-one": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
+      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "peer": true
+    },
+    "node_modules/mgrs": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz",
+      "integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA=="
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "optional": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "peer": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "peer": true,
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.0.tgz",
+      "integrity": "sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw=="
+    },
+    "node_modules/moment": {
+      "version": "2.29.4",
+      "resolved": "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/needle": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz",
+      "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==",
+      "optional": true,
+      "dependencies": {
+        "debug": "^3.2.6",
+        "iconv-lite": "^0.6.3",
+        "sax": "^1.2.4"
+      },
+      "bin": {
+        "needle": "bin/needle"
+      },
+      "engines": {
+        "node": ">= 4.4.x"
+      }
+    },
+    "node_modules/needle/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "optional": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/needle/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "optional": true
+    },
+    "node_modules/neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz",
+      "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==",
+      "peer": true
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-wheel-es": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
+    },
+    "node_modules/nprogress": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz",
+      "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
+    },
+    "node_modules/object-inspect": {
+      "version": "1.12.3",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/ol": {
+      "version": "6.15.1",
+      "resolved": "https://registry.npmmirror.com/ol/-/ol-6.15.1.tgz",
+      "integrity": "sha512-ZG2CKTpJ8Q+tPywYysVwPk+yevwJzlbwjRKhoCvd7kLVWMbfBl1O/+Kg/yrZZrhG9FNXbFH4GeOZ5yVRqo3P4w==",
+      "dependencies": {
+        "geotiff": "2.0.4",
+        "ol-mapbox-style": "^8.0.5",
+        "pbf": "3.2.1",
+        "rbush": "^3.0.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/openlayers"
+      }
+    },
+    "node_modules/ol-mapbox-style": {
+      "version": "8.2.1",
+      "resolved": "https://registry.npmmirror.com/ol-mapbox-style/-/ol-mapbox-style-8.2.1.tgz",
+      "integrity": "sha512-3kBBuZC627vDL8vnUdfVbCbfkhkcZj2kXPHQcuLhC4JJEA+XkEVEtEde8x8+AZctRbHwBkSiubTPaRukgLxIRw==",
+      "dependencies": {
+        "@mapbox/mapbox-gl-style-spec": "^13.23.1",
+        "mapbox-to-css-font": "^2.4.1"
+      }
+    },
+    "node_modules/pako": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
+      "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
+    },
+    "node_modules/parse-headers": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/parse-headers/-/parse-headers-2.0.5.tgz",
+      "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA=="
+    },
+    "node_modules/parse-node-version": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
+      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
+    },
+    "node_modules/pbf": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/pbf/-/pbf-3.2.1.tgz",
+      "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
+      "dependencies": {
+        "ieee754": "^1.1.12",
+        "resolve-protobuf-schema": "^2.1.0"
+      },
+      "bin": {
+        "pbf": "bin/pbf"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pinia": {
+      "version": "2.0.35",
+      "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.0.35.tgz",
+      "integrity": "sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.5.0",
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.4.0",
+        "typescript": ">=4.4.4",
+        "vue": "^2.6.14 || ^3.2.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.4.21",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz",
+      "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.4",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/proj4": {
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.9.0.tgz",
+      "integrity": "sha512-BoDXEzCVnRJVZoOKA0QHTFtYoE8lUxtX1jST38DJ8U+v1ixY70Kpwi0Llu6YqSWEH2xqu4XMEBNGcgeRIEywoA==",
+      "dependencies": {
+        "mgrs": "1.0.0",
+        "wkt-parser": "^1.3.1"
+      }
+    },
+    "node_modules/protocol-buffers-schema": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
+      "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
+    },
+    "node_modules/prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+      "optional": true
+    },
+    "node_modules/punycode": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+      "peer": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.11.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
+      "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
+      "dependencies": {
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/quickselect": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/quickselect/-/quickselect-2.0.0.tgz",
+      "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "peer": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/raw-loader": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
+      "integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q==",
+      "dev": true
+    },
+    "node_modules/rbush": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/rbush/-/rbush-3.0.1.tgz",
+      "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==",
+      "dependencies": {
+        "quickselect": "^2.0.0"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/resolve": {
+      "version": "1.22.1",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/resolve-protobuf-schema": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
+      "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
+      "dependencies": {
+        "protocol-buffers-schema": "^3.3.1"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "2.79.1",
+      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz",
+      "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+      "dev": true,
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "peer": true
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "optional": true
+    },
+    "node_modules/sass": {
+      "version": "1.58.0",
+      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.58.0.tgz",
+      "integrity": "sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==",
+      "dev": true,
+      "dependencies": {
+        "chokidar": ">=3.0.0 <4.0.0",
+        "immutable": "^4.0.0",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "bin": {
+        "sass": "sass.js"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/sass-loader": {
+      "version": "13.2.0",
+      "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-13.2.0.tgz",
+      "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==",
+      "dev": true,
+      "dependencies": {
+        "klona": "^2.0.4",
+        "neo-async": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 14.15.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "fibers": ">= 3.1.0",
+        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+        "sass": "^1.3.0",
+        "sass-embedded": "*",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "fibers": {
+          "optional": true
+        },
+        "node-sass": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+      "optional": true
+    },
+    "node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "peer": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/script-loader": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.2.tgz",
+      "integrity": "sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==",
+      "dev": true,
+      "dependencies": {
+        "raw-loader": "~0.5.1"
+      }
+    },
+    "node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "optional": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/serialize-javascript": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+      "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
+      "peer": true,
+      "dependencies": {
+        "randombytes": "^2.1.0"
+      }
+    },
+    "node_modules/side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/sort-asc": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmmirror.com/sort-asc/-/sort-asc-0.1.0.tgz",
+      "integrity": "sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sort-desc": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmmirror.com/sort-desc/-/sort-desc-0.1.1.tgz",
+      "integrity": "sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sort-object": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/sort-object/-/sort-object-0.3.2.tgz",
+      "integrity": "sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==",
+      "dependencies": {
+        "sort-asc": "^0.1.0",
+        "sort-desc": "^0.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/sourcemap-codec": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+      "deprecated": "Please use @jridgewell/sourcemap-codec instead"
+    },
+    "node_modules/ssf": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
+      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+      "dependencies": {
+        "frac": "~1.1.2"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ssr-window": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
+      "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
+    },
+    "node_modules/string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
+    },
+    "node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "peer": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/swiper": {
+      "version": "9.0.3",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-9.0.3.tgz",
+      "integrity": "sha512-hHYI6CeUHcDyv6IakzAQrUv6nS5BMRn6KOkui16nhtdgYBlWgUdlaMbcdT0o4RJxpwSktCTLgpBtCm+WwwVYRw==",
+      "funding": [
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/swiperjs"
+        },
+        {
+          "type": "open_collective",
+          "url": "http://opencollective.com/swiper"
+        }
+      ],
+      "dependencies": {
+        "ssr-window": "^4.0.2"
+      },
+      "engines": {
+        "node": ">= 4.7.0"
+      }
+    },
+    "node_modules/tapable": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+      "peer": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/terser": {
+      "version": "5.17.6",
+      "resolved": "https://registry.npmmirror.com/terser/-/terser-5.17.6.tgz",
+      "integrity": "sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ==",
+      "dependencies": {
+        "@jridgewell/source-map": "^0.3.2",
+        "acorn": "^8.5.0",
+        "commander": "^2.20.0",
+        "source-map-support": "~0.5.20"
+      },
+      "bin": {
+        "terser": "bin/terser"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/terser-webpack-plugin": {
+      "version": "5.3.9",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+      "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+      "peer": true,
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jest-worker": "^27.4.5",
+        "schema-utils": "^3.1.1",
+        "serialize-javascript": "^6.0.1",
+        "terser": "^5.16.8"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.1.0"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "esbuild": {
+          "optional": true
+        },
+        "uglify-js": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
+      "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
+    },
+    "node_modules/typedarray": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.7.tgz",
+      "integrity": "sha512-ueeb9YybpjhivjbHP2LdFDAjbS948fGEPj+ACAMs4xCMmh72OCOMQWBQKlaN4ZNQ04yfLSDLSx1tGRIoWimObQ==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
+      "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "peer": true,
+      "dependencies": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "peer": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+    },
+    "node_modules/utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "dependencies": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
+    "node_modules/vite": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.5.tgz",
+      "integrity": "sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.15.9",
+        "postcss": "^8.4.18",
+        "resolve": "^1.22.1",
+        "rollup": "^2.79.1"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "@types/node": ">= 14",
+        "less": "*",
+        "sass": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vkbeautify": {
+      "version": "0.99.3",
+      "resolved": "https://registry.npmjs.org/vkbeautify/-/vkbeautify-0.99.3.tgz",
+      "integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q=="
+    },
+    "node_modules/vue": {
+      "version": "3.2.47",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.47.tgz",
+      "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.2.47",
+        "@vue/compiler-sfc": "3.2.47",
+        "@vue/runtime-dom": "3.2.47",
+        "@vue/server-renderer": "3.2.47",
+        "@vue/shared": "3.2.47"
+      }
+    },
+    "node_modules/vue-demi": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz",
+      "integrity": "sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-moment": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/vue-moment/-/vue-moment-4.1.0.tgz",
+      "integrity": "sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw==",
+      "dependencies": {
+        "moment": "^2.19.2"
+      },
+      "peerDependencies": {
+        "vue": ">=1.x.x"
+      }
+    },
+    "node_modules/vue-router": {
+      "version": "4.1.6",
+      "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz",
+      "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==",
+      "dev": true,
+      "dependencies": {
+        "@vue/devtools-api": "^6.4.5"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/watchpack": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+      "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+      "peer": true,
+      "dependencies": {
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.1.2"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/web-worker": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/web-worker/-/web-worker-1.2.0.tgz",
+      "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
+    },
+    "node_modules/webpack": {
+      "version": "5.88.1",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz",
+      "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==",
+      "peer": true,
+      "dependencies": {
+        "@types/eslint-scope": "^3.7.3",
+        "@types/estree": "^1.0.0",
+        "@webassemblyjs/ast": "^1.11.5",
+        "@webassemblyjs/wasm-edit": "^1.11.5",
+        "@webassemblyjs/wasm-parser": "^1.11.5",
+        "acorn": "^8.7.1",
+        "acorn-import-assertions": "^1.9.0",
+        "browserslist": "^4.14.5",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^5.15.0",
+        "es-module-lexer": "^1.2.1",
+        "eslint-scope": "5.1.1",
+        "events": "^3.2.0",
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.2.9",
+        "json-parse-even-better-errors": "^2.3.1",
+        "loader-runner": "^4.2.0",
+        "mime-types": "^2.1.27",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^3.2.0",
+        "tapable": "^2.1.1",
+        "terser-webpack-plugin": "^5.3.7",
+        "watchpack": "^2.4.0",
+        "webpack-sources": "^3.2.3"
+      },
+      "bin": {
+        "webpack": "bin/webpack.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependenciesMeta": {
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-sources": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+      "peer": true,
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/wkt-parser": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.3.3.tgz",
+      "integrity": "sha512-ZnV3yH8/k58ZPACOXeiHaMuXIiaTk1t0hSUVisbO0t4RjA5wPpUytcxeyiN2h+LZRrmuHIh/1UlrR9e7DHDvTw=="
+    },
+    "node_modules/wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/word": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
+      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/x2js": {
+      "version": "3.4.4",
+      "resolved": "https://registry.npmjs.org/x2js/-/x2js-3.4.4.tgz",
+      "integrity": "sha512-yG/ThaBCgnsa3aoMPAe7QwDpcyU4D70hjXC4Y1lZSfD/Tgd0MpE19FnZZRAjekryw0c8cffpOt9zsPEiqktO6Q==",
+      "dependencies": {
+        "@xmldom/xmldom": "^0.8.3"
+      }
+    },
+    "node_modules/xlsx": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+      "dependencies": {
+        "adler-32": "~1.3.0",
+        "cfb": "~1.2.1",
+        "codepage": "~1.15.0",
+        "crc-32": "~1.2.1",
+        "ssf": "~0.11.2",
+        "wmf": "~1.0.1",
+        "word": "~0.3.0"
+      },
+      "bin": {
+        "xlsx": "bin/xlsx.njs"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/xml-utils": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmmirror.com/xml-utils/-/xml-utils-1.7.0.tgz",
+      "integrity": "sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw=="
+    },
+    "node_modules/xmldom": {
+      "version": "0.1.31",
+      "resolved": "https://registry.npmmirror.com/xmldom/-/xmldom-0.1.31.tgz",
+      "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
+      "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0",
+      "engines": {
+        "node": ">=0.1"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    },
+    "node_modules/zrender": {
+      "version": "5.4.3",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz",
+      "integrity": "sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ==",
+      "dependencies": {
+        "tslib": "2.3.0"
+      }
+    },
+    "node_modules/zrender/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    }
+  }
+}

+ 53 - 0
package.json

@@ -0,0 +1,53 @@
+{
+    "name": "calligraphy-learning-system",
+    "private": true,
+    "version": "0.0.0",
+    "type": "module",
+    "scripts": {
+        "dev": "vite --host",
+        "build": "vite build",
+        "build-55": "vite build --mode production-55",
+        "preview": "vite preview"
+    },
+    "dependencies": {
+        "@amap/amap-jsapi-loader": "^1.0.1",
+        "@element-plus/icons-vue": "^2.1.0",
+        "@icon-park/vue-next": "^1.4.2",
+        "@mapbox/togeojson": "^0.16.0",
+        "axios": "0.24.0",
+        "circle-to-polygon": "^2.2.0",
+        "coordtransform": "^2.1.2",
+        "driver.js": "^0.9.8",
+        "echarts": "^5.4.2",
+        "element-plus": "^2.3.3",
+        "file-saver": "^2.0.5",
+        "highlight.js": "^11.8.0",
+        "html2canvas": "^1.4.1",
+        "jquery": "^3.6.1",
+        "js-base64": "^3.7.5",
+        "js-cookie": "^3.0.1",
+        "less": "^4.1.3",
+        "less-loader": "^11.1.3",
+        "nprogress": "0.2.0",
+        "ol": "^6.5.0",
+        "pinia": "^2.0.33",
+        "proj4": "^2.8.0",
+        "qs": "^6.11.2",
+        "swiper": "^9.0.2",
+        "terser": "^5.17.6",
+        "vkbeautify": "^0.99.3",
+        "vue": "^3.2.41",
+        "vue-moment": "^4.1.0",
+        "x2js": "^3.4.4",
+        "xlsx": "^0.18.5"
+    },
+    "devDependencies": {
+        "@types/file-saver": "^2.0.5",
+        "@vitejs/plugin-vue": "^3.2.0",
+        "sass": "^1.56.2",
+        "sass-loader": "^13.2.0",
+        "script-loader": "^0.7.2",
+        "vite": "^3.2.3",
+        "vue-router": "^4.1.6"
+    }
+}

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/js/140000.geojson


+ 27 - 0
public/js/config.js

@@ -0,0 +1,27 @@
+/**基础地图 */
+let BaseMap = {
+    baiduVec: "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x={0}&y={1}&z={2}&styles=pl&udt=20151021&scaler=1&p=1",
+    baiduImg: "http://shangetu0.map.bdimg.com/it/u=x={0};y={1};z={2};v=009;type=sate&fm=46&udt=20150504&app=webearth2&v=009&udt=20150601",
+    // 天地图
+    tdtImg: "http://192.168.100.252:9081/map/file/img/TILEKEY/IMAGE/EPSG_3857/png/DOM_NMG/{z}/{x}/{y}?ol=false",
+    //tdtImg: "http://t3.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=7ae072fdee55b245b267992f3e66fd0a",
+    //tdtImg: "http://192.168.100.55:8080/geowinmap/ds?serviceproviderid=map.cachedtms&serviceid=gettile&tilename=sate&x={x}&y={y}&z={z}",
+    //tdtImgAnn: "http://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=7ae072fdee55b245b267992f3e66fd0a",
+    //行政区底图
+    tdtImgAnn: "/arcgis/rest/services/kjgh/XZQH_QX/MapServer/tile/{z}/{y}/{x}",
+    tdtVec: "http://t2.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=7ae072fdee55b245b267992f3e66fd0a",
+    tdtVecAnn: "http://t2.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=7ae072fdee55b245b267992f3e66fd0a",
+    arcImg: `https://106.14.159.47:6443/`,
+    cesiumDSM: "http://192.168.100.111:8001/3196C7C60C074D2A8BA9B07241A4D298/terrain/DSM/map/file/wmts/bil/DSM_ORDOS_/",
+    jxMap: "",
+    //tdtImg: "http://192.168.100.111:9082/map/file/img/TILEKEY/IMAGE/EPSG_3857/png/DOM_SDDT/{z}/{x}/{y}?ol=false",
+    //tdtImg: "/maps/img/{z}/{x}/{y}.jpg",
+    //tdtVec: "/maps/vec/{z}/{x}/{y}/x={x}&y={y}&z={z}.png",
+
+    // tdtImgAnn: "/arcgis/rest/services/kjgh/XZQDS/MapServer/tile/{z}/{y}/{x}",
+    // jxMap: "/arcgis/rest/services/kjgh/CZKFBJ/MapServer/tile/{z}/{y}/{x}",
+};
+let MapCenter = {
+    point: [112.235, 37.4],
+    extent: [13250478.427, 5140873.799, 13807458.564, 5771928.021],
+};

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/js/xzqds.geojson


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/js/xzqxs.geojson


+ 16 - 0
src/App.vue

@@ -0,0 +1,16 @@
+<template>
+    <router-view></router-view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+        }
+    },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 90 - 0
src/api/gdal/index.js

@@ -0,0 +1,90 @@
+import request from '@/api/main/request.js'
+
+//获取gdb下的矢量图层
+export function getlayers(parameter) {
+    return request({
+        url: '/vector/gdb/getlayers',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+//删除矢量图层后台缓存
+export function remove(parameter) {
+    return request({
+        url: '/vector/gdb/remove',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+//获取mdb下的表名
+export function gettables(parameter) {
+    return request({
+        url: '/vector/mdb/gettables',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+//获取mdb下的指定表
+export function gettable(parameter) {
+    return request({
+        url: '/vector/mdb/gettable',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+// 矢量图层空间查询、属性查询(SPATIALFILTER参数参考geojson标准,ATTRIBUTEFILTER参数参考sql语言规范)
+export function filter(parameter) {
+    return request({
+        url: '/vector/gdb/filter',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+// 获取矢量图层字段集合
+export function getFields(parameter) {
+    return request({
+        url: '/vector/gdb/getFields',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+// 获取矢量图层唯一值
+export function getUniqueValue(parameter) {
+    return request({
+        url: '/vector/gdb/getUniqueValue',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+// esrijson转shp
+export function jsonToShp(parameter) {
+    return request({
+        url: '/analyse/tool/jsonToShp',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}

+ 74 - 0
src/api/main/index.js

@@ -0,0 +1,74 @@
+/**
+ * @Description:
+ * @version:
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2023-01-11 13:52:38
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-03-09 18:13:44
+ */
+
+import request from './request'
+import { createMessagen } from '@/api/mainn/index.js'
+
+let isDev =
+    import.meta.env.MODE == "development"
+
+// 2 航空影像
+export function hangkongQueryAllDataByGeojson(data) {
+    let url = '/system/prodcutygyx/queryAllDataByGeojson'
+    // if (!isDev || ) {
+    //     url = '/system' + url
+    // }
+    return request({
+        url,
+        method: 'POST',
+        data
+    })
+}
+
+// 3 地图产品
+export function queryAllDataByGeojson(data) {
+    let url = '/system/books/queryAllDataByGeojson'
+    // if (!isDev || ) {
+    //     url = '/system' + url
+    // }
+    return request({
+        url,
+        method: 'POST',
+        data
+    })
+}
+
+// 4 视频产品(实景三维)
+export function shipinQueryAllDataByGeojson(data) {
+    let url = '/system/sjsw/queryAllDataByGeojson'
+
+    // if (!isDev || ) {
+    //     url = '/system' + url
+    // }
+    return request({
+        url,
+        method: 'POST',
+        data
+    })
+}
+
+// 提交留言
+export function createMessage(data) {
+    createMessagen()
+    let url = '/system/message/createMessage'
+    return request({
+        url,
+        method: 'post',
+        params: data,
+    })
+}
+
+// 查询实景三维数据列表
+export function listSjsw(query) {
+  return request({
+      url: '/system/sjsw/list',
+      method: 'get',
+      params: query
+  })
+}

+ 84 - 0
src/api/main/request.js

@@ -0,0 +1,84 @@
+/**
+ * @Description: 
+ * @version: 
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2023-01-11 13:52:38
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-03-03 14:12:11
+ */
+import axios from 'axios';
+import NProgress from 'nprogress'
+import { ElMessage, ElLoading} from "element-plus";
+import { tansParams, blobValidate } from "@/utils/common.js";
+import { saveAs } from 'file-saver'
+let downloadLoadingInstance;
+axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
+
+const service = axios.create({
+    baseURL: import.meta.env.VITE_BASE_API,
+    // withCredentials: true,
+    timeout: 100000
+})
+
+service.interceptors.request.use((config) => {
+    NProgress.start()
+    return config
+}, (error) => {
+    NProgress.done()
+    console.log(error);
+    ElMessage.error(error)
+    return Promise.reject(error);
+})
+
+service.interceptors.response.use((response) => {
+    NProgress.done()
+    const res = response.data
+    // 未设置状态码则默认成功状态
+    res.code = res.code || 200;
+    if (res.code !== '200' && res.code !== 200) {
+        console.log(res.message || res.msg || 'Error');
+        ElMessage({
+            message: res.message || res.msg || 'Error',
+            type: 'warning',
+        })
+        return Promise.reject(new Error(res.message || res.msg || 'Error'))
+    } else {
+        return res
+    }
+}, (error) => {
+    NProgress.done()
+    console.log('err' + error)
+    ElMessage.error('请求失败,请稍后再试')
+    return Promise.reject(error)
+})
+// 通用下载方法
+export function download(url, params, filename,noloading) {
+  if(!noloading){
+    downloadLoadingInstance = ElLoading.service({
+        text: "正在下载数据,请稍候",
+        background: "rgba(0, 0, 0, 0.7)",
+    });
+  }
+  return service.post(url, params, {
+      transformRequest: [(params) => { return tansParams(params) }],
+      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+      responseType: 'blob'
+    }).then(async (data) => {
+      const isLogin = await blobValidate(data);
+      if (isLogin) {
+        const blob = new Blob([data])
+        saveAs(blob, filename)
+      } else {
+        const resText = await data.text();
+        const rspObj = JSON.parse(resText);
+        const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
+        ElMessage.error(errMsg);
+      }
+      downloadLoadingInstance && downloadLoadingInstance.close();
+    }).catch((r) => {
+      console.error(r)
+      ElMessage.error('下载文件出现错误,请联系管理员!')
+      downloadLoadingInstance && downloadLoadingInstance.close();
+    })
+  }
+export default service;

+ 50 - 0
src/api/main/request9289.js

@@ -0,0 +1,50 @@
+/**
+ * @Description: 
+ * @version: 
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2023-01-11 13:52:38
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-03-03 14:12:11
+ */
+import axios from 'axios';
+import { ElMessage } from 'element-plus'
+import NProgress from 'nprogress'
+
+const service = axios.create({
+    baseURL: import.meta.env.VITE_GDAL_API,
+    withCredentials: true,
+    timeout: 100000
+})
+
+service.interceptors.request.use((config) => {
+    NProgress.start()
+    return config
+}, (error) => {
+    NProgress.done()
+    console.log(error);
+    ElMessage.error(error)
+    return Promise.reject(error);
+})
+
+service.interceptors.response.use((response) => {
+    NProgress.done()
+    const res = response.data
+
+    if (res.code !== '200' && res.code !== 200) {
+        console.log(res.message || res.msg || 'Error');
+        ElMessage({
+            message: res.message || res.msg || 'Error',
+            type: 'warning',
+        })
+        return Promise.reject(new Error(res.message || res.msg || 'Error'))
+    } else {
+        return res
+    }
+}, (error) => {
+    NProgress.done()
+    console.log('err' + error)
+    ElMessage.error('请求失败,请稍后再试')
+    return Promise.reject(error)
+})
+
+export default service;

+ 12 - 0
src/api/map/mapApi.js

@@ -0,0 +1,12 @@
+import request from '@/api/main/request.js'
+//查询资源目录
+export function getTree(parameter) {
+    return request({
+        url: '/dbms/image/tree',
+        method: 'get',
+        params: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}

+ 211 - 0
src/api/metadata/index.js

@@ -0,0 +1,211 @@
+/*
+ * @Description: 元数据
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2023-07-05 15:03:10
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-07-11 15:39:03
+ */
+
+import request from './request'
+
+let isDev = import.meta.env.MODE == "development"
+
+// 获取初始信息
+export function getinfo(data) {
+    let url = '/metadata/getinfo'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params: data,
+    })
+}
+
+// 自动获取元数据
+export function gather(data) {
+    let url = '/metadata/gather'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params: data,
+    })
+}
+
+// 元数据保存
+export function save(data) {
+    let url = '/metadata/save'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'post',
+        data: data,
+    })
+}
+
+// ========
+
+// 矢量元数据导入
+export function impMeta(data) {
+    let url = '/metadata/impMeta'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'post',
+        data: data,
+    })
+}
+
+// 获取xml文件
+export function getXmlDoc(data) {
+    let url = '/metadata/getXmlDoc'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'post',
+        data: data,
+    })
+}
+
+// 获取元数据资源节点目录
+export function getXmlDir(data) {
+    let url = '/metadata/getXmlDir'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'post',
+        data: data,
+    })
+}
+
+// 获取元数据资源节点目录
+export function saveXmlValue(data) {
+    let url = '/metadata/saveXmlValue'
+    if (!isDev) {
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'post',
+        data: data,
+    })
+}
+
+// =======
+// 获取质检列表
+export function getList(data) {
+    let url = '/datacheck/list'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params: data,
+    })
+}
+
+// 获取质检方案
+export function getscheme(data) {
+    let url = '/datacheck/getscheme'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params: data,
+    })
+}
+
+// 新建质检
+export function startcheck(data) {
+    let url = '/datacheck/startcheck'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'post',
+        data,
+        headers: { 'Content-Type': 'application/json' },
+    })
+}
+
+// 删除
+export function datacheckdelete(params) {
+    let url = '/datacheck/delete'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params,
+    })
+}
+
+// ===========
+// 管理列表
+export function datamanagelist(params) {
+    let url = '/datamanage/list'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params,
+    })
+}
+
+// 加入管理
+export function datamanageadd(params) {
+    let url = '/datamanage/add'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params,
+    })
+}
+// 移除管理
+export function datamanagedelete(params) {
+    let url = '/datamanage/delete'
+    if (!isDev) {
+
+        url = '/dbms' + url
+    }
+    return request({
+        url,
+        method: 'get',
+        params,
+    })
+}
+

+ 51 - 0
src/api/metadata/request.js

@@ -0,0 +1,51 @@
+/*
+ * @Description: 元数据
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2023-07-05 15:03:10
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-07-05 15:04:50
+ */
+
+import axios from 'axios';
+import { ElMessage } from 'element-plus'
+import NProgress from 'nprogress'
+axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
+
+const service = axios.create({
+    baseURL: import.meta.env.VITE_DZZ_API,
+    // withCredentials: true,
+    timeout: 100000
+})
+
+service.interceptors.request.use((config) => {
+    NProgress.start()
+    return config
+}, (error) => {
+    NProgress.done()
+    console.log(error);
+    ElMessage.error(error)
+    return Promise.reject(error);
+})
+
+service.interceptors.response.use((response) => {
+    NProgress.done()
+    const res = response.data
+
+    if (res.code !== '200' && res.code !== 200) {
+        console.log(res.message || res.msg || 'Error');
+        ElMessage({
+            message: res.message || res.msg || 'Error',
+            type: 'warning',
+        })
+        return Promise.reject(new Error(res.message || res.msg || 'Error'))
+    } else {
+        return res
+    }
+}, (error) => {
+    NProgress.done()
+    console.log('err' + error)
+    ElMessage.error('请求失败,请稍后再试')
+    return Promise.reject(error)
+})
+
+export default service;

+ 45 - 0
src/api/yxsj/yxsjApi.js

@@ -0,0 +1,45 @@
+/*
+ * @Description: 
+ * @Author: 王志鹏
+ * @Date: 2023-07-06 08:55:16
+ * @LastEditors: 王志鹏
+ * @LastEditTime: 2023-07-18 10:00:09
+ */
+import request from '@/api/main/request.js'
+import qs from 'qs'
+
+//影像数据查询
+export function getYxsj(parameter) {
+    return request({
+        url: '/dbms/image/query',
+        method: 'post',
+        data: qs.stringify(parameter),
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
+        }
+    })
+}
+
+//影像覆盖率查询
+export function getYxfgl(parameter) {
+    return request({
+        url: '/dbms/image/overlap',
+        method: 'post',
+        data: qs.stringify(parameter),
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
+        }
+    })
+}
+
+//上传shp压缩包解压并返回geojson
+export function shp2Geojson(parameter) {
+    return request({
+        url: '/dbms/upload/shp2geojson',
+        method: 'post',
+        data: parameter,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}

BIN
src/assets/401_images/401.gif


BIN
src/assets/404_images/404.png


BIN
src/assets/404_images/404_cloud.png


+ 65 - 0
src/assets/common.scss

@@ -0,0 +1,65 @@
+body * {
+  box-sizing: border-box;
+  flex-shrink: 0;
+}
+body {
+  font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma,
+    Arial, PingFang SC-Light, Microsoft YaHei;
+}
+button {
+  margin: 0;
+  padding: 0;
+  border: 1px solid transparent;
+  outline: none;
+  background-color: transparent;
+}
+
+button:active {
+  opacity: 0.6;
+}
+.flex-col {
+  display: flex;
+  flex-direction: column;
+}
+.flex-row {
+  display: flex;
+  flex-direction: row;
+}
+.justify-start {
+    display: flex;
+    justify-content: flex-start;
+  }
+.justify-center {
+    display: flex;
+    justify-content: center;
+}
+  
+.justify-end {
+    display: flex;
+    justify-content: flex-end;
+}
+.justify-evenly {
+    display: flex;
+    justify-content: space-evenly;
+}
+.justify-around {
+    display: flex;
+    justify-content: space-around;
+}
+.justify-between {
+    display: flex;
+    justify-content: space-between;
+}
+.align-start {
+    display: flex;
+    align-items: flex-start;
+}
+.align-center {
+    display: flex;
+    align-items: center;
+}
+.align-end {
+    display: flex;
+    align-items: flex-end;
+}
+    

+ 539 - 0
src/assets/icon/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 1909 - 0
src/assets/icon/demo_index.html

@@ -0,0 +1,1909 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>iconfont Demo</title>
+  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
+  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
+  <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
+  <link rel="stylesheet" href="demo.css">
+  <link rel="stylesheet" href="iconfont.css">
+  <script src="iconfont.js"></script>
+  <!-- jQuery -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
+  <!-- 代码高亮 -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
+  <style>
+    .main .logo {
+      margin-top: 0;
+      height: auto;
+    }
+
+    .main .logo a {
+      display: flex;
+      align-items: center;
+    }
+
+    .main .logo .sub-title {
+      margin-left: 0.5em;
+      font-size: 22px;
+      color: #fff;
+      background: linear-gradient(-45deg, #3967FF, #B500FE);
+      -webkit-background-clip: text;
+      -webkit-text-fill-color: transparent;
+    }
+  </style>
+</head>
+<body>
+  <div class="main">
+    <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
+      <img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
+      
+    </a></h1>
+    <div class="nav-tabs">
+      <ul id="tabs" class="dib-box">
+        <li class="dib active"><span>Unicode</span></li>
+        <li class="dib"><span>Font class</span></li>
+        <li class="dib"><span>Symbol</span></li>
+      </ul>
+      
+    </div>
+    <div class="tab-container">
+      <div class="content unicode" style="display: block;">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf00c3;</span>
+                <div class="name">搜索文件</div>
+                <div class="code-name">&amp;#xf00c3;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf019b;</span>
+                <div class="name">远景</div>
+                <div class="code-name">&amp;#xf019b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf01a0;</span>
+                <div class="name">全景</div>
+                <div class="code-name">&amp;#xf01a0;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf0206;</span>
+                <div class="name">多云</div>
+                <div class="code-name">&amp;#xf0206;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf0106;</span>
+                <div class="name">微信</div>
+                <div class="code-name">&amp;#xf0106;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61b;</span>
+                <div class="name">电话</div>
+                <div class="code-name">&amp;#xe61b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe640;</span>
+                <div class="name">信封</div>
+                <div class="code-name">&amp;#xe640;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe678;</span>
+                <div class="name">电话_填充</div>
+                <div class="code-name">&amp;#xe678;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf018b;</span>
+                <div class="name">加</div>
+                <div class="code-name">&amp;#xf018b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xf018c;</span>
+                <div class="name">减</div>
+                <div class="code-name">&amp;#xf018c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6ce;</span>
+                <div class="name">眼睛</div>
+                <div class="code-name">&amp;#xe6ce;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe74b;</span>
+                <div class="name">删除</div>
+                <div class="code-name">&amp;#xe74b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe624;</span>
+                <div class="name">wxb定位</div>
+                <div class="code-name">&amp;#xe624;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe661;</span>
+                <div class="name">眼睛</div>
+                <div class="code-name">&amp;#xe661;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe652;</span>
+                <div class="name">用户</div>
+                <div class="code-name">&amp;#xe652;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe76c;</span>
+                <div class="name">地球 全球</div>
+                <div class="code-name">&amp;#xe76c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe60a;</span>
+                <div class="name">地球</div>
+                <div class="code-name">&amp;#xe60a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6ca;</span>
+                <div class="name">funnel-漏斗</div>
+                <div class="code-name">&amp;#xe6ca;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe64f;</span>
+                <div class="name">楼房</div>
+                <div class="code-name">&amp;#xe64f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe65e;</span>
+                <div class="name">搜索地址</div>
+                <div class="code-name">&amp;#xe65e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe628;</span>
+                <div class="name">微信</div>
+                <div class="code-name">&amp;#xe628;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe603;</span>
+                <div class="name">名词解释</div>
+                <div class="code-name">&amp;#xe603;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6f0;</span>
+                <div class="name">高级查询</div>
+                <div class="code-name">&amp;#xe6f0;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe650;</span>
+                <div class="name">眼睛</div>
+                <div class="code-name">&amp;#xe650;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61c;</span>
+                <div class="name">信封</div>
+                <div class="code-name">&amp;#xe61c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe605;</span>
+                <div class="name">景点</div>
+                <div class="code-name">&amp;#xe605;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8c8;</span>
+                <div class="name">224用户</div>
+                <div class="code-name">&amp;#xe8c8;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe60c;</span>
+                <div class="name">景点</div>
+                <div class="code-name">&amp;#xe60c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61a;</span>
+                <div class="name">天气</div>
+                <div class="code-name">&amp;#xe61a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe689;</span>
+                <div class="name">地球</div>
+                <div class="code-name">&amp;#xe689;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe645;</span>
+                <div class="name">删除</div>
+                <div class="code-name">&amp;#xe645;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe646;</span>
+                <div class="name">订单</div>
+                <div class="code-name">&amp;#xe646;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe630;</span>
+                <div class="name">模型列表</div>
+                <div class="code-name">&amp;#xe630;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe517;</span>
+                <div class="name">AK-MN_盾牌</div>
+                <div class="code-name">&amp;#xe517;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe621;</span>
+                <div class="name">在线客服</div>
+                <div class="code-name">&amp;#xe621;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe60d;</span>
+                <div class="name">日志</div>
+                <div class="code-name">&amp;#xe60d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe750;</span>
+                <div class="name">信封</div>
+                <div class="code-name">&amp;#xe750;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xeaf3;</span>
+                <div class="name">加号</div>
+                <div class="code-name">&amp;#xeaf3;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xeaf5;</span>
+                <div class="name">减号</div>
+                <div class="code-name">&amp;#xeaf5;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xeb23;</span>
+                <div class="name">电话</div>
+                <div class="code-name">&amp;#xeb23;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xebcc;</span>
+                <div class="name">眼睛_显示_o</div>
+                <div class="code-name">&amp;#xebcc;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe606;</span>
+                <div class="name">测面</div>
+                <div class="code-name">&amp;#xe606;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xec7b;</span>
+                <div class="name">删除</div>
+                <div class="code-name">&amp;#xec7b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe639;</span>
+                <div class="name">工具箱</div>
+                <div class="code-name">&amp;#xe639;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67d;</span>
+                <div class="name">地球</div>
+                <div class="code-name">&amp;#xe67d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xeb11;</span>
+                <div class="name">上传</div>
+                <div class="code-name">&amp;#xeb11;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xeb1e;</span>
+                <div class="name">卷帘</div>
+                <div class="code-name">&amp;#xeb1e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xea98;</span>
+                <div class="name">24gl-square</div>
+                <div class="code-name">&amp;#xea98;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe629;</span>
+                <div class="name">截屏</div>
+                <div class="code-name">&amp;#xe629;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe856;</span>
+                <div class="name">微信</div>
+                <div class="code-name">&amp;#xe856;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68f;</span>
+                <div class="name">17-地球</div>
+                <div class="code-name">&amp;#xe68f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6c5;</span>
+                <div class="name">日历</div>
+                <div class="code-name">&amp;#xe6c5;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe710;</span>
+                <div class="name">测距_line</div>
+                <div class="code-name">&amp;#xe710;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe651;</span>
+                <div class="name">截屏</div>
+                <div class="code-name">&amp;#xe651;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61e;</span>
+                <div class="name">信封图标</div>
+                <div class="code-name">&amp;#xe61e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe8ae;</span>
+                <div class="name">定位</div>
+                <div class="code-name">&amp;#xe8ae;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe662;</span>
+                <div class="name">记事本</div>
+                <div class="code-name">&amp;#xe662;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe684;</span>
+                <div class="name">盾牌-01</div>
+                <div class="code-name">&amp;#xe684;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62a;</span>
+                <div class="name">样本编辑</div>
+                <div class="code-name">&amp;#xe62a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe52a;</span>
+                <div class="name">绘制</div>
+                <div class="code-name">&amp;#xe52a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe779;</span>
+                <div class="name">添加订单</div>
+                <div class="code-name">&amp;#xe779;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe64e;</span>
+                <div class="name">tx-六边形</div>
+                <div class="code-name">&amp;#xe64e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe696;</span>
+                <div class="name">日历</div>
+                <div class="code-name">&amp;#xe696;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe607;</span>
+                <div class="name">添加订单</div>
+                <div class="code-name">&amp;#xe607;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe625;</span>
+                <div class="name">记事本</div>
+                <div class="code-name">&amp;#xe625;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6be;</span>
+                <div class="name">漏斗</div>
+                <div class="code-name">&amp;#xe6be;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe711;</span>
+                <div class="name">漏斗</div>
+                <div class="code-name">&amp;#xe711;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe691;</span>
+                <div class="name">上传</div>
+                <div class="code-name">&amp;#xe691;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe60f;</span>
+                <div class="name">图层</div>
+                <div class="code-name">&amp;#xe60f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xea07;</span>
+                <div class="name">地图尺子,测量,测距,距离</div>
+                <div class="code-name">&amp;#xea07;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xea70;</span>
+                <div class="name">正方形</div>
+                <div class="code-name">&amp;#xea70;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6c7;</span>
+                <div class="name">卷帘</div>
+                <div class="code-name">&amp;#xe6c7;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe747;</span>
+                <div class="name">测距_1</div>
+                <div class="code-name">&amp;#xe747;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe602;</span>
+                <div class="name">六边形</div>
+                <div class="code-name">&amp;#xe602;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe765;</span>
+                <div class="name">空间测面</div>
+                <div class="code-name">&amp;#xe765;</div>
+              </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="unicode-">Unicode 引用</h2>
+          <hr>
+
+          <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
+          <ul>
+            <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+            <li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
+          </ul>
+          <blockquote>
+            <p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
+          </blockquote>
+          <p>Unicode 使用步骤如下:</p>
+          <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
+<pre><code class="language-css"
+>@font-face {
+  font-family: 'iconfont';
+  src: url('iconfont.ttf?t=1665298257000') format('truetype');
+}
+</code></pre>
+          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
+<pre><code class="language-css"
+>.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+<pre>
+<code class="language-html"
+>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
+</code></pre>
+          <blockquote>
+            <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+          </blockquote>
+          </div>
+      </div>
+      <div class="content font-class">
+        <ul class="icon_lists dib-box">
+          
+          <li class="dib">
+            <span class="icon iconfont icon-sousuowenjian"></span>
+            <div class="name">
+              搜索文件
+            </div>
+            <div class="code-name">.icon-sousuowenjian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yuanjing"></span>
+            <div class="name">
+              远景
+            </div>
+            <div class="code-name">.icon-yuanjing
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-quanjing"></span>
+            <div class="name">
+              全景
+            </div>
+            <div class="code-name">.icon-quanjing
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-duoyun"></span>
+            <div class="name">
+              多云
+            </div>
+            <div class="code-name">.icon-duoyun
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-weixin"></span>
+            <div class="name">
+              微信
+            </div>
+            <div class="code-name">.icon-weixin
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dianhua"></span>
+            <div class="name">
+              电话
+            </div>
+            <div class="code-name">.icon-dianhua
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xinfeng"></span>
+            <div class="name">
+              信封
+            </div>
+            <div class="code-name">.icon-xinfeng
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dianhuatianchong"></span>
+            <div class="name">
+              电话_填充
+            </div>
+            <div class="code-name">.icon-dianhuatianchong
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jia"></span>
+            <div class="name">
+              加
+            </div>
+            <div class="code-name">.icon-jia
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jian"></span>
+            <div class="name">
+              减
+            </div>
+            <div class="code-name">.icon-jian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yanjing"></span>
+            <div class="name">
+              眼睛
+            </div>
+            <div class="code-name">.icon-yanjing
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shanchu"></span>
+            <div class="name">
+              删除
+            </div>
+            <div class="code-name">.icon-shanchu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-wxbdingwei"></span>
+            <div class="name">
+              wxb定位
+            </div>
+            <div class="code-name">.icon-wxbdingwei
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yanjing1"></span>
+            <div class="name">
+              眼睛
+            </div>
+            <div class="code-name">.icon-yanjing1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yonghu"></span>
+            <div class="name">
+              用户
+            </div>
+            <div class="code-name">.icon-yonghu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-diqiuquanqiu"></span>
+            <div class="name">
+              地球 全球
+            </div>
+            <div class="code-name">.icon-diqiuquanqiu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-diqiu"></span>
+            <div class="name">
+              地球
+            </div>
+            <div class="code-name">.icon-diqiu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-funnelloudou"></span>
+            <div class="name">
+              funnel-漏斗
+            </div>
+            <div class="code-name">.icon-funnelloudou
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-loufang"></span>
+            <div class="name">
+              楼房
+            </div>
+            <div class="code-name">.icon-loufang
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-sousuodizhi"></span>
+            <div class="name">
+              搜索地址
+            </div>
+            <div class="code-name">.icon-sousuodizhi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-weixin1"></span>
+            <div class="name">
+              微信
+            </div>
+            <div class="code-name">.icon-weixin1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-mingcijieshi"></span>
+            <div class="name">
+              名词解释
+            </div>
+            <div class="code-name">.icon-mingcijieshi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-query1"></span>
+            <div class="name">
+              高级查询
+            </div>
+            <div class="code-name">.icon-query1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yj"></span>
+            <div class="name">
+              眼睛
+            </div>
+            <div class="code-name">.icon-yj
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xinfeng1"></span>
+            <div class="name">
+              信封
+            </div>
+            <div class="code-name">.icon-xinfeng1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jingdian"></span>
+            <div class="name">
+              景点
+            </div>
+            <div class="code-name">.icon-jingdian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yonghu1"></span>
+            <div class="name">
+              224用户
+            </div>
+            <div class="code-name">.icon-yonghu1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jingdian1"></span>
+            <div class="name">
+              景点
+            </div>
+            <div class="code-name">.icon-jingdian1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-tianqi"></span>
+            <div class="name">
+              天气
+            </div>
+            <div class="code-name">.icon-tianqi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-diqiu1"></span>
+            <div class="name">
+              地球
+            </div>
+            <div class="code-name">.icon-diqiu1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-changyonggoupiaorenshanchu"></span>
+            <div class="name">
+              删除
+            </div>
+            <div class="code-name">.icon-changyonggoupiaorenshanchu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dingdan"></span>
+            <div class="name">
+              订单
+            </div>
+            <div class="code-name">.icon-dingdan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-moxingliebiao"></span>
+            <div class="name">
+              模型列表
+            </div>
+            <div class="code-name">.icon-moxingliebiao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-mn_dunpai"></span>
+            <div class="name">
+              AK-MN_盾牌
+            </div>
+            <div class="code-name">.icon-mn_dunpai
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-zaixiankefu"></span>
+            <div class="name">
+              在线客服
+            </div>
+            <div class="code-name">.icon-zaixiankefu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-rizhi"></span>
+            <div class="name">
+              日志
+            </div>
+            <div class="code-name">.icon-rizhi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xinfeng2"></span>
+            <div class="name">
+              信封
+            </div>
+            <div class="code-name">.icon-xinfeng2
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jiahao"></span>
+            <div class="name">
+              加号
+            </div>
+            <div class="code-name">.icon-jiahao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jianhao"></span>
+            <div class="name">
+              减号
+            </div>
+            <div class="code-name">.icon-jianhao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dianhua1"></span>
+            <div class="name">
+              电话
+            </div>
+            <div class="code-name">.icon-dianhua1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yanjing_xianshi_o"></span>
+            <div class="name">
+              眼睛_显示_o
+            </div>
+            <div class="code-name">.icon-yanjing_xianshi_o
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-cemian"></span>
+            <div class="name">
+              测面
+            </div>
+            <div class="code-name">.icon-cemian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shanchu1"></span>
+            <div class="name">
+              删除
+            </div>
+            <div class="code-name">.icon-shanchu1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-gongjuxiang"></span>
+            <div class="name">
+              工具箱
+            </div>
+            <div class="code-name">.icon-gongjuxiang
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-diqiu2"></span>
+            <div class="name">
+              地球
+            </div>
+            <div class="code-name">.icon-diqiu2
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shangchuan"></span>
+            <div class="name">
+              上传
+            </div>
+            <div class="code-name">.icon-shangchuan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-juanlian"></span>
+            <div class="name">
+              卷帘
+            </div>
+            <div class="code-name">.icon-juanlian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-24gl-square"></span>
+            <div class="name">
+              24gl-square
+            </div>
+            <div class="code-name">.icon-24gl-square
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jieping"></span>
+            <div class="name">
+              截屏
+            </div>
+            <div class="code-name">.icon-jieping
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-weixin2"></span>
+            <div class="name">
+              微信
+            </div>
+            <div class="code-name">.icon-weixin2
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon--diqiu"></span>
+            <div class="name">
+              17-地球
+            </div>
+            <div class="code-name">.icon--diqiu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-rili"></span>
+            <div class="name">
+              日历
+            </div>
+            <div class="code-name">.icon-rili
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-ranging_line"></span>
+            <div class="name">
+              测距_line
+            </div>
+            <div class="code-name">.icon-ranging_line
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jieping1"></span>
+            <div class="name">
+              截屏
+            </div>
+            <div class="code-name">.icon-jieping1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xinfengtubiao"></span>
+            <div class="name">
+              信封图标
+            </div>
+            <div class="code-name">.icon-xinfengtubiao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dingwei"></span>
+            <div class="name">
+              定位
+            </div>
+            <div class="code-name">.icon-dingwei
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jishiben"></span>
+            <div class="name">
+              记事本
+            </div>
+            <div class="code-name">.icon-jishiben
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dunpai-"></span>
+            <div class="name">
+              盾牌-01
+            </div>
+            <div class="code-name">.icon-dunpai-
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yangbenbianji"></span>
+            <div class="name">
+              样本编辑
+            </div>
+            <div class="code-name">.icon-yangbenbianji
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-huizhi"></span>
+            <div class="name">
+              绘制
+            </div>
+            <div class="code-name">.icon-huizhi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-ziyuan35"></span>
+            <div class="name">
+              添加订单
+            </div>
+            <div class="code-name">.icon-ziyuan35
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-tx-liubianxing"></span>
+            <div class="name">
+              tx-六边形
+            </div>
+            <div class="code-name">.icon-tx-liubianxing
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-rili1"></span>
+            <div class="name">
+              日历
+            </div>
+            <div class="code-name">.icon-rili1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-tianjiadingdan"></span>
+            <div class="name">
+              添加订单
+            </div>
+            <div class="code-name">.icon-tianjiadingdan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jishiben1"></span>
+            <div class="name">
+              记事本
+            </div>
+            <div class="code-name">.icon-jishiben1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-loudou"></span>
+            <div class="name">
+              漏斗
+            </div>
+            <div class="code-name">.icon-loudou
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-loudou1"></span>
+            <div class="name">
+              漏斗
+            </div>
+            <div class="code-name">.icon-loudou1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shangchuan1"></span>
+            <div class="name">
+              上传
+            </div>
+            <div class="code-name">.icon-shangchuan1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-tuceng"></span>
+            <div class="name">
+              图层
+            </div>
+            <div class="code-name">.icon-tuceng
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-map-ruler"></span>
+            <div class="name">
+              地图尺子,测量,测距,距离
+            </div>
+            <div class="code-name">.icon-map-ruler
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-checkbox"></span>
+            <div class="name">
+              正方形
+            </div>
+            <div class="code-name">.icon-checkbox
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-juanlian1"></span>
+            <div class="name">
+              卷帘
+            </div>
+            <div class="code-name">.icon-juanlian1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-ceju_1"></span>
+            <div class="name">
+              测距_1
+            </div>
+            <div class="code-name">.icon-ceju_1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-hexagon"></span>
+            <div class="name">
+              六边形
+            </div>
+            <div class="code-name">.icon-hexagon
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-kongjiancemian"></span>
+            <div class="name">
+              空间测面
+            </div>
+            <div class="code-name">.icon-kongjiancemian
+            </div>
+          </li>
+          
+        </ul>
+        <div class="article markdown">
+        <h2 id="font-class-">font-class 引用</h2>
+        <hr>
+
+        <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
+        <p>与 Unicode 使用方式相比,具有如下特点:</p>
+        <ul>
+          <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
+          <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
+<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
+</code></pre>
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
+</code></pre>
+        <blockquote>
+          <p>"
+            iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+        </blockquote>
+      </div>
+      </div>
+      <div class="content symbol">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-sousuowenjian"></use>
+                </svg>
+                <div class="name">搜索文件</div>
+                <div class="code-name">#icon-sousuowenjian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yuanjing"></use>
+                </svg>
+                <div class="name">远景</div>
+                <div class="code-name">#icon-yuanjing</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-quanjing"></use>
+                </svg>
+                <div class="name">全景</div>
+                <div class="code-name">#icon-quanjing</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-duoyun"></use>
+                </svg>
+                <div class="name">多云</div>
+                <div class="code-name">#icon-duoyun</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-weixin"></use>
+                </svg>
+                <div class="name">微信</div>
+                <div class="code-name">#icon-weixin</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dianhua"></use>
+                </svg>
+                <div class="name">电话</div>
+                <div class="code-name">#icon-dianhua</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xinfeng"></use>
+                </svg>
+                <div class="name">信封</div>
+                <div class="code-name">#icon-xinfeng</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dianhuatianchong"></use>
+                </svg>
+                <div class="name">电话_填充</div>
+                <div class="code-name">#icon-dianhuatianchong</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jia"></use>
+                </svg>
+                <div class="name">加</div>
+                <div class="code-name">#icon-jia</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jian"></use>
+                </svg>
+                <div class="name">减</div>
+                <div class="code-name">#icon-jian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yanjing"></use>
+                </svg>
+                <div class="name">眼睛</div>
+                <div class="code-name">#icon-yanjing</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shanchu"></use>
+                </svg>
+                <div class="name">删除</div>
+                <div class="code-name">#icon-shanchu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-wxbdingwei"></use>
+                </svg>
+                <div class="name">wxb定位</div>
+                <div class="code-name">#icon-wxbdingwei</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yanjing1"></use>
+                </svg>
+                <div class="name">眼睛</div>
+                <div class="code-name">#icon-yanjing1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yonghu"></use>
+                </svg>
+                <div class="name">用户</div>
+                <div class="code-name">#icon-yonghu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-diqiuquanqiu"></use>
+                </svg>
+                <div class="name">地球 全球</div>
+                <div class="code-name">#icon-diqiuquanqiu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-diqiu"></use>
+                </svg>
+                <div class="name">地球</div>
+                <div class="code-name">#icon-diqiu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-funnelloudou"></use>
+                </svg>
+                <div class="name">funnel-漏斗</div>
+                <div class="code-name">#icon-funnelloudou</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-loufang"></use>
+                </svg>
+                <div class="name">楼房</div>
+                <div class="code-name">#icon-loufang</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-sousuodizhi"></use>
+                </svg>
+                <div class="name">搜索地址</div>
+                <div class="code-name">#icon-sousuodizhi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-weixin1"></use>
+                </svg>
+                <div class="name">微信</div>
+                <div class="code-name">#icon-weixin1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-mingcijieshi"></use>
+                </svg>
+                <div class="name">名词解释</div>
+                <div class="code-name">#icon-mingcijieshi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-query1"></use>
+                </svg>
+                <div class="name">高级查询</div>
+                <div class="code-name">#icon-query1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yj"></use>
+                </svg>
+                <div class="name">眼睛</div>
+                <div class="code-name">#icon-yj</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xinfeng1"></use>
+                </svg>
+                <div class="name">信封</div>
+                <div class="code-name">#icon-xinfeng1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jingdian"></use>
+                </svg>
+                <div class="name">景点</div>
+                <div class="code-name">#icon-jingdian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yonghu1"></use>
+                </svg>
+                <div class="name">224用户</div>
+                <div class="code-name">#icon-yonghu1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jingdian1"></use>
+                </svg>
+                <div class="name">景点</div>
+                <div class="code-name">#icon-jingdian1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tianqi"></use>
+                </svg>
+                <div class="name">天气</div>
+                <div class="code-name">#icon-tianqi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-diqiu1"></use>
+                </svg>
+                <div class="name">地球</div>
+                <div class="code-name">#icon-diqiu1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-changyonggoupiaorenshanchu"></use>
+                </svg>
+                <div class="name">删除</div>
+                <div class="code-name">#icon-changyonggoupiaorenshanchu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dingdan"></use>
+                </svg>
+                <div class="name">订单</div>
+                <div class="code-name">#icon-dingdan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-moxingliebiao"></use>
+                </svg>
+                <div class="name">模型列表</div>
+                <div class="code-name">#icon-moxingliebiao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-mn_dunpai"></use>
+                </svg>
+                <div class="name">AK-MN_盾牌</div>
+                <div class="code-name">#icon-mn_dunpai</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-zaixiankefu"></use>
+                </svg>
+                <div class="name">在线客服</div>
+                <div class="code-name">#icon-zaixiankefu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-rizhi"></use>
+                </svg>
+                <div class="name">日志</div>
+                <div class="code-name">#icon-rizhi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xinfeng2"></use>
+                </svg>
+                <div class="name">信封</div>
+                <div class="code-name">#icon-xinfeng2</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jiahao"></use>
+                </svg>
+                <div class="name">加号</div>
+                <div class="code-name">#icon-jiahao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jianhao"></use>
+                </svg>
+                <div class="name">减号</div>
+                <div class="code-name">#icon-jianhao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dianhua1"></use>
+                </svg>
+                <div class="name">电话</div>
+                <div class="code-name">#icon-dianhua1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yanjing_xianshi_o"></use>
+                </svg>
+                <div class="name">眼睛_显示_o</div>
+                <div class="code-name">#icon-yanjing_xianshi_o</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-cemian"></use>
+                </svg>
+                <div class="name">测面</div>
+                <div class="code-name">#icon-cemian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shanchu1"></use>
+                </svg>
+                <div class="name">删除</div>
+                <div class="code-name">#icon-shanchu1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-gongjuxiang"></use>
+                </svg>
+                <div class="name">工具箱</div>
+                <div class="code-name">#icon-gongjuxiang</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-diqiu2"></use>
+                </svg>
+                <div class="name">地球</div>
+                <div class="code-name">#icon-diqiu2</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shangchuan"></use>
+                </svg>
+                <div class="name">上传</div>
+                <div class="code-name">#icon-shangchuan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-juanlian"></use>
+                </svg>
+                <div class="name">卷帘</div>
+                <div class="code-name">#icon-juanlian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-24gl-square"></use>
+                </svg>
+                <div class="name">24gl-square</div>
+                <div class="code-name">#icon-24gl-square</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jieping"></use>
+                </svg>
+                <div class="name">截屏</div>
+                <div class="code-name">#icon-jieping</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-weixin2"></use>
+                </svg>
+                <div class="name">微信</div>
+                <div class="code-name">#icon-weixin2</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon--diqiu"></use>
+                </svg>
+                <div class="name">17-地球</div>
+                <div class="code-name">#icon--diqiu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-rili"></use>
+                </svg>
+                <div class="name">日历</div>
+                <div class="code-name">#icon-rili</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-ranging_line"></use>
+                </svg>
+                <div class="name">测距_line</div>
+                <div class="code-name">#icon-ranging_line</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jieping1"></use>
+                </svg>
+                <div class="name">截屏</div>
+                <div class="code-name">#icon-jieping1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xinfengtubiao"></use>
+                </svg>
+                <div class="name">信封图标</div>
+                <div class="code-name">#icon-xinfengtubiao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dingwei"></use>
+                </svg>
+                <div class="name">定位</div>
+                <div class="code-name">#icon-dingwei</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jishiben"></use>
+                </svg>
+                <div class="name">记事本</div>
+                <div class="code-name">#icon-jishiben</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dunpai-"></use>
+                </svg>
+                <div class="name">盾牌-01</div>
+                <div class="code-name">#icon-dunpai-</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yangbenbianji"></use>
+                </svg>
+                <div class="name">样本编辑</div>
+                <div class="code-name">#icon-yangbenbianji</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-huizhi"></use>
+                </svg>
+                <div class="name">绘制</div>
+                <div class="code-name">#icon-huizhi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-ziyuan35"></use>
+                </svg>
+                <div class="name">添加订单</div>
+                <div class="code-name">#icon-ziyuan35</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tx-liubianxing"></use>
+                </svg>
+                <div class="name">tx-六边形</div>
+                <div class="code-name">#icon-tx-liubianxing</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-rili1"></use>
+                </svg>
+                <div class="name">日历</div>
+                <div class="code-name">#icon-rili1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tianjiadingdan"></use>
+                </svg>
+                <div class="name">添加订单</div>
+                <div class="code-name">#icon-tianjiadingdan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jishiben1"></use>
+                </svg>
+                <div class="name">记事本</div>
+                <div class="code-name">#icon-jishiben1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-loudou"></use>
+                </svg>
+                <div class="name">漏斗</div>
+                <div class="code-name">#icon-loudou</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-loudou1"></use>
+                </svg>
+                <div class="name">漏斗</div>
+                <div class="code-name">#icon-loudou1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shangchuan1"></use>
+                </svg>
+                <div class="name">上传</div>
+                <div class="code-name">#icon-shangchuan1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tuceng"></use>
+                </svg>
+                <div class="name">图层</div>
+                <div class="code-name">#icon-tuceng</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-map-ruler"></use>
+                </svg>
+                <div class="name">地图尺子,测量,测距,距离</div>
+                <div class="code-name">#icon-map-ruler</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-checkbox"></use>
+                </svg>
+                <div class="name">正方形</div>
+                <div class="code-name">#icon-checkbox</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-juanlian1"></use>
+                </svg>
+                <div class="name">卷帘</div>
+                <div class="code-name">#icon-juanlian1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-ceju_1"></use>
+                </svg>
+                <div class="name">测距_1</div>
+                <div class="code-name">#icon-ceju_1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-hexagon"></use>
+                </svg>
+                <div class="name">六边形</div>
+                <div class="code-name">#icon-hexagon</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-kongjiancemian"></use>
+                </svg>
+                <div class="name">空间测面</div>
+                <div class="code-name">#icon-kongjiancemian</div>
+            </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="symbol-">Symbol 引用</h2>
+          <hr>
+
+          <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+            这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
+          <ul>
+            <li>支持多色图标了,不再受单色限制。</li>
+            <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
+            <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
+            <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
+          </ul>
+          <p>使用步骤如下:</p>
+          <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
+<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
+</code></pre>
+          <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
+<pre><code class="language-html">&lt;style&gt;
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+&lt;/style&gt;
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
+  &lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
+&lt;/svg&gt;
+</code></pre>
+          </div>
+      </div>
+
+    </div>
+  </div>
+  <script>
+  $(document).ready(function () {
+      $('.tab-container .content:first').show()
+
+      $('#tabs li').click(function (e) {
+        var tabContent = $('.tab-container .content')
+        var index = $(this).index()
+
+        if ($(this).hasClass('active')) {
+          return
+        } else {
+          $('#tabs li').removeClass('active')
+          $(this).addClass('active')
+
+          tabContent.hide().eq(index).fadeIn()
+        }
+      })
+    })
+  </script>
+</body>
+</html>

+ 313 - 0
src/assets/icon/iconfont.css

@@ -0,0 +1,313 @@
+@font-face {
+  font-family: "iconfont"; /* Project id  */
+  src: url('iconfont.ttf?t=1665298257000') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-sousuowenjian:before {
+  content: "\f00c3";
+}
+
+.icon-yuanjing:before {
+  content: "\f019b";
+}
+
+.icon-quanjing:before {
+  content: "\f01a0";
+}
+
+.icon-duoyun:before {
+  content: "\f0206";
+}
+
+.icon-weixin:before {
+  content: "\f0106";
+}
+
+.icon-dianhua:before {
+  content: "\e61b";
+}
+
+.icon-xinfeng:before {
+  content: "\e640";
+}
+
+.icon-dianhuatianchong:before {
+  content: "\e678";
+}
+
+.icon-jia:before {
+  content: "\f018b";
+}
+
+.icon-jian:before {
+  content: "\f018c";
+}
+
+.icon-yanjing:before {
+  content: "\e6ce";
+}
+
+.icon-shanchu:before {
+  content: "\e74b";
+}
+
+.icon-wxbdingwei:before {
+  content: "\e624";
+}
+
+.icon-yanjing1:before {
+  content: "\e661";
+}
+
+.icon-yonghu:before {
+  content: "\e652";
+}
+
+.icon-diqiuquanqiu:before {
+  content: "\e76c";
+}
+
+.icon-diqiu:before {
+  content: "\e60a";
+}
+
+.icon-funnelloudou:before {
+  content: "\e6ca";
+}
+
+.icon-loufang:before {
+  content: "\e64f";
+}
+
+.icon-sousuodizhi:before {
+  content: "\e65e";
+}
+
+.icon-weixin1:before {
+  content: "\e628";
+}
+
+.icon-mingcijieshi:before {
+  content: "\e603";
+}
+
+.icon-query1:before {
+  content: "\e6f0";
+}
+
+.icon-yj:before {
+  content: "\e650";
+}
+
+.icon-xinfeng1:before {
+  content: "\e61c";
+}
+
+.icon-jingdian:before {
+  content: "\e605";
+}
+
+.icon-yonghu1:before {
+  content: "\e8c8";
+}
+
+.icon-jingdian1:before {
+  content: "\e60c";
+}
+
+.icon-tianqi:before {
+  content: "\e61a";
+}
+
+.icon-diqiu1:before {
+  content: "\e689";
+}
+
+.icon-changyonggoupiaorenshanchu:before {
+  content: "\e645";
+}
+
+.icon-dingdan:before {
+  content: "\e646";
+}
+
+.icon-moxingliebiao:before {
+  content: "\e630";
+}
+
+.icon-mn_dunpai:before {
+  content: "\e517";
+}
+
+.icon-zaixiankefu:before {
+  content: "\e621";
+}
+
+.icon-rizhi:before {
+  content: "\e60d";
+}
+
+.icon-xinfeng2:before {
+  content: "\e750";
+}
+
+.icon-jiahao:before {
+  content: "\eaf3";
+}
+
+.icon-jianhao:before {
+  content: "\eaf5";
+}
+
+.icon-dianhua1:before {
+  content: "\eb23";
+}
+
+.icon-yanjing_xianshi_o:before {
+  content: "\ebcc";
+}
+
+.icon-cemian:before {
+  content: "\e606";
+}
+
+.icon-shanchu1:before {
+  content: "\ec7b";
+}
+
+.icon-gongjuxiang:before {
+  content: "\e639";
+}
+
+.icon-diqiu2:before {
+  content: "\e67d";
+}
+
+.icon-shangchuan:before {
+  content: "\eb11";
+}
+
+.icon-juanlian:before {
+  content: "\eb1e";
+}
+
+.icon-24gl-square:before {
+  content: "\ea98";
+}
+
+.icon-jieping:before {
+  content: "\e629";
+}
+
+.icon-weixin2:before {
+  content: "\e856";
+}
+
+.icon--diqiu:before {
+  content: "\e68f";
+}
+
+.icon-rili:before {
+  content: "\e6c5";
+}
+
+.icon-ranging_line:before {
+  content: "\e710";
+}
+
+.icon-jieping1:before {
+  content: "\e651";
+}
+
+.icon-xinfengtubiao:before {
+  content: "\e61e";
+}
+
+.icon-dingwei:before {
+  content: "\e8ae";
+}
+
+.icon-jishiben:before {
+  content: "\e662";
+}
+
+.icon-dunpai-:before {
+  content: "\e684";
+}
+
+.icon-yangbenbianji:before {
+  content: "\e62a";
+}
+
+.icon-huizhi:before {
+  content: "\e52a";
+}
+
+.icon-ziyuan35:before {
+  content: "\e779";
+}
+
+.icon-tx-liubianxing:before {
+  content: "\e64e";
+}
+
+.icon-rili1:before {
+  content: "\e696";
+}
+
+.icon-tianjiadingdan:before {
+  content: "\e607";
+}
+
+.icon-jishiben1:before {
+  content: "\e625";
+}
+
+.icon-loudou:before {
+  content: "\e6be";
+}
+
+.icon-loudou1:before {
+  content: "\e711";
+}
+
+.icon-shangchuan1:before {
+  content: "\e691";
+}
+
+.icon-tuceng:before {
+  content: "\e60f";
+}
+
+.icon-map-ruler:before {
+  content: "\ea07";
+}
+
+.icon-checkbox:before {
+  content: "\ea70";
+}
+
+.icon-juanlian1:before {
+  content: "\e6c7";
+}
+
+.icon-ceju_1:before {
+  content: "\e747";
+}
+
+.icon-hexagon:before {
+  content: "\e602";
+}
+
+.icon-kongjiancemian:before {
+  content: "\e765";
+}
+

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
src/assets/icon/iconfont.js


+ 534 - 0
src/assets/icon/iconfont.json

@@ -0,0 +1,534 @@
+{
+  "id": "",
+  "name": "",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "1124",
+      "name": "搜索文件",
+      "font_class": "sousuowenjian",
+      "unicode": "f00c3",
+      "unicode_decimal": 983235
+    },
+    {
+      "icon_id": "1340",
+      "name": "远景",
+      "font_class": "yuanjing",
+      "unicode": "f019b",
+      "unicode_decimal": 983451
+    },
+    {
+      "icon_id": "1345",
+      "name": "全景",
+      "font_class": "quanjing",
+      "unicode": "f01a0",
+      "unicode_decimal": 983456
+    },
+    {
+      "icon_id": "1447",
+      "name": "多云",
+      "font_class": "duoyun",
+      "unicode": "f0206",
+      "unicode_decimal": 983558
+    },
+    {
+      "icon_id": "77156",
+      "name": "微信",
+      "font_class": "weixin",
+      "unicode": "f0106",
+      "unicode_decimal": 983302
+    },
+    {
+      "icon_id": "144688",
+      "name": "电话",
+      "font_class": "dianhua",
+      "unicode": "e61b",
+      "unicode_decimal": 58907
+    },
+    {
+      "icon_id": "145456",
+      "name": "信封",
+      "font_class": "xinfeng",
+      "unicode": "e640",
+      "unicode_decimal": 58944
+    },
+    {
+      "icon_id": "145699",
+      "name": "电话_填充",
+      "font_class": "dianhuatianchong",
+      "unicode": "e678",
+      "unicode_decimal": 59000
+    },
+    {
+      "icon_id": "162780",
+      "name": "加",
+      "font_class": "jia",
+      "unicode": "f018b",
+      "unicode_decimal": 983435
+    },
+    {
+      "icon_id": "162781",
+      "name": "减",
+      "font_class": "jian",
+      "unicode": "f018c",
+      "unicode_decimal": 983436
+    },
+    {
+      "icon_id": "278748",
+      "name": "眼睛",
+      "font_class": "yanjing",
+      "unicode": "e6ce",
+      "unicode_decimal": 59086
+    },
+    {
+      "icon_id": "577357",
+      "name": "删除",
+      "font_class": "shanchu",
+      "unicode": "e74b",
+      "unicode_decimal": 59211
+    },
+    {
+      "icon_id": "591955",
+      "name": "wxb定位",
+      "font_class": "wxbdingwei",
+      "unicode": "e624",
+      "unicode_decimal": 58916
+    },
+    {
+      "icon_id": "630126",
+      "name": "眼睛",
+      "font_class": "yanjing1",
+      "unicode": "e661",
+      "unicode_decimal": 58977
+    },
+    {
+      "icon_id": "650809",
+      "name": "用户",
+      "font_class": "yonghu",
+      "unicode": "e652",
+      "unicode_decimal": 58962
+    },
+    {
+      "icon_id": "688062",
+      "name": "地球 全球",
+      "font_class": "diqiuquanqiu",
+      "unicode": "e76c",
+      "unicode_decimal": 59244
+    },
+    {
+      "icon_id": "705660",
+      "name": "地球",
+      "font_class": "diqiu",
+      "unicode": "e60a",
+      "unicode_decimal": 58890
+    },
+    {
+      "icon_id": "792387",
+      "name": "funnel-漏斗",
+      "font_class": "funnelloudou",
+      "unicode": "e6ca",
+      "unicode_decimal": 59082
+    },
+    {
+      "icon_id": "802969",
+      "name": "楼房",
+      "font_class": "loufang",
+      "unicode": "e64f",
+      "unicode_decimal": 58959
+    },
+    {
+      "icon_id": "830294",
+      "name": "搜索地址",
+      "font_class": "sousuodizhi",
+      "unicode": "e65e",
+      "unicode_decimal": 58974
+    },
+    {
+      "icon_id": "880414",
+      "name": "微信",
+      "font_class": "weixin1",
+      "unicode": "e628",
+      "unicode_decimal": 58920
+    },
+    {
+      "icon_id": "993666",
+      "name": "名词解释",
+      "font_class": "mingcijieshi",
+      "unicode": "e603",
+      "unicode_decimal": 58883
+    },
+    {
+      "icon_id": "1038621",
+      "name": "高级查询",
+      "font_class": "query1",
+      "unicode": "e6f0",
+      "unicode_decimal": 59120
+    },
+    {
+      "icon_id": "1183248",
+      "name": "眼睛",
+      "font_class": "yj",
+      "unicode": "e650",
+      "unicode_decimal": 58960
+    },
+    {
+      "icon_id": "1312062",
+      "name": "信封",
+      "font_class": "xinfeng1",
+      "unicode": "e61c",
+      "unicode_decimal": 58908
+    },
+    {
+      "icon_id": "1315594",
+      "name": "景点",
+      "font_class": "jingdian",
+      "unicode": "e605",
+      "unicode_decimal": 58885
+    },
+    {
+      "icon_id": "1727459",
+      "name": "224用户",
+      "font_class": "yonghu1",
+      "unicode": "e8c8",
+      "unicode_decimal": 59592
+    },
+    {
+      "icon_id": "2121721",
+      "name": "景点",
+      "font_class": "jingdian1",
+      "unicode": "e60c",
+      "unicode_decimal": 58892
+    },
+    {
+      "icon_id": "2380665",
+      "name": "天气",
+      "font_class": "tianqi",
+      "unicode": "e61a",
+      "unicode_decimal": 58906
+    },
+    {
+      "icon_id": "2746603",
+      "name": "地球",
+      "font_class": "diqiu1",
+      "unicode": "e689",
+      "unicode_decimal": 59017
+    },
+    {
+      "icon_id": "2892818",
+      "name": "删除",
+      "font_class": "changyonggoupiaorenshanchu",
+      "unicode": "e645",
+      "unicode_decimal": 58949
+    },
+    {
+      "icon_id": "2892820",
+      "name": "订单",
+      "font_class": "dingdan",
+      "unicode": "e646",
+      "unicode_decimal": 58950
+    },
+    {
+      "icon_id": "3590946",
+      "name": "模型列表",
+      "font_class": "moxingliebiao",
+      "unicode": "e630",
+      "unicode_decimal": 58928
+    },
+    {
+      "icon_id": "4178679",
+      "name": "AK-MN_盾牌",
+      "font_class": "mn_dunpai",
+      "unicode": "e517",
+      "unicode_decimal": 58647
+    },
+    {
+      "icon_id": "4315719",
+      "name": "在线客服",
+      "font_class": "zaixiankefu",
+      "unicode": "e621",
+      "unicode_decimal": 58913
+    },
+    {
+      "icon_id": "4520330",
+      "name": "日志",
+      "font_class": "rizhi",
+      "unicode": "e60d",
+      "unicode_decimal": 58893
+    },
+    {
+      "icon_id": "5042249",
+      "name": "信封",
+      "font_class": "xinfeng2",
+      "unicode": "e750",
+      "unicode_decimal": 59216
+    },
+    {
+      "icon_id": "5387527",
+      "name": "加号",
+      "font_class": "jiahao",
+      "unicode": "eaf3",
+      "unicode_decimal": 60147
+    },
+    {
+      "icon_id": "5387532",
+      "name": "减号",
+      "font_class": "jianhao",
+      "unicode": "eaf5",
+      "unicode_decimal": 60149
+    },
+    {
+      "icon_id": "5387648",
+      "name": "电话",
+      "font_class": "dianhua1",
+      "unicode": "eb23",
+      "unicode_decimal": 60195
+    },
+    {
+      "icon_id": "5388069",
+      "name": "眼睛_显示_o",
+      "font_class": "yanjing_xianshi_o",
+      "unicode": "ebcc",
+      "unicode_decimal": 60364
+    },
+    {
+      "icon_id": "5650847",
+      "name": "测面",
+      "font_class": "cemian",
+      "unicode": "e606",
+      "unicode_decimal": 58886
+    },
+    {
+      "icon_id": "6061533",
+      "name": "删除",
+      "font_class": "shanchu1",
+      "unicode": "ec7b",
+      "unicode_decimal": 60539
+    },
+    {
+      "icon_id": "6193800",
+      "name": "工具箱",
+      "font_class": "gongjuxiang",
+      "unicode": "e639",
+      "unicode_decimal": 58937
+    },
+    {
+      "icon_id": "6539412",
+      "name": "地球",
+      "font_class": "diqiu2",
+      "unicode": "e67d",
+      "unicode_decimal": 59005
+    },
+    {
+      "icon_id": "7335404",
+      "name": "上传",
+      "font_class": "shangchuan",
+      "unicode": "eb11",
+      "unicode_decimal": 60177
+    },
+    {
+      "icon_id": "7335458",
+      "name": "卷帘",
+      "font_class": "juanlian",
+      "unicode": "eb1e",
+      "unicode_decimal": 60190
+    },
+    {
+      "icon_id": "7594407",
+      "name": "24gl-square",
+      "font_class": "24gl-square",
+      "unicode": "ea98",
+      "unicode_decimal": 60056
+    },
+    {
+      "icon_id": "7617412",
+      "name": "截屏",
+      "font_class": "jieping",
+      "unicode": "e629",
+      "unicode_decimal": 58921
+    },
+    {
+      "icon_id": "8288886",
+      "name": "微信",
+      "font_class": "weixin2",
+      "unicode": "e856",
+      "unicode_decimal": 59478
+    },
+    {
+      "icon_id": "8308099",
+      "name": "17-地球",
+      "font_class": "-diqiu",
+      "unicode": "e68f",
+      "unicode_decimal": 59023
+    },
+    {
+      "icon_id": "8361799",
+      "name": "日历",
+      "font_class": "rili",
+      "unicode": "e6c5",
+      "unicode_decimal": 59077
+    },
+    {
+      "icon_id": "9834416",
+      "name": "测距_line",
+      "font_class": "ranging_line",
+      "unicode": "e710",
+      "unicode_decimal": 59152
+    },
+    {
+      "icon_id": "10156374",
+      "name": "截屏",
+      "font_class": "jieping1",
+      "unicode": "e651",
+      "unicode_decimal": 58961
+    },
+    {
+      "icon_id": "10857643",
+      "name": "信封图标",
+      "font_class": "xinfengtubiao",
+      "unicode": "e61e",
+      "unicode_decimal": 58910
+    },
+    {
+      "icon_id": "11372652",
+      "name": "定位",
+      "font_class": "dingwei",
+      "unicode": "e8ae",
+      "unicode_decimal": 59566
+    },
+    {
+      "icon_id": "11987023",
+      "name": "记事本",
+      "font_class": "jishiben",
+      "unicode": "e662",
+      "unicode_decimal": 58978
+    },
+    {
+      "icon_id": "12184874",
+      "name": "盾牌-01",
+      "font_class": "dunpai-",
+      "unicode": "e684",
+      "unicode_decimal": 59012
+    },
+    {
+      "icon_id": "13075023",
+      "name": "样本编辑",
+      "font_class": "yangbenbianji",
+      "unicode": "e62a",
+      "unicode_decimal": 58922
+    },
+    {
+      "icon_id": "14008818",
+      "name": "绘制",
+      "font_class": "huizhi",
+      "unicode": "e52a",
+      "unicode_decimal": 58666
+    },
+    {
+      "icon_id": "14488459",
+      "name": "添加订单",
+      "font_class": "ziyuan35",
+      "unicode": "e779",
+      "unicode_decimal": 59257
+    },
+    {
+      "icon_id": "14718729",
+      "name": "tx-六边形",
+      "font_class": "tx-liubianxing",
+      "unicode": "e64e",
+      "unicode_decimal": 58958
+    },
+    {
+      "icon_id": "15765353",
+      "name": "日历",
+      "font_class": "rili1",
+      "unicode": "e696",
+      "unicode_decimal": 59030
+    },
+    {
+      "icon_id": "15983693",
+      "name": "添加订单",
+      "font_class": "tianjiadingdan",
+      "unicode": "e607",
+      "unicode_decimal": 58887
+    },
+    {
+      "icon_id": "16050274",
+      "name": "记事本",
+      "font_class": "jishiben1",
+      "unicode": "e625",
+      "unicode_decimal": 58917
+    },
+    {
+      "icon_id": "16517972",
+      "name": "漏斗",
+      "font_class": "loudou",
+      "unicode": "e6be",
+      "unicode_decimal": 59070
+    },
+    {
+      "icon_id": "16728171",
+      "name": "漏斗",
+      "font_class": "loudou1",
+      "unicode": "e711",
+      "unicode_decimal": 59153
+    },
+    {
+      "icon_id": "17898907",
+      "name": "上传",
+      "font_class": "shangchuan1",
+      "unicode": "e691",
+      "unicode_decimal": 59025
+    },
+    {
+      "icon_id": "17937347",
+      "name": "图层",
+      "font_class": "tuceng",
+      "unicode": "e60f",
+      "unicode_decimal": 58895
+    },
+    {
+      "icon_id": "18171091",
+      "name": "地图尺子,测量,测距,距离",
+      "font_class": "map-ruler",
+      "unicode": "ea07",
+      "unicode_decimal": 59911
+    },
+    {
+      "icon_id": "18175801",
+      "name": "正方形",
+      "font_class": "checkbox",
+      "unicode": "ea70",
+      "unicode_decimal": 60016
+    },
+    {
+      "icon_id": "24888067",
+      "name": "卷帘",
+      "font_class": "juanlian1",
+      "unicode": "e6c7",
+      "unicode_decimal": 59079
+    },
+    {
+      "icon_id": "26696768",
+      "name": "测距_1",
+      "font_class": "ceju_1",
+      "unicode": "e747",
+      "unicode_decimal": 59207
+    },
+    {
+      "icon_id": "27938688",
+      "name": "六边形",
+      "font_class": "hexagon",
+      "unicode": "e602",
+      "unicode_decimal": 58882
+    },
+    {
+      "icon_id": "31229432",
+      "name": "空间测面",
+      "font_class": "kongjiancemian",
+      "unicode": "e765",
+      "unicode_decimal": 59237
+    }
+  ]
+}

BIN
src/assets/icon/iconfont.ttf


BIN
src/assets/images/m-cesium.png


BIN
src/assets/images/m-cityLine.png


BIN
src/assets/images/m-earth.png


BIN
src/assets/images/m-normal.png


BIN
src/assets/images/maptype.png


BIN
src/assets/images/shadow_6bf0ecd.png


+ 127 - 0
src/assets/less/_variables.less

@@ -0,0 +1,127 @@
+@colors: {
+    a: red;
+    white: #fff;
+    ztblue: rgb(0, 120, 215)
+}
+
+@font_size: {
+    -5: -5px;
+    -10: -10px;
+    -15: -15px;
+    -30: -30px;
+    -32: -32px;
+    -40: -40px;
+    0: 0px;
+    1: 1px;
+    2: 2px;
+    3: 3px;
+    4: 4px;
+    5: 5px;
+    6: 6px;
+    7: 7px;
+    8: 8px;
+    9: 9px;
+    10: 10px;
+    11: 11px;
+    12: 12px;
+    13: 13px;
+    14: 14px;
+    15: 15px;
+    16: 16px;
+    17: 17px;
+    18: 18px;
+    19: 19px;
+    20: 20px;
+    21: 21px;
+    22: 22px;
+    23: 23px;
+    24: 24px;
+    25: 25px;
+    26: 26px;
+    27: 27px;
+    28: 28px;
+    29: 29px;
+    30: 30px;
+    31: 31px;
+    32: 32px;
+    33: 33px;
+    34: 34px;
+    35: 35px;
+    36: 36px;
+    37: 37px;
+    38: 38px;
+    39: 39px;
+    40: 40px;
+    41: 41px;
+    42: 42px;
+    43: 43px;
+    44: 44px;
+    45: 45px;
+    48: 48px;
+    50: 50px;
+    55: 55px;
+    60: 60px;
+    65: 65px;
+    70: 70px;
+    75: 75px;
+    80: 80px;
+    90: 90px;
+    100: 100px;
+    110: 110px;
+    120: 120px;
+    123: 123px;
+    124: 124px;
+    125: 125px;
+    130: 130px;
+    135: 135px;
+    140: 140px;
+    150: 150px;
+    155: 155px;
+    160: 160px;
+    170: 170px;
+    180: 180px;
+    190: 190px;
+    200: 200px;
+    210: 210px;
+    220: 220px;
+    230: 230px;
+    240: 240px;
+    250: 250px;
+    260: 260px;
+    270: 270px;
+    279: 279px;
+    280: 280px;
+    287: 287px;
+    300: 300px;
+    310: 310px;
+    320: 320px;
+    330: 330px;
+    340: 340px;
+    350: 350px;
+    360: 360px;
+    370: 370px;
+    375: 375px;
+    380: 380px;
+    390: 390px;
+    395: 395px;
+    400: 400px;
+    420: 420px;
+    431: 431px;
+    445: 445px;
+    450: 450px;
+    480: 480px;
+    490: 490px;
+    500: 500px;
+    520: 520px;
+    750: 750px;
+    600: 600px;
+    650: 650px;
+    800: 800px;
+    820: 820px;
+    840: 840px;
+    900: 900px;
+    1000: 1000px;
+    1120: 1120px;
+    1200: 1200px;
+    1300: 1300px;
+}

+ 35 - 0
src/assets/less/map.less

@@ -0,0 +1,35 @@
+.map-popupinfo{
+    overflow:hidden;min-width:240px;background:white;padding:10px;list-style:none;border: 1px solid rgba(0,0,0,.2);box-shadow: 0 5px 10px rgba(0,0,0,.2);border-radius:5px;margin-bottom:15px;
+    .popupinfo-title{
+        padding: 2px 5px;margin: 0;font-size: 14px;border-radius: 5px 5px 0 0;color:#000;
+    }
+    .popupinfo-content{
+        min-width:220px;
+        max-width: 400px;
+        max-height: 200px;
+        overflow-y: auto;
+        line-height: 25px;
+        list-style-type: none;
+        padding: 0;
+        li{ 
+            span{
+                color:#8c8484;
+                &:first-child{
+                    color:#333;
+                }
+            }
+        }
+    }
+    .popupinfo-poi{
+        width:20px;height:20px;position: absolute;left: 45%;bottom: -30px;transform: 45;width: 0;border-width: 13px;border-style: solid;border-color: white transparent transparent transparent;
+    }
+    .popupinfo-close{
+        float:right;
+        font-size:16px;
+    }
+}
+.maps-btn, .maps-btn .el-input__inner{
+    background-color: rgba(0,0,0,0.45);
+    color: rgba(255,255,255,0.8);
+    border-color: rgba(0,0,0,0.8);
+}

+ 754 - 0
src/assets/less/style.less

@@ -0,0 +1,754 @@
+@import "./_variables";
+
+a {
+  text-decoration: none;
+}
+
+.el-tree-node__content {
+  height: auto !important;
+  line-height: 24px;
+
+  .el-tree-node__expand-icon {
+    padding: 5px;
+    font-size: 25px !important;
+  }
+}
+
+.el-dropdown {
+  font-size: initial;
+}
+
+.nulldata {
+  color: #888888;
+  text-align: center;
+  padding: 20px;
+  font-size: 16px;
+  line-height: 40px;
+}
+
+.el-button {
+  min-height: 30px;
+  padding: 8px 15px;
+  // line-height: 14px;
+}
+
+.el-button--mini {
+  // min-height: 20px;
+  height: auto;
+  min-height: initial;
+  font-size: 10px;
+  padding: 5px 8px;
+  border-radius: 3px;
+}
+
+.link-text {
+  color: #409eff;
+  cursor: pointer;
+
+  &:hover {
+    color: rgb(104, 180, 255);
+
+    &.link-line {
+      text-decoration: underline;
+    }
+  }
+}
+
+// 小手
+.pointer {
+  cursor: pointer;
+}
+
+//左菜单
+.minRightMenuWidth {
+  width: 250px;
+}
+
+.minRightMenuWidth-body {
+  width: calc(100% - 250px);
+}
+
+.el-menu-vertical-demo {
+  height: 100%;
+}
+
+.el-submenu .el-menu-item {
+  padding: 0 10px;
+  min-width: 100%;
+}
+
+.tool-right {
+  >div {
+    color: #606266;
+  }
+}
+
+//定位
+.posi-rel {
+  position: relative;
+
+  .posi-abs {
+    position: absolute;
+
+    &.posi-center {
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+    }
+
+    &.top-center {
+      top: 50%;
+      transform: translate(0, -50%);
+    }
+
+    &.left-center {
+      left: 50%;
+      transform: translate(-50%, 0%);
+    }
+  }
+}
+
+//查询
+.map-search {
+  position: absolute;
+  z-index: 999;
+  top: 40px;
+  right: 1px;
+  background: rgba(255, 255, 255, 1);
+  border-radius: 5px;
+  width: 440px;
+  border: 1px solid #ddd;
+
+  .map-search-content {
+    margin-top: 10px;
+    max-height: 60vh;
+    overflow-y: auto;
+
+    .map-search-card {
+      cursor: pointer;
+    }
+  }
+}
+
+//文字不能选中
+.select-none {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+// 滚动条样式
+.scroll-style {
+  ::-webkit-scrollbar {
+    width: 8px;
+    /*对垂直流动条有效*/
+    height: 8px;
+  }
+
+  ::-webkit-scrollbar-track {
+    -webkit-box-shadow: none;
+    background-color: #fff;
+  }
+
+  ::-webkit-scrollbar-thumb {
+    border-radius: 7px;
+    background-color: rgb(221, 222, 224);
+  }
+
+  ::-webkit-scrollbar-thumb:hover {
+    /*当焦点不在当前区域滑块的状态*/
+    border-radius: 7px;
+    background-color: rgb(199, 201, 204);
+  }
+}
+
+// bth样式
+.btn-style {
+  line-height: 0;
+  padding: 0px 20px;
+
+  i {
+    line-height: 0;
+  }
+}
+
+.btn-mini-style {
+  line-height: 0;
+  padding: 0px 20px;
+
+  i {
+    line-height: 0;
+  }
+}
+
+// .el-form-item {
+//     margin-bottom: 10px;
+// }
+
+// 不能换行
+.nowrap {
+  white-space: nowrap;
+}
+
+// 去掉item间距
+.label-margin {
+  &.bottom-none {
+    margin-bottom: 0px;
+  }
+
+  &.right-none {
+    margin-right: 0px;
+  }
+}
+
+// label 
+.label-style {
+  label {
+    color: rgb(124, 124, 124)
+  }
+}
+
+.popper-cascader {
+  .el-cascader-menu {
+    max-height: 400px;
+    overflow: auto;
+    height: inherit;
+  }
+}
+
+.label-input-style {
+  margin-bottom: 15px;
+
+  label {
+
+    color: rgb(124, 124, 124)
+  }
+
+  input {
+    height: 30px;
+    line-height: 30px;
+
+  }
+
+  .el-select__caret {
+    vertical-align: super;
+  }
+
+  .el-form-item__error {
+    top: 92%;
+  }
+}
+
+.cell-item .caozuo {
+  padding: 0 !important;
+  cursor: pointer;
+
+  &.danger {
+    color: #f56c6c;
+
+    &:hover {
+      color: #f78989;
+    }
+  }
+}
+
+.txt-info {
+  cursor: pointer;
+  color: rgb(180, 180, 180);
+  margin-left: 5px;
+}
+
+// 文字提示
+.el-popper.is-dark {
+  max-width: 300px;
+  background-color: rgba(88, 94, 107, 1);
+
+  .el-popper__arrow:before {
+    background-color: rgba(88, 94, 107, 1);
+  }
+}
+
+// 输入框样式
+.input-style {
+  line-height: 0px;
+
+  input {
+    // 
+    padding: 0px 15px;
+  }
+
+  .el-select__caret {
+    vertical-align: super;
+  }
+
+  .el-form-item__error {
+    top: 92%;
+  }
+}
+
+.el-timeline-item__timestamp.is-bottom {
+  margin-top: 0;
+}
+
+.cascader-style {
+  line-height: 0px;
+  // .el-input {
+  //     height: 40px !important;
+  //     line-height: 40px;
+  //     min-height: 40px;
+  // }
+
+  // input {
+  //     height: 40px !important;
+  //     line-height: 40px;
+  //     min-height: 40px;
+  //     
+  //     padding: 0px 15px;
+  // }
+
+  // i {
+  //     line-height: 40px !important;
+  // }
+}
+
+//浮动
+.float-r {
+  float: right;
+}
+
+//浮动
+.float-l {
+  float: left;
+}
+
+//布局
+.flex-box {
+  display: flex;
+
+  &.column {
+    flex-direction: column;
+  }
+
+  &.align-center {
+    align-items: center;
+  }
+
+  &.align-between {
+    align-items: space-between;
+  }
+
+  &.align-end {
+    align-items: flex-end;
+  }
+
+  &.align-around {
+    align-items: space-around;
+  }
+
+  &.justify-center {
+    justify-content: center;
+  }
+
+  &.justify-between {
+    justify-content: space-between;
+  }
+
+  &.justify-end {
+    justify-content: flex-end;
+  }
+
+  &.justify-around {
+    justify-content: space-around;
+  }
+
+  .flex-content {
+    flex: 1;
+  }
+
+  &.nowrap {
+    flex-wrap: nowrap;
+  }
+
+  &.wrap {
+    flex-wrap: wrap;
+  }
+}
+
+// 占满容器
+.max-box {
+  width: 100%;
+  height: 100%;
+}
+
+.max-width {
+  width: 100%;
+}
+
+.max-height {
+  height: 100%;
+}
+
+// ie盒模型
+.box-sizing {
+  box-sizing: border-box;
+}
+
+// 字体加粗
+.font-bold {
+  font-weight: bold;
+}
+
+// 文字居中
+.text-center {
+  text-align: center;
+}
+
+// 文字居中
+.text-justify {
+  text-align: justify;
+}
+
+.text-right {
+  text-align: right;
+}
+
+.text-left {
+  text-align: left;
+}
+
+
+//文章一行显示,多余省略号显示
+.title-item {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+// 字体对其方式
+.text-justify {
+  text-align: justify;
+}
+
+.inline-block {
+  display: inline-block
+}
+
+// 滚动条
+.overflow-auto {
+  overflow: auto;
+}
+
+.overflow-hidden {
+  overflow: hidden;
+}
+
+.block-title {
+
+  color: #605e5e;
+  padding-left: 10px;
+  position: relative;
+
+  &::after {
+    position: absolute;
+    content: "";
+    background: #3a8ee6;
+    left: 0;
+    top: 3px;
+    width: 5px;
+    height: 15px;
+    border-radius: 3px;
+  }
+}
+
+.w-card {
+
+  border: 1px solid #e8e8e8;
+  border-radius: 3px;
+  padding: 5px 10px;
+  margin-bottom: 10px;
+
+  // cursor: pointer
+  &:hover {
+    border-color: rgba(64, 158, 255, .19);
+    -webkit-box-shadow: 0 2px 8px rgba(64, 158, 255, 0.29);
+    box-shadow: 0 2px 8px rgba(64, 158, 255, .29);
+    background-color: rgba(64, 158, 255, 0.02);
+  }
+
+  .w-card-btns {
+    button {
+      background-color: rgba(255, 255, 255, 0.3);
+      padding: 0 5px;
+      min-height: 25px;
+    }
+  }
+}
+
+.el-table {
+  th {
+    background-color: #f5f7f9 !important;
+
+    >.cell {
+      white-space: pre-line;
+      color: #657180;
+      // text-align: center;
+    }
+  }
+}
+
+.ul-list {
+  list-style-type: none;
+  padding: 0;
+  margin: 2px 0;
+
+  >li {
+    cursor: pointer;
+    padding: 0 15px;
+    line-height: 45px;
+
+    &:hover {
+      color: #3a8ee6;
+    }
+
+    &.active {
+      font-weight: bold;
+      background-color: #d9ecff;
+      color: #3a8ee6;
+    }
+  }
+}
+
+.el-form-item__label {
+  font-size: 14px;
+}
+
+.form-detail {
+  .el-form-item {
+    margin-bottom: 0;
+  }
+
+  .el-form-item__label,
+  .el-form-item__content {
+    line-height: 30px;
+    vertical-align: middle;
+  }
+}
+
+.logs {
+
+  .el-timeline-item__tail,
+  .el-timeline-item__node {
+    margin-top: 10px;
+  }
+}
+
+.el-tabs__item {
+  padding: 0 15px !important;
+}
+
+each(@colors, {
+  .text-@{key} {
+    color: @value;
+  }
+
+  .bg-@{key} {
+    background-color: @value;
+  }
+});
+
+each(@font_size, {
+  .font-@{key} {
+    font-size: @value;
+  }
+
+  .fonts-@{key} {
+    font-size: @value !important;
+  }
+
+  .line-@{key} {
+    line-height: @value;
+  }
+
+  .margin-top-@{key} {
+    margin-top:@value;
+  }
+
+  .margin-bottom-@{key} {
+    margin-bottom:@value;
+  }
+
+  .margin-left-@{key} {
+    margin-left:@value;
+  }
+
+  .margin-right-@{key} {
+    margin-right:@value;
+  }
+
+  .margin-lr-@{key} {
+    margin-left:@value;
+    margin-right:@value;
+  }
+
+  .margin-tb-@{key} {
+    margin-top:@value;
+    margin-bottom:@value;
+  }
+
+  .padding-top-@{key} {
+    padding-top:@value;
+  }
+
+  .padding-bottom-@{key} {
+    padding-bottom:@value;
+  }
+
+  .padding-left-@{key} {
+    padding-left:@value;
+  }
+
+  .padding-right-@{key} {
+    padding-right:@value;
+  }
+
+  .padding-@{key} {
+    padding:@value;
+  }
+
+  .padding-lr-@{key} {
+    margin-left:@value;
+    margin-right:@value;
+  }
+
+  .padding-tb-@{key} {
+    margin-top:@value;
+    margin-bottom:@value;
+  }
+
+  .width-@{key} {
+    width:@value;
+  }
+
+  .widths-@{key} {
+    width:@value !important;
+  }
+
+  .height-@{key} {
+    height:@value;
+  }
+
+  .height-100-@{key} {
+    height:calc(100% - @value);
+  }
+
+  .width-100-@{key} {
+    width:calc(100% - @value);
+  }
+
+  .height-50-@{key} {
+    height:calc(50% - @value);
+  }
+
+  .width-50-@{key} {
+    width:calc(50% - @value);
+  }
+
+  .min-width-@{key} {
+    min-width:@value;
+  }
+
+  .min-height-@{key} {
+    min-height:@value;
+  }
+
+  .max-width-@{key} {
+    max-width:@value;
+  }
+
+  .max-height-@{key} {
+    max-height:@value;
+  }
+
+  .top-@{key} {
+    top:@value;
+  }
+
+  .bottom-@{key} {
+    bottom:@value;
+  }
+
+  .left-@{key} {
+    left:@value;
+  }
+
+  .right-@{key} {
+    right:@value;
+  }
+
+  .border-radius-@{key} {
+    border-radius:@value;
+  }
+
+  .border-top-right-radius-@{key} {
+    border-top-right-radius:@value;
+  }
+
+  .border-top-left-radius-@{key} {
+    border-top-left-radius:@value;
+  }
+
+  .border-bottom-right-radius-@{key} {
+    border-bottom-right-radius:@value;
+  }
+
+  .border-bottom-left-radius-@{key} {
+    border-bottom-left-radius:@value;
+  }
+
+  .input-height-@{key} {
+    input {
+      height: @value;
+      line-height: 0px;
+      min-height: @value;
+
+    }
+
+    i {
+      vertical-align: super;
+      line-height: 0;
+    }
+  }
+
+});
+
+
+.file-dialog .el-overlay {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  background-color: #fff;
+
+  .image {
+    img {
+      width: 100%;
+    }
+  }
+
+  .el-dialog {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    margin: 0;
+  }
+
+  .el-dialog__header {
+    flex-shrink: 0;
+  }
+
+  .el-dialog__body {
+    flex: auto;
+    padding: 0;
+  }
+}

+ 70 - 0
src/assets/styles/index.scss

@@ -0,0 +1,70 @@
+//scss 语法糖包含常用的布局方式 flex column
+// @import './scss-suger.scss';
+//重置 element-plus 样式
+// @import './reset-elemenet-plus-style.scss';
+//动画文件
+// @import './transition.scss';
+@import './public.css';
+
+//reset style
+body {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  font-size: 14px;
+}
+* {
+  box-sizing: border-box;
+}
+*::before,
+*::after {
+  box-sizing: border-box;
+}
+a:focus,
+a:active {
+  outline: none;
+}
+a,
+a:focus,
+a:hover {
+  cursor: pointer;
+  color: inherit;
+  text-decoration: none;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  line-height: 1;
+  font-weight: 400;
+  margin: 0;
+  padding: 0;
+}
+span,
+output {
+  display: inline-block;
+  line-height: 1;
+}
+
+//scroll
+@mixin main-show-wh() {
+  /* css 声明 */
+  //height: calc(100vh - #{$navBarHeight} - #{$tagViewHeight} - #{$appMainPadding * 2});
+  height: calc(100vh - #{var(--nav-bar-height)} - #{var(--tag-view-height)} - #{calc(var(--app-main-padding) * 2)});
+  width: 100%;
+}
+.scroll-y {
+  @include main-show-wh();
+  overflow-y: auto;
+}
+.scroll-x {
+  @include main-show-wh();
+  overflow-x: auto;
+}
+.scroll-xy {
+  @include main-show-wh();
+  overflow: auto;
+}

+ 221 - 0
src/assets/styles/public.css

@@ -0,0 +1,221 @@
+/**
+ * @Description: 公共样式
+ */
+
+/* 样式初始化-start */
+html,
+body,
+div,
+input,
+ul,
+li,
+select {
+  margin: 0;
+  padding: 0;
+  /* box-sizing: border-box; */
+}
+
+ul,
+li {
+  list-style: none;
+  cursor: default;
+}
+
+:focus {
+  outline: 0;
+}
+
+/* 样式初始化-end */
+
+/* 公共滚动条 */
+::-webkit-scrollbar {
+  width: 9px;
+  height: 9px;
+}
+
+::-webkit-scrollbar-track-piece {
+  background-color: #ebebeb;
+  -webkit-border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:vertical {
+  height: 32px;
+  background-color: #ccc;
+  -webkit-border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:horizontal {
+  width: 32px;
+  background-color: #ccc;
+  -webkit-border-radius: 4px;
+}
+
+/* a标签去除默认样式,包含以下四种的链接*/
+a {
+  text-decoration: none;
+  color: #303133;
+}
+
+/*正常的未被访问过的链接*/
+a:link {
+  text-decoration: none;
+}
+
+/*已经访问过的链接*/
+a:visited {
+  text-decoration: none;
+}
+
+/*鼠标划过(停留)的链接*/
+a:hover {
+  text-decoration: none;
+}
+
+/* 正在点击的链接*/
+a:active {
+  text-decoration: none;
+}
+
+/* 测试专用-start */
+.red {
+  outline: red solid 1px;
+  background-color: rgb(245, 135, 135);
+}
+
+.orange {
+  outline: orange solid 1px;
+  background-color: rgb(252, 212, 104);
+}
+
+.green {
+  outline: green solid 1px;
+  background-color: rgb(144, 238, 144);
+}
+
+.blue {
+  outline: blue solid 1px;
+  background-color: rgb(119, 137, 236);
+}
+
+.yellow {
+  outline: yellow solid 1px;
+  background-color: rgb(245, 245, 81);
+}
+
+.pink {
+  outline: pink solid 1px;
+  background-color: rgb(245, 81, 171);
+}
+
+/* 测试专用-end */
+
+/* 常用代码 */
+.none {
+  display: none !important;
+}
+
+.hidden {
+  visibility: hidden;
+}
+
+.unable {
+  opacity: 0.8;
+  filter: grayscale(100%);
+  cursor: not-allowed;
+}
+
+/* 不换行 */
+.ellipsis {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  /* padding-left: 5px; */
+}
+
+.wh {
+  width: 100%;
+  height: 100%;
+}
+
+.px {
+  width: 100px;
+  height: 100px;
+}
+
+.ib {
+  display: inline-block;
+}
+
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+}
+
+input[type="number"] {
+  -moz-appearance: textfield;
+}
+
+::-webkit-input-placeholder {
+  /* WebKit browsers */
+  color: #ccc;
+}
+
+::-moz-placeholder {
+  /* Mozilla Firefox 19+ */
+  color: #ccc;
+}
+
+:-ms-input-placeholder {
+  /* Internet Explorer 10+ */
+  color: #ccc;
+}
+
+.center {
+  position: absolute;
+  left: 50%;
+  transform: translateX(-50%);
+}
+
+.middle {
+  position: absolute;
+  top: 50%;
+  transform: translateX(-50%) translateY(-50%);
+}
+
+.ib {
+  display: inline-block;
+  width: 100px;
+  height: 100px;
+}
+
+* {
+  moz-user-select: -moz-none;
+  -moz-user-select: none;
+  -o-user-select: none;
+  -khtml-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
+    "Microsoft YaHei", "微软雅黑", Arial, sans-serif !important;
+}
+
+.pan {
+  background: #fff;
+  border: 1px solid #d7d7d7;
+  border-radius: 4px;
+  box-shadow: 3px 3px 5px 5px #cccccc61;
+}
+
+.vgwf {
+  font-size: 15px !important;
+  font-family: PingFang SC !important;
+  font-weight: 400 !important;
+  color: #939393 !important;
+  line-height: 26px !important;
+}
+
+.scale1 {
+  scale: 1.5;
+  transform-origin: right top;
+}

+ 4 - 0
src/assets/styles/reset-elemenet-plus-style.scss

@@ -0,0 +1,4 @@
+//leave the padding of  el-scroll sidebar
+.el-scrollbar__view {
+  padding-bottom: 80px;
+}

+ 274 - 0
src/assets/styles/scss-suger.scss

@@ -0,0 +1,274 @@
+/*脱落文档流定位*/
+.center-50 {
+  //居中定位
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 10;
+}
+.center-top60 {
+  position: absolute;
+  top: 60%;
+  left: 50%;
+  transform: translate(-50%, -60%);
+  z-index: 10;
+}
+.center-top70 {
+  position: absolute;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, -70%);
+  z-index: 10;
+}
+.center-top80 {
+  position: absolute;
+  top: 80%;
+  left: 50%;
+  transform: translate(-50%, -80%);
+  z-index: 10;
+}
+.center-top90 {
+  position: absolute;
+  top: 80%;
+  left: 50%;
+  transform: translate(-50%, -90%);
+  z-index: 10;
+}
+/*fixed*/
+.fixed-center-50 {
+  //居中定位
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 10;
+}
+.fixed-center-top60 {
+  position: fixed;
+  top: 60%;
+  left: 50%;
+  transform: translate(-50%, -60%);
+  z-index: 10;
+}
+.fixed-center-top70 {
+  position: fixed;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, -70%);
+  z-index: 10;
+}
+.fixed-center-top80 {
+  position: fixed;
+  top: 80%;
+  left: 50%;
+  transform: translate(-50%, -80%);
+  z-index: 10;
+}
+.fixed-center-top90 {
+  position: fixed;
+  top: 90%;
+  left: 50%;
+  transform: translate(-50%, -90%);
+  z-index: 10;
+}
+.fixed-center-top95 {
+  position: fixed;
+  top: 95%;
+  left: 50%;
+  transform: translate(-50%, -95%);
+  z-index: 10;
+}
+
+/*
+flex布局 第一个字母为主轴
+*/
+//start
+.rowSS {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  align-items: flex-start;
+}
+.rowSC {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  align-items: center;
+}
+.rowSE {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  align-items: flex-end;
+}
+//space-between
+.rowBS {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: flex-start;
+}
+.rowBC {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.rowBE {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: flex-end;
+}
+//space-around
+.rowAS {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  align-items: flex-start;
+}
+.rowAC {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  align-items: center;
+}
+.rowAE {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  align-items: flex-end;
+}
+//center
+.rowCS {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: flex-start;
+}
+.rowCC {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+}
+
+.rowCE {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: flex-end;
+}
+
+/*col*/
+//start
+.columnSS {
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: flex-start;
+}
+.columnSC {
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: center;
+}
+.columnSE {
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: flex-end;
+}
+//space-between
+.columnBS {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: flex-start;
+}
+.columnBC {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+}
+.columnBE {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: flex-end;
+}
+//space-around
+.columnAS {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  align-items: flex-start;
+}
+.columnAC {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  align-items: center;
+}
+.columnAE {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  align-items: flex-end;
+}
+//center
+.columnCS {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-start;
+}
+.columnCC {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+.columnCE {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-end;
+}
+
+//*图标
+.star-icon {
+  color: #f56c6c;
+  font-size: 14px;
+  margin-right: 4px;
+}
+
+.fix-btn-to-bottom {
+  position: fixed;
+  bottom: 0;
+  left: 50%;
+  transform: translate(-50%, 0);
+  z-index: 10;
+  height: 60px;
+  background: #fff;
+  width: 100vw;
+}
+
+//table操作栏
+.table-operation-btn {
+  span {
+    //点击样式
+    cursor: pointer;
+    color: #477ef5;
+  }
+}
+
+//table操作栏
+.btn-click-style {
+  //点击样式
+  cursor: pointer;
+  color: #477ef5;
+}

+ 44 - 0
src/assets/styles/transition.scss

@@ -0,0 +1,44 @@
+// vue global transition css define
+/* sidebar-logo-fade */
+.sidebar-logo-fade-enter-active {
+  transition: opacity var(--logo-switch-duration);
+}
+.sidebar-logo-fade-enter-from,
+.sidebar-logo-fade-leave-to {
+  opacity: 0;
+}
+
+/* fade-transform AppMain*/
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all var(--page-transform-duration);
+}
+
+.fade-transform-enter-from {
+  opacity: 0;
+  transform: translateX(-10px);
+}
+
+.fade-transform-leave-to {
+  opacity: 0;
+  transform: translateX(10px);
+}
+.fade-transform-active {
+  position: absolute;
+}
+
+/* breadcrumb transition */
+.breadcrumb-enter-active,
+.breadcrumb-leave-active {
+  transition: all var(--breadcrumb-change-duration);
+}
+
+.breadcrumb-enter-from,
+.breadcrumb-leave-active {
+  opacity: 0;
+  transform: translateX(10px);
+}
+
+.breadcrumb-leave-active {
+  position: absolute;
+}

+ 1 - 0
src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 206 - 0
src/components/mapview/basemap.vue

@@ -0,0 +1,206 @@
+<template>
+  <div
+    id="mapType-wrapper"
+    class=""
+    v-on:mouseover="changeActive($event)"
+    v-on:mouseout="removeActive($event)"
+  >
+    <div id="mapType">
+      <div
+        @click="mapShift('tdtVec', 1)"
+        :class="{
+          mapTypeCard: showClass,
+          normal: showClass,
+          choosedType: showClass,
+          active: 1 == showActive,
+        }"
+      >
+        <span>矢量</span>
+      </div>
+      <div
+        @click="mapShift('tdtImg', 2)"
+        :class="{
+          mapTypeCard: showClass,
+          earth: showClass,
+          active: 2 == showActive,
+        }"
+      >
+        <span>影像</span>
+      </div>
+      <!-- <div
+        @click="mapShift('cesium', 3)"
+        :class="{
+          mapTypeCard: showClass,
+          cesium: showClass,
+          active: 3 == showActive,
+        }"
+      >
+        <span>三维</span>
+      </div>
+      <div
+        @click="mapShift('cityLine', 4)"
+        :class="{
+          mapTypeCard: showClass,
+          cityLine: showClass,
+          active: 4 == showActive,
+        }"
+      >
+        <span>市界</span>
+      </div> -->
+    </div>
+  </div>
+</template>
+<script>
+import "ol/ol.css";
+// import "cesium/Widgets/widgets.css";
+import arcMap from "@/utils/arcMap.js";
+// import olCeMap from "@/utils/olcesium.js";
+import { reactive, toRefs } from "vue";
+export default {
+  props: {
+    option: {
+      type: Object,
+    },
+  },
+  setup(prop) {
+    let mapActive = reactive({
+      showActive: 1,
+      showClass: true,
+      changeActive($event) {
+        $event.currentTarget.className = "expand";
+      },
+      removeActive($event) {
+        $event.currentTarget.className = null;
+      },
+      mapShift(name, index) {
+        mapActive.showActive = index;
+        var iii = arcMap._basemap;
+        if (index == 3) {
+          // if (olCeMap.map) {
+          //   olCeMap.map.setEnabled(true);
+          // } else {
+          //   olCeMap.loadMap(arcMap.map, { base: ["mapDiv"] });
+          //   olCeMap.map.setEnabled(true);
+          //   setTimeout(() => {
+          //     olCeMap.getPosition();
+          //   }, 5000);
+          // }
+        } else {
+          // if (olCeMap.map) {
+          //   olCeMap.map.setEnabled(false);
+          // }
+          var viewAnimate = arcMap.map.getView();
+          viewAnimate.animate({
+            rotation: 0,
+          });
+          for (var i = 0; i < iii.length; i++) {
+            iii[i].setVisible(true);
+            if (
+              iii[i].get("name").indexOf(name) < 0 &&
+              iii[i].get("name") != "jxMap"
+            ) {
+              iii[i].setVisible(false);
+            } else if (iii[i].get("name") == "") {
+              return;
+            }
+          }
+        }
+      },
+    });
+    return { ...toRefs(mapActive) };
+  },
+};
+</script>
+<style lang="less">
+/*切换地图的样式*/
+#mapType-wrapper {
+  position: absolute;
+  bottom: 20px;
+  right: 0px;
+  z-index: 3;
+  cursor: pointer;
+  transition: right 0.4s;
+}
+#mapType .mapTypeCard {
+  position: absolute;
+  padding-left: 15px;
+  height: 55px;
+  width: 70px;
+  border-radius: 5px;
+  box-sizing: border-box;
+  background-image: url("~@/assets/images/shadow_6bf0ecd.png");
+  display: inline-block;
+  transition-property: right, background-image;
+  transition-duration: 0.4s;
+  border: 1px solid rgba(153, 153, 153, 0.42);
+}
+#mapType .mapTypeCard:hover {
+  border: 1px solid #0078d7;
+}
+.mapTypeCard span {
+  position: absolute;
+  font-size: 10px;
+  bottom: 0;
+  right: 0;
+  background: rgba(254, 254, 254, 0.68);
+  padding: 1px 3px;
+  font-family: Arial, Helvetica, SimSun, sans-serif;
+}
+#mapType .mapTypeCard.active span {
+  background: #0078d7;
+  color: #fff;
+}
+.normal {
+  z-index: 4;
+  background-position: 0 0;
+  right: 10px;
+  background-size: 100%;
+}
+.earth {
+  z-index: 3;
+  right: 15px;
+  // background-position: 0 -65px;
+}
+.cesium {
+  z-index: 2;
+  right: 20px;
+  // background-position: 0 -200px;
+}
+.cityLine {
+  z-index: 1;
+  right: 25px;
+  // background-position: 0 -135px;
+}
+.cesium-credit-logoContainer {
+  display: none !important;
+}
+.choosedType {
+  background-image: url("~@/assets/images/maptype.png") !important;
+}
+.expand #mapType .normal {
+  background-image: url("~@/assets/images/m-normal.png");
+  right: 10px;
+}
+.expand #mapType .cesium {
+  background-image: url("~@/assets/images/m-cesium.png");
+  right: 154px;
+}
+.expand #mapType .earth {
+  background-image: url("~@/assets/images/m-earth.png");
+  right: 82px;
+}
+.expand #mapType .cityLine {
+  background-image: url("~@/assets/images/m-cityLine.png");
+  right: 226px;
+}
+.expand {
+  width: 296px;
+}
+#mapType {
+  height: 60px;
+  cursor: pointer;
+  transition-property: width, background-color;
+  transition-duration: 0.4s;
+  background-color: rgba(255, 255, 255, 0);
+}
+</style>

+ 220 - 0
src/components/mapview/fastnav.vue

@@ -0,0 +1,220 @@
+<!--
+ * @Description: 导航
+ * @Author: 王志鹏
+ * @Date: 2023-07-14 10:13:31
+ * @LastEditors: 王志鹏
+ * @LastEditTime: 2023-07-17 15:10:23
+-->
+
+<style lang="less">
+.fastnav {
+  width: 500px;
+  padding: 10px;
+  .el-dropdown-menu__item {
+    color: unset !important;
+    padding: 0px;
+    line-height: unset;
+    display: block;
+    white-space: initial;
+  }
+  .title {
+    border-bottom: 1px solid #dadada;
+    line-height: 25px;
+    font-weight: bold;
+    color: #4c4c4c;
+    padding-bottom: 10px;
+    span {
+      display: inline-block;
+      margin-right: 10px;
+      cursor: pointer;
+    }
+    span:hover {
+      color: #0078d7;
+    }
+  }
+  .el-dropdown-menu__item:hover {
+    background: unset !important;
+    color: unset !important;
+    cursor: unset !important;
+  }
+  .slimScrollDiv {
+    position: relative;
+    overflow: auto;
+    width: auto;
+    height: 300px;
+    .city-province {
+      margin: 4px 0;
+      position: relative;
+      .city-left {
+        float: left;
+        font-weight: 700;
+        line-height: 18px;
+        cursor: pointer;
+      }
+      .city-right {
+        white-space: normal;
+        margin-bottom: 8px;
+        line-height: 18px;
+        span {
+          color: #42a5f5;
+          margin-right: 10px;
+          margin-bottom: 10px;
+          display: inline-block;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+}
+</style>
+<template>
+  <div>
+    <el-dropdown :show-timeout="10" :hide-timeout="100">
+      <div class="top">
+        <el-icon>
+          <promotion />
+        </el-icon>
+        {{ cityTitle }}
+        <el-icon>
+          <arrow-down />
+        </el-icon>
+      </div>
+      <template #dropdown>
+        <el-dropdown-menu class="fastnav">
+          <template v-for="(item, index) in data" :key="index">
+            <el-dropdown-item>
+              <!-- 本市及下辖各个城区旗县title -->
+              <div class="title">
+                <span @click="getFeature(item, 'XZQDS')">{{ item.name }}</span>
+                <!-- <span @click="getFeature(item, 'ZXCQFW')">市中心城区</span> -->
+                <template v-for="(res, i) in item.children" :key="i">
+                  <span @click="getFeature(res, 'XZQXS')" class="">{{
+                    res.name
+                  }}</span>
+                </template>
+              </div>
+
+              <!-- 区县旗及下辖乡镇街道 -->
+              <div class="slimScrollDiv">
+                <div class="city-province">
+                  <div v-for="(iii, s) in item.children" :key="s">
+                    <div class="city-left">{{ iii.name }}:</div>
+                    <div class="city-right">
+                      <span
+                        v-for="(iis, t) in iii.children"
+                        :key="t"
+                        @click="getFeature(iis, 'XZQXZ')"
+                        >{{ iis.name }}</span
+                      >
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </el-dropdown-item>
+          </template>
+        </el-dropdown-menu>
+      </template>
+    </el-dropdown>
+  </div>
+</template>
+
+<script>
+import { reactive, ref, toRefs, watch, onMounted } from "vue";
+import arcMap from "@/utils/arcMap.js";
+// import { GetXzq } from "@/api/homeApi.js";
+import request from '@/utils/requestTwo.js';
+import { Base64 } from 'js-base64';
+import Feature from "ol/Feature";
+import Polygon from "ol/geom/Polygon.js";
+
+export default {
+  props: {
+    hisname: {
+      type: String,
+    },
+  },
+  components: {},
+  setup(prop, context) {
+    const nav = reactive({
+        data: [],
+        cityTitle: "导航",
+        map: "map",
+        xzqLx: ["140000","xzqds","xzqxs"],
+        GeoJson: "",
+        mapJson: "",
+        getFeature(item, type) {
+          nav.cityTitle = item.name;
+          let geom = []
+          item.coordinates[0].map((coordinate)=>{
+            geom.push(coordinate)
+          })
+          let polygon = new Polygon([geom]);
+          var f = new Feature({ geometry: polygon });
+          arcMap.onLocation(f)
+        },
+        LoadMapJson(callback) {
+            request({
+                method: 'get',
+                url: nav.GeoJson
+            }).then(res => {
+                var geojson = JSON.parse(Base64.decode(res));
+                callback(geojson)
+            })
+        },
+    });
+
+
+    onMounted(() => {
+        nav.xzqLx.map((lx)=>{
+          nav.GeoJson = `/js/${lx}.geojson`;
+          if(lx == "140000"){
+            nav.LoadMapJson((geojson) => {
+              nav.mapJson = geojson;
+              geojson.features.map((item)=>{
+                nav.data.push({...item.properties,children:[],...item.geometry})
+              })
+            });
+          }
+          if(lx == "xzqds"){
+            nav.LoadMapJson((geojson) => {
+              nav.mapJson = geojson;
+              geojson.features.map((item)=>{
+                nav.data[0].children.push({...item.properties,children:[],...item.geometry})
+              })
+            });
+          }
+          if(lx == "xzqxs"){
+            nav.LoadMapJson((geojson) => {
+              nav.mapJson = geojson;
+              nav.data[0].children.map((res)=>{
+                geojson.features.map((item)=>{
+                  if(item.properties.xzqdm.toString().substring(0,4) == res.xzqdm.toString().substring(0,4)){
+                    res.children.push({...item.properties,...item.geometry})
+                  }
+                })
+              })
+            });
+          }
+        })
+    //   GetXzq({
+    //     city: true,
+    //   }).then((res) => {
+    //     if (res.success) {
+    //       nav.data = res.data;
+    //     }
+    //   });
+    });
+
+    return { ...toRefs(nav) };
+  },
+};
+</script>
+
+<style scoped>
+.top{
+    cursor:pointer;
+    display: flex;
+    align-content: center;
+    justify-content: center;
+}
+</style>

+ 69 - 0
src/components/mapview/index.js

@@ -0,0 +1,69 @@
+/*
+ * @Author: 牛夏蕊
+ * @Description: 
+ * @Date: 2023-04-01 14:45:02
+ * @LastEditTime: 2023-05-12 09:40:59
+ */
+import analysistabs from './analysistabs'
+import dlmx from './analysistabs/dlmx'
+import fxjg from './analysistabs/fxjg'
+import xzqhfx from './analysistabs/xzqhfx'
+import attrtable from './attrtable'
+import basemap from './basemap'
+import contrastanalysis from './contrastanalysis'
+import range from './range/range'
+import zbRange from './range/zbRange'
+import factorfilter from './factorfilter'
+import fastNav from './fastnav'
+import history from './history'
+import legend from './legend'
+import mousemenu from './mousemenu'
+import queryfilter from './queryfilter'
+import rightLayer from './rightLayer'
+import screencontrast from './screencontrast'
+import screencontrastmap from './screencontrastmap'
+import poisearch from './search/poisearch'
+import tdcontent from './search/tdcontent'
+import tdsearch from './search/tdsearch'
+import xmsearch from './search/xmsearch'
+import yqsearch from './search/yqsearch'
+import slider from './slider'
+import slideretab from './slideretab'
+import slidertrast from './slidertrast'
+import sqlEditor from './sqlEditor'
+import tool from './tool'
+import transparency from './transparency'
+import JJCharts from "./statistic/jingji/charts.vue"
+
+export { 
+    analysistabs,
+    dlmx,
+    fxjg,
+    xzqhfx,
+    attrtable,
+    basemap,
+    contrastanalysis,
+    range,
+    zbRange,
+    factorfilter,
+    fastNav,
+    history,
+    legend,
+    mousemenu,
+    queryfilter,
+    rightLayer,
+    screencontrast,
+    screencontrastmap,
+    poisearch,
+    tdcontent,
+    tdsearch,
+    xmsearch,
+    yqsearch,
+    slider,
+    slideretab,
+    slidertrast,
+    sqlEditor,
+    tool,
+    transparency,
+    JJCharts,
+}

+ 599 - 0
src/components/mapview/range/range.vue

@@ -0,0 +1,599 @@
+<template>
+    <div class="map-range">
+        <div
+            style="
+                display: flex;
+                height: 90px;
+                flex-direction: row;
+                justify-content: space-around;
+                padding-top: 10px;
+            "
+            class="dic_select"
+        >
+            <div class="item" @click="onChangeRange('0')">
+                <div class="icon_div">
+                    <svg
+                        t="1688458030553"
+                        class="icon"
+                        viewBox="0 0 1024 1024"
+                        version="1.1"
+                        xmlns="http://www.w3.org/2000/svg"
+                        p-id="2329"
+                        width="30"
+                        height="30"
+                    >
+                        <path
+                            d="M512 112.6c124.2 0 225.3 110.2 225.3 245.8 0 70.6-89.3 203.6-225.3 338C376 562 286.7 429 286.7 358.4c0-135.5 101.1-245.8 225.3-245.8m0-81.9c-169.7 0-307.2 146.7-307.2 327.7 0 149 208.1 357.9 281.8 427.2 7.3 6.9 16.4 10.3 25.4 10.3 9.1 0 18.2-3.4 25.4-10.3 73.6-69.3 281.8-278.3 281.8-427.2 0-181-137.5-327.7-307.2-327.7z"
+                            p-id="2330"
+                        ></path>
+                        <path
+                            d="M512 471c-67.8 0-122.9-55.1-122.9-122.9S444.2 225.3 512 225.3s122.9 55.1 122.9 122.9S579.8 471 512 471z m0-163.8c-22.6 0-41 18.4-41 41s18.4 41 41 41 41-18.4 41-41-18.4-41-41-41zM901.1 706.6c-22.5 0-41 18.4-41 41v163.8H163.8V747.5c0-22.5-18.4-41-41-41s-41 18.4-41 41v204.8c0 22.5 18.4 41 41 41H901c22.5 0 41-18.4 41-41V747.5c0.1-22.5-18.4-40.9-40.9-40.9z"
+                            p-id="2331"
+                        ></path>
+                    </svg>
+                </div>
+                <div
+                    class="name"
+                    :style="model.fwlx == '0' ? 'color:#409eff' : ''"
+                >
+                    选择行政区
+                </div>
+            </div>
+
+            <div class="item" @click="onChangeRange('4')">
+                <div class="icon_div">
+                    <svg
+                        t="1688459075327"
+                        class="icon"
+                        viewBox="0 0 1024 1024"
+                        version="1.1"
+                        xmlns="http://www.w3.org/2000/svg"
+                        p-id="3367"
+                        width="30"
+                        height="30"
+                    >
+                        <path
+                            d="M410.0096 756.6336l144.7936 144.8448-165.9392 33.1776a10.24 10.24 0 0 1-12.032-12.032l33.1776-165.9904zM896 102.4a25.6 25.6 0 0 1 25.6 25.6V307.2h-102.4V204.8H204.8v614.4h102.4v102.4H128a25.6 25.6 0 0 1-25.6-25.6v-768a25.6 25.6 0 0 1 25.6-25.6h768z m-69.632 274.1248l108.544 108.544a25.6 25.6 0 0 1 0 36.2496l-343.9104 343.9104-144.7936-144.7936 343.9104-343.9104a25.6 25.6 0 0 1 36.2496 0z"
+                            fill="#fff"
+                            p-id="3368"
+                        ></path>
+                    </svg>
+                </div>
+                <div
+                    class="name"
+                    :style="model.fwlx == '4' ? 'color:#409eff' : ''"
+                >
+                    绘制矩形
+                </div>
+            </div>
+
+            <div class="item" @click="onChangeRange('1')">
+                <div class="icon_div">
+                    <svg
+                        t="1688459235941"
+                        class="icon"
+                        viewBox="0 0 1024 1024"
+                        version="1.1"
+                        xmlns="http://www.w3.org/2000/svg"
+                        p-id="6198"
+                        width="30"
+                        height="30"
+                    >
+                        <path
+                            d="M134.393 215.563L577.26 72.293C579.649 31.966 613.109 0 654.035 0c42.478 0 76.912 34.434 76.912 76.912 0 13.09-3.27 25.415-9.037 36.205l211.806 301.234a77.395 77.395 0 0 1 13.372-1.158c42.478 0 76.912 34.434 76.912 76.912s-34.434 76.913-76.912 76.913c-0.924 0-1.844-0.016-2.759-0.049l-208.94 366.664a77.388 77.388 0 0 1 1.172 13.455c0 42.478-34.434 76.912-76.912 76.912-31.791 0-59.077-19.289-70.794-46.8L205.743 882.16c-12.15 8.036-26.716 12.716-42.375 12.716-42.478 0-76.912-34.434-76.912-76.912 0-23.083 10.168-43.79 26.27-57.889L60.867 341.903C26.092 334.523 0 303.642 0 266.667c0-42.478 34.434-76.913 76.912-76.913 22.862 0 43.393 9.975 57.481 25.81zM126.692 325.3l51.743 417.229c35.263 7.002 61.846 38.115 61.846 75.437 0 1.987-0.076 3.956-0.224 5.906l350.117 90.178c12.36-25.942 38.824-43.874 69.475-43.874 10.633 0 20.763 2.158 29.975 6.06l194.741-341.607c-8.935-12.564-14.19-27.93-14.19-44.523 0-13.076 3.263-25.389 9.02-36.171l-211.827-301.26a77.397 77.397 0 0 1-13.333 1.15c-19.457 0-37.225-7.224-50.771-19.137L152.587 280.484c-3.237 17.841-12.628 33.54-25.895 44.815z"
+                            p-id="6199"
+                        ></path>
+                    </svg>
+                </div>
+                <div
+                    class="name"
+                    :style="model.fwlx == '1' ? 'color:#409eff' : ''"
+                >
+                    绘制任意多边形
+                </div>
+            </div>
+
+            <div class="item" @click="onChangeRange('2')">
+                <div class="icon_div">
+                    <svg
+                        t="1688459179642"
+                        class="icon"
+                        viewBox="0 0 1024 1024"
+                        version="1.1"
+                        xmlns="http://www.w3.org/2000/svg"
+                        p-id="4386"
+                        width="30"
+                        height="30"
+                    >
+                        <path
+                            d="M515.072 964.096c0 21.504-17.408 39.424-39.424 39.424H114.176c-21.504 0-39.424-17.92-39.424-39.424V333.824c0-11.264 4.608-21.504 12.288-29.184L382.976 30.72c7.168-6.656 16.896-10.24 26.624-10.24h440.32c21.504 0 39.424 17.92 39.424 39.424v466.944c0 21.504-17.408 39.424-39.424 39.424-21.504 0-39.424-17.92-39.424-39.424V99.328H495.104v343.04c0 21.504-17.408 39.424-39.424 39.424H160.256c-2.048 0-4.608 0-6.656-0.512v442.88h322.048c21.504 0.512 38.912 18.432 39.424 39.936zM160.256 403.456h256V107.52L153.6 350.72v52.736h6.656z m736.768 335.36c20.992 0 38.4-17.408 38.4-38.4s-17.408-38.4-38.4-38.4h-248.832c-20.992 0-38.4 17.408-38.4 38.4v249.344c-1.024 20.992 15.872 38.912 36.864 39.936 20.992 1.024 38.912-15.872 39.936-36.864V793.6l196.608 197.12c14.848 14.848 39.424 14.848 54.272 0s14.848-39.424 0-54.272l-197.12-197.12 156.672-0.512z"
+                            fill=""
+                            p-id="4387"
+                        ></path>
+                    </svg>
+                </div>
+                <div
+                    class="name"
+                    :style="model.fwlx == '2' ? 'color:#409eff' : ''"
+                >
+                    导入文件
+                </div>
+            </div>
+        </div>
+        <div style="height: 40px; width: 100%; margin: 10px 0">
+            <div
+                v-if="model.fwlx == 0"
+                style="
+                    width: 90%;
+                    height: 100%;
+                    display: flex;
+                    align-item: center;
+                    padding-left: 15px;
+                "
+            >
+                <div
+                    class="text-left box-sizing padding-right-5 nowrap"
+                    style="color: rgb(96, 98, 102); width: 100px"
+                >
+                    行政区划:
+                </div>
+                <el-cascader
+                    :options="xzq.options"
+                    :props="xzq.props"
+                    v-model="xzq.xzqbh"
+                    clearable
+                    ref="cascader"
+                    class="cascader-style"
+                    popper-class="popper-cascader"
+                    :filterable="true"
+                    style="width: calc(100% - 40px)"
+                    @change="setXzqdm"
+                    :show-all-levels="false"
+                ></el-cascader>
+                <!-- :props="{ ...xzq.props, expandTrigger: 'hover' }" -->
+            </div>
+            <div
+                v-if="model.fwlx == 1 || model.fwlx == 4"
+                class="max-height flex-box align-center padding-left-15 posi-rel"
+                style="
+                    width: 90%;
+                    height: 100%;
+                    display: flex;
+                    align-item: center;
+                    padding-left: 15px;
+                    position: relative;
+                "
+            >
+                <div
+                    class="text-left box-sizing padding-right-5 nowrap"
+                    style="color: rgb(96, 98, 102)"
+                >
+                    绘制范围:
+                </div>
+
+                <div
+                    class="flex-box align-center"
+                    :class="model.xzmj == 0 ? 'pointer' : ''"
+                    @click="drawMap"
+                    style="margin: 0 15px"
+                >
+                    <el-button plain v-if="model.xzmj == 0" icon="edit-pen"
+                        >绘制范围</el-button
+                    >
+                    <span v-if="model.xzmj != 0">{{ model.xzmj }} m²</span>
+                </div>
+                <div
+                    class="posi-abs pointer"
+                    style="right: 0; color: #409eff"
+                    @click="clearAll"
+                >
+                    清除
+                </div>
+            </div>
+            <div
+                v-if="model.fwlx == 2"
+                style="
+                    width: 90%;
+                    overflow: hidden;
+                    height: 100%;
+                    display: flex;
+                    align-item: center;
+                    padding-left: 15px;
+                "
+            >
+                <div
+                    class="text-left box-sizing padding-right-5 nowrap"
+                    style="color: rgb(96, 98, 102)"
+                >
+                    文件名称:
+                </div>
+                <el-upload
+                    class="upload-demo"
+                    style="max-width: calc(100% - 40px); margin-left: 15px"
+                    :on-change="handleChange"
+                    :auto-upload="false"
+                    :show-file-list="false"
+                    :file-list="fileList"
+                >
+                    <el-tooltip
+                        v-if="fileList.length > 0"
+                        :content="fileList[0].name"
+                        placement="bottom-start"
+                        effect="light"
+                    >
+                        <span
+                            class="title-item"
+                            style="display: inline-block; width: 100%"
+                            >{{ fileList[0].name }}</span
+                        >
+                    </el-tooltip>
+                    <el-button v-else class="upload-btn" icon="Upload"
+                        >上传文件</el-button
+                    >
+                </el-upload>
+            </div>
+            <div
+                v-if="model.fwlx == 3"
+                style="
+                    width: 90%;
+                    overflow: hidden;
+                    height: 100%;
+                    display: flex;
+                    align-item: center;
+                    padding-left: 15px;
+                "
+            >
+                <div
+                    class="text-left box-sizing padding-right-5 nowrap"
+                    style="color: rgb(96, 98, 102)"
+                >
+                    坐标:
+                </div>
+                <el-button type="text" @click="zbdVisible = true"
+                    ><span v-if="formZbd.zbds">修改坐标信息</span
+                    ><span v-else>点击输入坐标信息</span></el-button
+                >
+            </div>
+        </div>
+        <!-- <zbRange
+      v-model:visible="zbdVisible"
+      v-if="zbdVisible"
+      v-model:formZbd="formZbd"
+      @zbJson="zbJson"
+    /> -->
+    </div>
+</template>
+
+<script>
+import OLTool from "@/utils/olTool.js";
+import GeoJSON from "ol/format/GeoJSON";
+// import { GetXzq } from "@/api/homeApi.js";
+// import { ShapeUpload } from "@/api/ghss/fzxz.js";
+import { reactive, toRefs, ref } from "@vue/reactivity";
+import { getCurrentInstance, onMounted, watch } from "@vue/runtime-core";
+import arcMap from "@/utils/arcMap.js";
+// import zbRange from "./zbRange.vue";
+// import { useStore } from "vuex";
+import { ElMessage } from "element-plus";
+import Draw, { createBox } from "ol/interaction/Draw";
+
+export default {
+    components: {
+        // zbRange,
+    },
+    props: {
+        //启用的组件,不传为所有
+        keys: {
+            type: Array,
+            default: ["hzjx", "xzq", "hx", "sc"],
+        },
+        activeTabs: {
+            type: String,
+        },
+    },
+    setup(prop, context) {
+        // const store = useStore();
+        const { proxy } = getCurrentInstance();
+        const range = reactive({
+            fwlist: {
+                xzq: {
+                    id: 0,
+                    name: "行政区",
+                    icon: "wind-power",
+                },
+                hx: {
+                    id: 1,
+                    name: "绘制",
+                    icon: "Share",
+                },
+                sc: {
+                    id: 2,
+                    name: "上传",
+                    icon: "Upload-filled",
+                },
+                zbd: {
+                    id: 3,
+                    name: "坐标点",
+                    icon: "Location",
+                },
+                hzjx: {
+                    id: 4,
+                    name: "绘制矩形",
+                    icon: "Location",
+                },
+            },
+            model: {
+                fwlx: 0,
+                xzfw: "",
+                xzmj: 0,
+                feature: null,
+            },
+
+            xzq: {
+                //行政区
+                props: {
+                    multiple: false,
+                    emitPath: false,
+                    checkStrictly: true,
+                },
+                options: [],
+                xzqbh: "",
+                xzqmc: "",
+            },
+            cascader: ref(null),
+
+            draw: null, //绘制
+
+            fileList: [], //文件
+
+            formZbd: {
+                //坐标点
+                zbx: "3857",
+                zbds: "",
+            },
+            zbdVisible: false,
+
+            //切换
+            onChangeRange(fwlx) {
+                range.clearAll();
+                range.model.fwlx = fwlx;
+            },
+            // 获取行政区
+            getXzq() {
+                // GetXzq({ city: true }).then((res) => {
+                //   if (res.success) {
+                //     range.xzq.options = proxy.$comfun.resetTree(res.data);
+                //   }
+                // });
+            },
+            // 行政区地图
+            setXzqdm(bsm) {
+                range.xzq.xzqmc = bsm
+                    ? range.cascader.getCheckedNodes()[0].label
+                    : "";
+                range.model.xzfw = bsm;
+                var layer = range.getLayer("common_layer");
+                layer.getSource().clear();
+                if (bsm) {
+                    var type = "";
+                    if (bsm.length === 4) {
+                        type = "XZQDS";
+                    } else if (bsm.length === 6) {
+                        type = "XZQXS";
+                    } else {
+                        type = "XZQXZ";
+                    }
+                    var url = `${SYS_LAYERS[type]}/0/query`;
+                    arcMap.SearchWfsFilter(
+                        url,
+                        `XZQDM='${bsm}'`,
+                        function (data) {
+                            range.model.xzmj = data[0].get("JSMJ");
+                            range.model.feature = data[0];
+                            layer.getSource().addFeatures(data);
+                            arcMap.zoomToextent(
+                                data[0].getGeometry().getExtent()
+                            );
+                        }
+                    );
+                    // proxy.$refs.cascader.dropDownVisible = false
+                }
+            },
+            //上传文件
+            handleChange(file, fileList) {
+                if (fileList.length > 0) {
+                    prop.fileList = [fileList[fileList.length - 1]]; //这一步,是 展示最后一次选择文件
+                    range.clearAll();
+                }
+                const formdata = new FormData();
+                formdata.append("file", file.raw);
+                // ShapeUpload(formdata).then((res) => {
+                //   if (res.success) {
+                //     var layer = arcMap.addGeoJson("common_layer", res.data.geojson);
+                //     model.xzfw = res.data.filepath;
+                //     range.model.feature = layer.getSource().getFeatures()[0];
+                //     range.model.xzmj = new OLTool().Tools.formatArea(
+                //         range.model.feature.getGeometry(),true);
+                //     arcMap.zoomToextent(layer.getSource().getExtent());
+                //   }
+                // });
+            },
+            //绘制
+            drawMap() {
+                if (range.model.xzmj == 0) {
+                    var tool = new OLTool();
+                    if (range.model.fwlx == 4) {
+                        var geometryFunction = createBox();
+                        var draw = new Draw({
+                            source: arcMap.tempLayers.dview_draw_Layer.getSource(),
+                            type: "Circle",
+                            geometryFunction: geometryFunction,
+                            stopClick: "doubleclick",
+                        });
+                        arcMap.map.addInteraction(draw);
+                        draw.on("drawend", function (e) {
+                            arcMap.map.removeInteraction(draw);
+                             var geom = e.feature.getGeometry();
+                            range.model.feature = e.feature;
+                            range.model.xzfw = arcMap.featureToGeojson(
+                                e.feature
+                            );
+                            range.model.xzmj = tool.Tools.formatArea(
+                                geom,
+                                true
+                            );
+                        });
+                    } else {
+                        var draw = tool.Draws();
+                        range.draw = draw;
+                        range.clearAll();
+                        draw.SetType("Polygon");
+                        draw.Start();
+                        draw.on("drawend", function (e) {
+                            e.stopPropagation();
+                            draw.End();
+                            var geom = e.feature.getGeometry();
+                            range.model.feature = e.feature;
+                            range.model.xzfw = arcMap.featureToGeojson(
+                                e.feature
+                            );
+                            range.model.xzmj = tool.Tools.formatArea(
+                                geom,
+                                true
+                            );
+                        });
+                    }
+                }
+            },
+            // 加载geojson数据
+            getLayer: function (name, json) {
+                let layer = arcMap.getLayer(name);
+                if (layer) {
+                    layer.getSource().clear();
+                } else {
+                    arcMap.addLayer(arcMap.CreateVecLayer(name));
+                    layer = arcMap.getLayer(name);
+                }
+                if (json) {
+                    var features = new GeoJSON().readFeatures(json, {
+                        defaultDataProjection: "EPSG:4326",
+                        featureProjection: "EPSG:3857",
+                    });
+                    layer.getSource().addFeatures(features);
+                }
+                return layer;
+            },
+            //坐标JSON
+            zbJson: function (json) {
+                range.zbdVisible = false;
+                var layer = arcMap.addGeoJson("common_layer", json);
+                arcMap.zoomToextent(layer.getSource().getExtent());
+                range.model.feature = arcMap.geojsonFeatures(json)[0];
+                range.model.xzfw = arcMap.featureToGeojson(range.model.feature);
+                range.model.xzmj = new OLTool().Tools.formatArea(geom, true);
+            },
+            //清除
+            clearAll() {
+                range.model.xzfw = "";
+                range.model.xzmj = 0;
+
+                arcMap.tempLayers.dview_draw_Layer.getSource().clear();
+                var dom = document.getElementsByClassName("tooltip");
+                var list = Array.from(dom);
+                list.forEach((current, index) => {
+                    current.remove();
+                });
+                arcMap.tempLayers.clear();
+                if (arcMap.getLayer("common_layer")) {
+                    arcMap.getLayer("common_layer").getSource().clear();
+                }
+                if (arcMap.getLayer("fzxz_layer")) {
+                    arcMap.getLayer("fzxz_layer").getSource().clear();
+                }
+            },
+            //输出:重置
+            reset() {
+                (range.model = {
+                    fwlx: range.fwlist[prop.keys[0]].id,
+                    XZFW: "",
+                    xzmj: 0,
+                }),
+                    (range.xzq.xzqbh = ""),
+                    (range.fileList = []), //文件
+                    (range.formZbd = {
+                        //坐标点
+                        zbx: "3857",
+                        zbds: "",
+                    }),
+                    range.clearAll();
+            },
+            //输出:获取范围
+            getRange() {
+                return range.model;
+            },
+        });
+        onMounted(() => {
+            range.model.fwlx = range.fwlist[prop.keys[0]].id;
+            range.getXzq();
+        });
+        watch(
+            () => prop.activeTabs,
+            (newValue, oldValue) => {
+                range.getXzq();
+            }
+        );
+        return { ...toRefs(range) };
+    },
+};
+</script>
+
+<style lang="less" scoped>
+.map-range {
+    .xz_type {
+        margin-bottom: 10px;
+        justify-content: space-evenly;
+        div {
+            i {
+                font-size: 36px;
+            }
+        }
+    }
+}
+.dic_select {
+    .item {
+        width: 90px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        cursor: pointer;
+
+        .icon_div {
+            height: 50px;
+            width: 50px;
+            border-radius: 50px;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            background: linear-gradient(325deg, #7ab7f9, #0078ff, transparent);
+            .icon {
+                width: 50px;
+                fill: currentColor;
+                color: #fff;
+            }
+        }
+        .name {
+            color: #333;
+            text-align: center;
+            width: 150%;
+        }
+    }
+}
+.flex-box {
+    display: flex;
+    align-content: center;
+}
+.pointer {
+    cursor: pointer;
+}
+</style>

+ 87 - 0
src/components/mapview/transparency.vue

@@ -0,0 +1,87 @@
+<template>
+  <!-- 透明度123 -->
+  <div class="block">
+    <span class="demonstration text-ztblue">透明度</span>
+    <el-icon style="float: right; cursor: pointer" @click="closeTran"
+      ><close
+    /></el-icon>
+    <div class="flex-box align-center">
+      <span class="demonstration" style="width: 88px">不透明度</span>
+      <el-slider
+        v-model="value1"
+        style="width: 170px"
+        @change="changeTransp()"
+      ></el-slider>
+      <span style="width: 30px; margin-left: 20px" class="">{{ value1 }}%</span>
+    </div>
+  </div>
+</template>
+
+<script>
+import { reactive, toRefs, toRaw, watch } from "vue";
+import { useStore } from "vuex";
+import myMap from "@/utils/map.js";
+export default {
+  props: {
+    db: {
+      type: Boolean,
+      default: false,
+    },
+    tran: {
+      type: Boolean,
+    },
+  },
+  setup(prop, content) {
+    const store = useStore();
+    const transparencyLayer = reactive({
+      layer: store.state.zyll.transparency,
+    });
+    const transparency = reactive({
+      value1: 100,
+      changeTransp() {
+        if (!prop.db) {
+          var layer = myMap.getLayer(toRaw(transparencyLayer.layer.url));
+          layer.setOpacity(transparency.value1 / 100);
+        } else {
+          var layer1 = myMap.getLayerByNameAndMap("analysisLayer", "map1");
+          var layer2 = myMap.getLayerByNameAndMap("analysisLayer", "map2");
+          layer1.setOpacity(transparency.value1 / 100);
+          layer2.setOpacity(transparency.value1 / 100);
+        }
+      },
+      closeTran() {
+        store.state.zyll.transparency.sign = false;
+        content.emit("update:tran", false);
+      },
+    });
+    watch(
+      () => store.state.zyll.transparency,
+      (layers, prevCount) => {
+        if (!prop.db) {
+          var layer = myMap.getLayer(toRaw(layers.url));
+          var value = layer.getOpacity();
+          transparencyLayer.layer = layers;
+          transparency.value1 = 100;
+          transparency.changeTransp();
+        }
+      }
+    );
+    return { ...toRefs(transparency) };
+  },
+};
+</script>
+
+<style scoped>
+.block {
+  position: absolute;
+  height: 60px;
+  left: 50%;
+  top: 10px;
+  z-index: 20;
+  background-color: #fff;
+  padding: 10px 20px 10px 5px;
+  transform: translate(-50%, 0);
+  border-radius: 4px;
+  text-align: center;
+}
+</style>

+ 255 - 0
src/components/mapview/vectorTileAttrtable.vue

@@ -0,0 +1,255 @@
+<!--
+ * @Descripttion: 矢量切片数据空间、属性查询结果
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2023-05-25 16:35:06
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2023-07-07 16:51:11
+-->
+<template>
+    <div
+        class="attrtable flex-box column posi-rel"
+    >
+        <el-table
+            :data="tableData"
+            border
+            @row-click="zoomFeature"
+            style="width: 100%;"
+            :height="tableHeight"
+            ref="table"
+        >
+            <el-table-column
+                v-for="item in tableHead"
+                :prop="item"
+                :label="item"
+                :key="item"
+                align="center"
+                :show-overflow-tooltip="true"
+            >
+            </el-table-column>
+        </el-table>
+        <div style="display: flex; height: 50px;justify-content: center">
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 50, 100]"
+                :page-size="limit"
+                :pager-count="2"
+                layout="total, sizes, prev, pager, next"
+                :total="total"
+            >
+            </el-pagination>
+        </div>
+        <!-- <div
+            class="posi-abs fixedbtn flex-box align-center justify-center pointer"
+            @click="setshow"
+            style="
+                background-color: #f8f8f8;
+                border: 1px solid #f2f2f2;
+                left: 2px;
+            "
+        >
+            属性表<span
+                class="iconfont icon-026cheng"
+                style="margin-left: 8px"
+                @click="close"
+            ></span>
+        </div> -->
+    </div>
+</template>
+
+<script>
+import { reactive, toRefs, watch, onMounted, nextTick } from "vue";
+import { getCurrentInstance } from "@vue/runtime-core";
+// import { useStore } from "vuex";
+import arcMap from "@/utils/arcMap.js";
+import Feature from "ol/Feature";
+import { filter } from "@/api/gdal/index.js";
+import Polygon from "ol/geom/Polygon.js";
+import { fromLonLat } from "ol/proj";
+import { addProjectionTransform } from "@/utils/CoordTransformate";
+export default {
+    props: {
+        queryParam:{
+            type:Object
+        }
+    },
+    setup(prop) {
+        const { proxy } = getCurrentInstance();
+        // const store = useStore();
+        onMounted(() => {
+            attrtable.initData();
+        });
+        watch(
+            () => prop.queryParam,
+            (newvalue, oldvalue) => {
+                if (!prop.queryParam) {
+                    return
+                }
+                attrtable.page = 1;
+                attrtable.limit = 20;
+                attrtable.initData();
+            },
+            {
+                deep: true,
+            }
+        );
+        const attrtable = reactive({
+            page: 1,
+            limit: 20,
+            total: 0,
+            tableHeight:'calc(100vh - 280px)',
+            is_show: false,
+            tableData: [],
+            tableHead: [],
+            geoInfo: {},
+            initData() {
+                let params = prop.queryParam;
+                filter({
+                    ...params,
+                    PAGE: attrtable.page,
+                    LIMIT: attrtable.limit,
+                })
+                    .then((res) => {
+                        if (res.code === 200) {
+                            attrtable.tableHead = [];
+                            attrtable.tableData = [];
+                            attrtable.total = res.count;
+                            if (res.data && res.data.length > 0) {
+                                attrtable.tableHead = Object.keys(
+                                    res.data[0].attributes
+                                );
+                            }
+                            let inSR = 'EPSG:' + res.epsg; //epsg:4529
+                            let outSR = "EPSG:3857";
+                            arcMap.tempLayers.dview_fliter_Layer.getSource().clear();
+                            res.data.map((item) => {
+                                attrtable.tableData.push(item.attributes);
+                                addProjectionTransform(item.geometry.rings, inSR, outSR, false, true, function (e) {
+                                    let coordsinfo = e.result;
+                                    attrtable.geoInfo[item.attributes.FID] = coordsinfo;
+                                    let geom = new Polygon(coordsinfo);
+                                    var f = new Feature({ geometry: geom });
+                                    arcMap.tempLayers.dview_fliter_Layer.getSource().addFeature(f);
+                                });
+                            });
+                        } else {
+                            attrtable.tableHead = [];
+                            attrtable.tableData = [];
+                        }
+                    })
+                    .finally(() => {
+                        proxy.$modal.closeLoading();
+                    });
+            },
+            // 单击表格行进行图斑定位
+            zoomFeature(item) {
+                let coordsinfo = attrtable.geoInfo[item.FID];
+                let geom = new Polygon(coordsinfo);
+                arcMap.zoomToextent(geom.getExtent());
+                var f = new Feature({ geometry: geom });
+                arcMap.onLocation(f);
+            },
+            handleSizeChange(val) {
+                attrtable.limit = val;
+                attrtable.page = 1;
+                attrtable.initData();
+            },
+            handleCurrentChange(val) {
+                attrtable.page = val;
+                attrtable.initData();
+            },
+        });
+        return { ...toRefs(attrtable) };
+    },
+};
+</script>
+
+<style lang="less">
+.attrtable {
+    max-width: calc(100% - 2px);
+    background-color: #fff;
+    padding-bottom: 5px;
+}
+.attrtable {
+    .el-table__body {
+        width: 100% !important;
+    }
+}
+.attrtable .el-table__body-wrapper .el-table__body td span {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+.attrtable .el-table th {
+    background: #f3f3f3;
+}
+.attrtable-show {
+    margin-bottom: -335px;
+    animation: show 0.5s 1;
+}
+@keyframes show {
+    from {
+        margin-bottom: 0px;
+    }
+    to {
+        margin-bottom: -335px;
+    }
+}
+.fixedbtn {
+    top: -30px;
+    left: 55px;
+    width: 100px;
+    height: 28px;
+    background-color: #fff;
+    z-index: 3;
+    border-top-right-radius: 4px;
+    border-bottom-right-radius: 4px;
+}
+:deep(.el-tabs--card > .el-tabs__header) {
+    background-color: rgba(242, 242, 242, 1);
+    border: none;
+}
+:deep(.el-tabs--card > .el-tabs__header .el-tabs__item.is-active) {
+    border: none;
+    background-color: #fff;
+}
+:deep(.el-tabs__item) {
+    border: none;
+}
+:deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) {
+    border: none;
+}
+:deep(.el-tabs--card > .el-tabs__header .el-tabs__item) {
+    border: none;
+}
+:deep(.el-table th, .el-table tr) {
+    background-color: rgba(242, 242, 242, 1);
+}
+::-webkit-scrollbar {
+    width: 5px;
+    height: 5px;
+}
+
+::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    background-color: #c6def5;
+    background-image: -webkit-linear-gradient(
+        45deg,
+        rgba(255, 255, 255, 0.2) 25%,
+        transparent 25%,
+        transparent 50%,
+        rgba(255, 255, 255, 0.2) 50%,
+        rgba(255, 255, 255, 0.2) 75%,
+        transparent 75%,
+        transparent
+    );
+}
+
+::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+    background: #ededed;
+}
+</style>

+ 719 - 0
src/components/mapview/vectorTileTool.vue

@@ -0,0 +1,719 @@
+<!--
+ * @Descripttion: 用于矢量切片数据的工具条
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2023-05-25 09:38:25
+ * @LastEditors: 王志鹏
+ * @LastEditTime: 2023-07-14 10:37:15
+-->
+<template>
+    <div class="tool flex-box tool-right max-height">
+        <!-- 导航 -->
+        <fastNav class="nav" />
+        <el-divider direction="vertical"></el-divider>
+        <div class="pointer" @click="imageQuery">
+            <span
+                class="iconfont icon-016fangdajing"
+                style="margin-right: 5px"
+            ></span
+            >影像查询
+        </div>
+        <el-divider direction="vertical"></el-divider>
+        <div class="pointer" @click="gdbQuery">
+            <span
+                class="iconfont icon-016fangdajing"
+                style="margin-right: 5px"
+            ></span
+            >专题数据查询
+        </div>
+        <el-divider direction="vertical"></el-divider>
+         <div class="pointer">
+            <span
+                class="iconfont icon-016fangdajing"
+                style="margin-right: 5px"
+            ></span
+            >影像追溯
+        </div>
+        <el-divider direction="vertical"></el-divider>
+
+        <el-dropdown :show-timeout="10" :hide-timeout="100">
+            <div class="pointer cooperation">
+                <i class="iconfont icon-022gongju"></i>
+                工具箱
+                <el-icon>
+                    <arrow-down />
+                </el-icon>
+            </div>
+            <template #dropdown>
+                <el-dropdown-menu>
+                    <el-dropdown-item
+                        v-for="item in typeList"
+                        :key="item.type"
+                        @click="drawMap(item.type)"
+                    >
+                        <i :class="'iconfont ' + item.icon"></i>
+                        {{ item.title }}
+                    </el-dropdown-item>
+                </el-dropdown-menu>
+            </template>
+        </el-dropdown>
+        <!-- 属性查询 -->
+        <el-dialog :close-on-click-modal="false" 
+            title="属性查询"
+            width="30%"
+            v-model="dialogVisibleAttrQuery"
+            @closed="closeDialogAttrQueryVisible"
+        >
+            <el-form
+                label-position="right"
+                label-width="100px"
+                ref="attrFormRef"
+                :model="attrForm"
+                :rules="rules"
+            >
+                <el-form-item label="资源图层" prop="selectLayer">
+                    <el-select
+                        v-model="attrForm.selectLayer"
+                        placeholder="请选择"
+                        style="width: 100%"
+                        @change="changeLayer()"
+                    >
+                        <el-option
+                            v-for="(item, index) in options"
+                            :key="index"
+                            :label="item.name"
+                            :value="item.bsm"
+                        >
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="选择属性:" prop="selectField">
+                    <el-select
+                        v-model="attrForm.selectField"
+                        placeholder="请选择"
+                        style="width: 100%"
+                        filterable
+                    >
+                        <el-option
+                            label="全部"
+                            value="all"
+                            selected
+                        ></el-option>
+                        <el-option
+                            v-for="item in selectFieldData"
+                            :key="item"
+                            :label="item"
+                            :value="item"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="属性值:" prop="value">
+                    <el-input
+                        v-model="attrForm.value"
+                        placeholder="多属性值查询请用(,)分隔"
+                        style="width: 100%"
+                    ></el-input>
+                </el-form-item>
+                <el-form-item label="关系:" prop="selectOperate">
+                    <el-select
+                        v-model="attrForm.selectOperate"
+                        placeholder="请选择"
+                        style="width: 100%"
+                    >
+                        <el-option label="包含" value="contains"></el-option>
+                        <el-option label="等于" value="equals"></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <div class="dialog-footer" style="text-align: right">
+                <el-button @click="closeDialogAttrQueryVisible"
+                    >取 消</el-button
+                >
+                <el-button type="primary" @click="confirmAttrQuery()"
+                    >确 定</el-button
+                >
+            </div>
+        </el-dialog>
+        <!-- 标绘文本 -->
+        <el-dialog :close-on-click-modal="false" 
+            title="请先输入文本,并确认"
+            width="30%"
+            v-model="dialogText"
+        >
+            <el-input v-model="searchKey.text"></el-input>
+            <div
+                class="dialog-footer"
+                style="text-align: right; margin-top: 10px"
+            >
+                <el-button @click="dialogText = false">取 消</el-button>
+                <el-button type="primary" @click="drawMap('textOk')"
+                    >确 定</el-button
+                >
+            </div>
+        </el-dialog>
+        <!-- 经纬度定位 -->
+        <el-dialog :close-on-click-modal="false"  title="经纬度定位" width="30%" v-model="dialogCommon">
+            <el-form
+                label-position="right"
+                label-width="100px"
+                :model="searchKey"
+            >
+                <el-form-item label="经度">
+                    <el-input v-model="searchKey.lon"></el-input>
+                </el-form-item>
+                <el-form-item label="纬度">
+                    <el-input v-model="searchKey.lat"></el-input>
+                </el-form-item>
+            </el-form>
+            <div class="dialog-footer" style="text-align: right">
+                <el-button @click="dialogCommon = false">取 消</el-button>
+                <el-button type="primary" @click="drawMap('commonOk')"
+                    >确 定</el-button
+                >
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import arcMap from "@/utils/arcMap.js";
+import OLTool from "@/utils/olTool.js";
+import { reactive, toRefs, toRaw, watch, ref, onMounted } from "vue";
+import { Fill, Stroke, Circle, Style } from "ol/style";
+import Text from "ol/style/Text";
+import { ElMessage } from "element-plus";
+import Draw, { createBox } from "ol/interaction/Draw";
+import { fromLonLat, get, transform } from "ol/proj";
+import fastNav from "@/components/mapview/fastnav.vue";
+import { getFields, getUniqueValue } from "@/api/gdal/index.js";
+import GeoJSON from "ol/format/GeoJSON";
+import Feature from "ol/Feature";
+import {
+    LineString,
+    MultiLineString,
+    MultiPoint,
+    MultiPolygon,
+    Point,
+    Polygon,
+    LinearRing,
+} from "ol/geom";
+export default {
+    props:{
+        showType:{
+            type: String,
+        }
+    },
+    components: {
+        fastNav,
+    },
+    setup(prop, context) {
+        // const { proxy } = getCurrentInstance();
+        // const store = useStore();
+        const parent = { ...context };
+        const childSearch = ref(null);
+        var Arcgis = arcMap;
+        const validateAttributeVal = (rule, value, callback) => {
+            if (searchData.attrForm.selectField != "all" && value === "") {
+                callback(new Error("请输入值后再查询"));
+            } else {
+                callback();
+            }
+        };
+        let searchData = reactive({
+            attrFormRef: ref(null), // 属性查询表单REF
+            selectFieldData: [], // 属性查询-属性字段
+            attrForm: {
+                selectLayer: "",
+                selectField: "all",
+                selectOperate: "contains",
+                value: "",
+            }, // 属性查询-表单
+            dialogVisibleAttrQuery: false, // 属性查询弹窗显隐
+            searchKey: {
+                type: "",
+                inputKm: 0,
+                address: "",
+                isShowKm: false,
+                drawType: null,
+                text: "",
+                lon: "",
+                lat: "",
+                value: "",
+            },
+            upload: {
+                type: "WMTS",
+                form: "Arcgis",
+                url: null,
+                name: null,
+            },
+            feature: {},
+            dialogVisible: false,
+            dialogText: false,
+            dialogVisibleAdd: false,
+            dialogVisibleUpload: false,
+            dialogSearch: "",
+            fileList: [],
+            dialogCommon: false,
+            options: [],
+            typeList: [
+                {
+                    type: "MeasureArea",
+                    title: "测面积",
+                    icon: "icon-cemianji",
+                },
+                {
+                    type: "MeasureLength",
+                    title: "测距离",
+                    icon: "icon-juli",
+                },
+                {
+                    type: "DrawPoint",
+                    title: "绘制点",
+                    icon: "icon-dian",
+                },
+                {
+                    type: "DrawLine",
+                    title: "绘制线",
+                    icon: "icon-xuanxianjuli",
+                },
+                {
+                    type: "DrawPolygon",
+                    title: "绘制面",
+                    icon: "icon-xuanmianmianji",
+                },
+                {
+                    type: "text",
+                    title: "标绘文本",
+                    icon: "icon-wenben",
+                },
+                {
+                    type: "ClearAll",
+                    title: "清除",
+                    icon: "icon-026cheng",
+                },
+            ],
+            rules: {
+                selectLayer: [
+                    {
+                        required: true,
+                        message: "请先开启或选择图层!",
+                        trigger: "change",
+                    },
+                ],
+                selectField: [
+                    {
+                        required: true,
+                        message: "请选择值!",
+                        trigger: "change",
+                    },
+                ],
+                selectOperate: [
+                    {
+                        required: true,
+                        message: "请选择值!",
+                        trigger: "change",
+                    },
+                ],
+                value: [{ validator: validateAttributeVal, trigger: "blur" }],
+            },
+            drawMap(type) {
+                var tool = new OLTool();
+                var draw = tool.Draws();
+                var measure = tool.Meatures("Length");
+                switch (type) {
+                    case "MeasureArea":
+                        measure.SetType("Area");
+                        measure.Start();
+                        break;
+                    case "MeasureLength":
+                        draw.End();
+                        measure.SetType("Length");
+                        measure.Start();
+                        break;
+                    case "DrawPoint":
+                        draw.SetType("Point");
+                        draw.Start();
+                        draw.on("drawend", function (e) {
+                            draw.End();
+                        });
+                        break;
+                    case "MeasureGc":
+                        draw.SetType("Point");
+                        draw.ClearAll();
+                        arcMap.map.removeOverlay(arcMap.getPopupOverlay());
+                        draw.Start();
+                        draw.on("drawend", function (e) {
+                            arcMap.SearchWfsData(
+                                SYS_LAYERS.DEM,
+                                e.feature.getGeometry(),
+                                function (fs) {
+                                    if (!fs.length) {
+                                        ElMessage.error(
+                                            "未查询到高程结果,请确认当前位置!"
+                                        );
+                                        return false;
+                                    }
+                                    var html = `<div id='popup_temp'><h3 ><strong>高程</strong><el-icon class='pointer popupinfo-close' id='closePop'><close /></el-icon>
+                  </h3><div class='popupinfo'><li><span>${
+                      fs[0].get("GRIDCODE") + "米"
+                  }</span></li>`;
+                                    arcMap.popupInfo(
+                                        {
+                                            feature: e.feature,
+                                        },
+                                        html
+                                    );
+                                    arcMap.map.updateSize();
+                                }
+                            );
+                            draw.End();
+                        });
+                        break;
+                    case "DrawLine":
+                        draw.SetType("LineString");
+                        draw.Start();
+                        draw.on("drawend", function (e) {
+                            draw.End();
+                            e.stopPropagation();
+                        });
+                        break;
+                    case "DrawPolygon":
+                        draw.SetType("Polygon");
+                        draw.Start();
+                        draw.on("drawend", function (e) {
+                            draw.End();
+                            e.stopPropagation();
+                        });
+                        break;
+                    case "full":
+                        var view = arcMap.map.getView();
+                        view.animate({
+                            center: fromLonLat([109.78, 39.6]),
+                            zoom: 12,
+                            duration: 1000,
+                        });
+                        break;
+                    case "ClearAll":
+                        draw.ClearAll();
+                        var dom = document.getElementsByClassName("tooltip");
+                        var list = Array.from(dom);
+                        list.forEach((current, index) => {
+                            current.remove();
+                        });
+                        arcMap.tempLayers.clear();
+                        if (arcMap.getLayer("common_layer")) {
+                            console.log("common_layer");
+                            arcMap.getLayer("common_layer").getSource().clear();
+                        }
+                        if (arcMap.getLayer("zoom_layer")) {
+                            arcMap.getLayer("zoom_layer").getSource().clear();
+                        }
+                        arcMap.map.removeOverlay(arcMap.getPopupOverlay());
+                        break;
+                    case "common":
+                        searchData.dialogCommon = true;
+                        break;
+                    case "commonOk":
+                        var regLon =
+                            /^-?(([0-9]|[0-9][0-9]|1[0-7][0-9])(\.[0-9]+)?|180)$/;
+                        var regLat = /^-?([0-8]?[0-9](\.[0-9]+)?|90)$/;
+                        if (
+                            !regLon.test(searchData.searchKey.lon) &&
+                            !regLat.test(searchData.searchKey.lat)
+                        ) {
+                            ElMessage.error("请输入正确的经纬度");
+                            return false;
+                        }
+                        var common = new tool.Common();
+                        common.QueryLocation(
+                            searchData.searchKey.lon,
+                            searchData.searchKey.lat
+                        );
+                        searchData.dialogCommon = false;
+                        break;
+                    case "text":
+                        searchData.dialogText = true;
+                        break;
+                    case "textOk":
+                        var style = new Style({
+                            text: new Text({
+                                font: "bold 14px Microsoft YaHei",
+                                fill: new Fill({
+                                    color: "#0078D7",
+                                }),
+                                stroke: new Stroke({
+                                    color: "#fff",
+                                    width: 2,
+                                }),
+                                offsetY: -5,
+                                text: searchData.searchKey.text,
+                            }),
+                        });
+                        var draw = tool.Draws({
+                            style: style,
+                        });
+                        draw.SetType("Point");
+                        searchData.dialogText = false;
+                        draw.Start();
+                        draw.on("drawend", function (e) {
+                            e.feature.setStyle(style);
+                            draw.End();
+                        });
+                        break;
+                    default:
+                        console.log("没有找到对应的工具");
+                        break;
+                }
+            },
+            searchMap(type) {
+                if (type === "Circle") {
+                    var geometryFunction = createBox();
+                    var draw = new Draw({
+                        source: arcMap.tempLayers.dview_factor_Layer.getSource(),
+                        type: type,
+                        geometryFunction: geometryFunction,
+                        stopClick: "doubleclick",
+                    });
+                    arcMap.map.addInteraction(draw);
+                    draw.on("drawend", function (e) {
+                        arcMap.map.removeInteraction(draw);
+                        searchData.dialogVisible = true;
+                        searchData.feature = e.feature;
+                        searchData.searchKey.type = type;
+                        searchData.searchKey.isShowKm = true;
+                    });
+                    return;
+                }
+                var tool = new OLTool();
+                var draw = tool.Draws();
+                draw.SetType(type);
+                draw.Start();
+                draw.on("drawend", function (e) {
+                    draw.End();
+                    searchData.dialogVisible = true;
+                    searchData.feature = e.feature;
+                    searchData.searchKey.type = type;
+                    switch (type) {
+                        case "Polygon":
+                            searchData.searchKey.isShowKm = true;
+                            break;
+                        case "LineString":
+                            searchData.searchKey.isShowKm = true;
+                            break;
+                        case "Point":
+                            searchData.searchKey.isShowKm = true;
+                            break;
+                    }
+                });
+            },
+            formatHeader(data, aliases) {
+                var header = [];
+                for (let key in data) {
+                    if (
+                        key != "geometry" &&
+                        key != "SHAPE.AREA" &&
+                        key != "SHAPE.LEN"
+                    ) {
+                        header.push({
+                            sxbm: aliases
+                                ? aliases[key]
+                                    ? aliases[key]
+                                    : key
+                                : key,
+                            sxmc: key,
+                        });
+                    }
+                }
+                return header;
+            },
+            //关闭查询窗口
+            closeDialogVisible() {
+                if (searchData.dialogVisible) searchData.drawMap("ClearAll");
+                searchData.dialogVisible = false;
+            },
+            // 点击属性查询按钮
+            attrQuery() {
+                if (searchData.options.length > 0) {
+                    searchData.attrForm.selectLayer = searchData.options[0].bsm;
+                    searchData.changeLayer();
+                    searchData.dialogVisibleAttrQuery = true;
+                } else {
+                    searchData.dialogVisibleAttrQuery = false;
+                    ElMessage.warning("未获取到数据,请先加载图层!");
+                }
+            },
+            // 属性查询——改变图层,根据图层获取字段
+            changeLayer() {
+                searchData.selectFieldData = [];
+                let index = searchData.options.findIndex(
+                    (item) => item.bsm === searchData.attrForm.selectLayer
+                );
+                if (index > -1) {
+                    getFields({
+                        DATAURI: searchData.options[index].path,
+                        LAYERNAME: searchData.options[index].name,
+                    }).then((res) => {
+                        if (res.code === 200) {
+                            searchData.selectFieldData = res.data;
+                        }
+                    });
+                }
+            },
+            // 确定属性查询
+            confirmAttrQuery() {
+                searchData.attrFormRef.validate((valid) => {
+                    if (valid) {
+                        proxy.$modal.loading("加载中...");
+                        arcMap.tempLayers.clear();
+                        let _item = searchData.options.find(
+                            (item) =>
+                                item.bsm == searchData.attrForm.selectLayer
+                        );
+                        let where = "";
+                        if (searchData.attrForm.selectField === "all") {
+                            where = "";
+                        } else {
+                            let queryParams = [];
+                            let fieldValue = searchData.attrForm.value;
+                            let operation = searchData.attrForm.selectOperate;
+                            let fieldName = searchData.attrForm.selectField;
+                            if (fieldValue.indexOf(",") > -1) {
+                                queryParams = fieldValue.split(",");
+                            } else {
+                                queryParams = fieldValue.split(",");
+                            }
+                            where = "";
+                            if (operation == "contains") {
+                                for (let l = 0; l < queryParams.length; l++) {
+                                    if (queryParams[l] == "") continue;
+                                    if (l > 0) {
+                                        where += " or ";
+                                    }
+                                    where +=
+                                        " " +
+                                        fieldName +
+                                        " like '%" +
+                                        queryParams[l] +
+                                        "%'";
+                                }
+                            } else if (operation == "equals") {
+                                where += fieldName + " in (";
+                                for (let l = 0; l < queryParams.length; l++) {
+                                    if (queryParams[l] == "") continue;
+                                    if (l > 0) {
+                                        where += ",";
+                                    }
+                                    where += "'" + queryParams[l] + "'";
+                                }
+                                where += ")";
+                            }
+                        }
+                        // store.commit("SET_QUERY_TABLE_PARAMS", {
+                        //     DATAURI: _item.path,
+                        //     LAYERNAME: _item.name,
+                        //     ATTRIBUTEFILTER: where,
+                        //     open: true,
+                        // });
+                        searchData.dialogVisibleAttrQuery = false;
+                    } else {
+                        return false;
+                    }
+                });
+            },
+            //关闭属性查询窗口
+            closeDialogAttrQueryVisible() {
+                if (searchData.dialogVisibleAttrQuery) {
+                    // searchData.drawMap("ClearAll");
+                    searchData.attrFormRef.resetFields();
+                    searchData.dialogVisibleAttrQuery = false;
+                }
+            },
+
+
+
+            imageQuery(){
+                parent.emit("update:showType", 'imageQuery');
+            },
+            gdbQuery(){
+                parent.emit("update:showType", 'gdbQuery');
+            },
+        });
+        // onMounted(() => {
+        //     searchData.options = [];
+        //     store.state.cgll.checkedLayersId.map((item) => {
+        //         searchData.options.push({
+        //             name: store.state.cgll.dictLayersInfo[item].name,
+        //             bsm: store.state.cgll.dictLayersInfo[item].id,
+        //             path: store.state.cgll.dictLayersInfo[item].filepath,
+        //         });
+        //     });
+        //     if (searchData.options.length > 0) {
+        //         searchData.searchKey.value = searchData.options[0].bsm;
+        //     }
+        // });
+
+        // watch(
+        //     () => store.state.cgll.checkedLayersId,
+        //     (newvalue, oldvalue) => {
+        //         searchData.options = [];
+        //         newvalue.map((item) => {
+        //             searchData.options.push({
+        //                 name: store.state.cgll.dictLayersInfo[item].name,
+        //                 bsm: store.state.cgll.dictLayersInfo[item].id,
+        //                 path: store.state.cgll.dictLayersInfo[item].filepath,
+        //             });
+        //         });
+        //         if (searchData.options.length > 0) {
+        //             searchData.searchKey.value = searchData.options[0].bsm;
+        //         }
+        //     },
+        //     {
+        //         deep: true,
+        //     }
+        // );
+        return { ...toRefs(searchData), childSearch };
+    },
+};
+</script>
+
+<style lang="less" scoped>
+.tool {
+    position: absolute;
+    right: 10px;
+    top: 15px;
+    height: 32px;
+}
+.flex-box{
+    display: flex;
+    align-items: center;    
+}
+.tool-left {
+    background-color: #fff;
+    padding: 0px 10px;
+    border-radius: 2px;
+}
+.tool-right {
+    background-color: #fff;
+    padding: 0px 10px;
+    border-radius: 2px;
+    border: 1px solid #e5e5e5;
+}
+.search-box {
+    opacity: 0.98 !important;
+    background: rgba(255, 255, 255, 0.98) !important;
+}
+.pointer{
+    cursor: pointer;
+}
+.nav{
+    display: flex;
+    align-content: center;
+    justify-content: center;
+}
+</style>
+
+<style scoped>
+:deep(.el-popper) {
+    top: 80px !important;
+}
+</style>

+ 48 - 0
src/main.js

@@ -0,0 +1,48 @@
+/**
+ * @Description:
+ * @version:
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2022-12-02 17:26:06
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-02-01 13:56:18
+ */
+import { createApp } from 'vue'
+import ElementPlus from 'element-plus'
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
+import 'element-plus/dist/index.css'
+import '@/style.css'
+import '@/assets/styles/index.scss' // global css
+import router from './router'
+import './permission'
+import { createPinia } from 'pinia'
+
+import NProgress from 'nprogress'
+NProgress.configure({ showSpinner: false })
+import 'nprogress/nprogress.css'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+// icon图标
+import "@/assets/icon/iconfont.css"
+
+import App from './App.vue'
+// 注册指令
+import plugins from "./plugins"; // plugins
+import hljs from 'highlight.js'
+import 'highlight.js/styles/atom-one-dark.css'
+
+const app = createApp(App)
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+  app.component(key, component)
+}
+app.use(plugins);
+app.use(router)
+app.use(createPinia())
+app.use(ElementPlus, {
+  locale: zhCn,
+})
+app.directive('highlight',function(el){  //自定义指令
+  let blocks = el.querySelectorAll('pre code');
+  blocks.forEach((block)=>{
+      hljs.highlightBlock(block)
+  })
+})
+app.mount('#app')

+ 165 - 0
src/permission.js

@@ -0,0 +1,165 @@
+/**
+ * @Description:
+ * @version:
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2023-04-07 15:06:28
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-05-09 09:26:50
+ */
+import router from '@/router/index';
+// import { project_name } from '/public/config/config.json';
+import { getToken } from '@/utils/auth'
+// import { Message } from 'element-ui'
+// import { mainStore } from "@/store/index";
+// import { getInfo } from "@/api/user/login";
+import { toRefs } from 'vue'
+import { ElMessageBox } from 'element-plus'
+import { ElMessage } from 'element-plus'
+import { ElNotification } from 'element-plus'
+
+
+router.beforeEach((to, from, next) => {
+  next()
+  return
+
+  const customerToken = getToken('Customer-Token')
+  const adminToken = getToken('Admin-Token')
+  // document.title = to.meta.title || project_name
+  const permission = to.meta.permission
+
+  let store = mainStore()
+  store.$patch({
+    token: customerToken
+  });
+
+  if (to.path === '/login') {
+    if (customerToken) {
+      // Message('您已经登录了')
+      let url
+      try {
+        url = this.$route.query.redirect || '/'
+      } catch (error) {
+        url = '/'
+      }
+      next(url)
+      return
+    }
+  }
+
+  if (permission === 0) {
+    next()
+  } else if (permission === 1) {
+    // 顾客登录
+    if (customerToken) {
+      next()
+    } else {
+      // ElMessageBox.$message('请登录后继续')
+      // ElMessage.success({
+      //   message: '请登录后继续'
+      // })
+
+      ElMessageBox.alert('请先登录后再使用该功能...', '提示', {
+        confirmButtonText: '去登录',
+        callback: () => {
+          next(`/login?redirect=${encodeURIComponent(encodeURIComponent(to.fullPath))}`)
+        },
+      })
+
+    }
+  } else if (permission === 2) {
+    // 管理员
+    if (adminToken) {
+      next()
+    } else {
+      next(`/admin/login?redirect=${encodeURIComponent(to.fullPath)}`)
+    }
+  } else {
+    next();
+  }
+
+  if (customerToken && !store.userInfo) {
+    getInfo().then((res) => {
+      store.$patch({
+        userInfo: JSON.stringify(res.data)
+      });
+      // this.$router.push({ path: this.redirect || "/" }).catch(() => {});
+
+      // window.socket = io('http://192.168.100.21:7001/', {
+      // window.socket = io('http://39.98.45.204:7001/', {
+      // window.socket = io('http://socket.bjsiwei.net.cn/', {
+      window.socket = io(import.meta.env.VITE_BASE_SOCKET, {
+        query: {},
+        transports: ['websocket', 'polling'],
+      })
+
+      socket.on("connect", () => {
+        // console.log("connected!", socket.id);
+        socket.emit("setName", res.data);
+      });
+
+      socket.on("message", (message) => {
+        console.log(message);
+      })
+
+      socket.on("changePrice", (message) => {
+        ElNotification({
+          title: '系统通知',
+          dangerouslyUseHTMLString: true,
+          message: `管理员已修改订单价格为:${message.account}元
+          <br/> <a href="/#/orderDetail?id=${message.id}" target="_blank" style="color: blue;">查看订单</a>`,
+          type: 'success',
+          duration: 0,
+        })
+
+        speech.speak({
+          text: `您有新的消息, 管理员已修改订单价格为:${message.account}元`
+        }).then(() => {
+          console.log("播报完成...")
+        })
+      });
+
+      socket.on("changeStatus", (message) => {
+
+        ElNotification({
+          title: '系统通知',
+          dangerouslyUseHTMLString: true,
+          message: `管理员已修改订单状态为:${message.status}
+          <br/> <a href="/#/orderDetail?id=${message.id}" target="_blank" style="color: blue;">查看订单</a>`,
+          type: 'success',
+          duration: 0,
+        })
+
+        speech.speak({
+          text: `您有新的消息, 管理员已修改订单状态为:${message.status}`
+        }).then(() => {
+          console.log("播报完成...")
+        })
+      });
+
+
+    }).catch(() => {
+      // this.loading = false;
+      // if (this.captchaEnabled) {
+      //     this.getCode();
+      // }
+
+      // Notification.requestPermission(function (status) {
+      //   if (status === "granted") {
+      //        var n = new Notification("Hi!");
+      //    } else {
+      //         alert("Hi!");
+      //    }
+      // });
+
+      // if(window.Notification && Notification.permission !== "denied") {
+      //   Notification.requestPermission(function(status) {
+      //       var n = new Notification('通知标题', { body: '这里是通知内容!' });
+      //   });
+      // }
+
+    });
+
+  }
+})
+
+router.afterEach((to, from) => { })

+ 18 - 0
src/plugins/index.js

@@ -0,0 +1,18 @@
+// import tab from './tab'
+// import auth from './auth'
+// import cache from './cache'
+import modal from './modal'
+// import download from './download'
+
+export default function installPlugins(app){
+  // 页签操作
+  // app.config.globalProperties.$tab = tab
+  // 认证对象
+  // app.config.globalProperties.$auth = auth
+  // 缓存对象
+  // app.config.globalProperties.$cache = cache
+  // 模态框对象
+  app.config.globalProperties.$modal = modal
+  // 下载文件
+  // app.config.globalProperties.$download = download
+}

+ 82 - 0
src/plugins/modal.js

@@ -0,0 +1,82 @@
+import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus'
+
+let loadingInstance;
+
+export default {
+  // 消息提示
+  msg(content) {
+    ElMessage.info(content)
+  },
+  // 错误消息
+  msgError(content) {
+    ElMessage.error(content)
+  },
+  // 成功消息
+  msgSuccess(content) {
+    ElMessage.success(content)
+  },
+  // 警告消息
+  msgWarning(content) {
+    ElMessage.warning(content)
+  },
+  // 弹出提示
+  alert(content) {
+    ElMessageBox.alert(content, "系统提示")
+  },
+  // 错误提示
+  alertError(content) {
+    ElMessageBox.alert(content, "系统提示", { type: 'error' })
+  },
+  // 成功提示
+  alertSuccess(content) {
+    ElMessageBox.alert(content, "系统提示", { type: 'success' })
+  },
+  // 警告提示
+  alertWarning(content) {
+    ElMessageBox.alert(content, "系统提示", { type: 'warning' })
+  },
+  // 通知提示
+  notify(content) {
+    ElNotification.info(content)
+  },
+  // 错误通知
+  notifyError(content) {
+    ElNotification.error(content);
+  },
+  // 成功通知
+  notifySuccess(content) {
+    ElNotification.success(content)
+  },
+  // 警告通知
+  notifyWarning(content) {
+    ElNotification.warning(content)
+  },
+  // 确认窗体
+  confirm(content) {
+    return ElMessageBox.confirm(content, "系统提示", {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: "warning",
+    })
+  },
+  // 提交内容
+  prompt(content) {
+    return ElMessageBox.prompt(content, "系统提示", {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: "warning",
+    })
+  },
+  // 打开遮罩层
+  loading(content) {
+    loadingInstance = ElLoading.service({
+      lock: true,
+      text: content,
+      background: "rgba(0, 0, 0, 0.7)",
+    })
+  },
+  // 关闭遮罩层
+  closeLoading() {
+    loadingInstance.close();
+  }
+}

+ 165 - 0
src/router/index.js

@@ -0,0 +1,165 @@
+/**
+ * @Description:
+ * @version:
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2022-12-09 12:04:31
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-05-08 17:34:17
+ */
+import { createRouter, createWebHashHistory } from 'vue-router'
+import Layout from '@/views/layout/index.vue';
+
+export const constantRoutes = [
+
+    {
+        path: '/',
+        name: 'Layout',
+        component: Layout,
+
+        children: [
+            {
+                path: '',
+                name: 'index',
+                component: () => import('@/views/dataPreprocessing/index.vue'),
+                meta: {
+                    title: '数据预处理',
+                }
+            },
+
+            {
+                path: 'dataManagement',
+                name: 'dataManagement',
+                component: () => import('@/views/dataManagement/index.vue'),
+                meta: {
+                    title: '数据管理',
+                }
+            },
+
+            {
+                path: 'dataStatistic',
+                name: 'dataStatistic',
+                component: () => import('@/views/dataStatistic/index.vue'),
+                meta: {
+                    title: '数据统计',
+                }
+            },
+            
+            {
+                path: 'dataStatistics',
+                name: 'dataStatistics',
+                component: () => import('@/views/dataStatistics/index.vue'),
+                meta: {
+                    title: '数据统计',
+                }
+            },
+
+            {
+                path: 'dataMaintenance',
+                name: 'dataMaintenance',
+                redirect: "/dataUpdates",
+                component: () => import('@/views/dataMaintenance/index.vue'),
+                meta: {
+                    title: '数据维护',
+                },
+                children: [
+                    {
+                        path: '/dataUpdates',
+                        name: 'dataUpdates',
+                        component: () => import('@/views/dataMaintenance/componets/dataUpdates.vue'),
+                        meta: { 
+                            title: '数据更新' 
+                        }
+                    },
+                    {
+                        path: '/mvdataManagement',
+                        name: 'mvdataManagement',
+                        component: () => import('@/views/dataMaintenance/componets/mvdataManagement.vue'),
+                        meta: { 
+                            title: '多版本数据管理' 
+                        }
+                    },
+                    {
+                        path: '/dataBackup',
+                        name: 'dataBackup',
+                        meta: {
+                            title: '数据备份' 
+                        },
+                        children: [
+                            {
+                                path: '/dataBackup/policyManagement',
+                                name: 'policyManagement',
+                                component: () => import('@/views/dataMaintenance/componets/dataBackup/policyManagement.vue'),
+                                meta: { 
+                                    title: '备份策略管理' 
+                                }
+                            },
+                            {
+                                path: '/dataBackup/taskManagement',
+                                name: 'taskManagement',
+                                component: () => import('@/views/dataMaintenance/componets/dataBackup/taskManagement.vue'),
+                                meta: { 
+                                    title: '备份任务管理' 
+                                }
+                            },
+                            {
+                                path: '/dataBackup/resumeManagement',
+                                name: 'resumeManagement',
+                                component: () => import('@/views/dataMaintenance/componets/dataBackup/resumeManagement.vue'),
+                                meta: { 
+                                    title: '数据恢复管理' 
+                                }
+                            },
+                        ]
+                    },
+                ]
+            },
+
+            {
+                path: 'logManagement',
+                name: 'logManagement',
+                component: () => import('@/views/logManagement/index.vue'),
+                meta: {
+                    title: '日志管理',
+                },
+            },
+
+            {
+                path: 'systemSettings',
+                name: 'systemSettings',
+                component: () => import('@/views/systemSettings/index.vue'),
+                meta: {
+                    title: '系统设置',
+                }
+            },
+        ]
+    },
+    {
+        path: '/404',
+        component: () => import('@/views/error/404.vue'),
+        hidden: true
+    },
+    {
+        path: '/401',
+        component: () => import('@/views/error/401.vue'),
+        hidden: true
+    },
+    {
+        path: '/:pathMatch(.*)*',
+        name: '404',
+        component: () => import('@/views/error/404.vue'),
+    },
+]
+
+const router = createRouter({
+    history: createWebHashHistory(),
+    scrollBehavior: () => ({ top: 0 }),
+    routes: [
+        ...constantRoutes,
+    ]
+})
+
+router.beforeEach((to, from, next) => {
+    next()
+})
+
+export default router

+ 96 - 0
src/style.css

@@ -0,0 +1,96 @@
+/**
+ * @Description: 
+ * @version: 
+ * @Author: 北京四维空间数码科技有限公司-研发部
+ * @Date: 2022-12-02 17:26:06
+ * @LastEditors: 北京四维空间数码科技有限公司-研发部
+ * @LastEditTime: 2023-01-12 11:56:18
+ */
+:root {
+  font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+  font-size: 16px;
+  line-height: 24px;
+  font-weight: 400;
+
+  color-scheme: light dark;
+  color: rgba(255, 255, 255, 0.87);
+  background-color: #242424;
+
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-text-size-adjust: 100%;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+body {
+  margin: 0;
+  place-items: center;
+  min-width: 320px;
+  min-height: 100vh;
+}
+
+h1 {
+  font-size: 3.2em;
+  line-height: 1.1;
+}
+
+button {
+  border-radius: 8px;
+  border: 1px solid transparent;
+  padding: 0.6em 1.2em;
+  font-size: 1em;
+  font-weight: 500;
+  font-family: inherit;
+  background-color: #1a1a1a;
+  cursor: pointer;
+  transition: border-color 0.25s;
+}
+button:hover {
+  border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+  outline: 4px auto -webkit-focus-ring-color;
+}
+
+.card {
+  padding: 2em;
+}
+
+@media (prefers-color-scheme: light) {
+  :root {
+    color: #213547;
+    background-color: #ffffff;
+  }
+  a:hover {
+    color: #747bff;
+  }
+  button {
+    background-color: #f9f9f9;
+  }
+}
+
+.amap-logo, .amap-copyright {
+    display: none !important;
+    opacity: 0 !important;
+}
+

+ 223 - 0
src/utils/CoordTransformate.js

@@ -0,0 +1,223 @@
+import proj4 from 'proj4'
+// import { register } from 'ol/proj/proj4';
+import { addCoordinateTransforms, transform, addProjection } from 'ol/proj'
+// import * as proj from 'ol/proj'
+import Projection from 'ol/proj/projection';
+
+import axios from 'axios';
+import prjConfig from '@/utils/Projection.json'
+//ol添加投影坐标系
+//addProjectionTransform([112.863, 42.417], "EPSG:4491", "EPSG:4526", false);
+// var prjConfig = {}
+export function addProjectionTransform(pointArr, inSR, outSR, isPointArr, isMultipleArr, callback) {
+    inSR = inSR ? inSR : "EPSG:3857";
+    outSR = outSR ? outSR : "EPSG:4326";
+    var thisResult = {
+        code: "200",
+        msg: "转换成功",
+        inSR: inSR,
+        outSR: outSR,
+        result: []
+    }
+    if (inSR == outSR) {
+        thisResult.result = pointArr;
+        callback(thisResult);
+        return;
+    }
+    // var prjConfig = InitialParameter("../Json/Projection.json");
+    // var prjConfig = {};
+    // let path = process.env.NODE_ENV === "production" ? process.env.VUE_APP_URL : "/"
+    // new Promise((resolve, reject) => {
+    //     if (Object.keys(prjConfig).length === 0) {
+    //         axios.get(path + 'utils/Projection.json').then(res=>{
+    //             prjConfig = res.data
+    //             resolve(prjConfig)
+    //         }).catch(e=>{reject(e)})
+    //     }else{
+    //         resolve(prjConfig)
+    //     }
+    // }).then(res=>{
+        
+    // axios.get(path + 'json/Projection.json').then(res => {
+        // prjConfig = res.data;
+        var projections = prjConfig.projections;
+        if (projections.hasOwnProperty(inSR) && projections.hasOwnProperty(outSR)) {
+            var projectionIn, projectionOut;
+            if (inSR != "EPSG:3857" && inSR != "EPSG:4326") {
+                proj4.defs(inSR, projections[inSR].proj4);
+                projectionIn = new Projection({
+                    code: inSR
+                });
+                addProjection(projectionIn);
+            }
+            if (outSR != "EPSG:3857" && outSR != "EPSG:4326") {
+                proj4.defs(outSR, projections[outSR].proj4);
+                projectionOut = new Projection({
+                    code: outSR
+                });
+                addProjection(projectionOut);
+            }
+            addCoordinateTransforms(inSR, outSR,
+                function (coordinate) {
+                    return proj4(inSR, outSR, coordinate);
+                },
+                function (coordinate) {
+                    return proj4(outSR, inSR, coordinate);
+                });
+        }
+        else {
+            thisResult.code = "400";
+            thisResult.msg = "无法识别的坐标系( ";
+            if (!projections.hasOwnProperty(inSR)) {
+                thisResult.result.push(inSR);
+                thisResult.msg += inSR;
+
+                if (!projections.hasOwnProperty(outSR)) {
+                    thisResult.result.push(outSR);
+                    thisResult.msg += (" " + outSR);
+                }
+            }
+            else {
+                if (!projections.hasOwnProperty(outSR)) {
+                    thisResult.result.push(outSR);
+                    thisResult.msg += outSR;
+                }
+            }
+            thisResult.msg += " )";
+            return thisResult;
+        }
+        if (isMultipleArr) {
+            for (var i = 0; i < pointArr.length; i++) {
+                thisResult.result.push([]);
+                for (var j = 0; j < pointArr[i].length; j++) {
+                    thisResult.result[i].push(transform(pointArr[i][j], inSR, outSR));
+                }
+            }
+        }
+        else {
+            if (isPointArr) {
+                for (var i = 0; i < pointArr.length; i++) {
+                    thisResult.result.push(transform(pointArr[i], inSR, outSR));
+                    //thisResult.result.push([]);
+                    //for (var j = 0; j < pointArr[i].length; j++) {
+                    //thisResult.result[i].push(transform(pointArr[i][j], inSR, outSR));
+                    //}
+                }
+            }
+            else {
+                for (var i = 0; i < pointArr.length / 2; i++) {
+                    thisResult.result.push(transform([pointArr[2 * i], pointArr[2 * i + 1]], inSR, outSR));
+                }
+            }
+        }
+        callback(thisResult);
+    // })
+
+    // }).catch(e=>{console.log(e);})
+}
+
+//Arcgis FlatCoordinates转rings数组
+export function flatCoordinatesToRings(pointArr) {
+    var thisResult = {
+        start: null,
+        result: [],
+        resultNum: 0
+    }
+    var next = null;
+    for (var i = 0; i < pointArr.length / 2; i++) {
+        next = [pointArr[2 * i], pointArr[2 * i + 1]];
+        if (thisResult.start == null) {
+            thisResult.start = next;
+            thisResult.result.push([]);
+            thisResult.result[thisResult.resultNum].push(next);
+            thisResult.resultNum++;
+        }
+        else if (next[0] == thisResult.start[0] && next[1] == thisResult.start[1]) {
+            thisResult.start = null;
+            thisResult.result[thisResult.resultNum - 1].push(next);
+        }
+        else {
+            thisResult.result[thisResult.resultNum - 1].push(next);
+        }
+    }
+    return thisResult.result;
+}
+
+//二维坐标转换########二维坐标转换########二维坐标转换########二维坐标转换
+//地图坐标系坐标数组转经纬度数组
+export function mapProjectionToWGS84_22(pointArr, prj) {
+    prj = prj ? prj : map_Projection;
+    var thisResult = new Array();
+    for (var i = 0; i < pointArr.length / 2; i++) {
+        thisResult.push(transform([pointArr[2 * i], pointArr[2 * i + 1]], prj, 'EPSG:4326'))
+    }
+    return thisResult;
+}
+//经纬度坐标转地图坐标
+export function WGS84TomapProjection_22(pointArr, isPointArr) {
+    var thisResult = new Array();
+    if (isPointArr) {
+        for (var i = 0; i < pointArr.length; i++) {
+            thisResult.push(transform([pointArr[i][0], pointArr[i][1]], 'EPSG:4326', m_baseParameter['map_Projection']));
+        }
+    }
+    else {
+        for (var i = 0; i < pointArr.length / 2; i++) {
+            thisResult.push(transform([pointArr[2 * i], pointArr[2 * i + 1]], 'EPSG:4326', m_baseParameter['map_Projection']));
+        }
+    }
+    return thisResult;
+}
+//地图坐标转2000坐标
+export function mapProjectionTo2000(pointArr) {
+    var thisResult = new Array();
+    if (map_Projection == "EPSG:3857") {
+        for (var i = 0; i < pointArr.length / 2; i++) {
+            thisResult.push([pointArr[2 * i], pointArr[2 * i + 1]]);
+        }
+    }
+    else {
+        for (var i = 0; i < pointArr.length / 2; i++) {
+            thisResult.push(transform([pointArr[2 * i], pointArr[2 * i + 1]], map_Projection, 'EPSG:3857'));
+        }
+    }
+    return thisResult;
+}
+//WGS84转2000坐标
+export function WGS84To2000(pointArr, isPointArr) {
+    var thisResult = new Array();
+    if (isPointArr) {
+        for (var i = 0; i < pointArr.length; i++) {
+            thisResult.push(transform(pointArr[i], 'EPSG:4326', 'EPSG:3857'));
+        }
+    }
+    else {
+        for (var i = 0; i < pointArr.length / 2; i++) {
+            thisResult.push(transform([pointArr[2 * i], pointArr[2 * i + 1]], 'EPSG:4326', 'EPSG:3857'));
+        }
+    }
+    return thisResult;
+}
+//坐标转换
+export function InSRToOutSR(pointArr, inSR, outSR, isPointArr) {
+    var thisResult = new Array();
+    if (isPointArr) {
+        for (var i = 0; i < pointArr.length; i++) {
+            thisResult.push(transform(pointArr[i], inSR, outSR));
+        }
+    }
+    else {
+        for (var i = 0; i < pointArr.length / 2; i++) {
+            thisResult.push(transform([pointArr[2 * i], pointArr[2 * i + 1]], inSR, outSR));
+        }
+    }
+    return thisResult;
+}
+//坐标格式转换
+export function FlatCoordToCoordArr(flatCoord) {
+    var result = new Array();
+    for (var i = 0; i < flatCoord.length / 2; i++) {
+        result.push([flatCoord[2 * i], flatCoord[2 * i + 1]]);
+    }
+    return result;
+}

+ 187 - 0
src/utils/Export2Excel.js

@@ -0,0 +1,187 @@
+//Export2Excel.js
+import { saveAs } from 'file-saver'
+import * as XLSX from "xlsx";
+
+function generateArray(table) {
+  var out = [];
+  var rows = table.querySelectorAll("tr");
+  var ranges = [];
+  for (var R = 0; R < rows.length; ++R) {
+    var outRow = [];
+    var row = rows[R];
+    var columns = row.querySelectorAll("td");
+    for (var C = 0; C < columns.length; ++C) {
+      var cell = columns[C];
+      var colspan = cell.getAttribute("colspan");
+      var rowspan = cell.getAttribute("rowspan");
+      var cellValue = cell.innerText;
+      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
+
+      //Skip ranges
+      ranges.forEach(function(range) {
+        if (
+          R >= range.s.r &&
+          R <= range.e.r &&
+          outRow.length >= range.s.c &&
+          outRow.length <= range.e.c
+        ) {
+          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
+        }
+      });
+
+      //Handle Row Span
+      if (rowspan || colspan) {
+        rowspan = rowspan || 1;
+        colspan = colspan || 1;
+        ranges.push({
+          s: {
+            r: R,
+            c: outRow.length
+          },
+          e: {
+            r: R + rowspan - 1,
+            c: outRow.length + colspan - 1
+          }
+        });
+      }
+
+      //Handle Value
+      outRow.push(cellValue !== "" ? cellValue : null);
+
+      //Handle Colspan
+      if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
+    }
+    out.push(outRow);
+  }
+  return [out, ranges];
+}
+
+function datenum(v, date1904) {
+  if (date1904) v += 1462;
+  var epoch = Date.parse(v);
+  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
+}
+
+function sheet_from_array_of_arrays(data, opts) {
+  var ws = {};
+  var range = {
+    s: {
+      c: 10000000,
+      r: 10000000
+    },
+    e: {
+      c: 0,
+      r: 0
+    }
+  };
+  for (var R = 0; R != data.length; ++R) {
+    for (var C = 0; C != data[R].length; ++C) {
+      if (range.s.r > R) range.s.r = R;
+      if (range.s.c > C) range.s.c = C;
+      if (range.e.r < R) range.e.r = R;
+      if (range.e.c < C) range.e.c = C;
+      var cell = {
+        v: data[R][C]
+      };
+      if (cell.v == null) continue;
+      var cell_ref = XLSX.utils.encode_cell({
+        c: C,
+        r: R
+      });
+
+      if (typeof cell.v === "number") cell.t = "n";
+      else if (typeof cell.v === "boolean") cell.t = "b";
+      else if (cell.v instanceof Date) {
+        cell.t = "n";
+        cell.z = XLSX.SSF._table[14];
+        cell.v = datenum(cell.v);
+      } else cell.t = "s";
+
+      ws[cell_ref] = cell;
+    }
+  }
+  if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
+  return ws;
+}
+
+function Workbook() {
+  if (!(this instanceof Workbook)) return new Workbook();
+  this.SheetNames = [];
+  this.Sheets = {};
+}
+
+function s2ab(s) {
+  var buf = new ArrayBuffer(s.length);
+  var view = new Uint8Array(buf);
+  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
+  return buf;
+}
+
+export function export_table_to_excel(id) {
+  var theTable = document.getElementById(id);
+  console.log("a");
+  var oo = generateArray(theTable);
+  var ranges = oo[1];
+
+  /* original data */
+  var data = oo[0];
+  var ws_name = "SheetJS";
+  console.log(data);
+
+  var wb = new Workbook(),
+    ws = sheet_from_array_of_arrays(data);
+
+  /* add ranges to worksheet */
+  // ws['!cols'] = ['apple', 'banan'];
+  ws["!merges"] = ranges;
+
+  /* add worksheet to workbook */
+  wb.SheetNames.push(ws_name);
+  wb.Sheets[ws_name] = ws;
+
+  var wbout = XLSX.write(wb, {
+    bookType: "xlsx",
+    bookSST: false,
+    type: "binary"
+  });
+
+  saveAs(
+    new Blob([s2ab(wbout)], {
+      type: "application/octet-stream"
+    }),
+    "test.xlsx"
+  );
+}
+
+function formatJson(jsonData) {
+  console.log(jsonData);
+}
+export function export_json_to_excel(th, jsonData, defaultTitle) {
+  /* original data */
+
+  var data = jsonData;
+  data.unshift(th);
+  var ws_name = "SheetJS";
+
+  var wb = new Workbook(),
+    ws = sheet_from_array_of_arrays(data);
+
+  /* add worksheet to workbook */
+  wb.SheetNames.push(ws_name);
+  wb.Sheets[ws_name] = ws;
+
+  var wbout = XLSX.write(wb, {
+    bookType: "xlsx",
+    bookSST: false,
+    type: "binary"
+  });
+  var title = defaultTitle || "列表";
+  saveAs(
+    new Blob([s2ab(wbout)], {
+      type: "application/octet-stream"
+    }),
+    title + ".xlsx"
+  );
+}
+
+

+ 587 - 0
src/utils/Projection.json

@@ -0,0 +1,587 @@
+{
+	"address":"http://epsg.io/",
+	"projections":{
+		"EPSG:3857":{
+			"center":[0.00,-0.00],
+			"extent":[-20026376.39,-20048966.10,20026376.39,20048966.10],
+			"proj4":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs",
+			"unit":"meter",
+			"codes":[900913,3587,54004,41001,102113,102100,3785],
+			"crs":"WGS 84",
+			"crsDetail":"WGS84/Pseudo-Mercator--Spherical Mercator,Google Maps,OpenStreetMap,Bing, ArcGIS, ESRI",
+			"crsAlias":"Web墨卡托,WGS84平面坐标系",
+			"ellipsoid":"WGS 84",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4326":{
+			"center":[0.00000000,0.00000000],
+			"extent":[-180.0,-90.0,180.0,90.0],
+			"proj4":"+proj=longlat +datum=WGS84 +no_defs",
+			"unit":"degree",
+			"codes":[],
+			"crs":"WGS 84",
+			"crsDetail":"WGS84--WGS84-World Geodetic System 1984,used in GPS",
+			"crsAlias":"WGS84地理坐标系",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4490":{
+			"center":[104.19500000,35.13000000],
+			"extent":[73.62,16.7,134.77,53.56],
+			"proj4":"+proj=longlat +ellps=GRS80 +no_defs",
+			"unit":"degree",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"China Geodetic Coordinate System 2000",
+			"crsAlias":"CGCS2000地理坐标系",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4497":{
+			"center":[104.19500000,35.13000000],
+			"extent":[73.62,16.7,134.77,53.56],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +ellps=GRS80 +units=m +no_defs ",
+			"unit":"degree",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"China Geodetic Coordinate System 2000",
+			"crsAlias":"CGCS2000地理坐标系",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4513":{
+			"center":[25505253.45,4233029.41],
+			"extent":[25375272.50,3965339.75,25626870.23,4502787.60],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 25",
+			"crsAlias":"CGCS_2000_3度分带第25带(中央经线75E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4514":{
+			"center":[26500000.00,4033256.76],
+			"extent":[26356780.75,3435266.95,26624607.97,4633842.66],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 26",
+			"crsAlias":"CGCS_2000_3度分带第26带(中央经线78E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4515":{
+			"center":[27500439.67,4198063.40],
+			"extent":[27355189.72,3315517.28,27617221.79,5083856.92],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 27",
+			"crsAlias":"CGCS_2000_3度分带第27带(中央经线81E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4516":{
+			"center":[28500000.00,4179194.53],
+			"extent":[28352803.51,3128167.77,28613592.51,5233908.47],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 28",
+			"crsAlias":"CGCS_2000_3度分带第28带(中央经线84E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4517":{
+			"center":[29500000.00,4261888.57],
+			"extent":[29352176.08,3077180.78,29609359.83,5450729.14],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 29",
+			"crsAlias":"CGCS_2000_3度分带第29带(中央经线87E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4518":{
+			"center":[30500000.00,4193068.64],
+			"extent":[30350541.60,3023992.26,30611765.09,5366231.03],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 30",
+			"crsAlias":"CGCS_2000_3度分带第30带(中央经线90E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4519":{
+			"center":[31500000.00,4032147.09],
+			"extent":[31352054.43,3067205.43,31618002.46,5000486.51],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 31",
+			"crsAlias":"CGCS_2000_3度分带第31带(中央经线93E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4520":{
+			"center":[32500448.73,4026043.95],
+			"extent":[32352762.30,3124842.44,32620089.90,4930490.22],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 32",
+			"crsAlias":"CGCS_2000_3度分带第32带(中央经线96E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4521":{
+			"center":[33500000.00,3552386.76],
+			"extent":[33344482.32,2371430.30,33622787.54,4737149.55],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 33",
+			"crsAlias":"CGCS_2000_3度分带第33带(中央经线99E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4522":{
+			"center":[34500000.00,3531872.69],
+			"extent":[34344166.57,2338205.65,34622925.70,4729373.22],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 34",
+			"crsAlias":"CGCS_2000_3度分带第34带(中央经线102E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4523":{
+			"center":[35500000.00,3581218.36],
+			"extent":[35345643.07,2489940.65,35623868.10,4676052.19],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 35",
+			"crsAlias":"CGCS_2000_3度分带第35带(中央经线105E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4524":{
+			"center":[36500000.00,3356695.62],
+			"extent":[36341298.83,2012660.02,36623358.71,4704933.89],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 36",
+			"crsAlias":"CGCS_2000_3度分带第36带(中央经线108E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4525":{
+			"center":[37500000.00,3498607.91],
+			"extent":[37341226.58,2003802.99,37618043.70,4998263.83],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 37",
+			"crsAlias":"CGCS_2000_3度分带第37带(中央经线111E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4526":{
+			"center":[38500000.00,3706538.80],
+			"extent":[38344577.88,2381397.91,38617340.63,5036050.38],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 38",
+			"crsAlias":"CGCS_2000_3度分带第38带(中央经线114E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4527":{
+			"center":[39500000.00,4012173.36],
+			"extent":[39345754.30,2501017.13,39607809.00,5528578.96],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 39",
+			"crsAlias":"CGCS_2000_3度分带第39带(中央经线117E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4528":{
+			"center":[40500000.00,4305182.26],
+			"extent":[40347872.25,2703739.74,40599933.05,5912395.20],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 40",
+			"crsAlias":"CGCS_2000_3度分带第40带(中央经线120E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4529":{
+			"center":[41500000.00,4528357.48],
+			"extent":[41352748.57,3123733.99,41599394.66,5937990.42],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 41",
+			"crsAlias":"CGCS_2000_3度分带第41带(中央经线123E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4530":{
+			"center":[42500000.00,5173340.81],
+			"extent":[42372262.47,4451705.13,42600236.64,5897928.74],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 42",
+			"crsAlias":"CGCS_2000_3度分带第42带(中央经线126E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4531":{
+			"center":[43500000.00,5074967.53],
+			"extent":[43374503.76,4582750.41,43606982.71,5569731.71],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 43",
+			"crsAlias":"CGCS_2000_3度分带第43带(中央经线129E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4532":{
+			"center":[44500000.00,5057184.16],
+			"extent":[44376543.13,4699379.62,44610019.44,5417367.63],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 44",
+			"crsAlias":"CGCS_2000_3度分带第44带(中央经线132E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4533":{
+			"center":[45434365.33,5221506.61],
+			"extent":[45383491.84,5080507.85,45482969.27,5362930.84],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger zone 45",
+			"crsAlias":"CGCS_2000_3度分带第45带(中央经线135E)_加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+
+
+
+		"EPSG:4534":{
+			"center":[505253.45,4233029.41],
+			"extent":[375272.50,3965339.75,626870.23,4502787.60],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 75E",
+			"crsAlias":"CGCS_2000_3度分带第25带(中央经线75E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4535":{
+			"center":[500000.00,4033256.76],
+			"extent":[356780.75,3435266.95,624607.97,4633842.66],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 78E",
+			"crsAlias":"CGCS_2000_3度分带第26带(中央经线78E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4536":{
+			"center":[500439.67,4198063.40],
+			"extent":[355189.72,3315517.28,617221.79,5083856.92],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 81E",
+			"crsAlias":"CGCS_2000_3度分带第27带(中央经线81E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4537":{
+			"center":[500000.00,4179194.53],
+			"extent":[352803.51,3128167.77,613592.51,5233908.47],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 84E",
+			"crsAlias":"CGCS_2000_3度分带第28带(中央经线84E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4538":{
+			"center":[500000.00,4261888.57],
+			"extent":[352176.08,3077180.78,609359.83,5450729.14],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 87E",
+			"crsAlias":"CGCS_2000_3度分带第29带(中央经线87E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4539":{
+			"center":[500000.00,4193068.64],
+			"extent":[350541.60,3023992.26,611765.09,5366231.03],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 90E",
+			"crsAlias":"CGCS_2000_3度分带第30带(中央经线90E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4540":{
+			"center":[500000.00,4032147.09],
+			"extent":[352054.43,3067205.43,618002.46,5000486.51],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 93E",
+			"crsAlias":"CGCS_2000_3度分带第31带(中央经线93E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4541":{
+			"center":[500448.73,4026043.95],
+			"extent":[352762.30,3124842.44,620089.90,4930490.22],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 96E",
+			"crsAlias":"CGCS_2000_3度分带第32带(中央经线96E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4542":{
+			"center":[500000.00,3552386.76],
+			"extent":[344482.32,2371430.30,622787.54,4737149.55],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 99E",
+			"crsAlias":"CGCS_2000_3度分带第33带(中央经线99E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4543":{
+			"center":[500000.00,3531872.69],
+			"extent":[344166.57,2338205.65,622925.70,4729373.22],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 102E",
+			"crsAlias":"CGCS_2000_3度分带第34带(中央经线102E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4544":{
+			"center":[500000.00,3581218.36],
+			"extent":[345643.07,2489940.65,623868.10,4676052.19],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 105E",
+			"crsAlias":"CGCS_2000_3度分带第35带(中央经线105E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4545":{
+			"center":[500000.00,3356695.62],
+			"extent":[341298.83,2012660.02,623358.71,4704933.89],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 108E",
+			"crsAlias":"CGCS_2000_3度分带第36带(中央经线108E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4546":{
+			"center":[500000.00,3498607.91],
+			"extent":[341226.58,2003802.99,618043.70,4998263.83],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 111E",
+			"crsAlias":"CGCS_2000_3度分带第37带(中央经线111E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4547":{
+			"center":[500000.00,3706538.80],
+			"extent":[344577.88,2381397.91,617340.63,5036050.38],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 114E",
+			"crsAlias":"CGCS_2000_3度分带第38带(中央经线114E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4548":{
+			"center":[500000.00,4012173.36],
+			"extent":[345754.30,2501017.13,607809.00,5528578.96],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 117E",
+			"crsAlias":"CGCS_2000_3度分带第39带(中央经线117E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4549":{
+			"center":[500000.00,4305182.26],
+			"extent":[347872.25,2703739.74,599933.05,5912395.20],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 120E",
+			"crsAlias":"CGCS_2000_3度分带第40带(中央经线120E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4550":{
+			"center":[500000.00,4528357.48],
+			"extent":[352748.57,3123733.99,599394.66,5937990.42],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 123E",
+			"crsAlias":"CGCS_2000_3度分带第41带(中央经线123E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4551":{
+			"center":[500000.00,5173340.81],
+			"extent":[372262.47,4451705.13,600236.64,5897928.74],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 126E",
+			"crsAlias":"CGCS_2000_3度分带第42带(中央经线126E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4552":{
+			"center":[500000.00,5074967.53],
+			"extent":[374503.76,4582750.41,606982.71,5569731.71],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 129E",
+			"crsAlias":"CGCS_2000_3度分带第43带(中央经线129E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4553":{
+			"center":[500000.00,5057184.16],
+			"extent":[376543.13,4699379.62,610019.44,5417367.63],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 132E",
+			"crsAlias":"CGCS_2000_3度分带第44带(中央经线132E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		},
+		"EPSG:4554":{
+			"center":[434365.33,5221506.61],
+			"extent":[383491.84,5080507.85,482969.27,5362930.84],
+			"proj4":"+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
+			"unit":"meter",
+			"codes":[],
+			"crs":"China Geodetic Coordinate System 2000",
+			"crsDetail":"CGCS2000 / 3-degree Gauss-Kruger CM 135E",
+			"crsAlias":"CGCS_2000_3度分带第45带(中央经线135E)_不加带号",
+			"ellipsoid":"CGCS2000",
+			"meridian":"Greenwich"
+		}
+	},
+	"order":[
+		{
+		"base":38,
+		"min":57,
+		"max":57
+		},
+		{
+		"base":43,
+		"min":26,
+		"max":26
+		},
+		{
+		"base":44,
+		"min":90,
+		"max":90
+		},
+		{
+		"base":45,
+		"min":13,
+		"max":33
+		},
+		{
+		"base":45,
+		"min":34,
+		"max":54
+		}
+	]
+}

+ 1381 - 0
src/utils/arcMap.js

@@ -0,0 +1,1381 @@
+/*
+ * @Descripttion: 
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2023-07-04 15:37:05
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2023-07-10 09:41:57
+ */
+import "ol/ol.css";
+import { Map, View } from 'ol';
+import TileLayer from 'ol/layer/Tile';
+import XYZ from 'ol/source/XYZ'
+import { fromLonLat, get, transform, Projection } from 'ol/proj';
+import MousePosition from 'ol/control/MousePosition';
+import VectorLayer from 'ol/layer/Vector';
+import VectorSource from 'ol/source/Vector';
+import { Fill, Stroke, Circle, Style, Icon, Text } from 'ol/style';
+import Feature from 'ol/Feature';
+import LinearRing from 'ol/geom/LinearRing';
+import Overlay from 'ol/Overlay';
+import TileArcGISRest from 'ol/source/TileArcGISRest';
+// import arcMap from "@/utils/map.js";
+import request from '@/utils/requestTwo.js'
+import EsriJSON from 'ol/format/EsriJSON';
+import { getTopLeft, getWidth, buffer, getCenter } from 'ol/extent';
+import '@/assets/less/map.less'
+// import MapConfig from '@/utils/mapconfig';
+import GeoJSON from 'ol/format/GeoJSON';
+import { getVectorContext } from 'ol/render';
+// import store from '@/store'
+// import { GetFieldValue } from "@/api/ghyzt/yztfield.js";
+import VectorTileLayer from 'ol/layer/VectorTile';
+import VectorTileSource from 'ol/source/VectorTile';
+import MVT from 'ol/format/MVT';
+import { createXYZ } from 'ol/tilegrid';
+import { appendParams } from 'ol/uri';
+import axios from "axios";
+import { createMapboxStreetsV6Style } from "@/utils/mvt_style.js";
+import {
+    LineString,
+    MultiLineString,
+    MultiPoint,
+    MultiPolygon,
+    Point,
+    Polygon,
+} from 'ol/geom';
+import { baseLayer } from './baseLayer.js'
+import { ElMessage } from "element-plus";
+
+var map;
+
+const arcMap = (function() {
+    var myMaps = {
+        _basemap: null,
+        _domid: null,
+        _EPSG: null,
+        _center: [121.662, 43.798],
+        EPSG: {
+            C3857: 'EPSG:3857',
+            C4326: 'EPSG:4326',
+            C4490: 'EPSG:4490', //国家2000
+            C4610: 'EPSG:4610', //西安1980
+        },
+        //地图
+        map: {},
+        //对比的地图
+        map1: null,
+        map2: null,
+        map3: null,
+        map4: null,
+        //比较地图
+        compareMap(type, view, item, option) {
+            var imgsource;
+            if (option.source) {
+                imgsource = option.source
+            } else {
+                if (item.type == 'WMTS') {
+                    imgsource = new XYZ({
+                        url: item.url + `/tile/{z}/{y}/{x}`,
+                    });
+                } else {
+                    imgsource = new TileArcGISRest({
+                        url: item.url,
+                    });
+                }
+            }
+            arcMap[type] = new Map({
+                layers: [
+                    new TileLayer({
+                        name: item.url,
+                        source: imgsource,
+                    })
+                ],
+                view: view,
+                target: type
+            })
+            var la = new VectorLayer({
+                name: "compare-feature",
+                declutter: false,
+                source: new VectorSource({
+                    features: [],
+                }),
+                style: new Style({
+                    stroke: new Stroke({
+                        color: '#1171d6',
+                        width: 4,
+                        lineDash: [1, 2, 3, 4, 5, 6],
+                    }),
+                }),
+                zIndex: 9,
+                visible: true
+            });
+            var la1 = new VectorLayer({
+                name: "detailedLayer",
+                declutter: false,
+                className: 'layer',
+                source: new VectorSource({
+                    features: [],
+                }),
+                style: new Style({
+                    stroke: new Stroke({
+                        color: '#ff0000',
+                        width: 2,
+                    }),
+                }),
+                zIndex: 9,
+                visible: true
+            });
+            var pointLayer = new VectorLayer({
+                zIndex: 999,
+                declutter: false,
+                source: new VectorSource(),
+                visible: false,
+            });
+            arcMap.addLayer(pointLayer, type);
+            // 把绘制了的canvas设置到style里面
+            var style = new Style({
+                image: new Icon({
+                    src: new URL('../assets/map/point.png',
+                        import.meta.url).href,
+                    // imgSize: [canvas.width, canvas.height],
+                    // rotation: (item.psjd-90) * Math.PI / 180
+                })
+            });
+            //创建一个Feature,并设置好在地图的位置
+            var shape = new Feature({
+                geometry: new Point([view.getCenter()[0], view.getCenter()[1]]),
+                id: 'screenCenter' + type,
+            });
+            // 应用具有不规则几何图形的样式到Feature
+            shape.setId('screenCenter' + type)
+            shape.setStyle(style);
+            // 将Feature添加到之前的创建的layer中去
+            pointLayer.getSource().addFeature(shape);
+
+            arcMap[type].addLayer(la, type);
+            arcMap[type].addLayer(la1, type);
+            if (option.click) {
+                arcMap[type].on('singleclick', function(evt) {
+                    for (var i = 1; i <= 4; i++) {
+                        if (arcMap['map' + i]) {
+                            arcMap['map' + i].removeOverlay(arcMap['map' + i].getOverlayById("popup_temp" + 'map' + i));
+                        }
+                    }
+                    var lonlat = arcMap.webMercatorToWgs84(evt.coordinate[0], evt.coordinate[1]);
+                    var view = arcMap[type].getView();
+                    arcMap.SearchWfsByLoc(item.url, `${lonlat[0]},${lonlat[1]}`, (view.getResolution() * 6.7), function(d, f) {
+                        if (d.length) {
+                            for (var i = 1; i <= 4; i++) {
+                                if (arcMap['map' + i]) {
+                                    var _cmap = arcMap.getLayerByNameAndMap('compare-feature', 'map' + i);
+                                    _cmap.getSource().clear();
+                                    _cmap.getSource().addFeatures(d);
+                                }
+                            }
+                            if (!item.attrs) {
+                                var data = d[0].getProperties();
+                                var header = [];
+                                for (let key in data) {
+                                    if (key != 'geometry') {
+                                        header.push({
+                                            sxbm: key,
+                                            sxmc: key
+                                        })
+                                    }
+                                }
+                                item.attrs = header;
+                            }
+                            arcMap.popupInfo({
+                                feature: d[0],
+                                type: type,
+                                position: evt,
+                                title: item.name,
+                                attrs: item.attrs
+                            })
+                            arcMap[type].updateSize();
+                        } else {
+
+                        }
+                    })
+                });
+            }
+            if (option.autoPupop) {
+                // arcMap[type].on('movestart',function(evt){
+                //     pointLayer.setVisible(false)
+                // })
+                arcMap[type].on('moveend', function(evt) {
+                    let cur_feature = pointLayer.getSource().getFeatureById('screenCenter' + type)
+                    if (cur_feature) {
+                        let CPoint = [arcMap[type].getView().getCenter()[0], arcMap[type].getView().getCenter()[1]]
+                        cur_feature.setGeometry(new Point(CPoint))
+                        var lonlat = arcMap.webMercatorToWgs84(CPoint[0], CPoint[1]);
+                        var view = arcMap[type].getView();
+                        for (var i = 1; i <= 4; i++) {
+                            if (arcMap['map' + i]) {
+                                arcMap['map' + i].removeOverlay(arcMap['map' + i].getOverlayById("popup_temp" + 'map' + i));
+                            }
+                        }
+                        arcMap.SearchWfsByLoc(item.url, `${lonlat[0]},${lonlat[1]}`, (view.getResolution() * 6.7), function(d, f) {
+                            if (d.length) {
+                                for (var i = 1; i <= 4; i++) {
+                                    if (arcMap['map' + i]) {
+                                        var _cmap = arcMap.getLayerByNameAndMap('compare-feature', 'map' + i);
+                                        _cmap.getSource().clear();
+                                        _cmap.getSource().addFeatures(d);
+                                    }
+                                }
+                                if (!item.attrs) {
+                                    var data = d[0].getProperties();
+                                    var header = [];
+                                    for (let key in data) {
+                                        if (key != 'geometry') {
+                                            header.push({
+                                                sxbm: key,
+                                                sxmc: key
+                                            })
+                                        }
+                                    }
+                                    item.attrs = header;
+                                }
+                                arcMap.popupInfo({
+                                    feature: d[0],
+                                    type: type,
+                                    position: { coordinate: CPoint },
+                                    title: item.name,
+                                    attrs: item.attrs
+                                })
+                                arcMap[type].updateSize();
+                            }
+                        })
+                    }
+                    // pointLayer.setVisible(true)
+                })
+            }
+        },
+        loadMap: function(domId, par = {}) {
+            var _op = {
+                center: MapCenter.point,
+                zoom: 8,
+                // base: ["tdtImg", "tdtImgAnn", "tdtVec", "tdtVecAnn", "jxMap", "cityLine"],
+                base: ["tdtImg"],
+                view: null
+            };
+            var option = Object.assign({}, _op, par);
+            //构建默认地图视图
+            if (!option.view) {
+                option.view = new View({
+                    projection: get('EPSG:3857'),
+                    center: fromLonLat(option.center),
+                    zoom: option.zoom,
+                    units: 'm',
+                    minZoom: 2,
+                })
+            }
+
+            arcMap._EPSG = arcMap.EPSG.C3857;
+            this._domid = domId;
+
+            this._basemap = [];
+            for (var i = 0; i < option.base.length; i++) {
+                var _layer = baseLayer[option.base[i]]();
+                if (_layer) {
+                    if (i == 0) {
+                        _layer.setVisible(true);
+                    }
+                    arcMap._basemap.push(_layer);
+                }
+            }
+            map = arcMap.map = new Map({
+                target: domId,
+                layers: this._basemap,
+                // view: option.view
+                view: new View({
+                    projection: get("EPSG:3857"),
+                    center: fromLonLat(option.center),
+                    zoom: option.zoom,
+                    units: "m",
+                    minZoom: 2,
+                }),
+            });
+            this.tempLayers.init();
+            // if (!option.hideCity)
+            //     this.cityLineDefault(!par.zoom)
+            // else if (!par.zoom)
+            // arcMap.zoomToextent(MapCenter.extent)
+        },
+        tempLayers: {
+            _draw: "dview_draw_Layer",
+            _factor: "dview_factor_Layer",
+            _search: "dview_search_Layer",
+            _fliter: "dview_fliter_Layer",
+            _location: "dview_location_Layer",
+            _cover: "dview_cover_Layer", // 影像查询_覆盖率_已覆盖的图层
+            _notcover: "dview_notcover_Layer", // 影像查询_覆盖率_未覆盖的图层
+            _extent: "dview_extent_Layer", // 影像查询四至范围边框
+            _hightlight_extent: "dview_hightlight_extent_Layer", // 影像查询四至范围边框
+
+            dview_draw_Layer: null,
+            dview_factor_Layer: null,
+            dview_search_Layer: null,
+            dview_fliter_Layer: null,
+            dview_location_Layer: null,
+            dview_cover_Layer: null,
+            dview_notcover_Layer: null,
+            dview_extent_Layer: null,
+            dview_hightlight_extent_Layer: null,
+            init: function() {
+                if (!arcMap.getLayer(this._draw)) {
+                    arcMap.addLayer(arcMap.CreateVecLayer(this._draw));
+                    this.dview_draw_Layer = arcMap.getLayer(this._draw);
+                }
+                if (!arcMap.getLayer(this._factor)) {
+                    var style = new Style({
+                        image: new Circle({
+                            radius: 7,
+                            fill: new Fill({
+                                color: "#1171d6",
+                            }),
+                        }),
+                        stroke: new Stroke({
+                            color: "#1171d6",
+                            width: 2,
+                            lineDash: [1, 2, 3, 4, 5, 6],
+                        }),
+                    });
+                    arcMap.addLayer(arcMap.CreateVecLayer(this._factor, style));
+                    this.dview_factor_Layer = arcMap.getLayer(this._factor);
+                }
+                if (!arcMap.getLayer(this._search)) {
+                    arcMap.addLayer(arcMap.CreateVecLayerOfPopup(this._search));
+                    this.dview_search_Layer = arcMap.getLayer(this._search);
+                    this.dview_search_Layer.setStyle(arcMap.SetSelectStyle);
+                }
+                if (!arcMap.getLayer(this._fliter)) {
+                    var style = new Style({
+                        fill: new Fill({
+                            color: "rgba(0, 120, 215,0.01)",
+                        }),
+                        stroke: new Stroke({
+                            color: "#0078d7",
+                            width: 2,
+                        }),
+                    });
+                    arcMap.addLayer(arcMap.CreateVecLayer(this._fliter, style));
+                    this.dview_fliter_Layer = arcMap.getLayer(this._fliter);
+                }
+                if (!arcMap.getLayer(this._location)) {
+                    arcMap.addLayer(
+                        arcMap.CreateVecLayer(
+                            this._location,
+                            new Style({
+                                fill: new Fill({
+                                    color: "rgba(255, 255, 255, 0.05)",
+                                }),
+                                stroke: new Stroke({
+                                    color: "#FF0000",
+                                    width: 2,
+                                }),
+                                image: new Circle({
+                                    radius: 7,
+                                    fill: new Fill({
+                                        color: "#FF0000",
+                                    }),
+                                }),
+                            }),
+                            null,
+                            99999
+                        )
+                    );
+                    this.dview_location_Layer = arcMap.getLayer(this._location);
+                }
+                if (!arcMap.getLayer(this._cover)) {
+                    arcMap.addLayer(
+                        arcMap.CreateVecLayer(
+                            this._cover,
+                            new Style({
+                                fill: new Fill({
+                                    color: "rgba(138, 239, 185, 0.8)",
+                                }),
+                                stroke: new Stroke({
+                                    color: "rgba(138, 239, 185, 0.8)",
+                                    width: 1,
+                                }),
+                                // image: new Circle({
+                                //     radius: 7,
+                                //     fill: new Fill({
+                                //         color: "#FF0000",
+                                //     }),
+                                // }),
+                            }),
+                            null,
+                            99999
+                        )
+                    );
+                    this.dview_cover_Layer = arcMap.getLayer(this._cover);
+                }
+                if (!arcMap.getLayer(this._notcover)) {
+                    arcMap.addLayer(
+                        arcMap.CreateVecLayer(
+                            this._notcover,
+                            new Style({
+                                fill: new Fill({
+                                    color: "rgba(251, 245, 78, 0.8)",
+                                }),
+                                stroke: new Stroke({
+                                    color: "rgba(251, 245, 78, 0.8)",
+                                    width: 1,
+                                }),
+                            }),
+                            null,
+                            99999
+                        )
+                    );
+                    this.dview_notcover_Layer = arcMap.getLayer(this._notcover);
+                }
+                if (!arcMap.getLayer(this._extent)) {
+                    arcMap.addLayer(
+                        arcMap.CreateVecLayer(
+                            this._extent,
+                            new Style({
+                                fill: new Fill({
+                                    color: "rgba(251, 245, 78, 0)",
+                                }),
+                                stroke: new Stroke({
+                                    color: "rgba(0, 0, 255, 1)",
+                                    width: 2,
+                                }),
+                            }),
+                            null,
+                            99999
+                        )
+                    );
+                    this.dview_extent_Layer = arcMap.getLayer(this._extent);
+                }
+                if (!arcMap.getLayer(this._hightlight_extent)) {
+                    arcMap.addLayer(
+                        arcMap.CreateVecLayer(
+                            this._hightlight_extent,
+                            new Style({
+                                fill: new Fill({
+                                    color: "rgba(255, 255, 255, 0.05)",
+                                }),
+                                stroke: new Stroke({
+                                    color: "#FF0000",
+                                    width: 2,
+                                }),
+                            }),
+                            null,
+                            99999
+                        )
+                    );
+                    this.dview_hightlight_extent_Layer = arcMap.getLayer(this._hightlight_extent);
+                }
+            },
+            clear: function(layer) {
+                if (layer) {
+                    layer.getSource().clear();
+                } else {
+                    this.dview_draw_Layer.getSource().clear();
+                    this.dview_factor_Layer.getSource().clear();
+                    this.dview_search_Layer.getSource().clear();
+                    this.dview_fliter_Layer.getSource().clear();
+                    this.dview_location_Layer.getSource().clear();
+                    this.dview_cover_Layer.getSource().clear();
+                    this.dview_notcover_Layer.getSource().clear();
+                    this.dview_extent_Layer.getSource().clear();
+                    this.dview_hightlight_extent_Layer.getSource().clear();
+                }
+            }
+        },
+        cityLineDefault(zoom) {
+            request({
+                url: `/js/${XZQ_DM}.geojson`,
+                method: 'get',
+            }).then(res => {
+                var f = new GeoJSON().readFeatures(Base64.decode(res));
+                var city = baseLayer.cityLine();
+                city.getSource().addFeatures(f);
+                city.setVisible(true);
+                arcMap.addLayer(city);
+                if (zoom)
+                    arcMap.zoomToextent(f[0].getGeometry().getExtent())
+            })
+        },
+        //按name获取
+        getLayer: function(name) {
+            var layer_ = null;
+            this.map.getLayers().forEach(function(layer, i) {
+                if (layer && layer.get("name") && layer.get("name") == name.toString()) {
+                    layer_ = layer;
+                    return;
+                }
+            });
+            return layer_;
+        },
+        //按id获取
+        getLayerById: function(id) {
+            var layer_ = null;
+            this.map.getLayers().forEach(function(layer, i) {
+                if (layer && layer.get("id") && layer.get("id") == id.toString()) {
+                    layer_ = layer;
+                    return;
+                }
+            });
+            return layer_;
+        },
+        //获取指定地图的图层
+        getLayerByNameAndMap: function(name, type) {
+            var layer_ = null;
+            this[type].getLayers().forEach(function(layer) {
+                if (layer && layer.get("name") && layer.get("name") == name) {
+                    layer_ = layer;
+                    return;
+                }
+            });
+            return layer_;
+        },
+        zoomToextent: function(extent, meters) {
+            meters = meters || 1000
+            var view = arcMap.map.getView()
+            view.fit(buffer(extent, meters), arcMap.map.getSize());
+        },
+        zoomToFeature: function(feature, meters) {
+            meters = meters || 1000;
+            let extent;
+            //添加支持多个feature sky220622 
+            if (Array.isArray(feature)) {
+                let cords = [];
+                for (let i = 0; i < feature.length; i++) {
+                    let cord = feature[i].getGeometry().getExtent();
+                    cords.push([cord[0], cord[1]]);
+                    cords.push([cord[2], cord[3]]);
+                }
+                let testfs = new Feature({ geometry: new LineString(cords) })
+                extent = testfs.getGeometry().getExtent();
+            } else {
+                extent = feature.getGeometry().getExtent();
+            }
+            arcMap.map.zoomToextent(feature.getGeometry().getExtent(), meters)
+        },
+        //缩放到中心点
+        zoomToCenter: function(zoom, center) {
+            var view = arcMap.map.getView()
+            view.setZoom(zoom || 12);
+            view.setCenter(fromLonLat(center || myMaps._center));
+        },
+        //缩放到图层
+        zoomToLayer: function(layurl, cl) {
+            var url = layurl + '?f=pjson' //空间查询url;
+            request({
+                method: 'get',
+                url: url,
+            }).then(res => {
+                var extent = [res.fullExtent.xmin, res.fullExtent.ymin, res.fullExtent.xmax, res.fullExtent.ymax];
+                myMaps.zoomToextent(extent, 20000)
+                if (cl) cl(extent);
+            })
+        },
+        //移动
+        moveToFeature: function(feature) {
+            let extent;
+            //sky220622 添加支持多个feature
+            if (Array.isArray(feature)) {
+                let cords = [];
+                for (let i = 0; i < feature.length; i++) {
+                    let cord = feature[i].getGeometry().getExtent();
+                    cords.push([cord[0], cord[1]]);
+                    cords.push([cord[2], cord[3]]);
+                }
+                let testfs = new Feature({ geometry: new LineString(cords) })
+                extent = testfs.getGeometry().getExtent();
+            } else {
+                extent = feature.getGeometry().getExtent();
+            }
+            var center = getCenter(extent)
+            var view = arcMap.map.getView()
+            view.setCenter(center);
+            arcMap.map.render();
+        },
+        addLayer: function(layer, type) {
+            if (type) {
+                this[type].addLayer(layer);
+            } else {
+                this.map.addLayer(layer);
+            }
+        },
+        //删除图层
+        removeLayer: function(layer) {
+            var _layer = layer
+            if (typeof(layer) == "string")
+                _layer = arcMap.getLayer(layer)
+            if (_layer)
+                _layer.setVisible(false);
+            this.map.removeLayer(_layer);
+        },
+        CreateVecLayer: function(layername, style, popup) {
+            style = style || new Style({
+                fill: new Fill({
+                    color: 'rgba(255, 255, 255, 0.2)'
+                }),
+                stroke: new Stroke({
+                    color: '#00008B',
+                    width: 2
+                }),
+                image: new Circle({
+                    radius: 7,
+                    fill: new Fill({
+                        color: '#00008B'
+                    })
+                })
+            });
+            if (typeof(style) == "string") {
+                style = MapConfig[style].style;
+            }
+            var _VectorLayer = new VectorLayer({
+                zIndex: 9,
+                declutter: false,
+                source: new VectorSource(),
+                name: layername,
+                style: style,
+                visible: true
+            });
+            if (popup) this.CreateLayerPopup(_VectorLayer, popup);
+            return _VectorLayer;
+        },
+        SetSelectStyle: function(feature, resolution) {
+            return new Style({
+                fill: new Fill({
+                    color: 'rgba(255, 255, 255, 0.2)'
+                }),
+                stroke: new Stroke({
+                    color: '#ffcc33',
+                    width: 2
+                }),
+                image: new Circle({
+                    radius: 7,
+                    fill: new Fill({
+                        color: '#ffcc33'
+                    })
+                }),
+            });
+        },
+        //地图平移
+        animateByGeom(g) {
+            var view = arcMap.map.getView();
+            var center = g.getCenter();
+            view.animate({
+                center: fromLonLat([center[0], center[1]]),
+                zoom: arcMap.map.getView().getZoom(),
+                duration: 1000,
+            });
+        },
+        CreateVecLayerOfPopup: function(layername, style) {
+            return this.CreateVecLayer(layername, style, true);
+        },
+        CreateLayerPopup: function(layer, popup) {
+            if (layer && typeof(layer) != "object")
+                layer = arcMap.getLayer(layer);
+            if (layer)
+                layer.popupInfo = popup;
+            return layer;
+        },
+        lonLatToWebMercator: function(lon, lat) {
+            var x = lon * 20037508.34 / 180;
+            var y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
+            y = y * 20037508.34 / 180;
+            return [x, y];
+        },
+        webMercatorToWgs84: function(x, y) {
+            var lon = x / 20037508.34 * 180;
+            var lat = y / 20037508.34 * 180;
+            lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2);
+            return [lon, lat];
+        },
+        LonLatDisplay: function() {
+            var mousePositionControl = new MousePosition({
+                coordinateFormat: function(e) {
+                    var es = arcMap.webMercatorToWgs84(e[0], e[1])
+                    return "经度:" + es[0].toFixed(2) + "° , 纬度:" + es[1].toFixed(2) + "°";
+                },
+                projection: get('EPSG:3857'),
+                className: 'lonlat',
+                target: document.getElementById('lonlat'),
+                undefinedHTML: '&nbsp;',
+            });
+            mousePositionControl.setMap(arcMap.map);
+        },
+        removePopupOverlay: function() {
+            arcMap.map.removeOverlay(arcMap.getPopupOverlay());
+        },
+        getPopupOverlay: function() {
+            return this.map.getOverlayById("popup_temp");
+        },
+        addOverlay: function(Overlay, type) {
+            if (type) {
+                this[type].addOverlay(Overlay);
+            } else {
+                this.map.addOverlay(Overlay);
+            }
+        },
+        //地图弹窗--点
+        popupInfo: function(option) {
+            var feature = option.feature;
+            var evt = option.position;
+            var _popupId_ = option.type ? "popup_temp" + option.type : "popup_temp";
+            if (typeof(option.type) == 'string') {
+                arcMap[option.type].removeOverlay(this.map.getOverlayById(_popupId_));
+            } else {
+                option.type = null;
+                arcMap.map.removeOverlay(arcMap.getPopupOverlay());
+            }
+            var html = arguments[1];
+            if (!html) {
+                html = "<div id='" + _popupId_ + "' class='map-popupinfo'>";
+                html += "<div class='popupinfo-title' >" + option.title + "<el-icon class='pointer popupinfo-close' id='closePop'><close /></el-icon></div>";
+                html += "<ul class='popupinfo-content'>";
+                if (Object.keys(option.attrs).length > 0) {
+                    for (var p in option.attrs) {
+                        var _value = feature.get(option.attrs[p].sxmc);
+                        if (option.attrs[p].callback) {
+                            _value = option.attrs[p].callback(_value)
+                        }
+                        if (_value == null) {
+                            _value = ''
+                        }
+                        html += "<li><span>" + (option.attrs[p].sxbm || option.attrs[p].name) + ":</span><span>" + _value + "</span></li>";
+                    }
+                }
+            }
+            html += "</ul><div class='popupinfo-poi'></div></div>";
+            var para = document.createElement("p");
+            para.innerHTML = html;
+            var text = option.type ? document.getElementById(option.type) : document.getElementById(arcMap._domid)
+            text.appendChild(para);
+            if (option.type) {
+                document.getElementById("closePop").onclick = function() {
+                    arcMap[option.type].removeOverlay(arcMap[option.type].getOverlayById(_popupId_));
+                }
+            } else {
+                document.getElementById("closePop").onclick = function() {
+                    arcMap.map.removeOverlay(arcMap.getPopupOverlay());
+                }
+            }
+            var popupElement = document.getElementById(_popupId_);
+            var coord = evt ? evt.coordinate : feature.getGeometry().getCoordinates();
+            var _overlay = new Overlay({
+                id: _popupId_,
+                position: coord,
+                positioning: 'bottom-center',
+                element: popupElement,
+                stopEvent: true,
+                autoPan: true,
+                autoPanAnimation: {
+                    duration: 250,
+                }
+            });
+            arcMap[option.type].addOverlay(_overlay, option.type);
+            popupElement.parentElement.style.zIndex = 1;
+            return _overlay;
+        },
+        SearchWfsByLoc: function(layers, feature, buffer, callback, layerParams) {
+            if (typeof(feature) == "string") {
+                var lonlat = (feature || '').split(",");
+                var point = fromLonLat(transform([lonlat[0], lonlat[1]], 'EPSG:3857', 'EPSG:4326'));
+                feature = new Feature({ geometry: new Point(arcMap.lonLatToWebMercator(point[0], point[1])) });
+            }
+            var geom;
+            var bf;
+            if (buffer) {
+                var ol3 = new jsts.io.OL3Parser();
+                ol3.inject(
+                    Point,
+                    LineString,
+                    LinearRing,
+                    Polygon,
+                    MultiPoint,
+                    MultiLineString,
+                    MultiPolygon
+                );
+                bf = new Feature({
+                    geometry: ol3.write(ol3.read(feature.getGeometry()).buffer(buffer))
+                });
+                geom = bf.getGeometry();
+            } else {
+                geom = feature.getGeometry();
+            }
+            arcMap.SearchWfsData(layers, geom, function(datas, res) {
+                callback(datas, bf, res);
+            }, layerParams)
+        },
+        //WFS查询
+        SearchWfsData: function(layers, data, cl, layerParams) {
+            if (!layers) {
+                console.warn("查询图层为空")
+                return;
+            }
+            var geo = new EsriJSON().writeGeometry(data);
+            var geometryType = 'esriGeometryPolygon';
+            if (data.getType() == 'Point') {
+                geometryType = 'esriGeometryPoint'
+            }
+            var params = {
+                "f": "json",
+                geometry: geo,
+                geometryType: geometryType,
+                inSR: 3857,
+                outSR: 3857,
+                returnGeometry: true,
+                spatialRel: 'esriSpatialRelIntersects',
+                outFields: "*"
+            };
+            const formData = new FormData();
+            for (let key in params) {
+                formData.append(key, params[key])
+            }
+            var url = layers.endsWith('query') ? layers : layers + '/0/query' //空间查询url;
+            request({
+                method: 'post',
+                url: url,
+                data: formData,
+                dataType: "json",
+            }).then(res => {
+                var features = new EsriJSON().readFeatures(res);
+                let aliases = res.fieldAliases
+                if (layerParams && layerParams.bsm) {
+                    // 对字典表进行优化,避免同一图层多次查询,vuex保存字典
+                    let haveDict = store.state.zyll.layerDict[layerParams.bsm]
+                    if (haveDict && Object.keys(haveDict).length > 0) {
+                        aliases = haveDict
+                        if (cl) cl(features, aliases);
+                    } else {
+                        // 查询字典维护表,若配置过有数据则查字典进行汉化,否则去查询server别名
+                        GetFieldValue({ bsm: layerParams.bsm }).then(res => {
+                            if (res.success) {
+                                if (res.data.length > 0) {
+                                    let obj = {},
+                                        dicObj = {}
+                                    res.data.map(t => {
+                                        obj[t.fieldname] = t.fieldaliasname
+                                    })
+                                    dicObj[layerParams.bsm] = obj
+                                    store.commit("SET_LAYERDICT", dicObj);
+                                    aliases = obj
+                                }
+                            }
+                        }).finally(() => { if (cl) cl(features, aliases); })
+                    }
+                } else {
+                    if (cl) cl(features, aliases);
+                }
+            })
+        },
+        //wfs属性查询
+        SearchWfsFilter(layers, filter, cl, layerParams) {
+            if (!layers) {
+                console.warn("查询图层为空")
+                return;
+            }
+            var url = layers.endsWith('query') ? layers : layers + '/0/query' //空间查询url;
+            arcMap.SearchWfsFilter2(url, filter, cl, layerParams);
+        },
+        //wfs属性查询
+        SearchWfsFilter2(url, filter, cl, layerParams) {
+            const formData = new FormData();
+            var params = {
+                "f": "pjson",
+                inSR: 3857,
+                outSR: 3857,
+                where: filter,
+                outFields: "*"
+            };
+            for (let key in params) {
+                formData.append(key, params[key])
+            }
+            request({
+                method: 'post',
+                url: url,
+                data: formData,
+                dataType: "json",
+            }).then(res => {
+                var features;
+                if (res.error && res.error.code == 400) {
+                    features = res.error
+                } else {
+                    features = new EsriJSON().readFeatures(res);
+                    let aliases = res.fieldAliases
+                    if (layerParams && layerParams.bsm) {
+                        // 对字典表进行优化,避免同一图层多次查询,vuex保存字典
+                        let haveDict = store.state.zyll.layerDict[layerParams.bsm]
+                        if (haveDict && Object.keys(haveDict).length > 0) {
+                            aliases = haveDict
+                            if (cl) cl(features, aliases);
+                        } else {
+                            // 查询字典维护表,若配置过有数据则查字典进行汉化,否则去查询server别名
+                            GetFieldValue({ bsm: layerParams.bsm }).then(res => {
+                                if (res.success) {
+                                    if (res.data.length > 0) {
+                                        let obj = {},
+                                            dicObj = {}
+                                        res.data.map(t => {
+                                            obj[t.fieldname] = t.fieldaliasname
+                                        })
+                                        dicObj[layerParams.bsm] = obj
+                                        store.commit("SET_LAYERDICT", dicObj);
+                                        aliases = obj
+                                    }
+                                }
+                            }).finally(() => { if (cl) cl(features, aliases); })
+                        }
+                    } else {
+                        if (cl) cl(features, aliases);
+                    }
+                }
+            })
+        },
+        // 获取字段
+        getField: function(layers, cl) {
+            var url = layers.url + '/0?f=pjson' //空间查询url;
+            request({
+                method: 'get',
+                url: url,
+            }).then(res => {
+                let aliases = {}
+                res.fields.map(t => {
+                    aliases[t.name] = t.alias
+                })
+                if (layers && layers.bsm) {
+                    // 对字典表进行优化,避免同一图层多次查询,vuex保存字典
+                    let haveDict = store.state.zyll.layerDict[layers.bsm]
+                    if (haveDict && Object.keys(haveDict).length > 0) {
+                        aliases = haveDict
+                        if (cl) cl(aliases);
+                    } else {
+                        // 查询字典维护表,若配置过有数据则查字典进行汉化,否则去查询server别名
+                        GetFieldValue({ bsm: layers.bsm }).then(res => {
+                            if (res.success) {
+                                if (res.data.length > 0) {
+                                    let obj = {},
+                                        dicObj = {}
+                                    res.data.map(t => {
+                                        obj[t.fieldname] = t.fieldaliasname
+                                    })
+                                    dicObj[layers.bsm] = obj
+                                    store.commit("SET_LAYERDICT", dicObj);
+                                    aliases = obj
+                                }
+                            }
+                        }).finally(() => { if (cl) cl(aliases); })
+                    }
+                } else {
+                    if (cl) cl(aliases);
+                }
+            })
+        },
+        //获取图例
+        getLegend: function(layers, cl) {
+            var url = layers + '/legend?f=pjson' //空间查询url;
+            request({
+                method: 'get',
+                url: url,
+            }).then(res => {
+                if (cl) cl(res.layers);
+            })
+        },
+        WMSTile: function(record) {
+            var _layer = new TileLayer({
+                name: record.url,
+                id: record.id,
+                source: new TileArcGISRest({
+                    url: record.url,
+                }),
+            });
+            arcMap.addLayer(_layer);
+        },
+        XYZTile: function(record) {
+            var imgsource = new XYZ({
+                crossOrigin: 'anonymous',
+                url: record.url,
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.id,
+                source: imgsource,
+            });
+            arcMap.addLayer(untiled);
+        },
+        TILE: function(record, call, zoom) {
+            var imgsource = new XYZ({
+                crossOrigin: 'anonymous',
+                url: record.url,
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1
+            });
+            if (call) {
+                return untiled;
+            }
+            arcMap.addLayer(untiled);
+            //ZOOM
+            if (zoom) {
+                arcMap.zoomToLayer(record.url);
+            }
+        },
+        // gdal矢量切片渲染
+        VectorTile: function(record, call, zoom) {
+            // var GDALPath = "../../.." + import.meta.env.VITE_BASE_API
+            var GDALPath =
+                import.meta.env.VITE_BASE_API
+
+            var tilesize = 512;
+            var layerWkid = 3857;
+            let LAYERDEF = {
+                DATAURI: record.DATAURI,
+                LAYERNAME: record.LAYERNAME,
+                SPATIALREF: !record.SPATIALREF ? 'EPSG:' + layerWkid : record.SPATIALREF,
+            }
+            axios.post(GDALPath + "/vector/gdb/cachelayer", { 'LAYERDEF': LAYERDEF }).then(function(data) {
+                if (data.code && data.code == 500) {
+                    ElMessage.warning(!data.msg ? '服务未找到' : data.msg)
+                    return
+                }
+                if (!data.data.LAYERINFO.EXTENT) {
+                    ElMessage.warning(`${record.LAYERNAME}图层要素为空!`)
+                    return
+                }
+                var layerId = data.data.LAYERID;
+                var tilegrid = createXYZ({
+                    extent: get('EPSG:' + layerWkid).getExtent(),
+                    maxZoom: 22,
+                    tileSize: [tilesize, tilesize]
+                });
+                var untiled = new VectorTileLayer({
+                    layerid: layerId,
+                    id: record.id,
+                    source: new VectorTileSource({
+                        format: new MVT(),
+                        projection: new Projection({ code: 'EPSG:' + layerWkid, units: 'm' }),
+                        //切片格网直接有4326坐标系统的坐标范围与缩放大小指定,因此每一级的都是固定的
+                        tileGrid: tilegrid,
+                        tileUrlFunction: function(tileCoord) {
+                            var extent = tilegrid.getExtent();
+                            var origin = getTopLeft(extent);
+                            var height = getWidth(extent);
+                            var tilemetric = height / (1 << tileCoord[0]);
+                            var minX = origin[0] + tilemetric * tileCoord[1];
+                            var maxX = minX + tilemetric;
+                            var maxY = origin[1] - tilemetric * tileCoord[2];
+                            var minY = maxY - tilemetric;
+                            var params = {};
+                            params["MINX"] = minX;
+                            params["MINY"] = minY;
+                            params["MAXX"] = maxX;
+                            params["MAXY"] = maxY;
+                            params["TILESIZE"] = tilesize;
+                            return appendParams(GDALPath + "/vector/gdb/gettile?LAYERID=" + layerId, params);
+                        }
+                    }),
+                });
+                if (record.style) {
+                    untiled.setStyle(new Style({
+                        fill: new Fill({
+                            color: record.style.fillColor
+                        }),
+                        stroke: new Stroke({
+                            color: record.style.strokeColor,
+                            width: 1
+                        }),
+                    }))
+                }
+                if (record.styleByField) {
+                    untiled.setStyle(createMapboxStreetsV6Style(Style, Fill, Stroke, Icon, Text))
+                }
+                if (call) {
+                    return untiled;
+                }
+                arcMap.addLayer(untiled);
+
+                var extent = [
+                    data.data.LAYERINFO.EXTENT.MINX,
+                    data.data.LAYERINFO.EXTENT.MINY,
+                    data.data.LAYERINFO.EXTENT.MAXX,
+                    data.data.LAYERINFO.EXTENT.MAXY,
+                ];
+                arcMap.zoomToextent(extent);
+
+                //ZOOM
+                if (zoom) {
+                    arcMap.zoomToLayer(record.url);
+                }
+            }).catch(function(error) {
+                console.log(error);
+                ElMessage.warning('服务未找到')
+            });
+        },
+        // gdal影像切片渲染
+        RasterTile: function(record, call, zoom) {
+            // var GDALPath = "../../.." + import.meta.env.VITE_BASE_API
+            var GDALPath =
+                import.meta.env.VITE_BASE_API
+            var tilesize = 512;
+            var layerWkid = 3857;
+            let bands = [1, 2, 3]
+                // 判断 如果影像名称包含以PAN结尾的数据,波段只传[1]
+            let nameSub = record.LAYERNAME.split("-")
+            if (nameSub[nameSub.length - 1].indexOf('PAN') > -1) {
+                bands = [1]
+            }
+            let LAYERDEF = {
+                DATAURI: record.DATAURI,
+                SPATIALREF: !record.SPATIALREF ? 'EPSG:' + layerWkid : record.SPATIALREF,
+                PROJECTION: !record.SPATIALREF ? 'EPSG:' + layerWkid : record.SPATIALREF,
+                BANDS: bands,
+                STRETCH: true
+            }
+            axios.post(GDALPath + "/vector/gdalraster/cachelayer", { 'LAYERDEF': LAYERDEF }).then(function(data) {
+                if (data.code && data.code == 500) {
+                    ElMessage.warning(!data.msg ? '服务未找到' : data.msg)
+                    return
+                }
+                if (!data.data.LAYERINFO.WARPEDEXTENT) {
+                    // ElMessage.warning(`${record.LAYERNAME}图层要素为空!`)
+                    return
+                }
+                var layerId = data.data.LAYERID;
+
+                var untiled = new TileLayer({
+                    layerid: layerId,
+                    id: record.id,
+                    source: new XYZ({
+                        crossOrigin: "anonymous",
+                        projection: LAYERDEF.SPATIALREF,
+                        tileUrlFunction: function(tileCoord) {
+                            var z = tileCoord[0];
+                            var x = tileCoord[1];
+                            var y = tileCoord[2];
+                            //后端服务计算范围
+                            return GDALPath + "/vector/gdalraster/tilexyz/" + layerId + "/" + layerWkid + "/" + z + "/" + x + "/" + y + "";
+                        },
+                        wrapX: true,
+                    })
+                });
+                if (call) {
+                    return untiled;
+                }
+                arcMap.addLayer(untiled);
+
+                var extent = [
+                    data.data.LAYERINFO.WARPEDEXTENT.MINX,
+                    data.data.LAYERINFO.WARPEDEXTENT.MINY,
+                    data.data.LAYERINFO.WARPEDEXTENT.MAXX,
+                    data.data.LAYERINFO.WARPEDEXTENT.MAXY,
+                ];
+                arcMap.zoomToextent(extent);
+            }).catch(function(error) {
+                console.log(error);
+                ElMessage.warning('服务未找到')
+            });
+        },
+
+        WMS: function(record, call, zoom) {
+            var sou = { url: record.url };
+            if (record.show) {
+                sou.params = {
+                    layers: "show:" + record.show
+                }
+            }
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: new TileArcGISRest(sou),
+                zIndex: (record.sort || 1) * -1
+            });
+            if (call) {
+                return untiled;
+            }
+            arcMap.addLayer(untiled);
+        },
+        IMG: function(record, call, zoom) {
+            var imgsource = new TileArcGISRest({
+                url: record.url
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1
+            });
+            if (call) {
+                return untiled;
+            }
+            arcMap.addLayer(untiled);
+        },
+        WMTS: function(record, call, zoom) {
+            // debugger
+            var imgsource = new XYZ({
+                crossOrigin: 'anonymous',
+                url: record.url + `/tile/{z}/{y}/{x}`,
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1
+            });
+            if (call) {
+                return untiled;
+            }
+            arcMap.addLayer(untiled);
+            //ZOOM
+            if (zoom) {
+                arcMap.zoomToLayer(record.url);
+            }
+        },
+        //加载图层
+        addProLayer: function(record, call, zoom) {
+            const formData = new FormData();
+            var params = {
+                "f": "pjson",
+                'clipping': {
+                    "hasZ": false,
+                    "hasM": false,
+                    "rings": [
+                        [
+                            [11817057.906963758, 4591719.129383848],
+                            [11817057.906963758, 4666026.131804026],
+                            [11876165.754922504, 4666026.131804026],
+                            [11876165.754922504, 4591719.129383848],
+                            [11817057.906963758, 4591719.129383848]
+                        ]
+                    ]
+                }
+            }
+            for (let key in params) {
+                formData.append(key, params[key])
+            }
+            var imgsource = new TileArcGISRest({
+                url: record.url,
+                params: JSON.stringify(params)
+            });
+            var untiled = new TileLayer({
+                url: record.url,
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1,
+            });
+            if (call) {
+                return untiled;
+            }
+            arcMap.addLayer(untiled);
+        },
+        //feature转coordinates
+        featureToCoordinates(feature) {
+            console.log(feature)
+            var geo = feature.geometry;
+            console.log(geo)
+        },
+
+
+
+        //条件查询地图切片
+        mapQueryTile(features, layurl, name, field) {
+            var objList = []
+            features.map((res, i) => {
+                objList.push(res.get(field || 'OBJECTID'));
+            })
+            var _layer = new TileLayer({
+                url: layurl,
+                name: name || 'QueryTile_Lay',
+                source: new TileArcGISRest({
+                    url: layurl,
+                    params: {
+                        layerDefs: JSON.stringify({ "0": `${field || 'OBJECTID'} in (${objList.join(',')})` }),
+                    }
+                })
+            });
+            //如果名称是空,那就先移除之前的图层
+            if (!name) arcMap.removeLayer('QueryTile_Lay');
+            arcMap.addLayer(_layer);
+            return _layer;
+        },
+
+        //地图裁剪
+        mapClip(feature, layer) {
+            layer.on('prerender', function(event) {
+                var ctx = event.context;
+                const vectorContext = getVectorContext(event);
+                ctx.save();
+                vectorContext.drawGeometry(feature.getGeometry());
+                ctx.clip();
+            });
+            layer.on('postrender', function(event) {
+                var ctx = event.context;
+                ctx.restore();
+            });
+        },
+        //地图裁剪2
+        mapClip2(feature, layer) {
+            var map = this.map;
+            // layer.on('prerender', function (event) {
+            //   console.log(123456,event)
+            //   var ctx = event.context;
+            //   const vectorContext = getVectorContext(event);
+            //   ctx.save();
+            //   vectorContext.drawGeometry(feature.getGeometry());
+            //   ctx.clip();
+            // });
+            layer.on('postrender', function(event) {
+                let vectorContext = getVectorContext(event);
+                event.context.globalCompositeOperation = 'destination-in';
+                vectorContext.drawFeature(feature, new Style({
+                    fill: new Fill({
+                        color: 'black', // 必需设置颜色
+                    })
+                }));
+                event.context.globalCompositeOperation = 'source-over';
+            });
+        },
+        featureToGeojson(f) {
+            var geoJson = new GeoJSON().writeGeometry(f.getGeometry(), {
+                dataProjection: get(arcMap.EPSG.C4326),
+                featureProjection: get(arcMap._EPSG),
+            });
+            return geoJson;
+        },
+        //定位
+        onLocation(feature, zoom) {
+            var show = 0;
+            if (zoom === undefined) zoom = true;
+
+            function sansuo() {
+                arcMap.tempLayers.dview_location_Layer.getSource().clear();
+                if (show % 2 == 0) {
+                    if (Array.isArray(feature)) {
+                        arcMap.tempLayers.dview_location_Layer
+                            .getSource()
+                            .addFeatures(feature);
+                    } else {
+                        arcMap.tempLayers.dview_location_Layer
+                            .getSource()
+                            .addFeature(feature);
+                        if (zoom)
+                            arcMap.zoomToextent(feature.getGeometry().getExtent(), 500);
+                    }
+                }
+                if (show < 4) {
+                    setTimeout(() => {
+                        sansuo();
+                    }, 200);
+                }
+                show++;
+            }
+            sansuo();
+        },
+    }
+    return myMaps;
+})();
+export default arcMap;

+ 18 - 0
src/utils/auth.js

@@ -0,0 +1,18 @@
+import Cookies from 'js-cookie'
+
+/**
+ * Admin-Token
+ * Customer-Token
+ */
+
+export function getToken (TokenKey) {
+    return Cookies.get(TokenKey)
+}
+
+export function setToken (TokenKey, token) {
+    return Cookies.set(TokenKey, token)
+}
+
+export function removeToken (TokenKey) {
+    return Cookies.remove(TokenKey)
+}

+ 100 - 0
src/utils/baseLayer.js

@@ -0,0 +1,100 @@
+import "ol/ol.css";
+import TileLayer from "ol/layer/Tile";
+import XYZ from "ol/source/XYZ";
+import VectorLayer from "ol/layer/Vector";
+import VectorSource from "ol/source/Vector";
+import { Fill, Stroke, Circle, Style } from "ol/style";
+export const baseLayer = {
+    /*天地图影像*/
+    tdtImg() {
+        if (!BaseMap.tdtImg) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtImg",
+            name: "tdtImg",
+            zIndex: -1000000000,
+            visible: false,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtImg,
+            }),
+        });
+    },
+    /*天地图注记影像*/
+    tdtImgAnn() {
+        if (!BaseMap.tdtImgAnn) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtImgAnn",
+            zIndex: -999999999,
+            name: "tdtImgAnn",
+            visible: false,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtImgAnn,
+            }),
+        });
+    },
+    /*天地图矢量*/
+    tdtVec() {
+        if (!BaseMap.tdtVec) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtVec",
+            name: "tdtVec",
+            zIndex: -1000000000,
+            visible: true,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtVec,
+            }),
+        });
+    },
+    /*天地图注记矢量*/
+    tdtVecAnn() {
+        if (!BaseMap.tdtVecAnn) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtVecAnn",
+            zIndex: -999999999,
+            name: "tdtVecAnn",
+            visible: true,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtVecAnn,
+            }),
+        });
+    },
+    /*界线*/
+    jxMap() {
+        if (!BaseMap.jxMap) return null;
+        return new TileLayer({
+            //界线
+            id: "jxMap",
+            zIndex: -999999999,
+            name: "jxMap",
+            visible: true,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.jxMap,
+            }),
+        });
+    },
+    cityLine() {
+        return new VectorLayer({
+            name: "cityLine",
+            source: new VectorSource({
+                features: [],
+            }),
+            style: new Style({
+                stroke: new Stroke({
+                    color: "#f02fff",
+                    width: 2,
+                    lineDash: [1, 2, 3, 4, 5, 6],
+                }),
+            }),
+            zIndex: 9,
+            visible: false,
+        });
+    },
+};

+ 259 - 0
src/utils/common.js

@@ -0,0 +1,259 @@
+
+
+/**
+ * 通用js方法封装处理
+ * Copyright (c) 2019 ruoyi
+ */
+// 日期格式化
+export function getFamtterTimer(nosplit) {
+    //传入时间
+    let date = new Date(),
+        Y = date.getFullYear(), // 年
+        M = date.getMonth() + 1, //月
+        D = date.getDate(), //日
+        h = date.getHours(), //小时
+        m = date.getMinutes(), //分钟
+        s = date.getSeconds(); //秒数
+    // let timer = Y+ '-' + getZero(M) + '-' + getZero(D) + ' ' + getZero(h) + ':' + getZero(m) + ':' + getZero(s);
+    let timer = Y + "-" + getZero(M) + "-" + getZero(D);
+    if (nosplit) {
+        timer = Y + '' + getZero(M) + '' + getZero(D) + '' + getZero(h) + '' + getZero(m) + '' + getZero(s)
+    }
+    return timer;
+}
+
+// 日期格式化
+export function parseTime(time, pattern) {
+    if (arguments.length === 0 || !time) {
+        return null
+    }
+    const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+    let date
+    if (typeof time === 'object') {
+        date = time
+    } else {
+        if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+            time = parseInt(time)
+        } else if (typeof time === 'string') {
+            time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
+        }
+        if ((typeof time === 'number') && (time.toString().length === 10)) {
+            time = time * 1000
+        }
+        date = new Date(time)
+    }
+    const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+    }
+    const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+        let value = formatObj[key]
+        // Note: getDay() returns 0 on Sunday
+        if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+        if (result.length > 0 && value < 10) {
+            value = '0' + value
+        }
+        return value || 0
+    })
+    return time_str
+}
+
+// 表单重置
+export function resetForm(refName) {
+    if (this.$refs[refName]) {
+        this.$refs[refName].resetFields();
+    }
+}
+
+// 添加日期范围
+export function addDateRange(params, dateRange, propName) {
+    let search = params;
+    search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+    dateRange = Array.isArray(dateRange) ? dateRange : [];
+    if (typeof (propName) === 'undefined') {
+        search.params['beginTime'] = dateRange[0];
+        search.params['endTime'] = dateRange[1];
+    } else {
+        search.params['begin' + propName] = dateRange[0];
+        search.params['end' + propName] = dateRange[1];
+    }
+    return search;
+}
+
+// 回显数据字典
+export function selectDictLabel(datas, value) {
+    if (value === undefined) {
+        return "";
+    }
+    var actions = [];
+    Object.keys(datas).some((key) => {
+        if (datas[key].value == ('' + value)) {
+            actions.push(datas[key].label);
+            return true;
+        }
+    })
+    if (actions.length === 0) {
+        actions.push(value);
+    }
+    return actions.join('');
+}
+
+// 回显数据字典(字符串数组)
+export function selectDictLabels(datas, value, separator) {
+    if (value === undefined) {
+        return "";
+    }
+    var actions = [];
+    var currentSeparator = undefined === separator ? "," : separator;
+    var temp = value.split(currentSeparator);
+    Object.keys(value.split(currentSeparator)).some((val) => {
+        var match = false;
+        Object.keys(datas).some((key) => {
+            if (datas[key].value == ('' + temp[val])) {
+                actions.push(datas[key].label + currentSeparator);
+                match = true;
+            }
+        })
+        if (!match) {
+            actions.push(temp[val] + currentSeparator);
+        }
+    })
+    return actions.join('').substring(0, actions.join('').length - 1);
+}
+
+// 字符串格式化(%s )
+export function sprintf(str) {
+    var args = arguments, flag = true, i = 1;
+    str = str.replace(/%s/g, function () {
+        var arg = args[i++];
+        if (typeof arg === 'undefined') {
+            flag = false;
+            return '';
+        }
+        return arg;
+    });
+    return flag ? str : '';
+}
+
+// 转换字符串,undefined,null等转化为""
+export function parseStrEmpty(str) {
+    if (!str || str == "undefined" || str == "null") {
+        return "";
+    }
+    return str;
+}
+
+// 数据合并
+export function mergeRecursive(source, target) {
+    for (var p in target) {
+        try {
+            if (target[p].constructor == Object) {
+                source[p] = mergeRecursive(source[p], target[p]);
+            } else {
+                source[p] = target[p];
+            }
+        } catch (e) {
+            source[p] = target[p];
+        }
+    }
+    return source;
+};
+
+/**
+ * 构造树型结构数据
+ * @param {*} data 数据源
+ * @param {*} id id字段 默认 'id'
+ * @param {*} parentId 父节点字段 默认 'parentId'
+ * @param {*} children 孩子节点字段 默认 'children'
+ */
+export function handleTree(data, id, parentId, children) {
+    let config = {
+        id: id || 'id',
+        parentId: parentId || 'parentId',
+        childrenList: children || 'children'
+    };
+
+    var childrenListMap = {};
+    var nodeIds = {};
+    var tree = [];
+
+    for (let d of data) {
+        let parentId = d[config.parentId];
+        if (childrenListMap[parentId] == null) {
+            childrenListMap[parentId] = [];
+        }
+        nodeIds[d[config.id]] = d;
+        childrenListMap[parentId].push(d);
+    }
+
+    for (let d of data) {
+        let parentId = d[config.parentId];
+        if (nodeIds[parentId] == null) {
+            tree.push(d);
+        }
+    }
+
+    for (let t of tree) {
+        adaptToChildrenList(t);
+    }
+
+    function adaptToChildrenList(o) {
+        if (childrenListMap[o[config.id]] !== null) {
+            o[config.childrenList] = childrenListMap[o[config.id]];
+        }
+        if (o[config.childrenList]) {
+            for (let c of o[config.childrenList]) {
+                adaptToChildrenList(c);
+            }
+        }
+    }
+    return tree;
+}
+
+/**
+* 参数处理
+* @param {*} params  参数
+*/
+export function tansParams(params) {
+    let result = ''
+    for (const propName of Object.keys(params)) {
+        const value = params[propName];
+        var part = encodeURIComponent(propName) + "=";
+        if (value !== null && value !== "" && typeof (value) !== "undefined") {
+            if (typeof value === 'object') {
+                for (const key of Object.keys(value)) {
+                    if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
+                        let params = propName + '[' + key + ']';
+                        var subPart = encodeURIComponent(params) + "=";
+                        result += subPart + encodeURIComponent(value[key]) + "&";
+                    }
+                }
+            } else {
+                result += part + encodeURIComponent(value) + "&";
+            }
+        }
+    }
+    return result
+}
+
+// 验证是否为blob格式
+export async function blobValidate(data) {
+    try {
+        const text = await data.text();
+        JSON.parse(text);
+        return false;
+    } catch (error) {
+        return true;
+    }
+}
+function getZero(num) {
+    if (parseInt(num) < 10) {
+        num = "0" + num;
+    }
+    return num;
+}

+ 283 - 0
src/utils/echartsoption.js

@@ -0,0 +1,283 @@
+import * as echarts from 'echarts'
+const CubeLeft = echarts.graphic.extendShape({
+    shape: {
+        x: 0,
+        y: 0
+    },
+    buildPath: function (ctx, shape) {
+        const xAxisPoint = shape.xAxisPoint
+        const c0 = [shape.x, shape.y]
+        const c1 = [shape.x - 9, shape.y - 9]
+        const c2 = [xAxisPoint[0] - 9, xAxisPoint[1] - 9]
+        const c3 = [xAxisPoint[0], xAxisPoint[1]]
+        ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath()
+    }
+})
+const CubeRight = echarts.graphic.extendShape({
+    shape: {
+        x: 0,
+        y: 0
+    },
+    buildPath: function (ctx, shape) {
+        const xAxisPoint = shape.xAxisPoint
+        const c1 = [shape.x, shape.y]
+        const c2 = [xAxisPoint[0], xAxisPoint[1]]
+        const c3 = [xAxisPoint[0] + 18, xAxisPoint[1] - 9]
+        const c4 = [shape.x + 18, shape.y - 9]
+        ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
+    }
+})
+const CubeTop = echarts.graphic.extendShape({
+    shape: {
+        x: 0,
+        y: 0
+    },
+    buildPath: function (ctx, shape) {
+        const c1 = [shape.x, shape.y]
+        const c2 = [shape.x + 18, shape.y - 9]
+        const c3 = [shape.x + 9, shape.y - 18]
+        const c4 = [shape.x - 9, shape.y - 9]
+        ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
+    }
+})
+echarts.graphic.registerShape('CubeLeft', CubeLeft)
+echarts.graphic.registerShape('CubeRight', CubeRight)
+echarts.graphic.registerShape('CubeTop', CubeTop)
+
+export const barOption = (data, details) => {
+    var option = {
+        tooltip: {
+            trigger: "axis",
+            formatter: function (params) {
+                var str = '';
+                str += '<span style=\"display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:#9ec1dc;\"></span>' + params[0].seriesName + '<br/>';
+                str += params[0].value + '(万亩)<br/>';
+                str += '<span style=\"display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:#57a2d8;\"></span>' + params[1].seriesName + '<br/>';
+                str += params[1].value + '(万亩)<br/>';
+                return str;
+            }
+        },
+        grid: {
+            left: 10,
+            right: 10,
+            bottom: '2%',
+            top: 0,
+            containLabel: true
+        },
+        xAxis: {
+            type: 'category',
+            data: [data.name],
+            axisLine: {
+                show: false,
+                lineStyle: {
+                    color: 'white'
+                }
+            },
+            axisLabel: {
+                show: false,
+                fontSize: 10
+            }
+        },
+        yAxis: {
+            axisLine: {
+                show: false,
+            },
+            splitLine: {
+                show: false
+            },
+            axisTick: {
+                show: false
+            },
+            axisLabel: {
+                show: false
+            },
+        },
+        series: [{
+            name: details.name[0],
+            type: 'custom',
+            renderItem: function (params, api) {
+                const location = api.coord([api.value(0), api.value(1)])
+                return {
+                    type: 'group',
+                    children: [{
+                        type: 'CubeLeft',
+                        shape: {
+                            api,
+                            xValue: api.value(0),
+                            yValue: api.value(1),
+                            x: location[0],
+                            y: location[1],
+                            xAxisPoint: api.coord([api.value(0), 0])
+                        },
+                        style: {
+                            fill: 'rgba(47,102,192,.27)'
+                        }
+                    }, {
+                        type: 'CubeRight',
+                        shape: {
+                            api,
+                            xValue: api.value(0),
+                            yValue: api.value(1),
+                            x: location[0],
+                            y: location[1],
+                            xAxisPoint: api.coord([api.value(0), 0])
+                        },
+                        style: {
+                            fill: 'rgba(59,128,226,.27)'
+                        }
+                    }, {
+                        type: 'CubeTop',
+                        shape: {
+                            api,
+                            xValue: api.value(0),
+                            yValue: api.value(1),
+                            x: location[0],
+                            y: location[1],
+                            xAxisPoint: api.coord([api.value(0), 0])
+                        },
+                        style: {
+                            fill: 'rgba(72,156,221,.27)'
+                        }
+                    }]
+                }
+            },
+            data: [data[details.key[0]]]
+        }, {
+            name: details.name[1],
+            type: 'custom',
+            renderItem: (params, api) => {
+                const location = api.coord([api.value(0), api.value(1)])
+                return {
+                    type: 'group',
+                    children: [{
+                        type: 'CubeLeft',
+                        shape: {
+                            api,
+                            xValue: api.value(0),
+                            yValue: api.value(1),
+                            x: location[0],
+                            y: location[1],
+                            xAxisPoint: api.coord([api.value(0), 0])
+                        },
+                        style: {
+                            fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                                offset: 0,
+                                color: '#3B80E2'
+                            },
+                            {
+                                offset: 1,
+                                color: '#49BEE5'
+                            }
+                            ])
+                        }
+                    }, {
+                        type: 'CubeRight',
+                        shape: {
+                            api,
+                            xValue: api.value(0),
+                            yValue: api.value(1),
+                            x: location[0],
+                            y: location[1],
+                            xAxisPoint: api.coord([api.value(0), 0])
+                        },
+                        style: {
+                            fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                                offset: 0,
+                                color: '#3B80E2'
+                            },
+                            {
+                                offset: 1,
+                                color: '#49BEE5'
+                            }
+                            ])
+                        }
+                    }, {
+                        type: 'CubeTop',
+                        shape: {
+                            api,
+                            xValue: api.value(0),
+                            yValue: api.value(1),
+                            x: location[0],
+                            y: location[1],
+                            xAxisPoint: api.coord([api.value(0), 0])
+                        },
+                        style: {
+                            fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                                offset: 0,
+                                color: '#3B80E2'
+                            },
+                            {
+                                offset: 1,
+                                color: '#49BEE5'
+                            }
+                            ])
+                        }
+                    }]
+                }
+            },
+            data: [data[details.key[1]]]
+        }, {
+            type: 'bar',
+            label: {
+                normal: {
+                    show: true,
+                    position: 'bottom',
+                    fontSize: 13,
+                    // color: '#fff',
+                    offset: [4, -75],
+                    formatter: (params) => {
+                        return data[details.key[1]] + '/' + data[details.key[0]]
+                    },
+                }
+            },
+            itemStyle: {
+                color: 'transparent'
+            },
+            data: [data[details.key[0]]]
+        }]
+    }
+    return option;
+}
+
+export const locationXy = (id) => {
+    switch (id) {
+        case "150502": return [13615264.947860649, 5415246.494936824];
+        case "150581": return [13308801.721789824, 5702679.422572563];
+        case "150523": return [13508397.568782162, 5441363.345619797];
+        case "150522": return [13668920.274506062, 5351049.759446745];
+        case "150521": return [13638530.053519499, 5481891.613494568];
+        case "150524": return [13532442.578793507, 5289957.717064263];
+        case "150525": return [13453851.018293457, 5316417.441335446];
+        case "150526": return [13423126.838834513, 5606923.837556483];
+    }
+}
+
+export const formatKeyValue = (type) => {
+    switch (type) {
+        case "NcTdccjsgm":
+            var deatils = {
+                name: ['可承载耕地面积', '现状耕地面积'],
+                key: ['kczgdmj2', 'xzgdmj2'],
+            }
+            return deatils;
+
+        case "CzTdccjsgm":
+            var deatils = {
+                name: ['可承载建设规模', '现状城镇建设用地面积'],
+                key: ['kczjsgm', 'xzczjsydmj'],
+            }
+            return deatils;
+        case "Nyszy":
+            var deatils = {
+                name: ['可承载耕地规模', '现状耕地面积'],
+                key: ['kczdgdgm2', 'xzgdmj2'],
+            }
+            return deatils;
+        case "Czszy":
+            var deatils = {
+                name: ['可承载城镇建设用地规模', '现状城镇建设用地规模'],
+                key: ['kczczjsydgm', 'xzczjsydmj'],
+            }
+            return deatils;
+    }
+}

+ 1178 - 0
src/utils/map.js

@@ -0,0 +1,1178 @@
+import "ol/ol.css";
+import { Map, View } from "ol";
+import TileLayer from "ol/layer/Tile";
+import Layer from 'ol/layer/Layer';
+import XYZ from "ol/source/XYZ";
+import { fromLonLat, get, transform } from "ol/proj";
+import MousePosition from "ol/control/MousePosition";
+import VectorLayer from "ol/layer/Vector";
+import VectorSource from "ol/source/Vector";
+import ImageLayer from "ol/layer/Image";
+import ImageWMS from "ol/source/ImageWMS";
+import { Fill, Stroke, Circle, Style } from "ol/style";
+import Feature from "ol/Feature";
+import LinearRing from "ol/geom/LinearRing";
+import TileWMS from "ol/source/TileWMS";
+import WFS from "ol/format/WFS";
+import GeoJSON from "ol/format/GeoJSON";
+import WKT from "ol/format/WKT";
+import { intersects, like } from "ol/format/filter";
+import MapConfig from "@/utils/mapconfig";
+import Overlay from "ol/Overlay";
+import arcMap from "@/utils/arcMap.js";
+import { buffer, getCenter } from "ol/extent";
+import {
+    LineString,
+    MultiLineString,
+    MultiPoint,
+    MultiPolygon,
+    Point,
+    Polygon,
+} from "ol/geom";
+// import _FormItem from "element-plus/lib/el-form-item";
+import request from "@/utils/requestTwo.js";
+import * as echarts from "echarts";
+import {
+    barOption,
+    locationXy,
+    formatKeyValue,
+} from "@/utils/echartsoption.js";
+import { Base64 } from "js-base64";
+// let Base64 = require('js-base64').Base64;
+var map;
+export const baseLayer = {
+    /*天地图影像*/
+    tdtImg() {
+        if (!BaseMap.tdtImg) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtImg",
+            name: "tdtImg",
+            zIndex: -1000000000,
+            visible: true,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtImg,
+            }),
+        });
+    },
+    /*天地图注记影像*/
+    tdtImgAnn() {
+        if (!BaseMap.tdtImgAnn) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtImgAnn",
+            zIndex: -999999999,
+            name: "tdtImgAnn",
+            visible: true,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtImgAnn,
+            }),
+        });
+    },
+    /*天地图矢量*/
+    tdtVec() {
+        if (!BaseMap.tdtVec) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtVec",
+            name: "tdtVec",
+            zIndex: -1000000000,
+            visible: false,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtVec,
+            }),
+        });
+    },
+    /*天地图注记矢量*/
+    tdtVecAnn() {
+        if (!BaseMap.tdtVecAnn) return null;
+        return new TileLayer({
+            //天地图
+            id: "tdtVecAnn",
+            zIndex: -999999999,
+            name: "tdtVecAnn",
+            visible: false,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.tdtVecAnn,
+            }),
+        });
+    },
+    /*界线*/
+    jxMap() {
+        if (!BaseMap.jxMap) return null;
+        return new TileLayer({
+            //界线
+            id: "jxMap",
+            zIndex: -999999999,
+            name: "jxMap",
+            visible: true,
+            source: new XYZ({
+                crossOrigin: "anonymous",
+                url: BaseMap.jxMap,
+            }),
+        });
+    },
+    cityLine() {
+        return new VectorLayer({
+            name: "cityLine",
+            source: new VectorSource({
+                features: [],
+            }),
+            style: new Style({
+                stroke: new Stroke({
+                    color: "#f02fff",
+                    width: 2,
+                    lineDash: [1, 2, 3, 4, 5, 6],
+                }),
+            }),
+            zIndex: 9,
+            visible: false,
+        });
+    },
+};
+
+const myMap = (function() {
+    var myMaps = {
+        _basemap: null,
+        _domid: null,
+        _EPSG: null,
+        EPSG: {
+            C3857: "EPSG:3857",
+            C4326: "EPSG:4326",
+            C4490: "EPSG:4490", //国家2000
+            C4610: "EPSG:4610", //西安1980
+        },
+        //地图
+        map: {},
+        //对比的地图
+        map1: null,
+        map2: null,
+        map3: null,
+        map4: null,
+        //比较地图
+        compareMap(type, view, layer) {
+            var format = "image/png";
+            var imgsource = new TileWMS({
+                ratio: 1,
+                url: BaseMap.geoImg,
+                params: {
+                    FORMAT: format,
+                    VERSION: "1.1.1",
+                    tilad: true,
+                    STYLES: "",
+                    LAYERS: layer,
+                },
+            });
+            arcMap[type] = myMap[type] = new Map({
+                layers: [
+                    new TileLayer({
+                        name: layer,
+                        source: imgsource,
+                    }),
+                ],
+                view: view,
+                target: type,
+            });
+            var la = new VectorLayer({
+                name: "compare-feature",
+                declutter: false,
+                source: new VectorSource({
+                    features: [],
+                }),
+                style: new Style({
+                    stroke: new Stroke({
+                        color: "#1171d6",
+                        width: 4,
+                        lineDash: [1, 2, 3, 4, 5, 6],
+                    }),
+                }),
+                zIndex: 9,
+                visible: true,
+            });
+            myMap[type].addLayer(la, type);
+            var _this = this;
+            myMap[type].on("singleclick", function(evt) {
+                var lonlat = myMap.webMercatorToWgs84(
+                    evt.coordinate[0],
+                    evt.coordinate[1]
+                );
+                var view = myMap[type].getView();
+                myMap.SearchWfsByLoc(
+                    layer,
+                    `${lonlat[0]},${lonlat[1]}`,
+                    view.getResolution() * 6.7,
+                    function(d, f) {
+                        if (d.length) {
+                            var layerConfig = MapConfig[layer];
+                            var layers = myMap.getLayerByNameAndMap(layer, type);
+                            layers.popupInfo = layerConfig.popupInfo;
+                            for (var i = 1; i <= 4; i++) {
+                                if (myMap["map" + i]) {
+                                    myMap["map" + i].removeOverlay(
+                                        _this["map" + i].getOverlayById("popup_temp" + "map" + i)
+                                    );
+                                    var _cmap = myMap.getLayerByNameAndMap(
+                                        "compare-feature",
+                                        "map" + i
+                                    );
+                                    _cmap.getSource().clear();
+                                    _cmap.getSource().addFeatures(d);
+                                }
+                            }
+                            layers.popupInfo(d[0], type, evt);
+                            myMap[type].updateSize();
+                        }
+                    }
+                );
+            });
+        },
+        loadMap: function(domId, par = {}) {
+            var _op = {
+                center: MapCenter.point,
+                zoom: 8,
+                base: [
+                    "tdtImg",
+                    "tdtImgAnn",
+                    "tdtVec",
+                    "tdtVecAnn",
+                    "jxMap",
+                    "cityLine",
+                ],
+                view: null,
+            };
+            var option = Object.assign({}, _op, par);
+            //构建默认地图视图
+            if (!option.view) {
+                option.view = new View({
+                    projection: get("EPSG:3857"),
+                    center: fromLonLat(option.center),
+                    zoom: option.zoom,
+                    units: "m",
+                    minZoom: 2,
+                });
+            }
+
+            var _map = option.map || "map";
+            myMap._EPSG = myMap.EPSG.C3857;
+            this._domid = domId;
+            this._basemap = [];
+            for (var i = 0; i < option.base.length; i++) {
+                var _layer = baseLayer[option.base[i]]();
+                if (_layer) {
+                    if (i == 0) {
+                        _layer.setVisible(true);
+                    }
+                    myMap._basemap.push(_layer);
+                }
+            }
+            myMap[_map] = arcMap[_map] = new Map({
+                target: domId,
+                layers: this._basemap,
+                view: new View({
+                    projection: get("EPSG:3857"),
+                    center: fromLonLat(option.center),
+                    zoom: option.zoom,
+                    units: "m",
+                    minZoom: 2,
+                }),
+            });
+            this.tempLayers.init();
+            if (option.click) {
+                myMap.map.on("singleclick", this.mapOnClick);
+            }
+            if (!option.hideCity) this.cityLineDefault(!par.zoom);
+            else if (!par.zoom) myMap.zoomToextent(MapCenter.extent);
+        },
+        mapOnClick: function(evt) {
+            var pixel = myMap.map.getEventPixel(evt.originalEvent);
+            var hit = myMap.map.hasFeatureAtPixel(pixel);
+            if (hit) {
+                myMap.map.forEachFeatureAtPixel(pixel, function(feature, layer) {
+                    if (!layer) {
+                        return;
+                    }
+                    //显示弹窗
+                    function popShow(config, html) {
+                        arcMap.popupInfo({
+                                feature: feature,
+                                position: evt,
+                                title: feature.get(config.title),
+                                attrs: config.attrs,
+                            },
+                            html
+                        );
+                        arcMap.map.updateSize();
+                    }
+                    //如果是方法就回调,否则检查配置
+                    if (typeof layer.popupInfo == "function") {
+                        layer.popupInfo(feature, popShow, evt);
+                    } else {
+                        var layerConfig = MapConfig[layer.get("name")];
+                        if (layer.popupInfo && layerConfig && layerConfig.popupInfo) {
+                            popShow(layerConfig);
+                        }
+                    }
+                });
+            } else {
+                myMap.map.removeOverlay(myMap.getPopupOverlay());
+            }
+        },
+        tempLayers: {
+            _draw: "dview_draw_Layer",
+            _search: "dview_search_Layer",
+            _fliter: "dview_fliter_Layer",
+            _factor: "dview_factor_Layer",
+            _location: "dview_location_Layer",
+            _redlayer: "redtemp_Layer",
+            _center: [109.77, 39.57],
+            dview_draw_Layer: null,
+            dview_search_Layer: null,
+            dview_fliter_Layer: null,
+            dview_factor_Layer: null,
+            dview_location_Layer: null,
+            redtemp_Layer: null,
+            init: function() {
+                if (!myMap.getLayer(this._draw)) {
+                    myMap.addLayer(myMap.CreateVecLayer(this._draw));
+                    this.dview_draw_Layer = myMap.getLayer(this._draw);
+                }
+                if (!myMap.getLayer(this._search)) {
+                    myMap.addLayer(myMap.CreateVecLayerOfPopup(this._search));
+                    this.dview_search_Layer = myMap.getLayer(this._search);
+                    this.dview_search_Layer.setStyle(myMap.SetSelectStyle);
+                }
+                if (!myMap.getLayer(this._location)) {
+                    myMap.addLayer(
+                        myMap.CreateVecLayer(
+                            this._location,
+                            new Style({
+                                fill: new Fill({
+                                    color: "rgba(255, 255, 255, 0.05)",
+                                }),
+                                stroke: new Stroke({
+                                    color: "#FF0000",
+                                    width: 2,
+                                }),
+                                image: new Circle({
+                                    radius: 7,
+                                    fill: new Fill({
+                                        color: "#FF0000",
+                                    }),
+                                }),
+                            }),
+                            null,
+                            99999
+                        )
+                    );
+                    this.dview_location_Layer = myMap.getLayer(this._location);
+                }
+                if (!myMap.getLayer(this._fliter)) {
+                    var style = new Style({
+                        fill: new Fill({
+                            color: "rgba(0, 120, 215,0.01)",
+                        }),
+                        stroke: new Stroke({
+                            color: "#0078d7",
+                            width: 2,
+                        }),
+                    });
+                    myMap.addLayer(myMap.CreateVecLayer(this._fliter, style));
+                    this.dview_fliter_Layer = myMap.getLayer(this._fliter);
+                }
+                if (!myMap.getLayer(this._factor)) {
+                    var style = new Style({
+                        image: new Circle({
+                            radius: 7,
+                            fill: new Fill({
+                                color: "#1171d6",
+                            }),
+                        }),
+                        stroke: new Stroke({
+                            color: "#1171d6",
+                            width: 2,
+                            lineDash: [1, 2, 3, 4, 5, 6],
+                        }),
+                    });
+                    myMap.addLayer(myMap.CreateVecLayer(this._factor, style));
+                    this.dview_factor_Layer = myMap.getLayer(this._factor);
+                }
+                //规划用地用海
+                if (!myMap.getLayer(this._redlayer)) {
+                    var style = new Style({
+                        image: new Circle({
+                            radius: 7,
+                            fill: new Fill({
+                                color: "#FF0000",
+                            }),
+                        }),
+                        stroke: new Stroke({
+                            color: "#FF0000",
+                            width: 4,
+                            lineDash: [1, 2, 3, 4, 5, 6],
+                        }),
+                    });
+                    myMap.addLayer(myMap.CreateVecLayer(this._redlayer, style));
+                    this.redtemp_Layer = myMap.getLayer(this._redlayer);
+                }
+            },
+            clear: function(layer) {
+                if (layer) {
+                    layer.getSource().clear();
+                } else {
+                    this.dview_draw_Layer.getSource().clear();
+                    this.dview_search_Layer.getSource().clear();
+                    this.dview_fliter_Layer.getSource().clear();
+                    this.dview_factor_Layer.getSource().clear();
+                    this.dview_location_Layer.getSource().clear();
+                    this.redtemp_Layer.getSource().clear();
+                }
+            },
+        },
+        cityLineDefault(zoom) {
+            request({
+                url: `/js/${XZQ_DM}.geojson`,
+                method: "get",
+            }).then((res) => {
+                var f = new GeoJSON().readFeatures(Base64.decode(res));
+                var city = baseLayer.cityLine();
+                city.getSource().addFeatures(f);
+                city.setVisible(true);
+                myMap.addLayer(city);
+                if (zoom) myMap.zoomToextent(f[0].getGeometry().getExtent());
+            });
+        },
+        updateSize: function(settime) {
+            var count = 0;
+
+            function usize() {
+                myMap.map.updateSize();
+                for (var i = 1; i <= 4; i++) {
+                    if (myMap["map" + i]) {
+                        myMap["map" + i].updateSize();
+                    }
+                }
+                if (count < 600) setTimeout(usize, 1);
+            }
+            if (settime) {
+                setTimeout(usize, 1);
+            } else usize();
+        },
+        //按name获取
+        getLayer: function(name) {
+            var layer_ = null;
+            this.map.getLayers().forEach(function(layer, i) {
+                if (
+                    layer &&
+                    layer.get("name") &&
+                    layer.get("name") == name.toString()
+                ) {
+                    layer_ = layer;
+                    return;
+                }
+            });
+            return layer_;
+        },
+        //按id获取
+        getLayerById: function(id, type) {
+            var map = this.map;
+            if (type) map = this[type];
+            var layer_ = null;
+            map.getLayers().forEach(function(layer, i) {
+                if (layer && layer.get("id") && layer.get("id") == id) {
+                    layer_ = layer;
+                    return;
+                }
+            });
+            return layer_;
+        },
+        //获取指定地图的图层
+        getLayerByNameAndMap: function(name, type) {
+            var layer_ = null;
+            this[type].getLayers().forEach(function(layer) {
+                if (layer && layer.get("name") && layer.get("name") == name) {
+                    layer_ = layer;
+                    return;
+                }
+            });
+            return layer_;
+        },
+        zoomToextent: function(extent, meters) {
+            meters = meters || 1000;
+            var view = myMap.map.getView();
+            view.fit(buffer(extent, meters), arcMap.map.getSize());
+        },
+        zoomToFeature: function(feature, meters) {
+            meters = meters || 1000;
+            let extent;
+            //添加支持多个feature sky220622
+            if (Array.isArray(feature)) {
+                let cords = [];
+                for (let i = 0; i < feature.length; i++) {
+                    let cord = feature[i].getGeometry().getExtent();
+                    cords.push([cord[0], cord[1]]);
+                    cords.push([cord[2], cord[3]]);
+                }
+                let testfs = new Feature({
+                    geometry: new LineString(cords),
+                });
+                extent = testfs.getGeometry().getExtent();
+            } else {
+                extent = feature.getGeometry().getExtent();
+            }
+
+            myMap.zoomToextent(extent, meters);
+        },
+        //缩放到中心点
+        zoomToCenter: function(zoom) {
+            var view = arcMap.map.getView();
+            view.setZoom(zoom || 12);
+            view.setCenter(fromLonLat(myMaps._center));
+        },
+        //缩放到图层 sky20220623
+        zoomToLayer: function(layurl, cl) {
+            var url = layurl + "?f=pjson"; //空间查询url;
+            request({
+                method: "get",
+                url: url,
+            }).then((res) => {
+                var extent = [
+                    res.fullExtent.xmin,
+                    res.fullExtent.ymin,
+                    res.fullExtent.xmax,
+                    res.fullExtent.ymax,
+                ];
+                myMaps.zoomToextent(extent, 20000);
+                if (cl) cl(extent);
+            });
+        },
+        //移动
+        moveToFeature: function(feature) {
+            let extent;
+            //sky220622 添加支持多个feature
+            if (Array.isArray(feature)) {
+                let cords = [];
+                for (let i = 0; i < feature.length; i++) {
+                    let cord = feature[i].getGeometry().getExtent();
+                    cords.push([cord[0], cord[1]]);
+                    cords.push([cord[2], cord[3]]);
+                }
+                let testfs = new Feature({
+                    geometry: new LineString(cords),
+                });
+                extent = testfs.getGeometry().getExtent();
+            } else {
+                extent = feature.getGeometry().getExtent();
+            }
+            var center = getCenter(extent);
+            var view = arcMap.map.getView();
+            view.setCenter(center);
+            arcMap.map.render();
+        },
+        addLayer: function(layer, type) {
+            if (type) {
+                this[type].addLayer(layer);
+            } else {
+                this.map.addLayer(layer);
+            }
+        },
+        //删除图层
+        removeLayer: function(layer) {
+            var _layer = layer;
+            if (typeof layer == "string") _layer = myMap.getLayer(layer);
+            this.map.removeLayer(_layer);
+        },
+        //删除以XX开头的图层(图层名称)
+        removeLayers: function(name) {
+            var lys = this.map.getLayers().array_;
+            for (var i = 0; i < lys.length; i++) {
+                var layer = lys[i];
+                if (
+                    (layer &&
+                        layer.get("name") &&
+                        layer.get("name").indexOf(name) == 0) ||
+                    (layer && layer.get("id") && layer.get("id").indexOf(name) == 0)
+                ) {
+                    this.map.removeLayer(layer);
+                    i--;
+                }
+            }
+        },
+        CreateVecLayer: function(layername, style, popup, zindex) {
+            style =
+                style ||
+                new Style({
+                    fill: new Fill({
+                        color: "rgba(255, 255, 255, 0.2)",
+                    }),
+                    stroke: new Stroke({
+                        color: "#ffcc33",
+                        width: 2,
+                    }),
+                    image: new Circle({
+                        radius: 7,
+                        fill: new Fill({
+                            color: "#ffcc33",
+                        }),
+                    }),
+                });
+            var _VectorLayer = new VectorLayer({
+                zIndex: zindex || 999,
+                declutter: false,
+                source: new VectorSource(),
+                name: layername,
+                style: style,
+                visible: true,
+            });
+            if (popup) this.CreateLayerPopup(_VectorLayer, popup);
+            return _VectorLayer;
+        },
+        SetSelectStyle: function(feature, resolution) {
+            var strs = new Array();
+            var l = feature.getId();
+            if (l != undefined) {
+                strs = feature.getId().split(".")[0];
+                for (var val in MapConfig) {
+                    var strL = (MapConfig[val].name || "").split(":")[1];
+                    if (strs == strL) {
+                        return MapConfig[val].style(feature);
+                    }
+                }
+            }
+            return new Style({
+                fill: new Fill({
+                    color: "rgba(255, 255, 255, 0.2)",
+                }),
+                stroke: new Stroke({
+                    color: "#ffcc33",
+                    width: 2,
+                }),
+                image: new Circle({
+                    radius: 7,
+                    fill: new Fill({
+                        color: "#ffcc33",
+                    }),
+                }),
+            });
+        },
+        CreateVecLayerOfPopup: function(layername, style) {
+            return this.CreateVecLayer(layername, style, true);
+        },
+        CreateLayerPopup: function(layer, popup) {
+            if (layer && typeof layer != "object") layer = myMap.getLayer(layer);
+            if (layer) layer.popupInfo = popup;
+            return layer;
+        },
+        lonLatToWebMercator: function(lon, lat) {
+            var x = (lon * 20037508.34) / 180;
+            var y =
+                Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180);
+            y = (y * 20037508.34) / 180;
+            return [x, y];
+        },
+        webMercatorToWgs84: function(x, y) {
+            var lon = (x / 20037508.34) * 180;
+            var lat = (y / 20037508.34) * 180;
+            lat =
+                (180 / Math.PI) *
+                (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2);
+            return [lon, lat];
+        },
+        featureToGeojson(f) {
+            var geoJson = new GeoJSON().writeGeometry(f.getGeometry(), {
+                dataProjection: get(myMap.EPSG.C4326),
+                featureProjection: get(myMap._EPSG),
+            });
+            return geoJson;
+        },
+        geojsonFeatures(geojson) {
+            var features = new GeoJSON().readFeatures(geojson, {
+                dataProjection: get(myMap.EPSG.C4326),
+                featureProjection: get(myMap._EPSG),
+            });
+            return features;
+        },
+        featureToWkt(f) {
+            var geoJson = new WKT().writeGeometry(f.getGeometry(), {
+                dataProjection: get(myMap.EPSG.C4326),
+                featureProjection: get(myMap._EPSG),
+            });
+            return geoJson;
+        },
+        LonLatDisplay: function() {
+            var mousePositionControl = new MousePosition({
+                coordinateFormat: function(e) {
+                    var es = myMap.webMercatorToWgs84(e[0], e[1]);
+                    return (
+                        "经度:" + es[0].toFixed(2) + "° , 纬度:" + es[1].toFixed(2) + "°"
+                    );
+                },
+                projection: get("EPSG:3857"),
+                className: "lonlat",
+                target: document.getElementById("lonlat"),
+                undefinedHTML: "&nbsp;",
+            });
+            mousePositionControl.setMap(myMap.map);
+        },
+        removePopupOverlay: function() {
+            myMap.map.removeOverlay(myMap.getPopupOverlay());
+        },
+        getPopupOverlay: function() {
+            return this.map.getOverlayById("popup_temp");
+        },
+        addOverlay: function(Overlay, type) {
+            if (type) {
+                this[type].addOverlay(Overlay);
+            } else {
+                this.map.addOverlay(Overlay);
+            }
+        },
+        //图表overlayer
+        addOverLayerByEcharts: function(data, type) {
+            var details = formatKeyValue(type);
+            var dom = document.querySelectorAll(".echartsOverlay");
+            if (dom && dom.length) {
+                dom.forEach((item) => {
+                    item.remove();
+                });
+            }
+            data.map((item) => {
+                var code = item.code;
+                if (type == "Nyszy" || type == "Czszy") {
+                    code = item.xzqdm;
+                }
+                var ele =
+                    "<div id='" + code + "' style='width:100px;height:100px;'></div>";
+                var para = document.createElement("div");
+                para.innerHTML = ele;
+                var _div = document.getElementById(myMap._domid);
+                _div.appendChild(para);
+                var echartbar = {
+                    chart: null,
+                    option: barOption(item, details),
+                };
+                echartbar.chart = echarts.init(document.getElementById(code));
+                echartbar.chart.setOption(echartbar.option, true);
+                window.addEventListener("resize", function() {
+                    echartbar.chart.resize();
+                });
+                var _overlay = new Overlay({
+                    id: code,
+                    position: locationXy(code),
+                    positioning: "bottom-center",
+                    element: document.getElementById(code),
+                    stopEvent: true,
+                    autoPan: true,
+                    autoPanAnimation: {
+                        duration: 250,
+                    },
+                    className: "echartsOverlay",
+                });
+                myMap.addOverlay(_overlay, "map");
+            });
+        },
+        //地图弹窗--点
+        popupInfo: function(option) {
+            var feature = option.feature;
+            var evt = option.position;
+            var _popupId_ = "popup_temp" + option.index;
+            if (typeof option.type == "string") {
+                myMap[option.type].removeOverlay(myMap.map1.getOverlayById(_popupId_));
+            } else {
+                option.type = null;
+                myMap.map1.removeOverlay(myMap.getPopupOverlay());
+            }
+            var html;
+            if (!html) {
+                html = "<div id='" + _popupId_ + "' class='map-popupinfo'>";
+                html +=
+                    "<div class='popupinfo-title' >" +
+                    option.title +
+                    "<el-icon class='pointer popupinfo-close' id='closePop'><close /></el-icon></div>";
+                html += "<ul class='popupinfo-content'>";
+                if (Object.keys(option.attrs).length > 0) {
+                    for (var p in option.attrs) {
+                        var _value = feature !== undefined ? feature.get(option.attrs[p].sxmc) : "";
+                        if (option.attrs[p].callback) {
+                            _value = option.attrs[p].callback(_value, feature);
+                        }
+                        if (
+                            _value == "" ||
+                            _value == "0" ||
+                            _value == 0 ||
+                            _value == null
+                        ) {
+                            _value = "";
+                        }
+                        html +=
+                            "<li><span>" +
+                            (option.attrs[p].sxbm || option.attrs[p].name) +
+                            ":</span><span>" +
+                            _value +
+                            "</span></li>";
+                    }
+                }
+            }
+            html += "</ul><div class='popupinfo-poi'></div></div>";
+            var para = document.createElement("p");
+            para.innerHTML = html;
+            var text = option.type ?
+                document.getElementById(option.type) :
+                document.getElementById(myMap._domid);
+            text.appendChild(para);
+            if (option.type) {
+                document.getElementById("closePop").onclick = function() {
+                    myMap[option.type].removeOverlay(
+                        myMap[option.type].getOverlayById(_popupId_)
+                    );
+                };
+            } else {
+                document.getElementById("closePop").onclick = function() {
+                    myMap.map1.removeOverlay(myMap.getPopupOverlay());
+                };
+            }
+            var popupElement = document.getElementById(_popupId_);
+            // var coord = evt ?
+            //     evt.coordinate :
+            //     getCenter(feature.getGeometry().getExtent());
+            if(option.index == 0){
+                var _overlay0 = new Overlay({
+                    id: "popup_temp0",
+                    position: option.tcPoint,
+                    positioning: "bottom-center",
+                    element: popupElement,
+                    stopEvent: true,
+                    autoPan: true,
+                    autoPanAnimation: {
+                        duration: 250,
+                    },
+                });
+                if(myMap.map1.getOverlayById(_popupId_)){
+                    myMap.map1.removeOverlay(myMap.map1.getOverlayById(_popupId_));
+
+                }
+                myMap.map1.addOverlay(_overlay0, option.type);
+            }else{
+                var _overlay1 = new Overlay({
+                    id: "popup_temp1",
+                    position: option.tcPoint,
+                    positioning: "bottom-center",
+                    element: popupElement,
+                    stopEvent: true,
+                    autoPan: true,
+                    autoPanAnimation: {
+                        duration: 250,
+                    },
+                });
+                myMap[option.type].addOverlay(_overlay1, option.type);
+            }
+            popupElement.parentElement.style.zIndex = 1;
+            // Status = Object.keys(option.attrs).length > 0 ? true : false;
+            // myMap[option.type].getLayerById("popup_temp0")
+            // setVisible(Status);
+            return _overlay0 , _overlay1;
+        },
+        SearchWfsByLoc: function(layers, feature, buffer, callback) {
+            if (typeof feature == "string") {
+                var lonlat = (feature || "").split(",");
+                var point = fromLonLat(
+                    transform([lonlat[0], lonlat[1]], "EPSG:3857", "EPSG:4326")
+                );
+                feature = new Feature({
+                    geometry: new Point(myMap.lonLatToWebMercator(point[0], point[1])),
+                });
+            }
+            var geom;
+            var bf;
+            if (buffer) {
+                var ol3 = new jsts.io.OL3Parser();
+                ol3.inject(
+                    Point,
+                    LineString,
+                    LinearRing,
+                    Polygon,
+                    MultiPoint,
+                    MultiLineString,
+                    MultiPolygon
+                );
+                bf = new Feature({
+                    geometry: ol3.write(ol3.read(feature.getGeometry()).buffer(buffer)),
+                });
+                geom = bf.getGeometry();
+            } else {
+                geom = feature.getGeometry();
+            }
+            myMap.SearchWfsData(layers, geom, function(datas) {
+                callback(datas, bf);
+            });
+        },
+        //WFS查询
+        SearchWfsData: function(layers, data, cl) {
+            var filter;
+            if (typeof data == "object") {
+                filter = intersects("geom", data, "");
+            } else {
+                var datas = (data || "").split(":");
+                filter = like(datas[0], "*" + datas[1] + "*");
+            }
+            var strs = new Array();
+            strs = (layers || "").split(",");
+            var featureRequest = new WFS().writeGetFeature({
+                srsName: "EPSG:3857",
+                featureNS: "p002",
+                featurePrefix: "p002",
+                featureTypes: strs,
+                outputFormat: "application/json",
+                filter: filter,
+            });
+            fetch("/geoserver/p002/ows", {
+                    method: "POST",
+                    body: new XMLSerializer().serializeToString(featureRequest),
+                })
+                .then(function(response) {
+                    return response.json();
+                })
+                .then(function(json) {
+                    var features = new GeoJSON().readFeatures(json);
+                    if (cl) cl(features);
+                });
+        },
+        //wfs属性查询
+        SearchWfsFilter(layers, filter, cl) {
+            var strs = new Array();
+            strs = (layers || "").split(",");
+            var featureRequest = new WFS().writeGetFeature({
+                srsName: "EPSG:3857",
+                featureNS: "p002",
+                featurePrefix: "p002",
+                featureTypes: strs,
+                outputFormat: "application/json",
+                filter: filter,
+            });
+            fetch("/geoserver/p002/wfs", {
+                    method: "POST",
+                    body: new XMLSerializer().serializeToString(featureRequest),
+                })
+                .then(function(response) {
+                    return response.json();
+                })
+                .then(function(json) {
+                    var features = new GeoJSON().readFeatures(json);
+                    if (cl) cl(features);
+                });
+        },
+        //图层数据叠加
+        addDjLayer(url, type) {},
+        //图层类型
+        WMSImage(url, name) {
+            var _layer = new ImageLayer({
+                name: name,
+                source: new ImageWMS({
+                    ratio: 1,
+                    url: url,
+                    params: {
+                        FORMAT: "image/png",
+                        VERSION: "1.1.1",
+                        STYLES: "",
+                        LAYERS: name,
+                    },
+                }),
+            });
+            return _layer;
+        },
+        WMSTile: function(record) {
+            var _layer = new TileLayer({
+                name: record.url,
+                id: record.id,
+                source: new TileWMS({
+                    ratio: 1,
+                    url: record.url,
+                    params: {
+                        FORMAT: "image/png",
+                        VERSION: "1.1.1",
+                        tilad: true,
+                        STYLES: "",
+                        LAYERS: record.url,
+                    },
+                }),
+            });
+            myMap.addLayer(_layer);
+        },
+        XYZTile: function(record) {
+            var imgsource = new XYZ({
+                crossOrigin: "anonymous",
+                url: record.url,
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.id,
+                source: imgsource,
+            });
+            myMap.addLayer(untiled);
+        },
+        vector: function(url, name, style) {
+            var _layer = new VectorLayer({
+                name: name,
+                declutter: false,
+                visible: true,
+                source: new VectorSource({
+                    projection: "EPSG:3857",
+                    url: url,
+                }),
+                style: style,
+                zIndex: 1,
+            });
+            return _layer;
+        },
+        TILE: function(record, call, zoom) {
+            var imgsource = new XYZ({
+                crossOrigin: "anonymous",
+                url: record.url,
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1,
+            });
+            if (call) {
+                return untiled;
+            }
+            myMap.addLayer(untiled);
+            //ZOOM
+            if (zoom) {
+                myMap.zoomToLayer(record.url);
+            }
+        },
+        WMS: function(record, call, zoom) {
+            var format = "image/png";
+            var imgsource = new TileWMS({
+                ratio: 1,
+                url: BaseMap.geoImg,
+                params: {
+                    FORMAT: format,
+                    VERSION: "1.1.1",
+                    tilad: true,
+                    STYLES: "",
+                    LAYERS: record.url,
+                },
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1,
+            });
+            if (call) {
+                return untiled;
+            }
+            myMap.addLayer(untiled);
+        },
+        WMTS: function(record, call, zoom) {
+            var imgsource = new XYZ({
+                crossOrigin: "anonymous",
+                url: record.url + `/tile/{z}/{y}/{x}`,
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.bsm || record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1,
+            });
+            if (call) {
+                return untiled;
+            }
+            myMap.addLayer(untiled);
+            //ZOOM
+            if (zoom) {
+                myMap.zoomToLayer(record.url);
+            }
+        },
+        //加载图层
+        addProLayer: function(record, call, zoom) {
+            var format = "image/png";
+            var imgsource = new TileWMS({
+                ratio: 1,
+                url: BaseMap.geoImg,
+                params: {
+                    FORMAT: format,
+                    VERSION: "1.1.1",
+                    tilad: true,
+                    STYLES: "",
+                    LAYERS: record.url,
+                },
+            });
+            var untiled = new TileLayer({
+                name: record.url,
+                id: record.id,
+                source: imgsource,
+                zIndex: (record.sort || 1) * -1,
+            });
+            if (call) {
+                return untiled;
+            }
+            myMap.addLayer(untiled);
+        },
+        // 加载geojson数据
+        addGeoJson: function(name, json) {
+            let layer = myMap.getLayer(name);
+            if (layer) {
+                layer.getSource().clear();
+            } else {
+                myMap.addLayer(myMap.CreateVecLayer(name));
+                layer = myMap.getLayer(name);
+            }
+            var features = new GeoJSON().readFeatures(json, {
+                defaultDataProjection: "EPSG:4326",
+                featureProjection: "EPSG:3857",
+            });
+            console.log(typeof json);
+            layer.getSource().addFeatures(features);
+            return layer;
+        },
+        zoomToFeatureJson: function(json) {
+            var feature = new GeoJSON().readFeature(json, {
+                defaultDataProjection: "EPSG:4326",
+                featureProjection: "EPSG:3857",
+            });
+            var f = new Feature({
+                geometry: feature.getGeometry(),
+            });
+            myMap.onLocation(f);
+        },
+        //定位
+        onLocation(feature, zoom) {
+            var show = 0;
+            if (zoom === undefined) zoom = true;
+
+            function sansuo() {
+                myMap.tempLayers.dview_location_Layer.getSource().clear();
+                if (show % 2 == 0) {
+                    if (Array.isArray(feature)) {
+                        myMap.tempLayers.dview_location_Layer
+                            .getSource()
+                            .addFeatures(feature);
+                    } else {
+                        myMap.tempLayers.dview_location_Layer
+                            .getSource()
+                            .addFeature(feature);
+                        if (zoom)
+                            myMap.zoomToextent(feature.getGeometry().getExtent(), 500);
+                    }
+                }
+                if (show < 4) {
+                    setTimeout(() => {
+                        sansuo();
+                    }, 200);
+                }
+                show++;
+            }
+            sansuo();
+        },
+    };
+    return myMaps;
+})();
+export default myMap;

+ 1996 - 0
src/utils/map/drawPlugin/DrawHelper.js

@@ -0,0 +1,1996 @@
+/**
+ * Created by thomas on 9/01/14.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * (c) www.geocento.com
+ * www.metaaps.com
+ *
+ */
+import * as Cesium from "cesium";
+export var DrawHelper = (function () {
+
+    // static variables
+    var ellipsoid = Cesium.Ellipsoid.WGS84;
+
+    // constructor
+    function _(cesiumWidget) {
+        this._scene = cesiumWidget.scene;
+        //this._tooltip = createTooltip(cesiumWidget.container);
+        //新增属性,为了拓展三维漫游飞行路线设定的起始点的相机视角
+        this._viewer = cesiumWidget;
+        this._cameraPosition = null;
+        this._cameraHeading = null;
+        this._cameraPitch = null;
+        this._cameraRoll = null;
+        //修改之处
+        this._tooltip = createTooltip();
+        this._surfaces = [];
+
+        this.initialiseHandlers();
+
+        this.enhancePrimitives();
+
+    }
+
+    _.prototype.initialiseHandlers = function () {
+        var scene = this._scene;
+        var _self = this;
+        // scene events
+        var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        function callPrimitiveCallback(name, position) {
+            if (_self._handlersMuted == true) return;
+            var pickedObject = scene.pick(position);
+            if (pickedObject && pickedObject.primitive && pickedObject.primitive[name]) {
+                pickedObject.primitive[name](position);
+            }
+        }
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftClick', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftDoubleClick', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+        var mouseOutObject;
+        handler.setInputAction(
+            function (movement) {
+                if (_self._handlersMuted == true) return;
+                var pickedObject = scene.pick(movement.endPosition);
+                if (mouseOutObject && (!pickedObject || mouseOutObject != pickedObject.primitive)) {
+                    !(mouseOutObject.isDestroyed && mouseOutObject.isDestroyed()) && mouseOutObject.mouseOut(movement.endPosition);
+                    mouseOutObject = null;
+                }
+                if (pickedObject && pickedObject.primitive) {
+                    pickedObject = pickedObject.primitive;
+                    if (pickedObject.mouseOut) {
+                        mouseOutObject = pickedObject;
+                    }
+                    if (pickedObject.mouseMove) {
+                        pickedObject.mouseMove(movement.endPosition);
+                    }
+                }
+            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftUp', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_UP);
+        handler.setInputAction(
+            function (movement) {
+                callPrimitiveCallback('leftDown', movement.position);
+            }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+    }
+
+    _.prototype.setListener = function (primitive, type, callback) {
+        primitive[type] = callback;
+    }
+
+    _.prototype.muteHandlers = function (muted) {
+        this._handlersMuted = muted;
+    }
+
+    // register event handling for an editable shape
+    // shape should implement setEditMode and setHighlighted
+    _.prototype.registerEditableShape = function (surface) {
+        var _self = this;
+
+        // handlers for interactions
+        // highlight polygon when mouse is entering
+        setListener(surface, 'mouseMove', function (position) {
+            surface.setHighlighted(true);
+            if (!surface._editMode) {
+                _self._tooltip.showAt(position, "点击编辑图形");
+            }
+        });
+        // hide the highlighting when mouse is leaving the polygon
+        setListener(surface, 'mouseOut', function (position) {
+            surface.setHighlighted(false);
+            _self._tooltip.setVisible(false);
+        });
+        setListener(surface, 'leftClick', function (position) {
+            surface.setEditMode(true);
+        });
+    }
+
+    _.prototype.startDrawing = function (cleanUp) {
+        // undo any current edit of shapes
+        this.disableAllEditMode();
+        // check for cleanUp first
+        if (this.editCleanUp) {
+            this.editCleanUp();
+        }
+        this.editCleanUp = cleanUp;
+        this.muteHandlers(true);
+    }
+
+    _.prototype.stopDrawing = function () {
+        // check for cleanUp first
+        if (this.editCleanUp) {
+            this.editCleanUp();
+            this.editCleanUp = null;
+        }
+        this.muteHandlers(false);
+    }
+
+    // make sure only one shape is highlighted at a time
+    _.prototype.disableAllHighlights = function () {
+        this.setHighlighted(undefined);
+    }
+
+    _.prototype.setHighlighted = function (surface) {
+        if (this._highlightedSurface && !this._highlightedSurface.isDestroyed() && this._highlightedSurface != surface) {
+            this._highlightedSurface.setHighlighted(false);
+        }
+        this._highlightedSurface = surface;
+    }
+
+    _.prototype.disableAllEditMode = function () {
+        this.setEdited(undefined);
+    }
+
+    _.prototype.setEdited = function (surface) {
+        if (this._editedSurface && !this._editedSurface.isDestroyed()) {
+            this._editedSurface.setEditMode(false);
+        }
+        this._editedSurface = surface;
+    }
+
+    var material = Cesium.Material.fromType(Cesium.Material.ColorType);
+    material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5);
+
+    var defaultShapeOptions = {
+        ellipsoid: Cesium.Ellipsoid.WGS84,
+        textureRotationAngle: 0.0,
+        height: 0.0,
+        asynchronous: true,
+        show: true,
+        debugShowBoundingVolume: false
+    }
+
+    var defaultSurfaceOptions = copyOptions(defaultShapeOptions, {
+        appearance: new Cesium.EllipsoidSurfaceAppearance({
+            aboveGround: false
+        }),
+        material: material,
+        granularity: Math.PI / 180.0
+    });
+
+    var defaultPolygonOptions = copyOptions(defaultShapeOptions, {});
+    var defaultExtentOptions = copyOptions(defaultShapeOptions, {});
+    var defaultCircleOptions = copyOptions(defaultShapeOptions, {});
+    var defaultEllipseOptions = copyOptions(defaultSurfaceOptions, { rotation: 0 });
+
+    var defaultPolylineOptions = copyOptions(defaultShapeOptions, {
+        width: 5,
+        geodesic: true,
+        granularity: 10000,
+        appearance: new Cesium.PolylineMaterialAppearance({
+            aboveGround: false
+        }),
+        material: material
+    });
+
+    //    Cesium.Polygon.prototype.setStrokeStyle = setStrokeStyle;
+    //
+    //    Cesium.Polygon.prototype.drawOutline = drawOutline;
+    //
+
+    var ChangeablePrimitive = (function () {
+        function _() { }
+
+        _.prototype.initialiseOptions = function (options) {
+
+            fillOptions(this, options);
+
+            this._ellipsoid = undefined;
+            this._granularity = undefined;
+            this._height = undefined;
+            this._textureRotationAngle = undefined;
+            this._id = undefined;
+
+            // set the flags to initiate a first drawing
+            this._createPrimitive = true;
+            this._primitive = undefined;
+            this._outlinePolygon = undefined;
+
+        }
+
+        _.prototype.setAttribute = function (name, value) {
+            this[name] = value;
+            this._createPrimitive = true;
+        };
+
+        _.prototype.getAttribute = function (name) {
+            return this[name];
+        };
+
+        /**
+         * @private
+         */
+        _.prototype.update = function (context, frameState, commandList) {
+
+            if (!Cesium.defined(this.ellipsoid)) {
+                throw new Cesium.DeveloperError('this.ellipsoid must be defined.');
+            }
+
+            if (!Cesium.defined(this.appearance)) {
+                throw new Cesium.DeveloperError('this.material must be defined.');
+            }
+
+            if (this.granularity < 0.0) {
+                throw new Cesium.DeveloperError('this.granularity and scene2D/scene3D overrides must be greater than zero.');
+            }
+
+            if (!this.show) {
+                return;
+            }
+
+            if (!this._createPrimitive && (!Cesium.defined(this._primitive))) {
+                // No positions/hierarchy to draw
+                return;
+            }
+
+            if (this._createPrimitive ||
+                (this._ellipsoid !== this.ellipsoid) ||
+                (this._granularity !== this.granularity) ||
+                (this._height !== this.height) ||
+                (this._textureRotationAngle !== this.textureRotationAngle) ||
+                (this._id !== this.id)) {
+
+                var geometry = this.getGeometry();
+                if (!geometry) {
+                    return;
+                }
+
+                this._createPrimitive = false;
+                this._ellipsoid = this.ellipsoid;
+                this._granularity = this.granularity;
+                this._height = this.height;
+                this._textureRotationAngle = this.textureRotationAngle;
+                this._id = this.id;
+
+                this._primitive = this._primitive && this._primitive.destroy();
+
+                this._primitive = new Cesium.Primitive({
+                    geometryInstances: new Cesium.GeometryInstance({
+                        geometry: geometry,
+                        id: this.id,
+                        pickPrimitive: this
+                    }),
+                    appearance: this.appearance,
+                    asynchronous: this.asynchronous
+                });
+
+                this._outlinePolygon = this._outlinePolygon && this._outlinePolygon.destroy();
+                if (this.strokeColor && this.getOutlineGeometry) {
+                    // create the highlighting frame
+                    this._outlinePolygon = new Cesium.Primitive({
+                        geometryInstances: new Cesium.GeometryInstance({
+                            geometry: this.getOutlineGeometry(),
+                            attributes: {
+                                color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.strokeColor)
+                            }
+                        }),
+                        appearance: new Cesium.PerInstanceColorAppearance({
+                            flat: true,
+                            renderState: {
+                                depthTest: {
+                                    enabled: true
+                                },
+                                //lineWidth : Math.min(this.strokeWidth || 4.0, context._aliasedLineWidthRange[1])
+                                lineWidth: Math.min(this.strokeWidth)
+                            }
+                        })
+                    });
+                }
+            }
+
+            var primitive = this._primitive;
+            primitive.appearance.material = this.material;
+            primitive.debugShowBoundingVolume = this.debugShowBoundingVolume;
+            primitive.update(context, frameState, commandList);
+            this._outlinePolygon && this._outlinePolygon.update(context, frameState, commandList);
+
+        };
+
+        _.prototype.isDestroyed = function () {
+            return false;
+        };
+
+        _.prototype.destroy = function () {
+            this._primitive = this._primitive && this._primitive.destroy();
+            return Cesium.destroyObject(this);
+        };
+
+        _.prototype.setStrokeStyle = function (strokeColor, strokeWidth) {
+            if (!this.strokeColor || !this.strokeColor.equals(strokeColor) || this.strokeWidth != strokeWidth) {
+                this._createPrimitive = true;
+                this.strokeColor = strokeColor;
+                this.strokeWidth = strokeWidth;
+            }
+        }
+
+        return _;
+    })();
+
+    _.ExtentPrimitive = (function () {
+        function _(options) {
+
+            if (!Cesium.defined(options.extent)) {
+                throw new Cesium.DeveloperError('Extent is required');
+            }
+
+            options = copyOptions(options, defaultSurfaceOptions);
+
+            this.initialiseOptions(options);
+
+            this.setExtent(options.extent);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setExtent = function (extent) {
+            this.setAttribute('extent', extent);
+        };
+
+        _.prototype.getExtent = function () {
+            return this.getAttribute('extent');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!Cesium.defined(this.extent)) {
+                return;
+            }
+
+            return new Cesium.RectangleGeometry({
+                rectangle: this.extent,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return new Cesium.RectangleOutlineGeometry({
+                rectangle: this.extent
+            });
+        }
+
+        return _;
+    })();
+
+    _.PolygonPrimitive = (function () {
+
+        function _(options) {
+
+            options = copyOptions(options, defaultSurfaceOptions);
+
+            this.initialiseOptions(options);
+
+            this.isPolygon = true;
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setPositions = function (positions) {
+            this.setAttribute('positions', positions);
+        };
+
+        _.prototype.getPositions = function () {
+            return this.getAttribute('positions');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!Cesium.defined(this.positions) || this.positions.length < 3) {
+                return;
+            }
+
+            return Cesium.PolygonGeometry.fromPositions({
+                positions: this.positions,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return Cesium.PolygonOutlineGeometry.fromPositions({
+                positions: this.getPositions()
+            });
+        }
+
+        return _;
+    })();
+
+    _.CirclePrimitive = (function () {
+
+        function _(options) {
+
+            if (!(Cesium.defined(options.center) && Cesium.defined(options.radius))) {
+                throw new Cesium.DeveloperError('Center and radius are required');
+            }
+
+            options = copyOptions(options, defaultSurfaceOptions);
+
+            this.initialiseOptions(options);
+
+            this.setRadius(options.radius);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setCenter = function (center) {
+            this.setAttribute('center', center);
+        };
+
+        _.prototype.setRadius = function (radius) {
+            this.setAttribute('radius', Math.max(0.1, radius));
+        };
+
+        _.prototype.getCenter = function () {
+            return this.getAttribute('center');
+        };
+
+        _.prototype.getRadius = function () {
+            return this.getAttribute('radius');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!(Cesium.defined(this.center) && Cesium.defined(this.radius))) {
+                return;
+            }
+
+            return new Cesium.CircleGeometry({
+                center: this.center,
+                radius: this.radius,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return new Cesium.CircleOutlineGeometry({
+                center: this.getCenter(),
+                radius: this.getRadius()
+            });
+        }
+
+        return _;
+    })();
+
+    _.EllipsePrimitive = (function () {
+        function _(options) {
+
+            if (!(Cesium.defined(options.center) && Cesium.defined(options.semiMajorAxis) && Cesium.defined(options.semiMinorAxis))) {
+                throw new Cesium.DeveloperError('Center and semi major and semi minor axis are required');
+            }
+
+            options = copyOptions(options, defaultEllipseOptions);
+
+            this.initialiseOptions(options);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setCenter = function (center) {
+            this.setAttribute('center', center);
+        };
+
+        _.prototype.setSemiMajorAxis = function (semiMajorAxis) {
+            if (semiMajorAxis < this.getSemiMinorAxis()) return;
+            this.setAttribute('semiMajorAxis', semiMajorAxis);
+        };
+
+        _.prototype.setSemiMinorAxis = function (semiMinorAxis) {
+            if (semiMinorAxis > this.getSemiMajorAxis()) return;
+            this.setAttribute('semiMinorAxis', semiMinorAxis);
+        };
+
+        _.prototype.setRotation = function (rotation) {
+            return this.setAttribute('rotation', rotation);
+        };
+
+        _.prototype.getCenter = function () {
+            return this.getAttribute('center');
+        };
+
+        _.prototype.getSemiMajorAxis = function () {
+            return this.getAttribute('semiMajorAxis');
+        };
+
+        _.prototype.getSemiMinorAxis = function () {
+            return this.getAttribute('semiMinorAxis');
+        };
+
+        _.prototype.getRotation = function () {
+            return this.getAttribute('rotation');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!(Cesium.defined(this.center) && Cesium.defined(this.semiMajorAxis) && Cesium.defined(this.semiMinorAxis))) {
+                return;
+            }
+
+            return new Cesium.EllipseGeometry({
+                ellipsoid: this.ellipsoid,
+                center: this.center,
+                semiMajorAxis: this.semiMajorAxis,
+                semiMinorAxis: this.semiMinorAxis,
+                rotation: this.rotation,
+                height: this.height,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                stRotation: this.textureRotationAngle,
+                ellipsoid: this.ellipsoid,
+                granularity: this.granularity
+            });
+        };
+
+        _.prototype.getOutlineGeometry = function () {
+            return new Cesium.EllipseOutlineGeometry({
+                center: this.getCenter(),
+                semiMajorAxis: this.getSemiMajorAxis(),
+                semiMinorAxis: this.getSemiMinorAxis(),
+                rotation: this.getRotation()
+            });
+        }
+
+        return _;
+    })();
+
+    _.PolylinePrimitive = (function () {
+
+        function _(options) {
+
+            options = copyOptions(options, defaultPolylineOptions);
+
+            this.initialiseOptions(options);
+
+        }
+
+        _.prototype = new ChangeablePrimitive();
+
+        _.prototype.setPositions = function (positions) {
+            this.setAttribute('positions', positions);
+        };
+
+        _.prototype.setWidth = function (width) {
+            this.setAttribute('width', width);
+        };
+
+        _.prototype.setGeodesic = function (geodesic) {
+            this.setAttribute('geodesic', geodesic);
+        };
+
+        _.prototype.getPositions = function () {
+            return this.getAttribute('positions');
+        };
+
+        _.prototype.getWidth = function () {
+            return this.getAttribute('width');
+        };
+
+        _.prototype.getGeodesic = function (geodesic) {
+            return this.getAttribute('geodesic');
+        };
+
+        _.prototype.getGeometry = function () {
+
+            if (!Cesium.defined(this.positions) || this.positions.length < 2) {
+                return;
+            }
+
+            return new Cesium.PolylineGeometry({
+                positions: this.positions,
+                height: this.height,
+                width: this.width < 1 ? 1 : this.width,
+                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
+                ellipsoid: this.ellipsoid
+            });
+        }
+
+        return _;
+    })();
+
+    var defaultBillboard = {
+        iconUrl: "img/toolbar/dragIcon.png",
+        shiftX: 0,
+        shiftY: 0
+    }
+
+    var dragBillboard = {
+        iconUrl: "img/toolbar/dragIcon.png",
+        shiftX: 0,
+        shiftY: 0
+    }
+
+    var dragHalfBillboard = {
+        iconUrl: "img/toolbar/dragIconLight.png",
+        shiftX: 0,
+        shiftY: 0
+    }
+
+    _.prototype.createBillboardGroup = function (points, options, callbacks) {
+        var markers = new _.BillboardGroup(this, options);
+        markers.addBillboards(points, callbacks);
+        return markers;
+    }
+
+    _.BillboardGroup = function (drawHelper, options) {
+
+        this._drawHelper = drawHelper;
+        this._scene = drawHelper._scene;
+
+        this._options = copyOptions(options, defaultBillboard);
+
+        // create one common billboard collection for all billboards
+        var b = new Cesium.BillboardCollection();
+        this._scene.primitives.add(b);
+        this._billboards = b;
+        // keep an ordered list of billboards
+        this._orderedBillboards = [];
+    }
+
+    _.BillboardGroup.prototype.createBillboard = function (position, callbacks) {
+
+        var billboard = this._billboards.add({
+            show: true,
+            position: position,
+            pixelOffset: new Cesium.Cartesian2(this._options.shiftX, this._options.shiftY),
+            eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0),
+            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+            verticalOrigin: Cesium.VerticalOrigin.CENTER,
+            scale: 1.0,
+            image: this._options.iconUrl,
+            color: new Cesium.Color(1.0, 1.0, 1.0, 1.0)
+        });
+
+        // if editable
+        if (callbacks) {
+            var _self = this;
+            var screenSpaceCameraController = this._scene.screenSpaceCameraController;
+
+            function enableRotation(enable) {
+                screenSpaceCameraController.enableRotate = enable;
+            }
+
+            function getIndex() {
+                // find index
+                for (var i = 0, I = _self._orderedBillboards.length; i < I && _self._orderedBillboards[i] != billboard; ++i);
+                return i;
+            }
+            if (callbacks.dragHandlers) {
+                var _self = this;
+                setListener(billboard, 'leftDown', function (position) {
+                    // TODO - start the drag handlers here
+                    // create handlers for mouseOut and leftUp for the billboard and a mouseMove
+                    function onDrag(position) {
+                        billboard.position = position;
+                        // find index
+                        for (var i = 0, I = _self._orderedBillboards.length; i < I && _self._orderedBillboards[i] != billboard; ++i);
+                        callbacks.dragHandlers.onDrag && callbacks.dragHandlers.onDrag(getIndex(), position);
+                    }
+
+                    function onDragEnd(position) {
+                        handler.destroy();
+                        enableRotation(true);
+                        callbacks.dragHandlers.onDragEnd && callbacks.dragHandlers.onDragEnd(getIndex(), position);
+                    }
+
+                    var handler = new Cesium.ScreenSpaceEventHandler(_self._scene.canvas);
+
+                    handler.setInputAction(function (movement) {
+                        var cartesian = _self._scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
+                        if (cartesian) {
+                            onDrag(cartesian);
+                        } else {
+                            onDragEnd(cartesian);
+                        }
+                    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+                    handler.setInputAction(function (movement) {
+                        onDragEnd(_self._scene.camera.pickEllipsoid(movement.position, ellipsoid));
+                    }, Cesium.ScreenSpaceEventType.LEFT_UP);
+
+                    enableRotation(false);
+
+                    callbacks.dragHandlers.onDragStart && callbacks.dragHandlers.onDragStart(getIndex(), _self._scene.camera.pickEllipsoid(position, ellipsoid));
+                });
+            }
+            if (callbacks.onDoubleClick) {
+                setListener(billboard, 'leftDoubleClick', function (position) {
+                    callbacks.onDoubleClick(getIndex());
+                });
+            }
+            if (callbacks.onClick) {
+                setListener(billboard, 'leftClick', function (position) {
+                    callbacks.onClick(getIndex());
+                });
+            }
+            if (callbacks.tooltip) {
+                setListener(billboard, 'mouseMove', function (position) {
+                    _self._drawHelper._tooltip.showAt(position, callbacks.tooltip());
+                });
+                setListener(billboard, 'mouseOut', function (position) {
+                    _self._drawHelper._tooltip.setVisible(false);
+                });
+            }
+        }
+
+        return billboard;
+    }
+
+    _.BillboardGroup.prototype.insertBillboard = function (index, position, callbacks) {
+        this._orderedBillboards.splice(index, 0, this.createBillboard(position, callbacks));
+    }
+
+    _.BillboardGroup.prototype.addBillboard = function (position, callbacks) {
+        this._orderedBillboards.push(this.createBillboard(position, callbacks));
+    }
+
+    _.BillboardGroup.prototype.addBillboards = function (positions, callbacks) {
+        var index = 0;
+        for (; index < positions.length; index++) {
+            this.addBillboard(positions[index], callbacks);
+        }
+    }
+
+    _.BillboardGroup.prototype.updateBillboardsPositions = function (positions) {
+        var index = 0;
+        for (; index < positions.length; index++) {
+            this.getBillboard(index).position = positions[index];
+        }
+    }
+
+    _.BillboardGroup.prototype.countBillboards = function () {
+        return this._orderedBillboards.length;
+    }
+
+    _.BillboardGroup.prototype.getBillboard = function (index) {
+        return this._orderedBillboards[index];
+    }
+
+    _.BillboardGroup.prototype.removeBillboard = function (index) {
+        this._billboards.remove(this.getBillboard(index));
+        this._orderedBillboards.splice(index, 1);
+    }
+
+    _.BillboardGroup.prototype.remove = function () {
+        this._billboards = this._billboards && this._billboards.removeAll() && this._billboards.destroy();
+    }
+
+    _.BillboardGroup.prototype.setOnTop = function () {
+        this._scene.primitives.raiseToTop(this._billboards);
+    }
+
+    _.prototype.startDrawingMarker = function (options) {
+
+        var options = copyOptions(options, defaultBillboard);
+
+        this.startDrawing(
+            function () {
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = scene.primitives;
+        var tooltip = this._tooltip;
+
+        var markers = new _.BillboardGroup(this, options);
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    markers.addBillboard(cartesian);
+                    _self.stopDrawing();
+                    options.callback(cartesian);
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                if (cartesian) {
+                    tooltip.showAt(position, "<p>点击添加标记 位置是: </p>" + getDisplayLatLngString(ellipsoid.cartesianToCartographic(cartesian)));
+                } else {
+                    tooltip.showAt(position, "<p>点击添加标记</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    }
+
+    _.prototype.startDrawingPolygon = function (options) {
+        var options = copyOptions(options, defaultSurfaceOptions);
+        this.startDrawingPolyshape(true, options);
+    }
+
+    _.prototype.startDrawingPolyline = function (options) {
+        var options = copyOptions(options, defaultPolylineOptions);
+        this.startDrawingPolyshape(false, options);
+    }
+
+    _.prototype.startDrawingPolyshape = function (isPolygon, options) {
+
+        this.startDrawing(
+            function () {
+                primitives.remove(poly);
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = scene.primitives;
+        var tooltip = this._tooltip;
+
+        var minPoints = isPolygon ? 3 : 2;
+        var poly;
+        if (isPolygon) {
+            poly = new DrawHelper.PolygonPrimitive(options);
+        } else {
+            poly = new DrawHelper.PolylinePrimitive(options);
+        }
+        poly.asynchronous = false;
+        primitives.add(poly);
+
+        var positions = [];
+        var markers = new _.BillboardGroup(this, defaultBillboard);
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    // first click
+                    if (positions.length == 0) {
+                        positions.push(cartesian.clone());
+                        markers.addBillboard(positions[0]);
+                        //设置起始点的camera视角
+                        if (_self._viewer.camera) {
+                            _self._cameraPosition = _self._viewer.camera.position;
+                            _self._cameraHeading = _self._viewer.camera.heading;
+                            _self._cameraPitch = _self._viewer.camera.pitch;
+                            _self._cameraRoll = _self._viewer.camera.roll;
+                        }
+                    }
+                    if (positions.length >= minPoints) {
+                        poly.positions = positions;
+                        poly._createPrimitive = true;
+                    }
+                    // add new point to polygon
+                    // this one will move with the mouse
+                    positions.push(cartesian);
+                    // add marker at the new position
+                    markers.addBillboard(cartesian);
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                if (positions.length == 0) {
+                    tooltip.showAt(position, "<p>添加第一个点</p>");
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        positions.pop();
+                        // make sure it is slightly different
+                        cartesian.y += (1 + Math.random());
+                        positions.push(cartesian);
+                        if (positions.length >= minPoints) {
+                            poly.positions = positions;
+                            poly._createPrimitive = true;
+                        }
+                        // update marker
+                        markers.getBillboard(positions.length - 1).position = cartesian;
+                        // show tooltip
+                        tooltip.showAt(position, "<p>添加一个新的坐标点 (" + positions.length + ")</p>" + (positions.length > minPoints ? "<p>双击完成多边形绘制</p>" : ""));
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.position;
+            if (position != null) {
+                if (positions.length < minPoints + 2) {
+                    return;
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        _self.stopDrawing();
+                        if (typeof options.callback == 'function') {
+                            // remove overlapping ones
+                            var index = positions.length - 1;
+                            options.callback(positions);
+                        }
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+
+    }
+
+    function getExtentCorners(value) {
+        return ellipsoid.cartographicArrayToCartesianArray([Cesium.Rectangle.northwest(value), Cesium.Rectangle.northeast(value), Cesium.Rectangle.southeast(value), Cesium.Rectangle.southwest(value)]);
+    }
+
+    _.prototype.startDrawingExtent = function (options) {
+
+        var options = copyOptions(options, defaultSurfaceOptions);
+
+        this.startDrawing(
+            function () {
+                if (extent != null) {
+                    primitives.remove(extent);
+                }
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = this._scene.primitives;
+        var tooltip = this._tooltip;
+
+        var firstPoint = null;
+        var extent = null;
+        var markers = null;
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        function updateExtent(value) {
+            if (extent == null) {
+                extent = new Cesium.Primitive();
+                extent.asynchronous = false;
+                extent.classificationType = ClassificationType.TERRAIN;
+                primitives.add(extent);
+            }
+            extent.rectangle = value;
+            // update the markers
+            var corners = getExtentCorners(value);
+            // create if they do not yet exist
+            if (markers == null) {
+                markers = new _.BillboardGroup(_self, defaultBillboard);
+                markers.addBillboards(corners);
+            } else {
+                markers.updateBillboardsPositions(corners);
+            }
+        }
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    if (extent == null) {
+                        // create the rectangle
+                        firstPoint = ellipsoid.cartesianToCartographic(cartesian);
+                        var value = getExtent(firstPoint, firstPoint);
+                        updateExtent(value);
+                    } else {
+                        _self.stopDrawing();
+                        if (typeof options.callback == 'function') {
+                            options.callback(getExtent(firstPoint, ellipsoid.cartesianToCartographic(cartesian)));
+                        }
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                if (extent == null) {
+                    tooltip.showAt(position, "<p>点击添加矩形坐标点</p>");
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        var value = getExtent(firstPoint, ellipsoid.cartesianToCartographic(cartesian));
+                        updateExtent(value);
+                        tooltip.showAt(position, "<p>拖动改变矩形大小</p><p>点击完成矩形绘制</p>");
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    }
+
+    _.prototype.startDrawingCircle = function (options) {
+
+        var options = copyOptions(options, defaultSurfaceOptions);
+
+        this.startDrawing(
+            function cleanUp() {
+                if (circle != null) {
+                    primitives.remove(circle);
+                }
+                markers.remove();
+                mouseHandler.destroy();
+                tooltip.setVisible(false);
+            }
+        );
+
+        var _self = this;
+        var scene = this._scene;
+        var primitives = this._scene.primitives;
+        var tooltip = this._tooltip;
+
+        var circle = null;
+        var markers = null;
+
+        var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+
+        // Now wait for start
+        mouseHandler.setInputAction(function (movement) {
+            if (movement.position != null) {
+                var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
+                if (cartesian) {
+                    if (circle == null) {
+                        // create the circle
+                        circle = new _.CirclePrimitive({
+                            center: cartesian,
+                            radius: 0,
+                            asynchronous: false,
+                            material: options.material
+                        });
+                        primitives.add(circle);
+                        markers = new _.BillboardGroup(_self, defaultBillboard);
+                        markers.addBillboards([cartesian]);
+                    } else {
+                        if (typeof options.callback == 'function') {
+                            options.callback(circle.getCenter(), circle.getRadius());
+                        }
+                        _self.stopDrawing();
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
+
+        mouseHandler.setInputAction(function (movement) {
+            var position = movement.endPosition;
+            if (position != null) {
+                if (circle == null) {
+                    tooltip.showAt(position, "<p>添加圆心点</p>");
+                } else {
+                    var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
+                    if (cartesian) {
+                        circle.setRadius(Cesium.Cartesian3.distance(circle.getCenter(), cartesian));
+                        markers.updateBillboardsPositions(cartesian);
+                        tooltip.showAt(position, "<p>移动鼠标改变圆半径</p><p>点击完成绘制圆</p>");
+                    }
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    }
+
+    _.prototype.enhancePrimitives = function () {
+
+        var drawHelper = this;
+
+        Cesium.Billboard.prototype.setEditable = function () {
+
+            if (this._editable) {
+                return;
+            }
+
+            this._editable = true;
+
+            var billboard = this;
+
+            var _self = this;
+
+            function enableRotation(enable) {
+                drawHelper._scene.screenSpaceCameraController.enableRotate = enable;
+            }
+
+            setListener(billboard, 'leftDown', function (position) {
+                // TODO - start the drag handlers here
+                // create handlers for mouseOut and leftUp for the billboard and a mouseMove
+                function onDrag(position) {
+                    billboard.position = position;
+                    _self.executeListeners({ name: 'drag', positions: position });
+                }
+
+                function onDragEnd(position) {
+                    handler.destroy();
+                    enableRotation(true);
+                    _self.executeListeners({ name: 'dragEnd', positions: position });
+                }
+
+                var handler = new Cesium.ScreenSpaceEventHandler(drawHelper._scene.canvas);
+
+                handler.setInputAction(function (movement) {
+                    var cartesian = drawHelper._scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
+                    if (cartesian) {
+                        onDrag(cartesian);
+                    } else {
+                        onDragEnd(cartesian);
+                    }
+                }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+                handler.setInputAction(function (movement) {
+                    onDragEnd(drawHelper._scene.camera.pickEllipsoid(movement.position, ellipsoid));
+                }, Cesium.ScreenSpaceEventType.LEFT_UP);
+
+                enableRotation(false);
+
+            });
+
+            enhanceWithListeners(billboard);
+
+        }
+
+        function setHighlighted(highlighted) {
+
+            var scene = drawHelper._scene;
+
+            // if no change
+            // if already highlighted, the outline polygon will be available
+            if (this._highlighted && this._highlighted == highlighted) {
+                return;
+            }
+            // disable if already in edit mode
+            if (this._editMode === true) {
+                return;
+            }
+            this._highlighted = highlighted;
+            // highlight by creating an outline polygon matching the polygon points
+            if (highlighted) {
+                // make sure all other shapes are not highlighted
+                drawHelper.setHighlighted(this);
+                this._strokeColor = this.strokeColor;
+                this.setStrokeStyle(Cesium.Color.fromCssColorString('white'), this.strokeWidth);
+            } else {
+                if (this._strokeColor) {
+                    this.setStrokeStyle(this._strokeColor, this.strokeWidth);
+                } else {
+                    this.setStrokeStyle(undefined, undefined);
+                }
+            }
+        }
+
+        function setEditMode(editMode) {
+            // if no change
+            if (this._editMode == editMode) {
+                return;
+            }
+            // make sure all other shapes are not in edit mode before starting the editing of this shape
+            drawHelper.disableAllHighlights();
+            // display markers
+            if (editMode) {
+                drawHelper.setEdited(this);
+                var scene = drawHelper._scene;
+                var _self = this;
+                // create the markers and handlers for the editing
+                if (this._markers == null) {
+                    var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+                    var editMarkers = new _.BillboardGroup(drawHelper, dragHalfBillboard);
+                    // function for updating the edit markers around a certain point
+                    function updateHalfMarkers(index, positions) {
+                        // update the half markers before and after the index
+                        var editIndex = index - 1 < 0 ? positions.length - 1 : index - 1;
+                        if (editIndex < editMarkers.countBillboards()) {
+                            editMarkers.getBillboard(editIndex).position = calculateHalfMarkerPosition(editIndex);
+                        }
+                        editIndex = index;
+                        if (editIndex < editMarkers.countBillboards()) {
+                            editMarkers.getBillboard(editIndex).position = calculateHalfMarkerPosition(editIndex);
+                        }
+                    }
+
+                    function onEdited() {
+                        _self.executeListeners({ name: 'onEdited', positions: _self.positions });
+                    }
+                    var handleMarkerChanges = {
+                        dragHandlers: {
+                            onDrag: function (index, position) {
+                                _self.positions[index] = position;
+                                updateHalfMarkers(index, _self.positions);
+                                _self._createPrimitive = true;
+                            },
+                            onDragEnd: function (index, position) {
+                                _self._createPrimitive = true;
+                                onEdited();
+                            }
+                        },
+                        onDoubleClick: function (index) {
+                            if (_self.positions.length < 4) {
+                                return;
+                            }
+                            // remove the point and the corresponding markers
+                            _self.positions.splice(index, 1);
+                            _self._createPrimitive = true;
+                            markers.removeBillboard(index);
+                            editMarkers.removeBillboard(index);
+                            updateHalfMarkers(index, _self.positions);
+                            onEdited();
+                        },
+                        tooltip: function () {
+                            if (_self.positions.length > 3) {
+                                return "双击移除该点";
+                            }
+                        }
+                    };
+                    // add billboards and keep an ordered list of them for the polygon edges
+                    markers.addBillboards(_self.positions, handleMarkerChanges);
+                    this._markers = markers;
+
+                    function calculateHalfMarkerPosition(index) {
+                        var positions = _self.positions;
+                        return ellipsoid.cartographicToCartesian(
+                            new Cesium.EllipsoidGeodesic(ellipsoid.cartesianToCartographic(positions[index]),
+                                ellipsoid.cartesianToCartographic(positions[index < positions.length - 1 ? index + 1 : 0])).interpolateUsingFraction(0.5)
+                        );
+                    }
+                    var halfPositions = [];
+                    var index = 0;
+                    var length = _self.positions.length + (this.isPolygon ? 0 : -1);
+                    for (; index < length; index++) {
+                        halfPositions.push(calculateHalfMarkerPosition(index));
+                    }
+                    var handleEditMarkerChanges = {
+                        dragHandlers: {
+                            onDragStart: function (index, position) {
+                                // add a new position to the polygon but not a new marker yet
+                                this.index = index + 1;
+                                _self.positions.splice(this.index, 0, position);
+                                _self._createPrimitive = true;
+                            },
+                            onDrag: function (index, position) {
+                                _self.positions[this.index] = position;
+                                _self._createPrimitive = true;
+                            },
+                            onDragEnd: function (index, position) {
+                                // create new sets of makers for editing
+                                markers.insertBillboard(this.index, position, handleMarkerChanges);
+                                editMarkers.getBillboard(this.index - 1).position = calculateHalfMarkerPosition(this.index - 1);
+                                editMarkers.insertBillboard(this.index, calculateHalfMarkerPosition(this.index), handleEditMarkerChanges);
+                                _self._createPrimitive = true;
+                                onEdited();
+                            }
+                        },
+                        tooltip: function () {
+                            return "拖动添加一个新的点";
+                        }
+                    };
+                    editMarkers.addBillboards(halfPositions, handleEditMarkerChanges);
+                    this._editMarkers = editMarkers;
+                    // add a handler for clicking in the globe
+                    this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                    this._globeClickhandler.setInputAction(
+                        function (movement) {
+                            var pickedObject = scene.pick(movement.position);
+                            if (!(pickedObject && pickedObject.primitive)) {
+                                _self.setEditMode(false);
+                            }
+                        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                    // set on top of the polygon
+                    markers.setOnTop();
+                    editMarkers.setOnTop();
+                }
+                this._editMode = true;
+            } else {
+                if (this._markers != null) {
+                    this._markers.remove();
+                    this._editMarkers.remove();
+                    this._markers = null;
+                    this._editMarkers = null;
+                    this._globeClickhandler.destroy();
+                }
+                this._editMode = false;
+            }
+
+        }
+
+        DrawHelper.PolylinePrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var polyline = this;
+            polyline.isPolygon = false;
+            polyline.asynchronous = false;
+
+            drawHelper.registerEditableShape(polyline);
+
+            polyline.setEditMode = setEditMode;
+
+            var originalWidth = this.width;
+
+            polyline.setHighlighted = function (highlighted) {
+                // disable if already in edit mode
+                if (this._editMode === true) {
+                    return;
+                }
+                if (highlighted) {
+                    drawHelper.setHighlighted(this);
+                    this.setWidth(originalWidth * 2);
+                } else {
+                    this.setWidth(originalWidth);
+                }
+            }
+
+            polyline.getExtent = function () {
+                return Cesium.Extent.fromCartographicArray(ellipsoid.cartesianArrayToCartographicArray(this.positions));
+            }
+
+            enhanceWithListeners(polyline);
+
+            polyline.setEditMode(false);
+
+        }
+
+        DrawHelper.PolygonPrimitive.prototype.setEditable = function () {
+
+            var polygon = this;
+            polygon.asynchronous = false;
+
+            var scene = drawHelper._scene;
+
+            drawHelper.registerEditableShape(polygon);
+
+            polygon.setEditMode = setEditMode;
+
+            polygon.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(polygon);
+
+            polygon.setEditMode(false);
+
+        }
+
+        DrawHelper.ExtentPrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var extent = this;
+            var scene = drawHelper._scene;
+
+            drawHelper.registerEditableShape(extent);
+            extent.asynchronous = false;
+
+            extent.setEditMode = function (editMode) {
+                // if no change
+                if (this._editMode == editMode) {
+                    return;
+                }
+                drawHelper.disableAllHighlights();
+                // display markers
+                if (editMode) {
+                    // make sure all other shapes are not in edit mode before starting the editing of this shape
+                    drawHelper.setEdited(this);
+                    // create the markers and handlers for the editing
+                    if (this._markers == null) {
+                        var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+
+                        function onEdited() {
+                            extent.executeListeners({ name: 'onEdited', extent: extent.extent });
+                        }
+                        var handleMarkerChanges = {
+                            dragHandlers: {
+                                onDrag: function (index, position) {
+                                    var corner = markers.getBillboard((index + 2) % 4).position;
+                                    extent.setExtent(getExtent(ellipsoid.cartesianToCartographic(corner), ellipsoid.cartesianToCartographic(position)));
+                                    markers.updateBillboardsPositions(getExtentCorners(extent.extent));
+                                },
+                                onDragEnd: function (index, position) {
+                                    onEdited();
+                                }
+                            },
+                            tooltip: function () {
+                                return "拖动改变矩形中心点";
+                            }
+                        };
+                        markers.addBillboards(getExtentCorners(extent.extent), handleMarkerChanges);
+                        this._markers = markers;
+                        // add a handler for clicking in the globe
+                        this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                        this._globeClickhandler.setInputAction(
+                            function (movement) {
+                                var pickedObject = scene.pick(movement.position);
+                                // disable edit if pickedobject is different or not an object
+                                /*if(!(pickedObject && !pickedObject.isDestroyed() && pickedObject.primitive)) {
+                                    extent.setEditMode(false);
+                                }*/
+                                //修改之处
+                                if (pickedObject.isDestroyed()) {
+                                    if (!(pickedObject && !pickedObject.isDestroyed() && pickedObject.primitive)) {
+                                        extent.setEditMode(false);
+                                    }
+                                } else {
+                                    if (!(pickedObject && pickedObject.primitive)) {
+                                        extent.setEditMode(false);
+                                    }
+                                }
+                            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                        // set on top of the polygon
+                        markers.setOnTop();
+                    }
+                    this._editMode = true;
+                } else {
+                    if (this._markers != null) {
+                        this._markers.remove();
+                        this._markers = null;
+                        this._globeClickhandler.destroy();
+                    }
+                    this._editMode = false;
+                }
+            }
+
+            extent.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(extent);
+
+            extent.setEditMode(false);
+
+        }
+
+        _.EllipsePrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var ellipse = this;
+            var scene = drawHelper._scene;
+
+            ellipse.asynchronous = false;
+
+            drawHelper.registerEditableShape(ellipse);
+
+            ellipse.setEditMode = function (editMode) {
+                // if no change
+                if (this._editMode == editMode) {
+                    return;
+                }
+                drawHelper.disableAllHighlights();
+                // display markers
+                if (editMode) {
+                    // make sure all other shapes are not in edit mode before starting the editing of this shape
+                    drawHelper.setEdited(this);
+                    var _self = this;
+                    // create the markers and handlers for the editing
+                    if (this._markers == null) {
+                        var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+
+                        function getMarkerPositions() {
+                            return Cesium.Shapes.computeEllipseBoundary(ellipsoid, ellipse.getCenter(), ellipse.getSemiMajorAxis(), ellipse.getSemiMinorAxis(), ellipse.getRotation() + Math.PI / 2, Math.PI / 2.0).splice(0, 4);
+                        }
+
+                        function onEdited() {
+                            ellipse.executeListeners({ name: 'onEdited', center: ellipse.getCenter(), semiMajorAxis: ellipse.getSemiMajorAxis(), semiMinorAxis: ellipse.getSemiMinorAxis(), rotation: 0 });
+                        }
+                        var handleMarkerChanges = {
+                            dragHandlers: {
+                                onDrag: function (index, position) {
+                                    var distance = Cesium.Cartesian3.distance(ellipse.getCenter(), position);
+                                    if (index % 2 == 0) {
+                                        ellipse.setSemiMajorAxis(distance);
+                                    } else {
+                                        ellipse.setSemiMinorAxis(distance);
+                                    }
+                                    markers.updateBillboardsPositions(getMarkerPositions());
+                                },
+                                onDragEnd: function (index, position) {
+                                    onEdited();
+                                }
+                            },
+                            tooltip: function () {
+                                return "Drag to change the excentricity and radius";
+                            }
+                        };
+                        markers.addBillboards(getMarkerPositions(), handleMarkerChanges);
+                        this._markers = markers;
+                        // add a handler for clicking in the globe
+                        this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                        this._globeClickhandler.setInputAction(
+                            function (movement) {
+                                var pickedObject = scene.pick(movement.position);
+                                if (!(pickedObject && pickedObject.primitive)) {
+                                    _self.setEditMode(false);
+                                }
+                            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                        // set on top of the polygon
+                        markers.setOnTop();
+                    }
+                    this._editMode = true;
+                } else {
+                    if (this._markers != null) {
+                        this._markers.remove();
+                        this._markers = null;
+                        this._globeClickhandler.destroy();
+                    }
+                    this._editMode = false;
+                }
+            }
+
+            ellipse.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(ellipse);
+
+            ellipse.setEditMode(false);
+        }
+
+        _.CirclePrimitive.prototype.getCircleCartesianCoordinates = function (granularity) {
+            var geometry = Cesium.CircleOutlineGeometry.createGeometry(new Cesium.CircleOutlineGeometry({ ellipsoid: ellipsoid, center: this.getCenter(), radius: this.getRadius(), granularity: granularity }));
+            var count = 0,
+                value, values = [];
+            for (; count < geometry.attributes.position.values.length; count += 3) {
+                value = geometry.attributes.position.values;
+                values.push(new Cesium.Cartesian3(value[count], value[count + 1], value[count + 2]));
+            }
+            return values;
+        };
+
+        _.CirclePrimitive.prototype.setEditable = function () {
+
+            if (this.setEditMode) {
+                return;
+            }
+
+            var circle = this;
+            var scene = drawHelper._scene;
+
+            circle.asynchronous = false;
+
+            drawHelper.registerEditableShape(circle);
+
+            circle.setEditMode = function (editMode) {
+                // if no change
+                if (this._editMode == editMode) {
+                    return;
+                }
+                drawHelper.disableAllHighlights();
+                // display markers
+                if (editMode) {
+                    // make sure all other shapes are not in edit mode before starting the editing of this shape
+                    drawHelper.setEdited(this);
+                    var _self = this;
+                    // create the markers and handlers for the editing
+                    if (this._markers == null) {
+                        var markers = new _.BillboardGroup(drawHelper, dragBillboard);
+
+                        function getMarkerPositions() {
+                            return _self.getCircleCartesianCoordinates(Cesium.Math.PI_OVER_TWO);
+                        }
+
+                        function onEdited() {
+                            circle.executeListeners({ name: 'onEdited', center: circle.getCenter(), radius: circle.getRadius() });
+                        }
+                        var handleMarkerChanges = {
+                            dragHandlers: {
+                                onDrag: function (index, position) {
+                                    circle.setRadius(Cesium.Cartesian3.distance(circle.getCenter(), position));
+                                    markers.updateBillboardsPositions(getMarkerPositions());
+                                },
+                                onDragEnd: function (index, position) {
+                                    onEdited();
+                                }
+                            },
+                            tooltip: function () {
+                                return "拖动改变圆半径";
+                            }
+                        };
+                        markers.addBillboards(getMarkerPositions(), handleMarkerChanges);
+                        this._markers = markers;
+                        // add a handler for clicking in the globe
+                        this._globeClickhandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+                        this._globeClickhandler.setInputAction(
+                            function (movement) {
+                                var pickedObject = scene.pick(movement.position);
+                                if (!(pickedObject && pickedObject.primitive)) {
+                                    _self.setEditMode(false);
+                                }
+                            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+                        // set on top of the polygon
+                        markers.setOnTop();
+                    }
+                    this._editMode = true;
+                } else {
+                    if (this._markers != null) {
+                        this._markers.remove();
+                        this._markers = null;
+                        this._globeClickhandler.destroy();
+                    }
+                    this._editMode = false;
+                }
+            }
+
+            circle.setHighlighted = setHighlighted;
+
+            enhanceWithListeners(circle);
+
+            circle.setEditMode(false);
+        }
+
+    }
+
+    _.DrawHelperWidget = (function () {
+
+        // constructor
+        function _(drawHelper, options) {
+
+            // container must be specified
+            if (!(Cesium.defined(options.container))) {
+                throw new Cesium.DeveloperError('Container is required');
+            }
+
+            var drawOptions = {
+                markerIcon: "img/draw/point.png",
+                polylineIcon: "img/draw/polyline.png",
+                polygonIcon: "img/draw/polygon.png",
+                circleIcon: "img/draw/circle.png",
+                extentIcon: "img/draw/extent.png",
+                straightArrowIcon: "img/draw/straightArrow.png",
+                attackArrowIcon: "img/draw/attackArrow.png",
+                pincerArrowIcon: "img/draw/pincerArrow.png",
+                clearIcon: "img/draw/clear.png",
+                polylineDrawingOptions: defaultPolylineOptions,
+                polygonDrawingOptions: defaultPolygonOptions,
+                extentDrawingOptions: defaultExtentOptions,
+                circleDrawingOptions: defaultCircleOptions
+            };
+
+            fillOptions(options, drawOptions);
+
+            var _self = this;
+
+            var toolbar = document.createElement('DIV');
+            toolbar.className = "drawtoolbar";
+            options.container.appendChild(toolbar);
+
+            function addIcon(id, url, title, callback) {
+                var div = document.createElement('DIV');
+                div.className = 'button';
+                div.title = title;
+                toolbar.appendChild(div);
+                div.onclick = callback;
+                var span = document.createElement('SPAN');
+                div.appendChild(span);
+                var image = document.createElement('IMG');
+                image.src = url;
+                span.appendChild(image);
+                return div;
+            }
+
+            var scene = drawHelper._scene;
+
+            addIcon('marker', options.markerIcon, '添加标记', function () {
+                drawHelper.startDrawingMarker({
+                    callback: function (position) {
+                        _self.executeListeners({ name: 'markerCreated', position: position });
+                    }
+                });
+            })
+
+            addIcon('polyline', options.polylineIcon, '画线', function () {
+                drawHelper.startDrawingPolyline({
+                    callback: function (positions) {
+                        _self.executeListeners({ name: 'polylineCreated', positions: positions });
+                    }
+                });
+            })
+
+            addIcon('polygon', options.polygonIcon, '画面', function () {
+                drawHelper.startDrawingPolygon({
+                    callback: function (positions) {
+                        _self.executeListeners({ name: 'polygonCreated', positions: positions });
+                    }
+                });
+            })
+
+            addIcon('extent', options.extentIcon, '矩形', function () {
+                drawHelper.startDrawingExtent({
+                    callback: function (extent) {
+                        _self.executeListeners({ name: 'extentCreated', extent: extent });
+                    }
+                });
+            })
+
+            addIcon('circle', options.circleIcon, '画圆', function () {
+                drawHelper.startDrawingCircle({
+                    callback: function (center, radius) {
+                        _self.executeListeners({ name: 'circleCreated', center: center, radius: radius });
+                    }
+                });
+            })
+
+            addIcon('straightArrowIcon', options.straightArrowIcon, '直线箭头', function () {
+                arrow.draw("straightArrow");
+            })
+
+            addIcon('attackArrowIcon', options.attackArrowIcon, '攻击箭头', function () {
+                arrow.draw("attackArrow");
+            })
+
+            addIcon('pincerArrowIcon', options.pincerArrowIcon, '钳击箭头', function () {
+                arrow.draw("pincerArrow");
+            })
+
+            // add a clear button at the end
+            // add a divider first
+            var div = document.createElement('DIV');
+            div.className = 'divider';
+            toolbar.appendChild(div);
+            addIcon('clear', options.clearIcon, '清除图形', function () {
+                //viewer.scene.primitives.removeAll();
+                //removeAllEntities();
+                arrow.clearAll();
+                return;
+                //修改之处
+                drawHelper.disableAllEditMode();
+                var primitives = scene.primitives;
+                var length = primitives.length;
+                for (var i = 0; i < length; ++i) {
+                    var p = primitives.get(i);
+                    if (p) {
+                        if (p.hasOwnProperty("type") && p.type == "plot") { //线、面、矩形、圆形
+                            primitives.remove(p);
+                        } else { //点图标类型
+                            if (p._billboards) {
+                                var billboards = p._billboards;
+                                var len = billboards.length;
+                                if (len > 0) {
+                                    for (var j = 0; j < len; j++) {
+                                        var billboard = billboards[j];
+                                        if (billboard._id == "plot") {
+                                            primitives.remove(p);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                }
+            });
+
+            enhanceWithListeners(this);
+
+        }
+
+        return _;
+
+    })();
+
+    _.prototype.addToolbar = function (container, options) {
+        options = copyOptions(options, { container: container });
+        return new _.DrawHelperWidget(this, options);
+    }
+
+    function getExtent(mn, mx) {
+        var e = new Cesium.Rectangle();
+
+        // Re-order so west < east and south < north
+        e.west = Math.min(mn.longitude, mx.longitude);
+        e.east = Math.max(mn.longitude, mx.longitude);
+        e.south = Math.min(mn.latitude, mx.latitude);
+        e.north = Math.max(mn.latitude, mx.latitude);
+
+        // Check for approx equal (shouldn't require abs due to re-order)
+        var epsilon = Cesium.Math.EPSILON7;
+
+        if ((e.east - e.west) < epsilon) {
+            e.east += epsilon * 2.0;
+        }
+
+        if ((e.north - e.south) < epsilon) {
+            e.north += epsilon * 2.0;
+        }
+
+        return e;
+    };
+
+    /*function createTooltip(frameDiv) {
+
+        var tooltip = function(frameDiv) {
+
+            var div = document.createElement('DIV');
+            div.className = "twipsy right";
+
+            var arrow = document.createElement('DIV');
+            arrow.className = "twipsy-arrow";
+            div.appendChild(arrow);
+
+            var title = document.createElement('DIV');
+            title.className = "twipsy-inner";
+            div.appendChild(title);
+
+            this._div = div;
+            this._title = title;
+
+            // add to frame div and display coordinates
+            frameDiv.appendChild(div);
+        }
+
+        tooltip.prototype.setVisible = function(visible) {
+            this._div.style.display = visible ? 'block' : 'none';
+        }
+
+        tooltip.prototype.showAt = function(position, message) {
+            if(position && message) {
+                this.setVisible(true);
+                this._title.innerHTML = message;
+                this._div.style.left = position.x + 10 + "px";
+                this._div.style.top = (position.y - this._div.clientHeight / 2) + "px";
+            }
+        }
+
+        return new tooltip(frameDiv);
+    }*/
+    //修改之处
+    function createTooltip() {
+
+        var tooltip = function () {
+
+            var div = document.createElement('DIV');
+            div.className = "twipsy right";
+
+            var arrow = document.createElement('DIV');
+            arrow.className = "twipsy-arrow";
+            div.appendChild(arrow);
+
+            var title = document.createElement('DIV');
+            title.className = "twipsy-inner";
+            div.appendChild(title);
+
+            this._div = div;
+            this._title = title;
+
+            // add to frame div and display coordinates
+            //frameDiv.appendChild(div);
+            $('.cesium-viewer').append(div);
+        }
+
+        tooltip.prototype.setVisible = function (visible) {
+            this._div.style.display = visible ? 'block' : 'none';
+        }
+
+        tooltip.prototype.showAt = function (position, message) {
+            if (position && message) {
+                this.setVisible(true);
+                this._title.innerHTML = message;
+                this._div.style.left = position.x + 10 + "px";
+                this._div.style.top = (position.y - this._div.clientHeight / 2) + "px";
+            }
+        }
+
+        return new tooltip();
+    }
+
+    function getDisplayLatLngString(cartographic, precision) {
+        return cartographic.longitude.toFixed(precision || 3) + ", " + cartographic.latitude.toFixed(precision || 3);
+    }
+
+    function clone(from, to) {
+        if (from == null || typeof from != "object") return from;
+        if (from.constructor != Object && from.constructor != Array) return from;
+        if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function ||
+            from.constructor == String || from.constructor == Number || from.constructor == Boolean)
+            return new from.constructor(from);
+
+        to = to || new from.constructor();
+
+        for (var name in from) {
+            to[name] = typeof to[name] == "undefined" ? clone(from[name], null) : to[name];
+        }
+
+        return to;
+    }
+
+    function fillOptions(options, defaultOptions) {
+        options = options || {};
+        var option;
+        for (option in defaultOptions) {
+            if (options[option] === undefined) {
+                options[option] = clone(defaultOptions[option]);
+            }
+        }
+    }
+
+    // shallow copy
+    function copyOptions(options, defaultOptions) {
+        var newOptions = clone(options),
+            option;
+        for (option in defaultOptions) {
+            if (newOptions[option] === undefined) {
+                newOptions[option] = clone(defaultOptions[option]);
+            }
+        }
+        return newOptions;
+    }
+
+    function setListener(primitive, type, callback) {
+        primitive[type] = callback;
+    }
+
+    function enhanceWithListeners(element) {
+
+        element._listeners = {};
+
+        element.addListener = function (name, callback) {
+            this._listeners[name] = (this._listeners[name] || []);
+            this._listeners[name].push(callback);
+            return this._listeners[name].length;
+        }
+
+        element.executeListeners = function (event, defaultCallback) {
+            if (this._listeners[event.name] && this._listeners[event.name].length > 0) {
+                var index = 0;
+                for (; index < this._listeners[event.name].length; index++) {
+                    this._listeners[event.name][index](event);
+                }
+            } else {
+                if (defaultCallback) {
+                    defaultCallback(event);
+                }
+            }
+        }
+
+    }
+
+    return _;
+})();

+ 608 - 0
src/utils/map/drawPlugin/GlobeBufferLineDrawer.js

@@ -0,0 +1,608 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobeBufferLineDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobeBufferLineDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    lineMaterial: null,
+    fill: true,
+    line: true,
+    lineWidth: 2,
+    extrudedHeight: 0,
+    radius: 1000,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        // _this.tooltip = new GlobeTooltip(viewer.container);
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyBufferLine: function (positions, radius, okHandler, cancelHandler) {
+        var _this = this;
+        _this.positions = positions;
+        _this.radius = radius;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyRegion2Map();
+    },
+    startDrawBufferLine: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            var num = _this.positions.length;
+            var tip = "<p style='margin: 0'>点击添加下一个点</p>";
+            if (num > 2) {
+                tip += "<p style='margin: 0'>右键结束绘制</p>";
+            }
+            _this.tooltip.showAt(position, tip);
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 3) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+
+            layer.prompt({
+                title: '请输入缓冲半径(单位km)'
+            }, function (value, index, elem) {
+                layer.close(index);
+                _this.radius = value * 1000;
+
+                //进入编辑状态
+                _this.clear();
+                _this._showModifyRegion2Map();
+            });
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.tempPositions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+                if (pickedAnchor.flag == "mid_anchor") {
+                    _this._updateModifyAnchors(oid);
+                }
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId) {
+                    return;
+                }
+                if (entity.flag != "anchor" && entity.flag != "mid_anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                if (entity.flag == "anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+                }
+                if (entity.flag == "mid_anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动创建新的控制点</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var oid = pickedAnchor.oid;
+            if (pickedAnchor.flag == "anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+                //左右两个中点
+                _this._updateNewMidAnchors(oid);
+            } else if (pickedAnchor.flag == "mid_anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.lineMaterial == null) {
+            _this.lineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.positions;
+        }, false);
+        var bData = {
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: _this.lineWidth || 2,
+                material: _this.lineMaterial
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.lineMaterial == null) {
+            _this.lineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+
+        var linePositions = new Cesium.CallbackProperty(function () {
+            return _this.tempPositions;
+        }, false);
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            var pnts = _this.computeBufferLine(_this.tempPositions, _this.radius || 1000);
+            var pHierarchy = new Cesium.PolygonHierarchy(pnts);
+            return pHierarchy;
+        }, false);
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: linePositions,
+                clampToGround: true,
+                width: _this.lineWidth || 2,
+                material: _this.lineMaterial,
+                show: _this.line
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateModifyAnchors: function (oid) {
+        var _this = this;
+        var num = _this.tempPositions.length;
+        if (oid == 0 || oid == num - 1) {
+            return;
+        }
+        //重新计算tempPositions
+        var p = _this.tempPositions[oid];
+        var p1 = _this.tempPositions[oid - 1];
+        var p2 = _this.tempPositions[oid + 1];
+
+        //计算中心
+        var cp1 = _this._computeCenterPotition(p1, p);
+        var cp2 = _this._computeCenterPotition(p, p2);
+
+        //插入点
+        var arr = [cp1, p, cp2];
+        _this.tempPositions.splice(oid, 1, cp1, p, cp2);
+
+        //重新加载锚点
+        _this._clearAnchors(_this.layerId);
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateNewMidAnchors: function (oid) {
+        var _this = this;
+        if (oid == null || oid == undefined) {
+            return;
+        }
+        //左边两个中点,oid2为临时中间点
+        var oid1 = null;
+        var oid2 = null;
+        //右边两个中点,oid3为临时中间点
+        var oid3 = null;
+        var oid4 = null;
+
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            oid1 = num - 2;
+            oid2 = num - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        } else if (oid == num - 2) {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = num - 1;
+            oid4 = 0;
+        } else {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        }
+
+        var c1 = _this.tempPositions[oid1];
+        var c = _this.tempPositions[oid];
+        var c4 = _this.tempPositions[oid4];
+
+        if (oid == 0) {
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid3].position.setValue(c3);
+        } else if (oid == num - 1) {
+            var c2 = _this._computeCenterPotition(c1, c);
+            _this.tempPositions[oid2] = c2;
+            _this.markers[oid2].position.setValue(c2);
+        } else {
+            var c2 = _this._computeCenterPotition(c1, c);
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid2] = c2;
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid2].position.setValue(c2);
+            _this.markers[oid3].position.setValue(c3);
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIconLight,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.sid = cartesian.sid; //记录原始序号
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _createMidPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "mid_anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            p1.sid = i - 1;
+            p2.sid = i;
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+        var last = pnts[num - 1];
+        _this.tempPositions.push(last);
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                var positions = [];
+                for (var i = 0; i < _this.tempPositions.length; i += 2) {
+                    var p = _this.tempPositions[i];
+                    positions.push(p);
+                }
+                _this.positions = positions;
+                _this.okHandler(positions, _this.radius);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    computeBufferLine: function (positions, radius) {
+        var _this = this;
+        var arr = [];
+        var first = positions[0];
+        var num = positions.length;
+        for (var i = 0; i < num; i++) {
+            var p = _this._cartesian2LonLat(positions[i]);
+            if (i == num - 1 && first == p) {
+                break;
+            }
+            arr.push([p.lon, p.lat]);
+        }
+
+        var line = turf.lineString(arr);
+        var feature = turf.buffer(line, radius * 1, { units: 'meters' });
+        var coordinates = feature.geometry.coordinates;
+        if (!coordinates || coordinates.length < 1) {
+            return null;
+        }
+        var pnts = coordinates[0];
+        if (!pnts || pnts.length < 3) {
+            return null;
+        }
+
+        var linePositions = [];
+        for (var j = 0; j < pnts.length; j++) {
+            var p = pnts[j];
+            var c = Cesium.Cartesian3.fromDegrees(p[0], p[1]);
+            linePositions.push(c);
+        }
+
+        return linePositions;
+    },
+    _cartesian2LonLat: function (cartesian) {
+        var _this = this;
+        //将笛卡尔坐标转换为地理坐标
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        //将弧度转为度的十进制度表示
+        var pos = {
+            lon: Cesium.Math.toDegrees(cartographic.longitude),
+            lat: Cesium.Math.toDegrees(cartographic.latitude),
+            alt: Math.ceil(cartographic.height)
+        };
+        return pos;
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _getLonLats: function (positions) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < positions.length; i++) {
+            var c = positions[i];
+            var p = _this._getLonLat(c);
+            p.sid = c.sid;
+            p.oid = c.oid;
+            arr.push(p);
+        }
+        return arr;
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "GlobeBufferLineDrawer"
+};

+ 577 - 0
src/utils/map/drawPlugin/GlobeCircleDrawer.js

@@ -0,0 +1,577 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobeCircleDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobeCircleDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    outlineEntity: null,
+    positions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_center.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    radiusLineMaterial: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 3,
+    extrudedHeight: 0,
+    toolBarIndex: null,
+    layerId: "globeEntityDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyCircle: function (positions, okHandler, cancelHandler) {
+        var _this = this;
+        _this.positions = positions;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyRegion2Map();
+        _this._showCircleOutline2Map();
+        _this._startModify();
+    },
+    startDrawCircle: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                _this._createCenter(cartesian, 0);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+                _this._showCircleOutline2Map();
+            }
+            _this.positions.push(cartesian);
+            if (num > 0) {
+                _this._createPoint(cartesian, 1);
+            }
+            if (num > 1) {
+                _this.positions.pop();
+                _this.viewer.entities.remove(floatingPoint);
+                _this.tooltip.setVisible(false);
+                _this.okHandler && _this.okHandler(_this.positions);
+                _this._startModify();
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>选择终点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.positions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            pickedAnchor.position.setValue(cartesian);
+            var oid = pickedAnchor.oid;
+            _this.positions[oid] = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _createCenter: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        return point;
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIconLight,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        return point;
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.radiusLineMaterial == null) {
+            _this.radiusLineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var dis = _this._computeCircleRadius3D(_this.positions);
+                dis = (dis / 1000).toFixed(3);
+                _this.entity.label.text = dis + "km";
+                var pnts = _this._computeCirclePolygon(_this.positions);
+                var pHierarchy = new Cesium.PolygonHierarchy(pnts);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var lineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                return _this.positions;
+            } else {
+                return null;
+            }
+        }, false);
+        var labelDynamicPosition = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var p1 = _this.positions[0];
+                var p2 = _this.positions[1];
+                var cp = _this._computeCenterPotition(p1, p2);
+                return cp;
+            } else {
+                return null;
+            }
+        }, false);
+        var bData = {
+            position: labelDynamicPosition,
+            label: {
+                text: "",
+                font: '14px Helvetica',
+                fillColor: Cesium.Color.RED,
+                // outlineColor: Cesium.Color.BLACK,
+                // outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -100)),
+                pixelOffset: new Cesium.Cartesian2(16, 16)
+            },
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                fill: _this.fill,
+                outline: _this.outline,
+                outlineWidth: _this.outlineWidth,
+                outlineColor: _this.outlineColor
+            }),
+            polyline: {
+                positions: lineDynamicPositions,
+                clampToGround: true,
+                width: 2,
+                material: _this.radiusLineMaterial
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.radiusLineMaterial == null) {
+            _this.radiusLineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            var dis = _this._computeCircleRadius3D(_this.positions);
+            dis = (dis / 1000).toFixed(3);
+            _this.entity.label.text = dis + "km";
+            var pnts = _this._computeCirclePolygon(_this.positions);
+            var pHierarchy = new Cesium.PolygonHierarchy(pnts);
+            return pHierarchy;
+        }, false);
+        var lineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                return _this.positions;
+            } else {
+                return null;
+            }
+        }, false);
+        var labelDynamicPosition = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var p1 = _this.positions[0];
+                var p2 = _this.positions[1];
+                var cp = _this._computeCenterPotition(p1, p2);
+                return cp;
+            } else {
+                return null;
+            }
+        }, false);
+        var dis = _this._computeCircleRadius3D(_this.positions);
+        dis = (dis / 1000).toFixed(3) + "km";
+        var bData = {
+            position: labelDynamicPosition,
+            label: {
+                text: dis,
+                font: '14px Helvetica',
+                fillColor: Cesium.Color.SKYBLUE,
+                outlineColor: Cesium.Color.BLACK,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -9000)),
+                pixelOffset: new Cesium.Cartesian2(16, 16)
+            },
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                fill: _this.fill,
+                outline: _this.outline,
+                outlineWidth: _this.outlineWidth,
+                outlineColor: _this.outlineColor
+            }),
+            polyline: {
+                positions: lineDynamicPositions,
+                clampToGround: true,
+                width: 2,
+                material: _this.radiusLineMaterial
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        _this._createCenter(_this.positions[0], 0);
+        _this._createPoint(_this.positions[1], 1);
+    },
+    _showCircleOutline2Map: function () {
+        var _this = this;
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+        var outelinePositions = new Cesium.CallbackProperty(function () {
+            var pnts = _this._computeCirclePolygon(_this.positions);
+            return pnts;
+        }, false);
+        var bData = {
+            polyline: {
+                positions: outelinePositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial
+            }
+        };
+        _this.outlineEntity = _this.viewer.entities.add(bData);
+        _this.outlineEntity.layerId = _this.layerId;
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _computeCirclePolygon: function (positions) {
+        var _this = this;
+
+        try {
+            if (!positions || positions.length < 2) {
+                return null;
+            }
+            var cp = positions[0];
+            var r = _this._computeCircleRadius3D(positions);
+            var pnts = _this._computeCirclePolygon2(cp, r);
+            return pnts;
+        } catch (err) {
+            return null;
+        }
+    },
+    _computeCirclePolygon2: function (center, radius) {
+        var _this = this;
+
+        try {
+            if (!center || radius <= 0) {
+                return null;
+            }
+            var cep = Cesium.EllipseGeometryLibrary.computeEllipsePositions({
+                center: center,
+                semiMajorAxis: radius,
+                semiMinorAxis: radius,
+                rotation: 0,
+                granularity: 0.005
+            }, false, true);
+            if (!cep || !cep.outerPositions) {
+                return null;
+            }
+            var pnts = Cesium.Cartesian3.unpackArray(cep.outerPositions);
+            var first = pnts[0];
+            pnts[pnts.length] = first;
+            return pnts;
+        } catch (err) {
+            return null;
+        }
+    },
+    _computeCirclePolygon3: function (center, semiMajorAxis, semiMinorAxis, rotation) {
+        var _this = this;
+
+        try {
+            if (!center || semiMajorAxis <= 0 || semiMinorAxis <= 0) {
+                return null;
+            }
+            var cep = Cesium.EllipseGeometryLibrary.computeEllipsePositions({
+                center: center,
+                semiMajorAxis: semiMajorAxis,
+                semiMinorAxis: semiMinorAxis,
+                rotation: rotation,
+                granularity: 0.005
+            }, false, true);
+            if (!cep || !cep.outerPositions) {
+                return null;
+            }
+            var pnts = Cesium.Cartesian3.unpackArray(cep.outerPositions);
+            var first = pnts[0];
+            pnts[pnts.length] = first;
+            return pnts;
+        } catch (err) {
+            return null;
+        }
+    },
+    _computeCirclePolygonForDegree: function (positions) {
+        var _this = this;
+        var cp = _this.ellipsoid.cartesianToCartographic(positions[0]);
+        var rp = _this.ellipsoid.cartesianToCartographic(positions[1]);
+        var x0 = cp.longitude;
+        var y0 = cp.latitude;
+        var xr = rp.longitude;
+        var yr = rp.latitude;
+        var r = Math.sqrt(Math.pow((x0 - xr), 2) + Math.pow((y0 - yr), 2));
+
+        var pnts = [];
+        for (var i = 0; i < 360; i++) {
+            var x1 = x0 + r * Math.cos(i * Math.PI / 180);
+            var y1 = y0 + r * Math.sin(i * Math.PI / 180);
+            var p1 = Cesium.Cartesian3.fromRadians(x1, y1);
+            pnts.push(p1);
+        }
+        return pnts;
+    },
+    _computeCircleRadius3D: function (positions) {
+        var distance = 0;
+        var c1 = positions[0];
+        var c2 = positions[1];
+        var x = Math.pow(c1.x - c2.x, 2);
+        var y = Math.pow(c1.y - c2.y, 2);
+        var z = Math.pow(c1.z - c2.z, 2);
+        var dis = Math.sqrt(x + y + z);
+        return dis;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        //_this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                _this.okHandler(_this.positions);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    CLASS_NAME: "GlobeCircleDrawer"
+};

+ 279 - 0
src/utils/map/drawPlugin/GlobePointDrawer.js

@@ -0,0 +1,279 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobePointDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePointDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    position: null,
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    image: "/src/assets/images/map/circle_red.png",
+    toolBarIndex: null,
+    layerId: "globeEntityDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this.entity = null;
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPoint: function (position, okHandler, cancelHandler) {
+        var _this = this;
+        _this.position = position;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this.entity = null;
+        _this._createPoint();
+        _this._startModify();
+    },
+    startDrawPoint: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this.entity = null;
+        _this.position = null;
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var wp = event.position;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            _this.position = cartesian;
+            _this.entity.position.setValue(cartesian);
+            _this.tooltip.setVisible(false);
+            _this._startModify();
+            _this.okHandler && _this.okHandler(_this.position);
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var wp = event.endPosition;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            // if (_this.position == null) {
+            _this.tooltip.showAt(wp, "<p style='margin: 0'>选择位置</p>");
+            // }
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            _this.position = cartesian;
+            if (_this.entity == null) {
+                _this._createPoint();
+            } else {
+                _this.entity.position.setValue(cartesian);
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var wp = event.position;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.position = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(wp);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(wp, "<p style='margin: 0'>移动位置</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var wp = event.endPosition;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            _this.tooltip.showAt(wp, "<p style='margin: 0'>移动位置</p>");
+
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            pickedAnchor.position.setValue(cartesian);
+            var oid = pickedAnchor.oid;
+            _this.position = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _createPoint: function () {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: _this.position,
+            // billboard: {
+            //     image: _this.image,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = 0;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.entity = point;
+        return point;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                var lonLat = _this._getLonLat(_this.position);
+                _this.okHandler(_this.position, lonLat);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height,
+            height: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    CLASS_NAME: "GlobePointDrawer"
+};

+ 302 - 0
src/utils/map/drawPlugin/GlobePointMeasure.js

@@ -0,0 +1,302 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobePointMeasure = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePointMeasure.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    position: null,
+    drawHandler: null,
+    modifyHandler: null,
+    callback: null,
+    image: "/src/assets/images/map/circle_red.png",
+    toolBarIndex: null,
+    layerId: "globeEntityDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this.entity = null;
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPoint: function (position, callback) {
+        var _this = this;
+        _this.position = position;
+        _this.callback = callback;
+        _this.entity = null;
+        _this._createPoint();
+        _this._startModify();
+    },
+    startDrawPoint: function (callback) {
+        var _this = this;
+        _this.callback = callback;
+        _this.entity = null;
+
+        _this.position = null;
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var wp = event.position;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            _this.position = cartesian;
+
+            _this.entity.position.setValue(cartesian);
+            var text = _this._getMeasureTip(_this.position);
+            _this.entity.label.text = text;
+
+            _this.tooltip.setVisible(false);
+            _this._startModify();
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var wp = event.endPosition;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            if (_this.position == null) {
+                _this.tooltip.showAt(wp, "<p style='margin: 0'>选择位置</p>");
+            }
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            _this.position = cartesian;
+            if (_this.entity == null) {
+                _this._createPoint();
+            } else {
+                _this.entity.position.setValue(cartesian);
+                var text = _this._getMeasureTip(_this.position);
+                _this.entity.label.text = text;
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var wp = event.position;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.position = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(wp);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(wp, "<p style='margin: 0'>移动位置</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var wp = event.endPosition;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            _this.tooltip.showAt(wp, "<p style='margin: 0'>移动位置</p>");
+
+            var ray = _this.camera.getPickRay(wp);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(wp, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            _this.position = cartesian;
+            pickedAnchor.position.setValue(cartesian);
+            var text = _this._getMeasureTip(_this.position);
+            _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _createPoint: function () {
+        var _this = this;
+        var text = _this._getMeasureTip(_this.position);
+        var point = _this.viewer.entities.add({
+            position: _this.position,
+            label: {
+                text: text,
+                font: '18px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.RED,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            // billboard: {
+            //     image: _this.image,
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = 0;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.entity = point;
+        return point;
+    },
+    _getMeasureTip: function (cartesian) {
+        var _this = this;
+        var pos = _this._getLonLat(cartesian);
+        if (!pos.alt) {
+            pos.alt = "";
+        } else {
+            pos.alt = pos.alt.toFixed(1);
+        }
+        pos.lon = pos.lon.toFixed(3);
+        pos.lat = pos.lat.toFixed(3);
+        var tip = "经度:" + pos.lon + ",纬度:" + pos.lat + "\n 海拔=" + pos.alt + "米";
+        return tip;
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            if (_this.callback) {
+                var lonLat = _this._getLonLat(_this.position);
+                _this.clear();
+                layer.close(_this.toolBarIndex);
+                _this.callback(_this.position, lonLat);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+        });
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    CLASS_NAME: "GlobePointMeasure"
+};

+ 574 - 0
src/utils/map/drawPlugin/GlobePolygonDrawer.js

@@ -0,0 +1,574 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobePolygonDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePolygonDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 2,
+    extrudedHeight: 0,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPolygon: function (positions, okHandler, cancelHandler) {
+        var _this = this;
+        _this.positions = positions;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyRegion2Map();
+    },
+    startDrawPolygon: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            var num = _this.positions.length;
+            var tip = "<p style='margin: 0'>点击添加下一个点</p>";
+            if (num > 3) {
+                tip += "<p style='margin: 0'>右键结束绘制</p>";
+            }
+            _this.tooltip.showAt(position, tip);
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 4) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+
+            //进入编辑状态
+            _this.clear();
+            _this._showModifyRegion2Map();
+            _this.okHandler(_this.positions);
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.tempPositions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+                if (pickedAnchor.flag == "mid_anchor") {
+                    _this._updateModifyAnchors(oid);
+                }
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId) {
+                    return;
+                }
+                if (entity.flag != "anchor" && entity.flag != "mid_anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                if (entity.flag == "anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+                }
+                if (entity.flag == "mid_anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动创建新的控制点</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var oid = pickedAnchor.oid;
+            if (pickedAnchor.flag == "anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+                //左右两个中点
+                _this._updateNewMidAnchors(oid);
+            } else if (pickedAnchor.flag == "mid_anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 2) {
+                var pHierarchy = new Cesium.PolygonHierarchy(_this.positions);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var arr = [].concat(_this.positions);
+                var first = _this.positions[0];
+                arr.push(first);
+                return arr;
+            } else {
+                return null;
+            }
+        }, false);
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 2) {
+                var pHierarchy = new Cesium.PolygonHierarchy(_this.tempPositions);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.tempPositions.length > 1) {
+                var arr = [].concat(_this.tempPositions);
+                var first = _this.tempPositions[0];
+                arr.push(first);
+                return arr;
+            } else {
+                return null;
+            }
+        }, false);
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateModifyAnchors: function (oid) {
+        var _this = this;
+
+        //重新计算tempPositions
+        var p = _this.tempPositions[oid];
+        var p1 = null;
+        var p2 = null;
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            p1 = _this.tempPositions[num - 1];
+            p2 = _this.tempPositions[oid + 1];
+        } else if (oid == num - 1) {
+            p1 = _this.tempPositions[oid - 1];
+            p2 = _this.tempPositions[0];
+        } else {
+            p1 = _this.tempPositions[oid - 1];
+            p2 = _this.tempPositions[oid + 1];
+        }
+        //计算中心
+        var cp1 = _this._computeCenterPotition(p1, p);
+        var cp2 = _this._computeCenterPotition(p, p2);
+
+        //插入点
+        var arr = [cp1, p, cp2];
+        _this.tempPositions.splice(oid, 1, cp1, p, cp2);
+
+        //重新加载锚点
+        _this._clearAnchors(_this.layerId);
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateNewMidAnchors: function (oid) {
+        var _this = this;
+        if (oid == null || oid == undefined) {
+            return;
+        }
+        //左边两个中点,oid2为临时中间点
+        var oid1 = null;
+        var oid2 = null;
+
+        //右边两个中点,oid3为临时中间点
+        var oid3 = null;
+        var oid4 = null;
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            oid1 = num - 2;
+            oid2 = num - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        } else if (oid == num - 2) {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = num - 1;
+            oid4 = 0;
+        } else {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        }
+
+        var c1 = _this.tempPositions[oid1];
+        var c = _this.tempPositions[oid];
+        var c4 = _this.tempPositions[oid4];
+
+        var c2 = _this._computeCenterPotition(c1, c);
+        var c3 = _this._computeCenterPotition(c4, c);
+
+        _this.tempPositions[oid2] = c2;
+        _this.tempPositions[oid3] = c3;
+
+        _this.markers[oid2].position.setValue(c2);
+        _this.markers[oid3].position.setValue(c3);
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIconLight,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _createMidPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "mid_anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        var first = pnts[0];
+        var last = pnts[num - 1];
+        if (_this._isSimpleXYZ(first, last) == false) {
+            pnts.push(first);
+            num += 1;
+        }
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                var positions = [];
+                for (var i = 0; i < _this.tempPositions.length; i += 2) {
+                    var p = _this.tempPositions[i];
+                    positions.push(p);
+                }
+                _this.positions = positions;
+                _this.okHandler(positions);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "GlobePolygonDrawer"
+};

+ 693 - 0
src/utils/map/drawPlugin/GlobePolygonMeasure.js

@@ -0,0 +1,693 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+import * as turf from '@turf/turf'
+export var GlobePolygonMeasure = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePolygonMeasure.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    callback: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 2,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPolygon: function (positions, callback) {
+        var _this = this;
+        _this.positions = positions;
+        _this.callback = callback;
+        _this._showModifyRegion2Map();
+    },
+    startDrawPolygon: function (callback) {
+        var _this = this;
+        _this.callback = callback;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var cartesian = getPickPositionGlobe(event.position, _this.viewer);
+            // var cartesian = viewer.scene.camera.pickEllipsoid(event.position,  viewer.scene.globe.ellipsoid);
+            // var position = event.position;
+            // if (!Cesium.defined(position)) {
+            //     return;
+            // }
+            // var ray = _this.camera.getPickRay(position);
+            // if (!Cesium.defined(ray)) {
+            //     return;
+            // }
+            // var cartesian = _this.scene.globe.pick(ray, _this.scene);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+            // if (_this.positions.length > 2) {
+            //     var text = _this._getMeasureTip(_this.positions);
+            //     _this.entity.label.text = text;
+            // }
+
+            _this.entity.position = cartesian;
+            // var text = _this._getMeasureTip(_this.positions);
+            // _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            var num = _this.positions.length;
+            var tip = _this._getMeasureTip(_this.positions);
+            tip = tip.replace("\n", "<br/>");
+            tip += "<p style='margin: 0'>点击添加下一个点</p>";
+            if (num > 3) {
+                tip += "<p style='margin: 0'>右键结束绘制</p>";
+            }
+            _this.tooltip.showAt(position, tip);
+
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            // var ray = _this.camera.getPickRay(position);
+            // if (!Cesium.defined(ray)) {
+            //     return;
+            // }
+            // var cartesian = _this.scene.globe.pick(ray, _this.scene);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+            if (_this.positions.length > 2) {
+                // var text = _this._getMeasureTip(_this.positions);
+                // _this.entity.label.text = text;
+            }
+
+            _this.entity.position = cartesian;
+            // var text = _this._getMeasureTip(_this.positions);
+            // _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 4) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+
+            //进入编辑状态
+            _this.clear();
+            _this._showModifyRegion2Map();
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.tempPositions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+                if (pickedAnchor.flag == "mid_anchor") {
+                    _this._updateModifyAnchors(oid);
+                }
+
+                _this.entity.position.setValue(cartesian);
+                var text = _this._getMeasureTip(_this.tempPositions);
+                _this.entity.label.text = text;
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId) {
+                    return;
+                }
+                if (entity.flag != "anchor" && entity.flag != "mid_anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                if (entity.flag == "anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+                }
+                if (entity.flag == "mid_anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动创建新的控制点</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var oid = pickedAnchor.oid;
+            if (pickedAnchor.flag == "anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+                //左右两个中点
+                _this._updateNewMidAnchors(oid);
+            } else if (pickedAnchor.flag == "mid_anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+            }
+
+            _this.entity.position.setValue(cartesian);
+            var text = _this._getMeasureTip(_this.tempPositions);
+            _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 2) {
+                var pHierarchy = new Cesium.PolygonHierarchy(_this.positions);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var arr = [].concat(_this.positions);
+                var first = _this.positions[0];
+                arr.push(first);
+                return arr;
+            } else {
+                return null;
+            }
+        }, false);
+        var num = _this.positions.length;
+        var last = _this.positions[num - 1];
+        var bData = {
+            position: last,
+            label: {
+                text: "",
+                font: '16px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.RED,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 2) {
+                var pHierarchy = new Cesium.PolygonHierarchy(_this.tempPositions);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.tempPositions.length > 1) {
+                var arr = [].concat(_this.tempPositions);
+                var first = _this.tempPositions[0];
+                arr.push(first);
+                return arr;
+            } else {
+                return null;
+            }
+        }, false);
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var num = _this.tempPositions.length;
+        var last = _this.tempPositions[num - 1];
+        var text = _this._getMeasureTip(_this.tempPositions);
+        var bData = {
+            position: last,
+            label: {
+                text: text,
+                font: '16px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.RED,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+        _this.callback && _this.callback(positions, text);
+    },
+    _updateModifyAnchors: function (oid) {
+        var _this = this;
+
+        //重新计算tempPositions
+        var p = _this.tempPositions[oid];
+        var p1 = null;
+        var p2 = null;
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            p1 = _this.tempPositions[num - 1];
+            p2 = _this.tempPositions[oid + 1];
+        } else if (oid == num - 1) {
+            p1 = _this.tempPositions[oid - 1];
+            p2 = _this.tempPositions[0];
+        } else {
+            p1 = _this.tempPositions[oid - 1];
+            p2 = _this.tempPositions[oid + 1];
+        }
+        //计算中心
+        var cp1 = _this._computeCenterPotition(p1, p);
+        var cp2 = _this._computeCenterPotition(p, p2);
+
+        //插入点
+        var arr = [cp1, p, cp2];
+        _this.tempPositions.splice(oid, 1, cp1, p, cp2);
+
+        //重新加载锚点
+        _this._clearAnchors(_this.layerId);
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateNewMidAnchors: function (oid) {
+        var _this = this;
+        if (oid == null || oid == undefined) {
+            return;
+        }
+        //左边两个中点,oid2为临时中间点
+        var oid1 = null;
+        var oid2 = null;
+
+        //右边两个中点,oid3为临时中间点
+        var oid3 = null;
+        var oid4 = null;
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            oid1 = num - 2;
+            oid2 = num - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        } else if (oid == num - 2) {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = num - 1;
+            oid4 = 0;
+        } else {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        }
+
+        var c1 = _this.tempPositions[oid1];
+        var c = _this.tempPositions[oid];
+        var c4 = _this.tempPositions[oid4];
+
+        var c2 = _this._computeCenterPotition(c1, c);
+        var c3 = _this._computeCenterPotition(c4, c);
+
+        _this.tempPositions[oid2] = c2;
+        _this.tempPositions[oid3] = c3;
+
+        _this.markers[oid2].position.setValue(c2);
+        _this.markers[oid3].position.setValue(c3);
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIconLight,
+            //     heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _createMidPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "mid_anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        var first = pnts[0];
+        var last = pnts[num - 1];
+        if (_this._isSimpleXYZ(first, last) == false) {
+            pnts.push(first);
+            num += 1;
+        }
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _getMeasureTip: function (pntList) {
+        var _this = this;
+        var dis2d = _this._computeLineDis2d(pntList);
+        var dis3d = _this._computeLineDis3d(pntList);
+        dis2d = dis2d.toFixed(1);
+        dis3d = dis3d.toFixed(1);
+        var tip = "周长:" + dis3d + "米";
+        if (pntList.length > 2) {
+            var area = _this._computeArea(pntList);
+            tip += "\n 面积:" + area.toFixed(1) + "平方米";
+        }
+        return tip;
+    },
+    _computeDis2d: function (c1, c2) {
+        var dis = Cesium.Cartesian2.distance(c1, c2);
+        return dis;
+    },
+    _computeDis3d: function (p1, p2) {
+        var dis = Cesium.Cartesian3.distance(p1, p2);
+        return dis;
+    },
+    _computeLineDis2d: function (pntList) {
+        var _this = this;
+        var total = 0;
+        for (var i = 1; i < pntList.length; i++) {
+            var p1 = pntList[i - 1];
+            var p2 = pntList[i];
+            var dis = _this._computeDis2d(p1, p2);
+            total += dis;
+        }
+        return total;
+    },
+    _computeLineDis3d: function (pntList) {
+        var _this = this;
+        var total = 0;
+        for (var i = 1; i < pntList.length; i++) {
+            var p1 = pntList[i - 1];
+            var p2 = pntList[i];
+            var dis = _this._computeDis3d(p1, p2);
+            total += dis;
+        }
+        return total;
+    },
+    _cartesian2LonLat: function (cartesian) {
+        var _this = this;
+        //将笛卡尔坐标转换为地理坐标
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        //将弧度转为度的十进制度表示
+        var pos = {
+            lon: Cesium.Math.toDegrees(cartographic.longitude),
+            lat: Cesium.Math.toDegrees(cartographic.latitude),
+            alt: Math.ceil(cartographic.height)
+        };
+        return pos;
+    },
+    _computeArea: function (positions) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < positions.length; i++) {
+            var p = _this._cartesian2LonLat(positions[i]);
+            arr.push([p.lon, p.lat]);
+        }
+        arr.push(arr[0]); //终点和起点重合
+
+        var polygon = turf.polygon([arr]);
+        var area = turf.area(polygon);
+        return area;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            if (_this.callback) {
+                var positions = [];
+                for (var i = 0; i < _this.tempPositions.length; i += 2) {
+                    var p = _this.tempPositions[i];
+                    positions.push(p);
+                }
+                _this.positions = positions;
+
+                _this.clear();
+                layer.close(_this.toolBarIndex);
+
+                var dis2d = _this._computeLineDis2d(positions);
+                var dis3d = _this._computeLineDis3d(positions);
+                var area = _this._computeArea(positions);
+                dis2d = dis2d.toFixed(3);
+                dis3d = dis3d.toFixed(3);
+                area = area.toFixed(3);
+
+                var rlt = {
+                    dis2d: dis2d,
+                    dis3d: dis3d,
+                    area: area
+                }
+                _this.callback(positions, rlt);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+        });
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "GlobePolygonMeasure"
+};

+ 580 - 0
src/utils/map/drawPlugin/GlobePolylineDrawer.js

@@ -0,0 +1,580 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobePolylineDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePolylineDrawer.prototype = {
+    cameraParams: {},// 记录起始点的相机参数
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPolyline: function (positions, okHandler, cancelHandler) {
+        var _this = this;
+        _this.positions = positions;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyPolyline2Map();
+    },
+    startDrawPolyline: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+        _this.tooltip = setTooltip(_this.viewer)
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.cameraParams = {
+                    "position": _this.viewer.camera.position,
+                    "Heading": _this.viewer.camera.heading,
+                    "Pitch": _this.viewer.camera.pitch,
+                    "Roll": _this.viewer.camera.roll
+                }
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showPolyline2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            var num = _this.positions.length;
+            var tip = "<p style='margin: 0'>点击添加下一个点</p>";
+            if (num > 2) {
+                tip += "<p style='margin: 0'>右键结束绘制</p>";
+            }
+            _this.tooltip.showAt(position, tip);
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 3) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+            _this.okHandler && _this.okHandler(_this.positions, _this.cameraParams);
+            //进入编辑状态
+            _this.clear();
+            // _this._showModifyPolyline2Map();
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.tempPositions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+                if (pickedAnchor.flag == "mid_anchor") {
+                    _this._updateModifyAnchors(oid);
+                }
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId) {
+                    return;
+                }
+                if (entity.flag != "anchor" && entity.flag != "mid_anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                if (entity.flag == "anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+                }
+                if (entity.flag == "mid_anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动创建新的控制点</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var oid = pickedAnchor.oid;
+            if (pickedAnchor.flag == "anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+                //左右两个中点
+                _this._updateNewMidAnchors(oid);
+            } else if (pickedAnchor.flag == "mid_anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showPolyline2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = new Cesium.PolylineGlowMaterialProperty({
+                glowPower: 0.25,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.9)
+            });
+        }
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.positions;
+        }, false);
+        var bData = {
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: 8,
+                material: _this.material
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyPolyline2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.tempPositions;
+        }, false);
+        if (_this.material == null) {
+            _this.material = new Cesium.PolylineGlowMaterialProperty({
+                glowPower: 0.25,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.9)
+            });
+        }
+        var bData = {
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: 8,
+                material: _this.material
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateModifyAnchors: function (oid) {
+        var _this = this;
+        var num = _this.tempPositions.length;
+        if (oid == 0 || oid == num - 1) {
+            return;
+        }
+        //重新计算tempPositions
+        var p = _this.tempPositions[oid];
+        var p1 = _this.tempPositions[oid - 1];
+        var p2 = _this.tempPositions[oid + 1];
+
+        //计算中心
+        var cp1 = _this._computeCenterPotition(p1, p);
+        var cp2 = _this._computeCenterPotition(p, p2);
+
+        //插入点
+        var arr = [cp1, p, cp2];
+        _this.tempPositions.splice(oid, 1, cp1, p, cp2);
+
+        //重新加载锚点
+        _this._clearAnchors(_this.layerId);
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateNewMidAnchors: function (oid) {
+        var _this = this;
+        if (oid == null || oid == undefined) {
+            return;
+        }
+        //左边两个中点,oid2为临时中间点
+        var oid1 = null;
+        var oid2 = null;
+        //右边两个中点,oid3为临时中间点
+        var oid3 = null;
+        var oid4 = null;
+
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            oid1 = num - 2;
+            oid2 = num - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        } else if (oid == num - 2) {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = num - 1;
+            oid4 = 0;
+        } else {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        }
+
+        var c1 = _this.tempPositions[oid1];
+        var c = _this.tempPositions[oid];
+        var c4 = _this.tempPositions[oid4];
+
+        if (oid == 0) {
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid3].position.setValue(c3);
+        } else if (oid == num - 1) {
+            var c2 = _this._computeCenterPotition(c1, c);
+            _this.tempPositions[oid2] = c2;
+            _this.markers[oid2].position.setValue(c2);
+        } else {
+            var c2 = _this._computeCenterPotition(c1, c);
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid2] = c2;
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid2].position.setValue(c2);
+            _this.markers[oid3].position.setValue(c3);
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIconLight,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.sid = cartesian.sid; //记录原始序号
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _createMidPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "mid_anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            p1.sid = i - 1;
+            p2.sid = i;
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+        var last = pnts[num - 1];
+        _this.tempPositions.push(last);
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            if (_this.okHandler) {
+                //var positions = [];
+                //for (var i = 0; i < _this.tempPositions.length; i += 2) {
+                //    var p = _this.tempPositions[i];
+                //    positions.push(p);
+                //}
+                var positions = _this._getPositionsWithSid();
+                var lonLats = _this._getLonLats(positions);
+                _this.clear();
+                layer.close(_this.toolBarIndex);
+
+                _this.positions = positions;
+                _this.okHandler(positions, lonLats);
+            } else {
+                _this.clear();
+                layer.close(_this.toolBarIndex);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _getPositionsWithSid: function () {
+        var _this = this;
+        var viewer = _this.viewer;
+        var rlt = [];
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1) {
+            return rlt;
+        }
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId != _this.layerId) {
+                continue;
+            }
+            if (entity.flag != "anchor") {
+                continue;
+            }
+            var p = entity.position.getValue(new Date().getTime());
+            p.sid = entity.sid;
+            p.oid = entity.oid;
+            rlt.push(p);
+        }
+        //排序
+        rlt.sort(function (obj1, obj2) {
+            if (obj1.oid > obj2.oid) {
+                return 1;
+            } else if (obj1.oid == obj2.oid) {
+                return 0;
+            } else {
+                return -1;
+            }
+        });
+        return rlt;
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height,
+            height: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _getLonLats: function (positions) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < positions.length; i++) {
+            var c = positions[i];
+            var p = _this._getLonLat(c);
+            p.sid = c.sid;
+            p.oid = c.oid;
+            arr.push(p);
+        }
+        return arr;
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "GlobePolylineDrawer"
+};

+ 575 - 0
src/utils/map/drawPlugin/GlobePolylineSpaceMeasure.js

@@ -0,0 +1,575 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobePolylineSpaceMeasure = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePolylineSpaceMeasure.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    callback: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPolyline: function (positions, callback) {
+        var _this = this;
+        _this.positions = positions;
+        _this.callback = callback;
+        _this._showModifyPolyline2Map();
+    },
+    startDrawPolyline: function (callback) {
+        var _this = this;
+        _this.callback = callback;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showPolyline2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+
+            _this.entity.position = cartesian;
+            // var text = _this._getMeasureTip(_this.positions);
+            // _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            var num = _this.positions.length;
+            var tip = _this._getMeasureTip(_this.positions);
+            tip += "<p style='margin: 0'>点击添加下一个点</p>";
+            if (num > 2) {
+                tip += "<p style='margin: 0'>右键结束绘制</p>";
+            }
+            _this.tooltip.showAt(position, tip);
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+
+            _this.entity.position.setValue(cartesian);
+            // var text = _this._getMeasureTip(_this.positions);
+            // _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 3) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+
+            //进入编辑状态
+            _this.clear();
+            _this._showModifyPolyline2Map();
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.tempPositions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+                if (pickedAnchor.flag == "mid_anchor") {
+                    _this._updateModifyAnchors(oid);
+                }
+
+                _this.entity.position.setValue(cartesian);
+                var text = _this._getMeasureTip(_this.tempPositions);
+                _this.entity.label.text = text;
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId) {
+                    return;
+                }
+                if (entity.flag != "anchor" && entity.flag != "mid_anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                if (entity.flag == "anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+                }
+                if (entity.flag == "mid_anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动创建新的控制点</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var oid = pickedAnchor.oid;
+            if (pickedAnchor.flag == "anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+                //左右两个中点
+                //_this._updateNewMidAnchors(oid);
+            } else if (pickedAnchor.flag == "mid_anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+            }
+
+            _this.entity.position.setValue(cartesian);
+            var text = _this._getMeasureTip(_this.tempPositions);
+            _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showPolyline2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = new Cesium.PolylineGlowMaterialProperty({
+                glowPower: 0.25,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.9)
+            });
+        }
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.positions;
+        }, false);
+        var num = _this.positions.length;
+        var last = _this.positions[num - 1];
+        var bData = {
+            position: last,
+            label: {
+                text: "",
+                font: '16px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.YELLOW,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: 8,
+                material: _this.material
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyPolyline2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.tempPositions;
+        }, false);
+        if (_this.material == null) {
+            _this.material = new Cesium.PolylineGlowMaterialProperty({
+                glowPower: 0.25,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.9)
+            });
+        }
+        var num = _this.tempPositions.length;
+        var last = _this.tempPositions[num - 1];
+        var text = _this._getMeasureTip(_this.tempPositions);
+        var bData = {
+            position: last,
+            label: {
+                text: text,
+                font: '16px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.YELLOW,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: 8,
+                material: _this.material
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            _this._createPoint(positions[i], i);
+        }
+        _this.callback && _this.callback(positions, text);
+    },
+    _updateModifyAnchors: function (oid) {
+        var _this = this;
+        var num = _this.tempPositions.length;
+        if (oid == 0 || oid == num - 1) {
+            return;
+        }
+        //重新计算tempPositions
+        var p = _this.tempPositions[oid];
+        var p1 = _this.tempPositions[oid - 1];
+        var p2 = _this.tempPositions[oid + 1];
+
+        //计算中心
+        var cp1 = _this._computeCenterPotition(p1, p);
+        var cp2 = _this._computeCenterPotition(p, p2);
+
+        //插入点
+        var arr = [cp1, p, cp2];
+        _this.tempPositions.splice(oid, 1, cp1, p, cp2);
+
+        //重新加载锚点
+        _this._clearAnchors(_this.layerId);
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateNewMidAnchors: function (oid) {
+        var _this = this;
+        if (oid == null || oid == undefined) {
+            return;
+        }
+        //左边两个中点,oid2为临时中间点
+        var oid1 = null;
+        var oid2 = null;
+        //右边两个中点,oid3为临时中间点
+        var oid3 = null;
+        var oid4 = null;
+
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            oid1 = num - 2;
+            oid2 = num - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        } else if (oid == num - 2) {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = num - 1;
+            oid4 = 0;
+        } else {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        }
+
+        var c1 = _this.tempPositions[oid1];
+        var c = _this.tempPositions[oid];
+        var c4 = _this.tempPositions[oid4];
+
+        if (oid == 0) {
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid3].position.setValue(c3);
+        } else if (oid == num - 1) {
+            var c2 = _this._computeCenterPotition(c1, c);
+            _this.tempPositions[oid2] = c2;
+            _this.markers[oid2].position.setValue(c2);
+        } else {
+            var c2 = _this._computeCenterPotition(c1, c);
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid2] = c2;
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid2].position.setValue(c2);
+            _this.markers[oid3].position.setValue(c3);
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var bData = {
+            position: cartesian,
+            // billboard: {
+            //     //image: _this.dragIconLight,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        };
+        var point = _this.viewer.entities.add(bData);
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _createMidPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "mid_anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _getMeasureTip: function (pntList) {
+        var _this = this;
+        var dis3d = _this._computeLineDis3d(pntList);
+        dis3d = dis3d.toFixed(1);
+        var tip = "距离:" + dis3d + "米";
+        return tip;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+        _this.tempPositions = [].concat(_this.positions);
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _computeDis2d: function (c1, c2) {
+        var dis = Cesium.Cartesian2.distance(c1, c2) / 1000;
+        return dis;
+    },
+    _computeDis3d: function (p1, p2) {
+        var dis = Cesium.Cartesian3.distance(p1, p2);
+        return dis;
+    },
+    _computeLineDis2d: function (pntList) {
+        var _this = this;
+        var total = 0;
+        for (var i = 1; i < pntList.length; i++) {
+            var p1 = pntList[i - 1];
+            var p2 = pntList[i];
+            var dis = _this._computeDis2d(p1, p2);
+            total += dis;
+        }
+        return total;
+    },
+    _computeLineDis3d: function (pntList) {
+        var _this = this;
+        var total = 0;
+        for (var i = 1; i < pntList.length; i++) {
+            var p1 = pntList[i - 1];
+            var p2 = pntList[i];
+            var dis = _this._computeDis3d(p1, p2);
+            total += dis;
+        }
+        return total;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            if (_this.callback) {
+                var positions = [];
+                for (var i = 0; i < _this.tempPositions.length; i += 2) {
+                    var p = _this.tempPositions[i];
+                    positions.push(p);
+                }
+                _this.positions = positions;
+
+                _this.clear();
+                layer.close(_this.toolBarIndex);
+
+                var dis2d = _this._computeLineDis2d(positions);
+                var dis3d = _this._computeLineDis3d(positions);
+                dis2d = dis2d.toFixed(3);
+                dis3d = dis3d.toFixed(3);
+
+                var rlt = {
+                    dis2d: dis2d,
+                    dis3d: dis3d
+                }
+                _this.callback(positions, rlt);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+        });
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "GlobePolylineSpaceMeasure"
+};

+ 622 - 0
src/utils/map/drawPlugin/GlobePolylineStickMeasure.js

@@ -0,0 +1,622 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobePolylineStickMeasure = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobePolylineStickMeasure.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    callback: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPolyline: function (positions, callback) {
+        var _this = this;
+        _this.positions = positions;
+        _this.callback = callback;
+        _this._showModifyPolyline2Map();
+    },
+    startDrawPolyline: function (callback) {
+        var _this = this;
+        _this.callback = callback;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showPolyline2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+
+            _this.entity.position = cartesian;
+            // var text = _this._getMeasureTip(_this.positions);
+            // _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            var num = _this.positions.length;
+            var tip = "<p style='margin: 0'>点击添加下一个点</p>";
+            if (num > 2) {
+                tip += "<p style='margin: 0'>右键结束绘制</p>";
+            }
+            _this.tooltip.showAt(position, tip);
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+
+            _this.entity.position.setValue(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 3) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+
+            //进入编辑状态
+            _this.clear();
+            _this._showModifyPolyline2Map();
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.tempPositions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+                if (pickedAnchor.flag == "mid_anchor") {
+                    _this._updateModifyAnchors(oid);
+                }
+
+                _this.entity.position.setValue(cartesian);
+                var text = _this._getMeasureTip(_this.tempPositions);
+                _this.entity.label.text = text;
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId) {
+                    return;
+                }
+                if (entity.flag != "anchor" && entity.flag != "mid_anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                if (entity.flag == "anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+                }
+                if (entity.flag == "mid_anchor") {
+                    _this.tooltip.showAt(position, "<p style='margin: 0'>移动创建新的控制点</p>");
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var oid = pickedAnchor.oid;
+            if (pickedAnchor.flag == "anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+                //左右两个中点
+                _this._updateNewMidAnchors(oid);
+            } else if (pickedAnchor.flag == "mid_anchor") {
+                pickedAnchor.position.setValue(cartesian);
+                _this.tempPositions[oid] = cartesian;
+            }
+
+            _this.entity.position.setValue(cartesian);
+            // var text = _this._getMeasureTip(_this.tempPositions);
+            // _this.entity.label.text = text;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showPolyline2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = new Cesium.PolylineGlowMaterialProperty({
+                glowPower: 0.25,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.9)
+            });
+        }
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.positions;
+        }, false);
+        var num = _this.positions.length;
+        var last = _this.positions[num - 1];
+        var bData = {
+            position: last,
+            label: {
+                text: "",
+                font: '16px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.YELLOW,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: 8,
+                material: _this.material
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyPolyline2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            return _this.tempPositions;
+        }, false);
+        if (_this.material == null) {
+            _this.material = new Cesium.PolylineGlowMaterialProperty({
+                glowPower: 0.25,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.9)
+            });
+        }
+        var num = _this.tempPositions.length;
+        var last = _this.tempPositions[num - 1];
+        var text = _this._getMeasureTip(_this.tempPositions);
+        var bData = {
+            position: last,
+            label: {
+                text: text,
+                font: '16px "微软雅黑", Arial, Helvetica, sans-serif, Helvetica',
+                fillColor: Cesium.Color.YELLOW,
+                outlineColor: Cesium.Color.SKYBLUE,
+                outlineWidth: 1,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                disableDepthTestDistance: Number.POSITIVE_INFINITY
+            },
+            polyline: {
+                positions: dynamicPositions,
+                clampToGround: true,
+                width: 8,
+                material: _this.material
+            }
+        };
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+        _this.callback && _this.callback(positions, text);
+    },
+    _updateModifyAnchors: function (oid) {
+        var _this = this;
+        var num = _this.tempPositions.length;
+        if (oid == 0 || oid == num - 1) {
+            return;
+        }
+        //重新计算tempPositions
+        var p = _this.tempPositions[oid];
+        var p1 = _this.tempPositions[oid - 1];
+        var p2 = _this.tempPositions[oid + 1];
+
+        //计算中心
+        var cp1 = _this._computeCenterPotition(p1, p);
+        var cp2 = _this._computeCenterPotition(p, p2);
+
+        //插入点
+        var arr = [cp1, p, cp2];
+        _this.tempPositions.splice(oid, 1, cp1, p, cp2);
+
+        //重新加载锚点
+        _this._clearAnchors(_this.layerId);
+        var positions = _this.tempPositions;
+        for (var i = 0; i < positions.length; i++) {
+            var ys = i % 2;
+            if (ys == 0) {
+                _this._createPoint(positions[i], i);
+            } else {
+                _this._createMidPoint(positions[i], i);
+            }
+        }
+    },
+    _updateNewMidAnchors: function (oid) {
+        var _this = this;
+        if (oid == null || oid == undefined) {
+            return;
+        }
+        //左边两个中点,oid2为临时中间点
+        var oid1 = null;
+        var oid2 = null;
+        //右边两个中点,oid3为临时中间点
+        var oid3 = null;
+        var oid4 = null;
+
+        var num = _this.tempPositions.length;
+        if (oid == 0) {
+            oid1 = num - 2;
+            oid2 = num - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        } else if (oid == num - 2) {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = num - 1;
+            oid4 = 0;
+        } else {
+            oid1 = oid - 2;
+            oid2 = oid - 1;
+            oid3 = oid + 1;
+            oid4 = oid + 2;
+        }
+
+        var c1 = _this.tempPositions[oid1];
+        var c = _this.tempPositions[oid];
+        var c4 = _this.tempPositions[oid4];
+
+        if (oid == 0) {
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid3].position.setValue(c3);
+        } else if (oid == num - 1) {
+            var c2 = _this._computeCenterPotition(c1, c);
+            _this.tempPositions[oid2] = c2;
+            _this.markers[oid2].position.setValue(c2);
+        } else {
+            var c2 = _this._computeCenterPotition(c1, c);
+            var c3 = _this._computeCenterPotition(c4, c);
+            _this.tempPositions[oid2] = c2;
+            _this.tempPositions[oid3] = c3;
+            _this.markers[oid2].position.setValue(c2);
+            _this.markers[oid3].position.setValue(c3);
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var bData = {
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIconLight,
+            //     eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        };
+        var point = _this.viewer.entities.add(bData);
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _createMidPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            // billboard: {
+            //     image: _this.dragIcon,
+            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            // }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "mid_anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _getMeasureTip: function (pntList) {
+        var _this = this;
+        var dis3d = _this._computeLineDis3d(pntList);
+        dis3d = dis3d.toFixed(1);
+        var tip = "贴地距离:" + dis3d + "米";
+        return tip;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+        var last = pnts[num - 1];
+        _this.tempPositions.push(last);
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _computeDis2d: function (c1, c2) {
+        var dis = Cesium.Cartesian2.distance(c1, c2) / 1000;
+        return dis;
+    },
+    _computeDis3d: function (p1, p2) {
+        var dis = Cesium.Cartesian3.distance(p1, p2);
+        return dis;
+    },
+    _computeLineDis2d: function (pntList) {
+        var _this = this;
+        var total = 0;
+        for (var i = 1; i < pntList.length; i++) {
+            var p1 = pntList[i - 1];
+            var p2 = pntList[i];
+            var dis = _this._computeDis2d(p1, p2);
+            total += dis;
+        }
+        return total;
+    },
+    _computeLineDis3d: function (pntList) {
+        var _this = this;
+        var total = 0;
+        var positions = _this._getStick2GroundLine(pntList);
+        for (var i = 1; i < positions.length; i++) {
+            var p1 = positions[i - 1];
+            var p2 = positions[i];
+            var dis = _this._computeDis3d(p1, p2);
+            total += dis;
+        }
+        return total;
+    },
+    //获取贴地线
+    _getStick2GroundLine: function (positions) {
+        var _this = this;
+
+        var flatPositions = Cesium.PolylinePipeline.generateArc({
+            positions: positions,
+            granularity: 0.000001
+        });
+        var cartesianArray = [];
+        for (var i = 0; i < flatPositions.length; i += 3) {
+            var cartesian = Cesium.Cartesian3.unpack(flatPositions, i);
+            cartesianArray.push(cartesian);
+        }
+
+        var raisedPositions = [];
+        for (var i = 0; i < cartesianArray.length; i += 3) {
+            var cartesian3 = _this._getStick2GroundPoint3d(cartesianArray[i]);
+            raisedPositions.push(cartesian3);
+        }
+        return raisedPositions;
+    },
+    //获取高程值
+    _getStick2GroundPoint3d: function (cartesian) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var ellipsoid = viewer.scene.globe.ellipsoid;
+
+        var cartographic = ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = viewer.scene.globe.getHeight(cartographic);
+        var cartesian3 = ellipsoid.cartographicToCartesian(cartographic);
+        return cartesian3;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            if (_this.callback) {
+                var positions = [];
+                for (var i = 0; i < _this.tempPositions.length; i += 2) {
+                    var p = _this.tempPositions[i];
+                    positions.push(p);
+                }
+                _this.positions = positions;
+
+                _this.clear();
+                layer.close(_this.toolBarIndex);
+
+                var dis2d = _this._computeLineDis2d(positions);
+                var dis3d = _this._computeLineDis3d(positions);
+                dis2d = dis2d.toFixed(3);
+                dis3d = dis3d.toFixed(3);
+
+                var rlt = {
+                    dis2d: dis2d,
+                    dis3d: dis3d
+                }
+                _this.callback(positions, rlt);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+        });
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "GlobePolylineStickMeasure"
+};

+ 404 - 0
src/utils/map/drawPlugin/GlobeRectangleDrawer.js

@@ -0,0 +1,404 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var GlobeRectangleDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobeRectangleDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 2,
+    extrudedHeight: 0,
+    toolBarIndex: null,
+    layerId: "globeEntityDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyRectangle: function (positions, okHandler, cancelHandler) {
+        var _this = this;
+        _this.positions = positions;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this._showModifyRegion2Map();
+        _this._startModify();
+    },
+    startDrawRectangle: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+            if (num > 1) {
+                _this.positions.pop();
+                _this.viewer.entities.remove(floatingPoint);
+                _this.tooltip.setVisible(false);
+                _this.okHandler && _this.okHandler(_this.positions);
+                _this._startModify();
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>选择终点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.positions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            pickedAnchor.position.setValue(cartesian);
+            var oid = pickedAnchor.oid;
+            _this.positions[oid] = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            billboard: {
+                image: _this.dragIconLight,
+                eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        return point;
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var rect = Cesium.Rectangle.fromCartesianArray(_this.positions);
+                return rect;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var rect = Cesium.Rectangle.fromCartesianArray(_this.positions);
+                var arr = [rect.west, rect.north, rect.east, rect.north, rect.east, rect.south, rect.west, rect.south, rect.west, rect.north];
+                var positions = Cesium.Cartesian3.fromRadiansArray(arr);
+                return positions;
+            } else {
+                return null;
+            }
+        }, false);
+        var bData = {
+            rectangle: {
+                coordinates: dynamicPositions,
+                material: _this.material,
+                show: _this.fill
+            },
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.rectangle.extrudedHeight = _this.extrudedHeight;
+            bData.rectangle.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.rectangle.closeTop = true;
+            bData.rectangle.closeBottom = true;
+            bData.rectangle.outline = false;
+            bData.rectangle.outlineWidth = 0;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#00f').withAlpha(0.7)
+            });
+        }
+        var dynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var rect = Cesium.Rectangle.fromCartesianArray(_this.positions);
+                return rect;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var rect = Cesium.Rectangle.fromCartesianArray(_this.positions);
+                var arr = [rect.west, rect.north, rect.east, rect.north, rect.east, rect.south, rect.west, rect.south, rect.west, rect.north];
+                var positions = Cesium.Cartesian3.fromRadiansArray(arr);
+                return positions;
+            } else {
+                return null;
+            }
+        }, false);
+        var bData = {
+            rectangle: {
+                coordinates: dynamicPositions,
+                material: _this.material,
+                show: _this.fill
+            },
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.rectangle.extrudedHeight = _this.extrudedHeight;
+            bData.rectangle.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.rectangle.closeTop = true;
+            bData.rectangle.closeBottom = true;
+            bData.rectangle.outline = false;
+            bData.rectangle.outlineWidth = 0;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.positions;
+        for (var i = 0; i < positions.length; i++) {
+            _this._createPoint(positions[i], i);
+        }
+    },
+    _computeRectangle: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var rect = Cesium.Rectangle.fromCartesianArray([p1, p2]);
+        return rect;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                _this.okHandler(_this.positions);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    CLASS_NAME: "GlobeRectangleDrawer"
+};

+ 57 - 0
src/utils/map/drawPlugin/GlobeTooltip.js

@@ -0,0 +1,57 @@
+/*
+ * @Descripttion: 
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-03 14:36:10
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-05 17:24:02
+ */
+import '@/styles/drawHelper.css'
+export var GlobeTooltip = function (frameDiv) {
+    this.init.apply(this, arguments);
+}
+
+GlobeTooltip.prototype = {
+    _frameDiv: null,
+    _div: null,
+    _title: null,
+    init: function (frameDiv) {
+        var _this = this;
+
+        var div = document.createElement('DIV');
+        div.className = "twipsy right";
+
+        var arrow = document.createElement('DIV');
+        arrow.className = "twipsy-arrow";
+        div.appendChild(arrow);
+
+        var title = document.createElement('DIV');
+        title.className = "twipsy-inner";
+        div.appendChild(title);
+
+        frameDiv.appendChild(div);
+
+        _this._div = div;
+        _this._title = title;
+        _this._frameDiv = frameDiv;
+    },
+    setVisible: function (visible) {
+        this._div.style.display = visible ? 'block' : 'none';
+    },
+    showAt: function (position, message, diff_left, diff_top) {
+        if (position && message) {
+            this.setVisible(true);
+            this._title.innerHTML = message;
+            if (!diff_left) {
+                this._div.style.left = position.x + 10 + "px";
+            } else {
+                this._div.style.left = position.x + diff_left + "px";
+            }
+            if (!diff_top) {
+                this._div.style.top = (position.y - this._div.clientHeight / 2) + "px";
+            } else {
+                this._div.style.top = position.y + diff_top + "px";
+            }
+        }
+    }
+};

+ 211 - 0
src/utils/map/drawPlugin/GlobeTracker.js

@@ -0,0 +1,211 @@
+import { GlobeBufferLineDrawer } from "@/utils/map/drawPlugin/GlobeBufferLineDrawer";
+import { GlobeCircleDrawer } from "@/utils/map/drawPlugin/GlobeCircleDrawer";
+import { GlobePointDrawer } from "@/utils/map/drawPlugin/GlobePointDrawer";
+import { GlobePointMeasure } from "@/utils/map/drawPlugin/GlobePointMeasure";
+import { GlobePolygonDrawer } from "@/utils/map/drawPlugin/GlobePolygonDrawer";
+import { GlobePolygonMeasure } from "@/utils/map/drawPlugin/GlobePolygonMeasure";
+import { GlobePolylineDrawer } from "@/utils/map/drawPlugin/GlobePolylineDrawer";
+import { GlobePolylineSpaceMeasure } from "@/utils/map/drawPlugin/GlobePolylineSpaceMeasure";
+import { GlobePolylineStickMeasure } from "@/utils/map/drawPlugin/GlobePolylineStickMeasure";
+import { GlobeRectangleDrawer } from "@/utils/map/drawPlugin/GlobeRectangleDrawer";
+import { PlotAttackArrowDrawer } from "@/utils/map/drawPlugin/PlotAttackArrowDrawer";
+import { PlotPincerArrowDrawer } from "@/utils/map/drawPlugin/PlotPincerArrowDrawer";
+import { PlotStraightArrowDrawer } from "@/utils/map/drawPlugin/PlotStraightArrowDrawer";
+
+
+export var GlobeTracker = function () {
+    this.init.apply(this, arguments);
+};
+
+GlobeTracker.prototype = {
+    viewer: null,
+    ctrArr: [],
+    pointDrawer: null,
+    polylineDrawer: null,
+    polygonDrawer: null,
+    circleDrawer: null,
+    rectDrawer: null,
+    bufferLineDrawer: null,
+    straightArrowDrawer: null,
+    attackArrowDrawer: null,
+    pincerArrowDrawer: null,
+    posMeasure: null,
+    spaceDisMeasure: null,
+    stickDisMeasure: null,
+    areaMeasure: null,
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+
+        _this.pointDrawer = new GlobePointDrawer(_this.viewer);
+        _this.ctrArr.push(_this.pointDrawer);
+
+        _this.polylineDrawer = new GlobePolylineDrawer(_this.viewer);
+        _this.ctrArr.push(_this.polylineDrawer);
+
+        _this.polygonDrawer = new GlobePolygonDrawer(_this.viewer);
+        _this.ctrArr.push(_this.polygonDrawer);
+
+        _this.circleDrawer = new GlobeCircleDrawer(_this.viewer);
+        _this.ctrArr.push(_this.circleDrawer);
+
+        _this.rectDrawer = new GlobeRectangleDrawer(_this.viewer);
+        _this.ctrArr.push(_this.rectDrawer);
+
+        _this.bufferLineDrawer = new GlobeBufferLineDrawer(_this.viewer);
+        _this.ctrArr.push(_this.bufferLineDrawer);
+
+        _this.straightArrowDrawer = new PlotStraightArrowDrawer(_this.viewer);
+        _this.ctrArr.push(_this.straightArrowDrawer);
+
+        _this.attackArrowDrawer = new PlotAttackArrowDrawer(_this.viewer);
+        _this.ctrArr.push(_this.attackArrowDrawer);
+
+        _this.pincerArrowDrawer = new PlotPincerArrowDrawer(_this.viewer);
+        _this.ctrArr.push(_this.pincerArrowDrawer);
+
+        _this.posMeasure = new GlobePointMeasure(_this.viewer);
+        _this.ctrArr.push(_this.posMeasure);
+
+        _this.spaceDisMeasure = new GlobePolylineSpaceMeasure(_this.viewer);
+        _this.ctrArr.push(_this.spaceDisMeasure);
+
+        _this.stickDisMeasure = new GlobePolylineStickMeasure(_this.viewer);
+        _this.ctrArr.push(_this.stickDisMeasure);
+
+        _this.areaMeasure = new GlobePolygonMeasure(_this.viewer);
+        _this.ctrArr.push(_this.areaMeasure);
+    },
+    clear: function () {
+        var _this = this;
+        for (var i = 0; i < _this.ctrArr.length; i++) {
+            try {
+                var ctr = _this.ctrArr[i];
+                if (ctr.clear) {
+                    ctr.clear();
+                }
+            } catch (err) {
+                console.log("发生未知出错:GlobeTracker.clear");
+            }
+        }
+    },
+    trackPoint: function (okHandler, cancelHandler, notClear) {
+        var _this = this;
+        //notClear ? null : _this.clear();
+        _this.clear();
+        if (_this.pointDrawer == null) {
+            _this.pointDrawer = new GlobePointDrawer(_this.viewer);
+            _this.ctrArr.push(_this.pointDrawer);
+        }
+        _this.pointDrawer.startDrawPoint(okHandler, cancelHandler);
+    },
+    trackPolyline: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.polylineDrawer == null) {
+            _this.polylineDrawer = new GlobePolylineDrawer(_this.viewer);
+            _this.ctrArr.push(_this.polylineDrawer);
+        }
+        _this.polylineDrawer.startDrawPolyline(okHandler, cancelHandler);
+    },
+    trackPolygon: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.polygonDrawer == null) {
+            _this.polygonDrawer = new GlobePolygonDrawer(_this.viewer);
+            _this.ctrArr.push(_this.polygonDrawer);
+        }
+        _this.polygonDrawer.startDrawPolygon(okHandler, cancelHandler);
+    },
+    trackCircle: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.circleDrawer == null) {
+            _this.circleDrawer = new GlobeCircleDrawer(_this.viewer);
+            _this.ctrArr.push(_this.circleDrawer);
+        }
+        _this.circleDrawer.startDrawCircle(okHandler, cancelHandler);
+    },
+    trackRectangle: function (okHandler, cancelHandler) {
+        var _this = this;
+        if (_this.rectDrawer == null) {
+            _this.rectDrawer = new GlobeRectangleDrawer(_this.viewer);
+            _this.ctrArr.push(_this.rectDrawer);
+        }
+        _this.clear();
+        _this.rectDrawer.startDrawRectangle(okHandler, cancelHandler);
+    },
+    trackBufferLine: function (okHandler, cancelHandler) {
+        var _this = this;
+        if (_this.bufferLineDrawer == null) {
+            _this.bufferLineDrawer = new GlobeBufferLineDrawer(_this.viewer);
+            _this.ctrArr.push(_this.bufferLineDrawer);
+        }
+        _this.clear();
+        _this.bufferLineDrawer.startDrawBufferLine(okHandler, cancelHandler);
+    },
+    trackStraightArrow: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.straightArrowDrawer == null) {
+            _this.straightArrowDrawer = new PlotStraightArrowDrawer(_this.viewer);
+            _this.ctrArr.push(_this.straightArrowDrawer);
+        }
+        _this.straightArrowDrawer.startDrawStraightArrow(okHandler, cancelHandler);
+    },
+    trackAttackArrow: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.attackArrowDrawer == null) {
+            _this.attackArrowDrawer = new PlotAttackArrowDrawer(_this.viewer);
+            _this.ctrArr.push(_this.attackArrowDrawer);
+        }
+        _this.attackArrowDrawer.startDrawAttackArrow(okHandler, cancelHandler);
+    },
+    trackPincerArrow: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.pincerArrowDrawer == null) {
+            _this.pincerArrowDrawer = new PlotPincerArrowDrawer(_this.viewer);
+            _this.ctrArr.push(_this.pincerArrowDrawer);
+        }
+        _this.pincerArrowDrawer.startDrawPincerArrow(okHandler, cancelHandler);
+    },
+    pickPosition: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.posMeasure == null) {
+            _this.posMeasure = new GlobePointMeasure(_this.viewer);
+            _this.ctrArr.push(_this.posMeasure);
+        }
+        _this.posMeasure.startDrawPoint(okHandler, cancelHandler);
+    },
+    pickSpaceDistance: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.spaceDisMeasure == null) {
+            _this.spaceDisMeasure = new GlobePolylineSpaceMeasure(_this.viewer);
+            _this.ctrArr.push(_this.spaceDisMeasure);
+        }
+        _this.spaceDisMeasure.startDrawPolyline(okHandler, cancelHandler);
+    },
+    pickStickDistance: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.stickDisMeasure == null) {
+            _this.stickDisMeasure = new GlobePolylineStickMeasure(_this.viewer);
+            _this.ctrArr.push(_this.stickDisMeasure);
+        }
+        _this.stickDisMeasure.startDrawPolyline(okHandler, cancelHandler);
+    },
+    pickArea: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.clear();
+        if (_this.areaMeasure == null) {
+            _this.areaMeasure = new GlobePolygonMeasure(_this.viewer);
+            _this.ctrArr.push(_this.areaMeasure);
+        }
+        _this.areaMeasure.startDrawPolygon(okHandler, cancelHandler);
+    },
+    CLASS_NAME: "GlobeTracker"
+};

+ 505 - 0
src/utils/map/drawPlugin/PlotAttackArrowDrawer.js

@@ -0,0 +1,505 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var PlotAttackArrowDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+PlotAttackArrowDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 2,
+    extrudedHeight: 0,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyAttackArrow: function (custom, okHandler, cancelHandler) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < custom.length; i++) {
+            var p = custom[i];
+            var c = Cesium.Cartesian3.fromDegrees(p[0], p[1]);
+            arr.push(c);
+        }
+        _this.positions = arr;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyRegion2Map();
+    },
+    startDrawAttackArrow: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>新增控制点</p><p>右键结束绘制</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 2) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+            _this._startModify();
+        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+        _this.drawHandler.setInputAction(function (movement) {
+            if (_this.positions.length < 2) {
+                return;
+            }
+            _this.positions.pop();
+            _this.viewer.entities.remove(floatingPoint);
+            _this.tooltip.setVisible(false);
+            _this._startModify();
+        }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.positions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            pickedAnchor.position.setValue(cartesian);
+            var oid = pickedAnchor.oid;
+            _this.positions[oid] = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var lonLats = _this._getLonLatArr(_this.positions);
+                var doubleArrow = xp.algorithm.tailedAttackArrow(lonLats);
+                var positions = doubleArrow.polygonalPoint;
+                if (positions == null || positions.length < 3) {
+                    return null;
+                }
+                var pHierarchy = new Cesium.PolygonHierarchy(positions);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length < 2) {
+                return null;
+            }
+            var lonLats = _this._getLonLatArr(_this.positions);
+            var doubleArrow = xp.algorithm.tailedAttackArrow(lonLats);
+            var positions = doubleArrow.polygonalPoint;
+            if (positions == null || positions.length < 3) {
+                return null;
+            }
+            var firstPoint = positions[0];
+            positions.push(firstPoint);
+            return positions;
+        }, false);
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var lonLats = _this._getLonLatArr(_this.positions);
+                var doubleArrow = xp.algorithm.tailedAttackArrow(lonLats);
+                var positions = doubleArrow.polygonalPoint;
+                if (positions == null || positions.length < 3) {
+                    return null;
+                }
+                var pHierarchy = new Cesium.PolygonHierarchy(positions);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length < 2) {
+                return null;
+            }
+            var lonLats = _this._getLonLatArr(_this.positions);
+            var doubleArrow = xp.algorithm.tailedAttackArrow(lonLats);
+            var positions = doubleArrow.polygonalPoint;
+            if (positions == null || positions.length < 2) {
+                return null;
+            }
+            var firstPoint = positions[0];
+            positions.push(firstPoint);
+            return positions;
+        }, false);
+
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.positions;
+        for (var i = 0; i < positions.length; i++) {
+            _this._createPoint(positions[i], i);
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            billboard: {
+                image: _this.dragIconLight,
+                eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        var first = pnts[0];
+        var last = pnts[num - 1];
+        if (_this._isSimpleXYZ(first, last) == false) {
+            pnts.push(first);
+            num += 1;
+        }
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                var lonLats = _this._getLonLatArr(_this.positions);
+                var doubleArrow = xp.algorithm.tailedAttackArrow(lonLats);
+                var positions = doubleArrow.polygonalPoint;
+                var custom = doubleArrow.controlPoint;
+
+                _this.okHandler(positions, custom);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _getLonLatArr: function (positions) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < positions.length; i++) {
+            var p = _this._getLonLat(positions[i]);
+            if (p != null) {
+                arr.push([p.lon, p.lat]);
+            }
+        }
+        return arr;
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "PlotAttackArrowDrawer"
+};

+ 537 - 0
src/utils/map/drawPlugin/PlotPincerArrowDrawer.js

@@ -0,0 +1,537 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var PlotPincerArrowDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+PlotPincerArrowDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 2,
+    extrudedHeight: 0,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyPincerArrow: function (custom, okHandler, cancelHandler) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < custom.length; i++) {
+            var p = custom[i];
+            var c = Cesium.Cartesian3.fromDegrees(p[0], p[1]);
+            arr.push(c);
+        }
+        _this.positions = arr;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyRegion2Map();
+    },
+    startDrawPincerArrow: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+
+            if (_this.positions.length > 5) {
+                _this.positions.pop();
+                _this.viewer.entities.remove(floatingPoint);
+                _this.tooltip.setVisible(false);
+                _this._startModify();
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>新增控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.positions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            pickedAnchor.position.setValue(cartesian);
+            var oid = pickedAnchor.oid;
+            _this.positions[oid] = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 2) {
+                try {
+                    var lonLats = _this._getLonLatArr(_this.positions);
+                    //去重
+                    _this._removeDuplicate(lonLats);
+                    var doubleArrow = xp.algorithm.doubleArrow(lonLats);
+                    var positions = doubleArrow.polygonalPoint;
+                    if (!Cesium.defined(positions)) {
+                        return null;
+                    }
+                    if (positions == null || positions.length < 3) {
+                        return null;
+                    }
+                    var pHierarchy = new Cesium.PolygonHierarchy(positions);
+                    return pHierarchy;
+                } catch (err) {
+                    return null;
+                }
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length < 3) {
+                return null;
+            }
+            try {
+                var lonLats = _this._getLonLatArr(_this.positions);
+                //去重
+                _this._removeDuplicate(lonLats);
+                var doubleArrow = xp.algorithm.doubleArrow(lonLats);
+                var positions = doubleArrow.polygonalPoint;
+                if (!Cesium.defined(positions)) {
+                    return null;
+                }
+                if (positions == null || positions.length < 3) {
+                    return null;
+                }
+                var firstPoint = positions[0];
+                positions.push(firstPoint);
+                return positions;
+            } catch (err) {
+                return null;
+            }
+        }, false);
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 2) {
+                try {
+                    var lonLats = _this._getLonLatArr(_this.positions);
+                    //去重
+                    _this._removeDuplicate(lonLats);
+                    var doubleArrow = xp.algorithm.doubleArrow(lonLats);
+                    var positions = doubleArrow.polygonalPoint;
+                    if (!Cesium.defined(positions)) {
+                        return null;
+                    }
+                    if (positions == null || positions.length < 3) {
+                        return null;
+                    }
+                    var pHierarchy = new Cesium.PolygonHierarchy(positions);
+                    return pHierarchy;
+                } catch (err) {
+                    return null;
+                }
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length < 3) {
+                return null;
+            }
+            try {
+                var lonLats = _this._getLonLatArr(_this.positions);
+                //去重
+                _this._removeDuplicate(lonLats);
+                var doubleArrow = xp.algorithm.doubleArrow(lonLats);
+                var positions = doubleArrow.polygonalPoint;
+                if (positions == null || positions.length < 2) {
+                    return null;
+                }
+                var firstPoint = positions[0];
+                positions.push(firstPoint);
+                return positions;
+            } catch (err) {
+                return null;
+            }
+        }, false);
+
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.positions;
+        for (var i = 0; i < positions.length; i++) {
+            _this._createPoint(positions[i], i);
+        }
+    },
+    _removeDuplicate: function (lonLats) {
+        if (!lonLats || lonLats.length < 2) {
+            return;
+        }
+        for (var i = 1; i < lonLats.length; i++) {
+            var p1 = lonLats[i - 1];
+            var p2 = lonLats[i];
+            if (p2[0] == p1[0] && p2[1] == p1[1]) {
+                lonLats.splice(i, 1);
+                i--;
+            }
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            billboard: {
+                image: _this.dragIconLight,
+                eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        var first = pnts[0];
+        var last = pnts[num - 1];
+        if (_this._isSimpleXYZ(first, last) == false) {
+            pnts.push(first);
+            num += 1;
+        }
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                var lonLats = _this._getLonLatArr(_this.positions);
+                var doubleArrow = xp.algorithm.doubleArrow(lonLats);
+                var positions = doubleArrow.polygonalPoint;
+                var custom = doubleArrow.controlPoint;
+                _this.okHandler(positions, custom);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _getLonLatArr: function (positions) {
+        var _this = this;
+        var arr = [];
+        for (var i = 0; i < positions.length; i++) {
+            var p = _this._getLonLat(positions[i]);
+            if (p != null) {
+                arr.push([p.lon, p.lat]);
+            }
+        }
+        return arr;
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "PlotPincerArrowDrawer"
+};

+ 484 - 0
src/utils/map/drawPlugin/PlotStraightArrowDrawer.js

@@ -0,0 +1,484 @@
+import { getPickPositionGlobe, setTooltip } from "@/utils/map/mapUtils";
+import * as Cesium from "cesium";
+export var PlotStraightArrowDrawer = function () {
+    this.init.apply(this, arguments);
+};
+
+PlotStraightArrowDrawer.prototype = {
+    viewer: null,
+    scene: null,
+    clock: null,
+    canvas: null,
+    camera: null,
+    ellipsoid: null,
+    tooltip: null,
+    entity: null,
+    positions: [],
+    tempPositions: [],
+    drawHandler: null,
+    modifyHandler: null,
+    okHandler: null,
+    cancelHandler: null,
+    dragIcon: "/src/assets/images/map/circle_gray.png",
+    dragIconLight: "/src/assets/images/map/circle_red.png",
+    material: null,
+    outlineMaterial: null,
+    fill: true,
+    outline: true,
+    outlineWidth: 2,
+    extrudedHeight: 0,
+    toolBarIndex: null,
+    markers: {},
+    layerId: "globeDrawerLayer",
+    init: function (viewer) {
+        var _this = this;
+        _this.viewer = viewer;
+        _this.scene = viewer.scene;
+        _this.clock = viewer.clock;
+        _this.canvas = viewer.scene.canvas;
+        _this.camera = viewer.scene.camera;
+        _this.ellipsoid = viewer.scene.globe.ellipsoid;
+        _this.tooltip = setTooltip(viewer)
+    },
+    clear: function () {
+        var _this = this;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        if (_this.modifyHandler) {
+            _this.modifyHandler.destroy();
+            _this.modifyHandler = null;
+        }
+        if (_this.toolBarIndex != null) {
+            layer.close(_this.toolBarIndex);
+        }
+        _this._clearMarkers(_this.layerId);
+        _this.tooltip.setVisible(false);
+    },
+    showModifyStraightArrow: function (positions, okHandler, cancelHandler) {
+        var _this = this;
+        var arr = [];
+        arr.push(positions[7]);
+        arr.push(positions[3]);
+        _this.positions = arr;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+        _this._showModifyRegion2Map();
+    },
+    startDrawStraightArrow: function (okHandler, cancelHandler) {
+        var _this = this;
+        _this.okHandler = okHandler;
+        _this.cancelHandler = cancelHandler;
+
+        _this.positions = [];
+        var floatingPoint = null;
+        _this.drawHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            var num = _this.positions.length;
+            if (num == 0) {
+                _this.positions.push(cartesian);
+                floatingPoint = _this._createPoint(cartesian, -1);
+                _this._showRegion2Map();
+            }
+            _this.positions.push(cartesian);
+            var oid = _this.positions.length - 2;
+            _this._createPoint(cartesian, oid);
+            if (num > 1) {
+                _this.positions.pop();
+                _this.viewer.entities.remove(floatingPoint);
+                _this.tooltip.setVisible(false);
+                _this._startModify();
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.drawHandler.setInputAction(function (event) {
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            if (_this.positions.length < 1) {
+                _this.tooltip.showAt(position, "<p style='margin: 0'>选择起点</p>");
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>选择终点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            floatingPoint.position.setValue(cartesian);
+            _this.positions.pop();
+            _this.positions.push(cartesian);
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _startModify: function () {
+        var _this = this;
+        var isMoving = false;
+        var pickedAnchor = null;
+        if (_this.drawHandler) {
+            _this.drawHandler.destroy();
+            _this.drawHandler = null;
+        }
+        // _this._showToolBar();
+
+        _this.modifyHandler = new Cesium.ScreenSpaceEventHandler(_this.canvas);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            var position = event.position;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            if (isMoving) {
+                isMoving = false;
+                pickedAnchor.position.setValue(cartesian);
+                var oid = pickedAnchor.oid;
+                _this.positions[oid] = cartesian;
+                _this.tooltip.setVisible(false);
+            } else {
+                var pickedObject = _this.scene.pick(position);
+                if (!Cesium.defined(pickedObject)) {
+                    return;
+                }
+                if (!Cesium.defined(pickedObject.id)) {
+                    return;
+                }
+                var entity = pickedObject.id;
+                if (entity.layerId != _this.layerId || entity.flag != "anchor") {
+                    return;
+                }
+                pickedAnchor = entity;
+                isMoving = true;
+                _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+        _this.modifyHandler.setInputAction(function (event) {
+            if (!isMoving) {
+                return;
+            }
+            var position = event.endPosition;
+            if (!Cesium.defined(position)) {
+                return;
+            }
+            _this.tooltip.showAt(position, "<p style='margin: 0'>移动控制点</p>");
+
+            var ray = _this.camera.getPickRay(position);
+            if (!Cesium.defined(ray)) {
+                return;
+            }
+            var cartesian = getPickPositionGlobe(position, _this.viewer);
+            if (!Cesium.defined(cartesian)) {
+                return;
+            }
+            pickedAnchor.position.setValue(cartesian);
+            var oid = pickedAnchor.oid;
+            _this.positions[oid] = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    _showRegion2Map: function () {
+        var _this = this;
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var p1 = _this.positions[0];
+                var p2 = _this.positions[1];
+                if (_this._isSimpleXYZ(p1, p2)) {
+                    return null;
+                }
+                var firstPoint = _this._getLonLat(p1);
+                var endPoints = _this._getLonLat(p2);
+                var arrow = xp.algorithm.fineArrow([firstPoint.lon, firstPoint.lat], [endPoints.lon, endPoints.lat]);
+                var pHierarchy = new Cesium.PolygonHierarchy(arrow);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length < 2) {
+                return null;
+            }
+            var p1 = _this.positions[0];
+            var p2 = _this.positions[1];
+            if (_this._isSimpleXYZ(p1, p2)) {
+                return null;
+            }
+            var firstPoint = _this._getLonLat(p1);
+            var endPoints = _this._getLonLat(p2);
+            var arrow = xp.algorithm.fineArrow([firstPoint.lon, firstPoint.lat], [endPoints.lon, endPoints.lat]);
+            arrow.push(arrow[0]);
+            return arrow;
+        }, false);
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+    },
+    _showModifyRegion2Map: function () {
+        var _this = this;
+
+        _this._startModify();
+        _this._computeTempPositions();
+
+        var dynamicHierarchy = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length > 1) {
+                var p1 = _this.positions[0];
+                var p2 = _this.positions[1];
+                if (_this._isSimpleXYZ(p1, p2)) {
+                    return null;
+                }
+                var firstPoint = _this._getLonLat(p1);
+                var endPoints = _this._getLonLat(p2);
+                var arrow = xp.algorithm.fineArrow([firstPoint.lon, firstPoint.lat], [endPoints.lon, endPoints.lat]);
+                var pHierarchy = new Cesium.PolygonHierarchy(arrow);
+                return pHierarchy;
+            } else {
+                return null;
+            }
+        }, false);
+        var outlineDynamicPositions = new Cesium.CallbackProperty(function () {
+            if (_this.positions.length < 2) {
+                return null;
+            }
+            var p1 = _this.positions[0];
+            var p2 = _this.positions[1];
+            if (_this._isSimpleXYZ(p1, p2)) {
+                return null;
+            }
+            var firstPoint = _this._getLonLat(p1);
+            var endPoints = _this._getLonLat(p2);
+            var arrow = xp.algorithm.fineArrow([firstPoint.lon, firstPoint.lat], [endPoints.lon, endPoints.lat]);
+            arrow.push(arrow[0]);
+            return arrow;
+        }, false);
+
+        if (_this.material == null) {
+            _this.material = Cesium.Color.fromCssColorString('#ff0').withAlpha(0.5);
+        }
+        if (_this.outlineMaterial == null) {
+            _this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({
+                dashLength: 16,
+                color: Cesium.Color.fromCssColorString('#f00').withAlpha(0.7)
+            });
+        }
+        var bData = {
+            polygon: new Cesium.PolygonGraphics({
+                hierarchy: dynamicHierarchy,
+                material: _this.material,
+                show: _this.fill
+            }),
+            polyline: {
+                positions: outlineDynamicPositions,
+                clampToGround: true,
+                width: _this.outlineWidth,
+                material: _this.outlineMaterial,
+                show: _this.outline
+            }
+        };
+        if (_this.extrudedHeight > 0) {
+            bData.polygon.extrudedHeight = _this.extrudedHeight;
+            bData.polygon.extrudedHeightReference = Cesium.HeightReference.RELATIVE_TO_GROUND;
+            bData.polygon.closeTop = true;
+            bData.polygon.closeBottom = true;
+        }
+        _this.entity = _this.viewer.entities.add(bData);
+        _this.entity.layerId = _this.layerId;
+        var positions = _this.positions;
+        for (var i = 0; i < positions.length; i++) {
+            _this._createPoint(positions[i], i);
+        }
+    },
+    _createPoint: function (cartesian, oid) {
+        var _this = this;
+        var point = _this.viewer.entities.add({
+            position: cartesian,
+            billboard: {
+                image: _this.dragIconLight,
+                eyeOffset: new Cesium.ConstantProperty(new Cesium.Cartesian3(0, 0, -500)),
+                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+            }
+        });
+        point.oid = oid;
+        point.layerId = _this.layerId;
+        point.flag = "anchor";
+        _this.markers[oid] = point;
+        return point;
+    },
+    _computeTempPositions: function () {
+        var _this = this;
+
+        var pnts = [].concat(_this.positions);
+        var num = pnts.length;
+        var first = pnts[0];
+        var last = pnts[num - 1];
+        if (_this._isSimpleXYZ(first, last) == false) {
+            pnts.push(first);
+            num += 1;
+        }
+        _this.tempPositions = [];
+        for (var i = 1; i < num; i++) {
+            var p1 = pnts[i - 1];
+            var p2 = pnts[i];
+            var cp = _this._computeCenterPotition(p1, p2);
+            _this.tempPositions.push(p1);
+            _this.tempPositions.push(cp);
+        }
+    },
+    _computeCenterPotition: function (p1, p2) {
+        var _this = this;
+        var c1 = _this.ellipsoid.cartesianToCartographic(p1);
+        var c2 = _this.ellipsoid.cartesianToCartographic(p2);
+        var cm = new Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
+        var cp = _this.ellipsoid.cartographicToCartesian(cm);
+        return cp;
+    },
+    _showToolBar: function () {
+        var _this = this;
+        // _this._createToolBar();
+        var width = $(window).width();
+        var wTop = 60;
+        var wLeft = parseInt((width - 145) / 2);
+        _this.toolBarIndex = layer.open({
+            title: false,
+            type: 1,
+            fixed: true,
+            resize: false,
+            shade: 0,
+            content: $("#shapeEditContainer"),
+            offset: [wTop + "px", wLeft + "px"],
+            move: "#shapeEditRTCorner"
+        });
+        var cssSel = "#layui-layer" + _this.toolBarIndex + " .layui-layer-close2";
+        $(cssSel).hide();
+    },
+    _createToolBar: function () {
+        var _this = this;
+        var objs = $("#shapeEditContainer");
+        objs.remove();
+        var html = '<div id="shapeEditContainer" style="padding: 10px 10px;">' +
+            '    <button name="btnOK" class="layui-btn layui-btn-xs layui-btn-normal"> <i class="layui-icon"></i> 确定 </button>' +
+            '    <button name="btnCancel" class="layui-btn layui-btn-xs layui-btn-danger"> <i class="layui-icon">ဆ</i> 取消 </button>' +
+            '    <div id="shapeEditRTCorner" style="width: 16px; position: absolute; right: 0px; top: 0px; bottom: 0px">' +
+            '    </div>' +
+            '</div>';
+        $("body").append(html);
+
+        var btnOK = $("#shapeEditContainer button[name='btnOK']");
+        var btnCancel = $("#shapeEditContainer button[name='btnCancel']");
+        btnOK.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.okHandler) {
+                var p1 = _this.positions[0];
+                var p2 = _this.positions[1];
+                var firstPoint = _this._getLonLat(p1);
+                var endPoints = _this._getLonLat(p2);
+                var arrow = xp.algorithm.fineArrow([firstPoint.lon, firstPoint.lat], [endPoints.lon, endPoints.lat]);
+
+                _this.okHandler(arrow);
+            }
+        });
+        btnCancel.unbind("click").bind("click", function () {
+            _this.clear();
+            layer.close(_this.toolBarIndex);
+            if (_this.cancelHandler) {
+                _this.cancelHandler();
+            }
+        });
+    },
+    _getLonLat: function (cartesian) {
+        var _this = this;
+        var cartographic = _this.ellipsoid.cartesianToCartographic(cartesian);
+        cartographic.height = _this.viewer.scene.globe.getHeight(cartographic);
+        var pos = {
+            lon: cartographic.longitude,
+            lat: cartographic.latitude,
+            alt: cartographic.height
+        };
+        pos.lon = Cesium.Math.toDegrees(pos.lon);
+        pos.lat = Cesium.Math.toDegrees(pos.lat);
+        return pos;
+    },
+    _isSimpleXYZ: function (p1, p2) {
+        if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
+            return true;
+        }
+        return false;
+    },
+    _clearMarkers: function (layerName) {
+        var _this = this;
+        var viewer = _this.viewer;
+        var entityList = viewer.entities.values;
+        if (entityList == null || entityList.length < 1)
+            return;
+        for (var i = 0; i < entityList.length; i++) {
+            var entity = entityList[i];
+            if (entity.layerId == layerName) {
+                viewer.entities.remove(entity);
+                i--;
+            }
+        }
+    },
+    _clearAnchors: function () {
+        var _this = this;
+        for (var key in _this.markers) {
+            var m = _this.markers[key];
+            _this.viewer.entities.remove(m);
+        }
+        _this.markers = {};
+    },
+    CLASS_NAME: "PlotStraightArrowDrawer"
+};

+ 89 - 0
src/utils/map/fly/fly.js

@@ -0,0 +1,89 @@
+/*
+ * @Descripttion: 定制飞行
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-08 17:18:39
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-08 17:55:14
+ */
+import * as Cesium from "cesium";
+let OrbitFlightCameraExection = null;
+/**
+ * 绕点飞行公共接口
+ */
+export function OrbitFlightCamera(viewer) {
+    if (OrbitFlightCameraExection) {
+        ClearOrbitFlightCamera(viewer);
+        return;
+    }
+    var ellipsoid = viewer.scene.globe.ellipsoid;
+    var center = viewer.scene.pickPosition(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, (viewer.canvas.clientHeight / 2)));
+    var carto_lt2 = ellipsoid.cartesianToCartographic(center);
+    if (viewer.terrainProvider) {
+        var allPoints = [carto_lt2];
+        try {
+            var promise = Cesium.sampleTerrain(viewer.terrainProvider, 15, allPoints);
+            promise.then(function (updatedPositions) {
+                updatedPositions[0].height = !updatedPositions[0].height ? 5000 : updatedPositions[0].height
+                var cameraHeight = Math.ceil(viewer.camera.positionCartographic.height);
+                var centerHeight = updatedPositions[0].height;
+                var DiffZ = cameraHeight - centerHeight;
+                var ellipsoid = viewer.scene.globe.ellipsoid;
+                var cameraAngle = Math.abs(Cesium.Math.toDegrees(viewer.camera.pitch));
+                var center = viewer.scene.pickPosition(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, (viewer.canvas.clientHeight / 2)));
+                var carto_lt2 = ellipsoid.cartesianToCartographic(center);
+                var position = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(carto_lt2.longitude), Cesium.Math.toDegrees(carto_lt2.latitude), centerHeight);
+                var distance = cameraHeight / Math.sin(cameraAngle * Math.PI / 180);
+                var centerDistance = centerHeight / Math.sin(cameraAngle * Math.PI / 180);
+                distance = distance - centerDistance;
+                // 给定飞行一周所需时间
+                var angle = 360 / 20;
+                var startTime = Cesium.JulianDate.fromDate(new Date());
+                var stopTime = Cesium.JulianDate.fromIso8601("2099-12-26");
+                viewer.clock.startTime = startTime.clone(); // 开始时间
+                viewer.clock.stopTime = stopTime.clone(); // 结速时间
+                viewer.clock.currentTime = startTime.clone(); // 当前时间
+                viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式
+                viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
+                // 相机的当前heading
+                var initialHeading = Cesium.Math.toDegrees(viewer.camera.heading);
+                var initialPitch = viewer.camera.pitch;
+                var initialRoll = viewer.camera.roll;
+                OrbitFlightCameraExection = function CameraTimeExecution() {
+                    // 当前已经过去的时间,单位s
+                    var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
+                    // var heading = Cesium.Math.toRadians(delTime * angle) - initialHeading;
+                    var heading = initialHeading - delTime * angle;
+                    if (heading < 0) {
+                        heading = heading + Math.ceil(Math.abs(heading) / 360) * 360;
+                    }
+                    viewer.scene.camera.setView({
+                        destination: center, // 点的坐标
+                        orientation: {
+                            heading: Cesium.Math.toRadians(heading),
+                            pitch: initialPitch,
+                            roll: initialRoll
+                        }
+                    });
+                    viewer.scene.camera.moveBackward(distance);
+                    if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
+                        viewer.clock.onTick.removeEventListener(OrbitFlightCameraExection);
+                    }
+                };
+                viewer.clock.onTick.addEventListener(OrbitFlightCameraExection);
+            });
+            // Cesium.when(promise, (updatedPositions) => {
+
+            // })
+        } catch (e) {
+
+        }
+    } else {
+    }
+}
+export function ClearOrbitFlightCamera(viewer) {
+    if (OrbitFlightCameraExection) {
+        viewer.clock.onTick.removeEventListener(OrbitFlightCameraExection);
+        OrbitFlightCameraExection = null;
+    }
+}

Fișier diff suprimat deoarece este prea mare
+ 182 - 0
src/utils/map/fun/ViewShed.js


+ 413 - 0
src/utils/map/fun/layerDraw.js

@@ -0,0 +1,413 @@
+/*
+ * @Descripttion: 绘制方法
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-05 15:41:37
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-10 16:38:14
+ */
+import * as Cesium from "cesium";
+import * as turf from '@turf/turf'
+import { GlobeTracker } from "@/utils/map/drawPlugin/GlobeTracker";
+import { getPickPositionGlobe, setTooltip, removeAllEntities } from "@/utils/map/mapUtils";
+import { Cartesian3_to_WGS84Arr } from "/src/utils/tools/CoordTransformate/CoordTransformate"
+
+let tracker = undefined;
+// 初始化绘制
+export function initTracker(viewer) {
+    if (!tracker) {
+        tracker = new GlobeTracker(viewer);
+    }
+    return tracker;
+}
+// 清除绘制
+export function clearTrack(viewer) {
+    if (tracker) {
+        tracker.clear();
+        tracker = undefined;
+    }
+}
+// 测量
+export function layerMeasure(viewer, type) {
+    let drawTracker = initTracker(viewer);
+    removeAllEntities(viewer);
+    switch (type) {
+        case "distance":
+            // 测距
+            drawTracker.pickSpaceDistance(function (positions, rlt) { });
+            break;
+        case "area":
+            // 测面
+            drawTracker.pickArea(function (positions, rlt) { });
+            break;
+        case "stickDistance":
+            // 贴地
+            drawTracker.pickStickDistance(function (positions, rlt) { });
+            break;
+        case "height":
+            // 测高
+            measureHeight(viewer)
+            break;
+        default:
+            break;
+    }
+}
+var drawBackFun = null;
+var drawBackSpecial = null;
+
+export function DrawHelper(viewer, type) {
+    let drawTracker = initTracker(viewer);
+    switch (type) {
+        case "drawPolygon":
+            drawTracker.trackPolygon(function (positions) {
+                drawBackFunHandle(viewer, positions, "polygon");
+            });
+            break;
+        case "drawPolyline":
+            drawTracker.trackPolyline(function (positions) {
+                drawBackFunHandle(viewer, positions, "polyline");
+            });
+            break;
+        case "drawRectangle":
+            drawTracker.trackRectangle(function (positions) {
+                drawBackFunHandle(viewer, positions, "rectangle");
+            });
+            break;
+        case "drawCircle":
+            drawTracker.trackCircle(function (positions) {
+                drawBackFunHandle(viewer, positions, "circle");
+            });
+            break;
+        case "drawPoint":
+            drawTracker.trackPoint(function (position) {
+                drawBackFunHandle(viewer, position, "point");
+            }, null, true);
+            break;
+        case "drawLabelPoint":
+            drawTracker.trackPoint(function (position) {
+                drawBackFunHandle(viewer, position);
+                layer.prompt({
+                    title: '请输入标注内容'
+                }, function (value, index, elem) {
+                    tracker.clear();
+                    layer.close(index);
+                    viewer.entities.add({
+                        id: getUUID(),
+                        name: getUUID(),
+                        position: position,
+                        point: {
+                            color: Cesium.Color.GREEN.withAlpha(1),
+                            pixelSize: 5,
+                            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                            outlineColor: Cesium.Color.YELLOW,
+                            outlineWidth: 2,
+                        },
+                        label: {
+                            text: value,
+                            fillColor: Cesium.Color.fromCssColorString('#ff0000'),
+                            font: '15px',
+                            showBackground: false,
+                            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+                            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+                            pixelOffset: new Cesium.Cartesian2(0, -30)
+                        }
+                    });
+                });
+            }, null, true);
+            break;
+        case "drawBufferLine":
+            drawTracker.trackBufferLine(function (positions, radius) { });
+            break;
+        case "straightArrow":
+            drawTracker.trackStraightArrow(function (positions) {
+                drawBackFunHandle(viewer, positions);
+            });
+            break;
+        case "attackArrow":
+            drawTracker.trackAttackArrow(function (positions, custom) {
+                drawBackFunHandle(viewer, positions);
+            });
+            break;
+        case "pincerArrow":
+            drawTracker.trackPincerArrow(function (positions, custom) {
+                drawBackFunHandle(viewer, positions);
+            });
+            break;
+        default:
+            break;
+    }
+}
+
+//绘制回调
+export function drawBackFunHandle(viewer, positions, type) {
+    //if (!drawBackFun || !type) { return;}
+    if (!(positions instanceof Array)) {
+        positions = [positions];
+    }
+    var drawPoints = Cartesian3_to_WGS84Arr(positions);
+    var points = Array.from(drawPoints);
+    points.push(points[0]);
+    var area = 0;
+    if (type != "point" && type != "polyline") {
+        var polygon = turf.polygon([points]);
+        area = turf.area(polygon);
+    } else if (type == "point" && drawBackSpecial) {
+        var entity = viewer.entities.add({
+            id: "dlxz_" + drawBackSpecial,
+            position: Cesium.Cartesian3.fromDegrees(points[0][0], points[0][1]),
+            //position: positions,
+            billboard: { //图标
+                image: '/src/assets/images/map/' + drawBackSpecial + '.png',
+                width: 50,
+                height: 50,
+                pixelOffset: new Cesium.Cartesian2(0, -20),   //偏移量
+            },
+        });
+        //viewer.zoomTo(entity);
+    }
+    var thisResult = {
+        prj: "EPSG:4326",
+        type: type,
+        // points: drawPoints //不闭合的
+        points: points // 闭合的
+    }
+    thisResult["mode"] = "3D";
+    thisResult["features"] = changeFormatToJson(thisResult.type, thisResult.points, thisResult.prj);
+    thisResult["area"] = area;
+    //TODO 绘制完成监听
+    // window.parent.parent.postMessage({
+    //     msg: "receiveDrawInfo",
+    //     info: JSON.stringify(thisResult)
+    // }, '*');
+    // window.parent.postMessage({
+    //     script: 'globleClearHandle()'
+    // });
+    if (drawBackFun) {
+        drawBackFun(thisResult.features);
+    }
+}
+
+export function changeFormatToJson(geomType, geomPoints, geomPrj) {
+    if (geomPrj) {
+        geomPrj = (geomPrj.split(":").length == 2 && (geomPrj.split(":")[0] == "EPSG" || geomPrj.split(":")[0] == "wkid")) ? geomPrj.split(":")[1] : geomPrj;
+    }
+    geomPrj = Number(geomPrj);
+    var geometry = null;
+    switch (geomType) {
+        case "point":
+        case "esriGeometryPoint":
+            geomType = "esriGeometryPoint";
+            geometry = { x: geomPoints[0][0], y: geomPoints[0][1] }
+            break;
+        case "polyline":
+        case "esriGeometryPolyline":
+            geomType = "esriGeometryPolyline";
+            geometry = {
+                paths: geomPoints
+            };
+            break;
+        case "polygon":
+        case "esriGeometryPolygon":
+        default:
+            geomType = "esriGeometryPolygon";
+            geometry = {
+                rings: [geomPoints]
+            };
+            break;
+    }
+    var thisResult1 = {
+        displayFieldName: "",
+        fieldAliases: {},
+        geometryType: geomType,
+        spatialReference: {
+            wkid: geomPrj,
+            latestWkid: geomPrj
+        },
+        fields: [],
+        features: [{
+            attributes: {},
+            geometry: geometry
+        }]
+    }
+    return thisResult1;
+}
+// 测高
+export function measureHeight(viewer, handler) {
+    var handler_g = handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
+    var positions = [];
+    var poly = null;
+    // var tooltip = document.getElementById("toolTip");
+    var tooltip = setTooltip(viewer)
+    var height = 0;
+    var cartesian = null;
+    var floatingPoint;
+    // tooltip.style.display = "block";
+    tooltip.setVisible(true);
+
+    handler.setInputAction(function (movement) {
+        tooltip.showAt(movement.endPosition, "<p style='margin: 0'>单击开始,右击结束</p>", 3, -25);
+        cartesian = getPickPositionGlobe(movement.endPosition, viewer);
+        if (positions.length >= 2) {
+            if (!Cesium.defined(poly)) {
+                poly = new PolyLinePrimitive(positions);
+            } else {
+                positions.pop();
+                positions.push(cartesian);
+            }
+            height = getHeight(positions);
+        }
+    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    handler.setInputAction(function (movement) {
+        tooltip.setVisible(false);
+        cartesian = getPickPositionGlobe(movement.position, viewer);
+
+        if (positions.length == 0) {
+            positions.push(cartesian.clone());
+            positions.push(cartesian);
+
+            floatingPoint = viewer.entities.add({
+                //parent: measure_entities,
+                name: '高度',
+                position: positions[0],
+                point: {
+                    pixelSize: 5,
+                    color: Cesium.Color.RED,
+                    outlineColor: Cesium.Color.WHITE,
+                    outlineWidth: 2,
+                    heightReference: Cesium.HeightReference.none
+                },
+                //label: {
+                //    text: "0米",
+                //    font: '18px sans-serif',
+                //    fillColor: Cesium.Color.GOLD,
+                //    style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                //    outlineWidth: 2,
+                //    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+                //    pixelOffset: new Cesium.Cartesian2(20, -40)
+                //}
+            });
+        }
+    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+
+    handler.setInputAction(function (movement) {
+        handler.destroy();
+        // tooltip.style.display = "none";
+        tooltip.setVisible(false);
+        var textDisance = height + "米";
+        var point1cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
+        var point2cartographic = Cesium.Cartographic.fromCartesian(positions[1]);
+        var point_temp = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(point1cartographic.longitude), Cesium.Math.toDegrees(point1cartographic.latitude), point2cartographic.height);
+        viewer.entities.add({
+            name: '直线距离',
+            position: point_temp,
+            point: {
+                pixelSize: 5,
+                color: Cesium.Color.RED,
+                outlineColor: Cesium.Color.WHITE,
+                outlineWidth: 2,
+                heightReference: Cesium.HeightReference.none
+            },
+            label: {
+                text: textDisance,
+                font: '18px sans-serif',
+                fillColor: Cesium.Color.GOLD,
+                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                outlineWidth: 2,
+                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+                pixelOffset: new Cesium.Cartesian2(20, -20)
+            }
+        });
+    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+
+    function getHeight(_positions) {
+        var cartographic = Cesium.Cartographic.fromCartesian(_positions[0]);
+        var cartographic1 = Cesium.Cartographic.fromCartesian(_positions[1]);
+        var height_temp = cartographic1.height - cartographic.height;
+        return height_temp.toFixed(2);
+    }
+
+    var PolyLinePrimitive = (function () {
+        function _(positions) {
+            this.options = {
+                //parent: measure_entities,
+                name: '直线',
+                polyline: {
+                    show: true,
+                    positions: [],
+                    material: Cesium.Color.AQUA,
+                    width: 2
+                },
+                ellipse: {
+                    show: true,
+                    // semiMinorAxis : 30.0,
+                    // semiMajorAxis : 30.0,
+                    // height: 20.0,
+                    material: Cesium.Color.GREEN.withAlpha(0.5),
+                    outline: true // height must be set for outline to display
+                }
+            };
+            this.positions = positions;
+            this._init();
+        }
+
+        _.prototype._init = function () {
+            var _self = this;
+            var _update = function () {
+                var temp_position = [];
+                temp_position.push(_self.positions[0]);
+                var point1cartographic = Cesium.Cartographic.fromCartesian(_self.positions[0]);
+                var point2cartographic = Cesium.Cartographic.fromCartesian(_self.positions[1]);
+                var point_temp = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(point1cartographic.longitude), Cesium.Math.toDegrees(point1cartographic.latitude), point2cartographic.height);
+                temp_position.push(point_temp);
+                return temp_position;
+            };
+            var _update_ellipse = function () {
+                return _self.positions[0];
+            };
+            var _semiMinorAxis = function () {
+                var point1cartographic = Cesium.Cartographic.fromCartesian(_self.positions[0]);
+                var point2cartographic = Cesium.Cartographic.fromCartesian(_self.positions[1]);
+                /**根据经纬度计算出距离**/
+                var geodesic = new Cesium.EllipsoidGeodesic();
+                geodesic.setEndPoints(point1cartographic, point2cartographic);
+                var s = geodesic.surfaceDistance;
+                return s;
+            };
+            var _height = function () {
+                var height_temp = getHeight(_self.positions);
+                return height_temp;
+            };
+            //实时更新polyline.positions
+            this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
+            this.options.position = new Cesium.CallbackProperty(_update_ellipse, false);
+            this.options.ellipse.semiMinorAxis = new Cesium.CallbackProperty(_semiMinorAxis, false);
+            this.options.ellipse.semiMajorAxis = new Cesium.CallbackProperty(_semiMinorAxis, false);
+            this.options.ellipse.height = new Cesium.CallbackProperty(_height, false);
+            viewer.entities.add(this.options);
+        };
+
+        return _;
+    })();
+}
+/**
+ * 全局绘制公共接口
+ * @param drawList
+ * @param callback
+ * @param special 起点终点start/end
+ * @constructor
+ */
+export function g_DrawFigure(viewer, drawList, callback, special) {
+    if (special) {
+        viewer.entities.removeById("dlxz_" + special);
+    } else {
+        removeAllEntities(viewer);
+    }
+    if (drawList && (drawList == "point" || drawList.toString().indexOf("point") > -1)) {
+        DrawHelper(viewer, "drawPoint")
+        drawBackSpecial = special;
+    } else {
+        DrawHelper(viewer, "drawPolygon")
+    }
+    drawBackFun = callback;
+}

+ 131 - 0
src/utils/map/fun/layerManager.js

@@ -0,0 +1,131 @@
+/*
+ * @Descripttion: 图层管理
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-07-30 10:08:50
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-10 16:34:18
+ */
+import { sw_servicetype, LayerHelper } from "@/utils/map/layerHelper";
+import { g_flyto } from "@/utils/map/fun/layerPosition";
+/**
+ * 加载默认图层
+ * @return {*}
+ */
+export function show3DLayersMap(MapConfigLayers, viewer) {
+    if (
+        MapConfigLayers.maplayers &&
+        MapConfigLayers.maplayers.length > 0
+    ) {
+        MapConfigLayers.maplayers.map((layerInfo) => {
+            if (layerInfo.checked) {
+                layerInfo.GUID = layerInfo.id;
+                // layerInfo.NAME = layerInfo.name;
+                layerInfo.NAME = "";
+                layerInfo.URL = layerInfo.layerurl;
+                var layerHelper = new LayerHelper(
+                    layerInfo,
+                    false,
+                    viewer
+                );
+                layerHelper.addLayer();
+            }
+        });
+    }
+}
+/**
+ * @Desc: 加载指定图层
+ * @param {*} layerinfo
+ * @param {*} visible
+ * @param {*} isbasemap
+ * @return {*}
+ */
+export function addService({ layerinfo = {}, visible = true, isbasemap = false }, viewer) {
+    if (!layerinfo) return;
+    layerinfo["URL"] = layerinfo["ADDRESS"];
+    var layerHelp = new LayerHelper(layerinfo, isbasemap, viewer);
+    layerHelp.addLayer(visible);
+}
+/**
+ * @Desc: 加载多个图层
+ * @param {*} layerinfos
+ * @return {*}
+ */
+export function addServices(layerinfos, viewer) {
+    if (layerinfos && layerinfos.length > 0) {
+        for (var i = 0; i < layerinfos.length; i++) {
+            var layerinfo = layerinfos[i];
+            this.addService({
+                layerinfo: layerinfo.layerinfo,
+                visible: layerinfo.visible,
+                isbasemap: layerinfo.isbasemap
+            }, viewer
+            );
+        }
+    }
+}
+/**
+ * 透明度控制
+ * @param id guid
+ * @param opacity  1-0
+ */
+export function globleSetLayerOpacity(id, opacity, viewer) {
+    // opacity = opacity ? parseFloat(opacity) : 1;
+    var thisLayerInfo = window.treeList[id];
+    var layerHelp = new LayerHelper(thisLayerInfo, false, viewer);
+    layerHelp.changeLayerTransparent(id, thisLayerInfo, opacity);
+}
+/**
+ * 调整图层顺序
+ * @param id  guid
+ * @param type  up / down
+ */
+export function globleSetLayerIndex(thisLayerInfo, type, viewer) {
+
+    var layerHelp = new LayerHelper(thisLayerInfo, false, viewer);
+    if (type == "up") {
+        layerHelp.moveToUp();
+    } else if (type == "down") {
+        layerHelp.moveToDown();
+    }
+}
+//定位到图层位置
+export function flyTo3DViewByLayerInfo(id, viewer) {
+    //获取要定位的图层信息
+    var locationLayer = window.treeList[id]
+        ? window.treeList[id]
+        : window.treeList;
+    if (locationLayer["SERVICETYPE"] === sw_servicetype.sw_oblique) {
+        return viewer.zoomTo(window.treeList[id].imageryLayer);
+    } else if (
+        locationLayer["SERVICETYPE"] === sw_servicetype.sw_terrain
+    ) {
+        return null;
+    }
+    var positions = locationLayer.POSITION;
+    if (positions != "") {
+        positions = positions.split(",");
+    }
+
+    if (positions.length < 3) {
+        //没有缩放级别时,补空
+        positions.push("");
+    }
+
+    //图层上移
+    //var layerHelp = new LayerHelper(locationLayer);
+    //var thisLayer = layerHelp.GetLayer();
+    //layerHelp.moveToUp();
+
+    if (positions != "") {
+        var height;
+        if (positions[2]) {
+            height = parseFloat(positions[2]) + 1000;
+        } else {
+            height = Math.ceil(
+                viewer.camera.positionCartographic.height
+            );
+        }
+        g_flyto(viewer, { lon: parseFloat(positions[0]), lat: parseFloat(positions[1]), height: height });
+    }
+}

+ 107 - 0
src/utils/map/fun/layerOverlay.js

@@ -0,0 +1,107 @@
+/*
+ * @Descripttion: 图层要素渲染
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-10 16:33:54
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-10 17:57:35
+ */
+import * as Cesium from "cesium";
+import { LayerHelper } from "@/utils/map/layerHelper";
+import { removeAllEntities } from "@/utils/map/mapUtils";
+
+/**
+ * 绘制分析范围
+ * @param params
+ */
+export function addAnalyseExtent(viewer, params) {
+    removeAllEntities(viewer);
+    var id = "c45B99afF137462FbfB85ffC01AddfA6";
+    // params = params || { "displayFieldName": "", "fieldAliases": {}, "geometryType": "esriGeometryPolygon", "spatialReference": { "wkid": 4326, "latestWkid": 4326 }, "fields": [], "features": [{ "attributes": {}, "geometry": { "rings": [[[108.68490335673884, 40.03110255792514, 0], [108.68338318114769, 39.93183352900264, 0], [108.75865006380822, 39.90653515582441, 0], [108.78511526888586, 39.93984386540289, 0], [108.81590456454865, 39.99891644965434, 0], [108.75135444605658, 40.06876811971662, 0], [108.73095374976525, 40.088455735067214, 0], [108.73095374976525, 40.088455735067214, 0]]] } }] }
+    if (typeof (params) == "string") {
+        params = JSON.parse(params)
+    }
+    if (params && params.features && params.features[0].geometry.rings[0]) {
+        var points = params.features[0].geometry.rings[0];
+        var allPoints = [];
+        for (var i = 0; i < points.length; i++) {
+            allPoints.push(points[i][0]);
+            allPoints.push(points[i][1]);
+        }
+        var polylinePoints = Array.from(allPoints);
+        polylinePoints.push(allPoints[0]);
+        polylinePoints.push(allPoints[1]);
+        var entity = viewer.entities.add({
+            name: 'analyse',
+            id: 'analyse_' + id,
+            polygon: {
+                hierarchy: Cesium.Cartesian3.fromDegreesArray(allPoints),
+                material: Cesium.Color.WHITE.withAlpha(0.2),
+                outline: true,
+                outlineColor: Cesium.Color.RED.withAlpha(1)
+            },
+            polyline: {
+                clampToGround: true,
+                material: Cesium.Color.RED.withAlpha(1),
+                positions: Cesium.Cartesian3.fromDegreesArray(polylinePoints),
+                width: 2
+            }
+        });
+        viewer.flyTo(entity);
+    } else {
+        console.log("必要参数为传递!");
+    }
+}
+/**
+ * 应用分析矢量切片服务
+ * 根据分析结果数据名称进行数据渲染
+ * @param resultName 不传参则为清除展示图层
+ * @param type 数据类型
+ */
+export function overlayVectorFeature(viewer, resultName, type) {
+    var path = import.meta.env.VITE_Vector_Path;
+    console.log(path);
+    var id = "c45B99afF137462FbfB85ffC01AddfA8";
+    if (window.treeList[id]) {
+        var imageryLayer = window.treeList[id].imageryLayer
+        viewer.scene.imageryLayers.remove(imageryLayer);
+        window.treeList[id].imageryLayer = null
+    }
+    if (!resultName) {
+        console.log("必要参数未传递!");
+        return;
+    }
+    var layerparam = {
+        "GUID": id,
+        "NAME": "",
+        "SERVICETYPE": "tile",
+        "SOURCE": "pbftile",
+        "DATAURI": path + "\\" + resultName + ".shp",
+        "LAYERNAME": resultName,
+        "SPATIALREF": "EPSG:4326"
+    };
+    var layer = new LayerHelper(layerparam, false, viewer);
+    layer.addLayer(true);
+}
+/**
+ * 矢量数据渲染geojson
+ * @param url
+ */
+export function geojsonLayer(viewer, url) {
+    var id = "c45B99afF137462FbfB85ffC01AddfA";
+    if (window.treeList[id]) {
+        globleStreamerpath.removeprimitive(id);
+        window.treeList[id].imageryLayer = null
+    }
+    if (url) {
+        var layerparam = {
+            "GUID": id,
+            "NAME": "",
+            "URL": url,
+            "SERVICETYPE": "geojson",
+            "ALIAS": "geodata"
+        };
+        var layer = new LayerHelper(layerparam, false, viewer);
+        layer.addLayer(true);
+    }
+}

+ 195 - 0
src/utils/map/fun/layerPosition.js

@@ -0,0 +1,195 @@
+/*
+ * @Descripttion: 图层定位
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-07-30 14:20:38
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-10 16:37:59
+ */
+/**
+ * 根据行政区代码定位
+ * @param XZQDM 行政区代码
+ */
+import * as Cesium from "cesium";
+import mapRequest from "@/utils/map/mapRequest";
+import { getErdsxqInfo } from "@/api/main/index.js";
+import { addProjectionTransform } from "/src/utils/tools/CoordTransformate/CoordTransformate"
+/**
+ * @Desc: 飞行
+ * @param {*} viewer
+ * @param {*} destination
+ * @param {*} lat
+ * @param {*} height
+ * @param {*} orientation
+ * @param {*} pitch
+ * @param {*} roll
+ * @return {*}
+ */
+export function g_flyto(viewer, destination = { lon: 108.9670415016, lat: 39.2470366195, height: 50000 }, orientation = { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-30), roll: 0.0 }) {
+    viewer.camera.flyTo({
+        destination: Cesium.Cartesian3.fromDegrees(destination.lon, destination.lat, destination.height),
+        orientation: {
+            heading: orientation.heading,
+            pitch: orientation.pitch,
+            roll: orientation.roll
+        }
+    })
+}
+/**
+ * 根据行政区代码定位
+ * @param XZQDM 行政区代码
+ */
+export function globleXZQPosition(XZQDM, viewer) {
+    getXZQExtents(XZQDM, function (extent) {
+        extent && addXZQFeatures(extent, viewer);
+    });
+}
+/**
+ * 根据经纬度定位
+ * @param x 经度
+ * @param y 纬度
+ * @param z 高程
+ */
+export function globleCoordinatePosition(x, y, z, name, viewer) {
+    var x = parseFloat(x);
+    var y = parseFloat(y);
+
+    var cartesian3 = Cesium.Cartesian3.fromDegrees(x, y, 0)
+    var pinBuilder = new Cesium.PinBuilder();
+    var plotentity = viewer.entities.add({
+        position: cartesian3,
+        billboard: {
+            image: pinBuilder.fromText(name, Cesium.Color.BLUE.withAlpha(0.75), 48).toDataURL(),
+            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(2000),
+            verticalOrigin: Cesium.VerticalOrigin.BOTTOM
+        },
+        point: {
+            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+            pixelSize: 5,
+            color: Cesium.Color.RED.withAlpha(1)
+        }
+    });
+    g_flyto(viewer, { lon: x, lat: y, height: (z ? z : 5000) }, { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-90), roll: 0.0 })
+}
+
+//根据行政区代码XZQDM在服务中查询服务范围
+export function getXZQExtents(XZQDM, callback) {
+    getErdsxqInfo({}).then((res) => {
+        res = typeof res == "string" ? JSON.parse(res) : res;
+        var thisResult = null;
+        var ip = res.data.xzqService + "/0/query";
+        var sql = res.data.xzqField + "='" + XZQDM + "'"
+        mapRequest({
+            url: ip,
+            method: 'get',
+            params: {
+                f: "json",
+                where: sql,
+                outSR: 3857
+            }
+        }).then((result) => {
+            result = typeof result == "string" ? JSON.parse(result) : result;
+            if (result.features.length > 0) {
+                result = handle2Geojson(result, "arcgis");
+                thisResult = result.features;
+            }
+            callback(thisResult)
+        })
+    });
+
+    // return thisResult;
+}
+//添加行政区图层并进行定位
+export function addXZQFeatures(features, viewer) {
+    var inSR = "EPSG:" + features[0].arcgis.spatialReference.latestWkid; //3857
+    var outSR = "EPSG:4326"
+    viewer.entities.removeAll();
+    var entity = null;
+    for (var m = 0; m < features.length; m++) {
+        var geom = features[m].geometry;
+        var geomtype = geom.type.toLowerCase();
+        if (geomtype.indexOf("polygon") > -1) {
+            var points = [];
+            addProjectionTransform(geom.coordinates[0][0], inSR, outSR, true, false, function (e) {
+                let coordinates = e.result
+                for (var i = 0; i < coordinates.length; i++) {
+                    var lon = coordinates[i][0];
+                    var lat = coordinates[i][1];
+                    points.push(lon);
+                    points.push(lat);
+                }
+                entity = viewer.entities.add({
+                    polyline: {
+                        clampToGround: true,
+                        material: Cesium.Color.fromCssColorString("#ff0000"),
+                        positions: Cesium.Cartesian3.fromDegreesArray(points),
+                        width: 5
+                    },
+                    polygon: {
+                        hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
+                        material: Cesium.Color.WHITE.withAlpha(0.15),
+                        outline: false,
+                        outlineColor: Cesium.Color.BLACK.withAlpha(0)
+                    }
+                });
+
+                if (entity) {
+                    let flyPromise = viewer.flyTo(entity, {
+                        offset: {
+                            heading: Cesium.Math.toRadians(0.0),
+                            pitch: Cesium.Math.toRadians(-45),
+                            range: 0
+                        }
+                    });
+                    flyPromise.then(function (flyPromise) {
+                        setTimeout(function () {
+                            viewer.entities.remove(entity);
+                            setTimeout(function () {
+                                viewer.entities.add(entity);
+                            }, 10);
+                        }, 50);
+                    });
+                }
+            })
+
+        }
+    }
+
+}
+
+//将行政区要素格式转换为geoJSON格式
+export function handle2Geojson(data, type) {
+    var geojson = {
+        "type": "FeatureCollection",
+        "features": []
+    };
+    type = type ? type : "arcgis";
+    switch (type) {
+        case "arcgis":
+            var param = data;
+            var arcgis = {
+                displayFieldName: "",
+                fieldAliases: {},
+                fields: [],
+                features: [param],
+                geometryType: param.geometryType,
+                spatialReference: param.spatialReference
+            }
+            if (param.geometryType == "esriGeometryPolygon" || param.geometry.rings) {
+                geojson.features.push({
+                    "type": "Feature",
+                    "geometry": {
+                        "type": "Polygon",
+                        //"coordinates": [param.geometry.rings]
+                        "coordinates": [param.features[0].geometry.rings]
+                    },
+                    "properties": param.features[0].attributes,
+                    "arcgis": arcgis
+                });
+            }
+            break;
+        default:
+            break;
+    }
+    return geojson;
+}

+ 715 - 0
src/utils/map/fun/layerQuery.js

@@ -0,0 +1,715 @@
+/*
+ * @Descripttion: 图层查询
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-01 16:25:45
+ * @LastEditors: 郭亚伟 2241880990@qq.com
+ * @LastEditTime: 2022-11-09 14:34:15
+ */
+import store from '@/store'
+import axios from 'axios';
+import * as Cesium from "cesium";
+import { getPickPositionGlobe, handleToGeojson, removeAllEntities, GetViewExtent, setTooltip, setScreenSpaceEventHandler, clearScreenSpaceEventHandler } from "@/utils/map/mapUtils";
+import { sw_servicetype, sw_source } from "@/utils/map/layerHelper";
+import mapRequest from "@/utils/map/mapRequest";
+import { getFieldsInfo } from "@/api/main/index.js";
+import { addProjectionTransform } from "/src/utils/tools/CoordTransformate/CoordTransformate"
+
+let { LayerFieldFilterInfo } = window.mapConfig
+let QueryHandler = null;
+let sampleLabel = null; // 点选标注
+/**
+ * @Desc: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-03 17:19:45
+ * @param {*} viewer
+ * @param {*} type 1:点选2:框选 5:i查询 
+ * @param {*} callback
+ * @return {*}
+ */
+export function layerQuery(viewer, type, callback) {
+    let tooltip = setTooltip(viewer);
+    removeAllEntities(viewer);
+    // identifyClear();
+    clearScreenSpaceEventHandler();
+    removeSampleLabel();
+    var cartesian = null;
+    let QueryHandler = setScreenSpaceEventHandler(viewer);
+    // QueryHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
+    var ellipsoid = viewer.scene.globe.ellipsoid;
+    switch (type) {
+        case "1":
+            QueryHandler.setInputAction(function (movement) {
+                //通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
+                cartesian = getPickPositionGlobe(movement.position, viewer);
+                if (cartesian) {
+                    //将笛卡尔坐标转换为地理坐标
+                    var cartographic = ellipsoid.cartesianToCartographic(cartesian);
+                    //将弧度转为度的十进制度表示
+                    var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
+                    var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
+                    var point = longitudeString + ',' + latitudeString;
+                    removeAllEntities(viewer)
+                    queryLayerInfoByPoint(viewer, { point: point, type: 1 }, function (result) {
+                        callback(result)
+                    })
+                    tooltip.setVisible(false);
+                }
+            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+            break;
+        case "2":
+            let activeShapePoints = [];
+            let activeShape;
+            let floatingPoint;
+            let drawingMode = 'rectangle';
+            viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
+            //鼠标左键
+            QueryHandler.setInputAction(function (event) {
+                let earthPosition = getPickPositionGlobe(event.position, viewer);
+                if (Cesium.defined(earthPosition)) {
+                    if (activeShapePoints.length === 0) {
+                        floatingPoint = createPoint(viewer, earthPosition);
+                        activeShapePoints.push(earthPosition);
+                        let dynamicPositions = new Cesium.CallbackProperty(function () {
+                            if (drawingMode === 'polygon') {
+                                return new Cesium.PolygonHierarchy(activeShapePoints);
+                            }
+                            return activeShapePoints;
+                        }, false);
+                        activeShape = drawShape(viewer, dynamicPositions); //绘制动态图
+                    }
+                    activeShapePoints.push(earthPosition);
+                    createPoint(viewer, earthPosition);
+                }
+            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+            //鼠标移动
+            QueryHandler.setInputAction(function (event) {
+                tooltip.setVisible(true);
+                var wp = event.endPosition;
+                if (!Cesium.defined(wp)) {
+                    return;
+                }
+                // var position = event.endPosition;
+                // if (!Cesium.defined(position)) {
+                //     return;
+                // }
+                var num = activeShapePoints.length;
+                if (num < 1) {
+                    tooltip.showAt(wp, "<p style='margin:0'>单击选择起点</p>")
+                    return;
+                }
+                tooltip.showAt(wp, "<p style='margin: 0'>右击结束绘制</p>");
+                if (Cesium.defined(floatingPoint)) {
+                    var newPosition = getPickPositionGlobe(event.endPosition, viewer);
+                    if (Cesium.defined(newPosition)) {
+                        floatingPoint.position.setValue(newPosition);
+                        activeShapePoints.pop();
+                        activeShapePoints.push(newPosition);
+                    }
+                }
+            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+            QueryHandler.setInputAction(function (event) {
+                var point1 = [activeShapePoints[0].x, activeShapePoints[0].y, activeShapePoints[0].z];
+                var point2 = [activeShapePoints[1].x, activeShapePoints[1].y, activeShapePoints[1].z];
+                var pointsArr = [point1, point2];
+                pointsArr = mapProjectionToWGS84_2(viewer, pointsArr);
+                // terminateShape();
+                activeShapePoints.pop(); //去除最后一个动态点
+                if (activeShapePoints.length) {
+                    drawShape(viewer, activeShapePoints); //绘制最终图
+                }
+                viewer.entities.remove(floatingPoint); //去除动态点图形(当前鼠标点)
+                viewer.entities.remove(activeShape); //去除动态图形
+                floatingPoint = undefined;
+                activeShape = undefined;
+
+                var drawPoint1 = [pointsArr[0].longitude, pointsArr[0].latitude];
+                var drawPoint2 = [pointsArr[1].longitude, pointsArr[0].latitude];
+                var drawPoint3 = [pointsArr[1].longitude, pointsArr[1].latitude];
+                var drawPoint4 = [pointsArr[0].longitude, pointsArr[1].latitude];
+                pointsArr = [drawPoint1, drawPoint2, drawPoint3, drawPoint4, drawPoint1];
+                var points = pointArrsToStringForQuery(pointsArr);
+                removeAllEntities(viewer);
+                queryLayerInfoByPoint(viewer, { point: points, type: 3 }, function (result) {
+                    callback(result)
+                })
+                tooltip.setVisible(false);
+                activeShapePoints = []
+            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
+            break;
+        case "5":
+            QueryHandler.setInputAction(function (movement) {
+                removeSampleLabel()
+                removeAllEntities(viewer);
+                //通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
+                cartesian = getPickPositionGlobe(movement.position, viewer);
+                if (cartesian) {
+                    //将笛卡尔坐标转换为地理坐标
+                    var cartographic = ellipsoid.cartesianToCartographic(cartesian);
+                    //将弧度转为度的十进制度表示
+                    var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
+                    var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
+                    var point = longitudeString + ',' + latitudeString;
+                    FilterQueryLayerInfoByPoint(viewer, point, 1, function (result) {
+                        if (result.length > 0) {
+                            let str = ''
+                            result.map((item, index) => {
+                                let key = item.key;
+                                let val = item.value;
+                                if (index == 0) {
+                                    str = `${key} : ${val}`;
+                                } else {
+                                    str += `</br>${key} : ${val}`;
+                                }
+                            })
+                            sampleLabel = new xt3d.PointObject.SampleLabel(viewer, cartesian, str);
+                            // sampleLabel = new xt3d.PointObject.DynamicDivLabel(viewer, cartesian, str);
+                        }
+                    });
+
+                    tooltip.setVisible(false);
+                }
+            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+            break;
+        default:
+            break;
+    }
+    if (type == "1" || type == "5") {
+        //鼠标移动
+        QueryHandler.setInputAction(function (event) {
+            tooltip.setVisible(true);
+            var wp = event.endPosition;
+            if (!Cesium.defined(wp)) {
+                return;
+            }
+            // if (cartesian == null) {
+            tooltip.showAt(wp, "<p style='margin: 0'>单击选择位置</p>")
+            // }
+            var position = getPickPositionGlobe(wp, viewer);
+            if (!Cesium.defined(position)) {
+                return;
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    }
+}
+
+export function queryLayerInfoByPoint(viewer, obj, callback) {
+    let point = obj.point;
+    let type = obj.type;
+    let layerIds = obj.layerIds;
+    let layerIdList = store.state.resourceTree.checkedNode;
+    let result;
+    let results = [];
+    if (!layerIds) {
+        layerIds = []
+        for (let i = 0; i < layerIdList.length; i++) {
+            let layerId = layerIdList[i];
+            let layerItem = window.treeList[layerId].imageryLayer;
+            if (layerItem["NAME"] && layerItem["SERVICETYPE"] != sw_servicetype.sw_terrain && layerItem["SERVICETYPE"] != sw_servicetype.sw_oblique && layerItem["SOURCE"] != sw_source.sw_mongodb) {
+                layerIds.push(layerId);
+            }
+        }
+    } else if (typeof (layerIds) == "string") {
+        layerIds = [layerIds];
+    }
+
+    if (layerIds.length == 0) {
+        callback("请先打开图层再查询");
+        clearScreenSpaceEventHandler();
+        // identifyClear();
+        return;
+    }
+    let flag = 0
+    for (let i = 0; i < layerIds.length; i++) {
+        let layerItem = window.treeList[layerIds[i]].imageryLayer;
+        let queryUrl = "";
+        let params = {};
+        let layerUrl = layerItem["URL"];
+        switch (layerItem["SERVICETYPE"]) {
+            case sw_servicetype.sw_tile://tile
+                switch (layerItem["SOURCE"]) {
+                    case sw_source.sw_arcgis://arcgis
+                    case sw_source.sw_arcgistile://arcgis
+                        queryUrl = layerUrl + '/identify';
+                        params = {
+                            sr: 4326,
+                            layers: 'visible',
+                            tolerance: 3,
+                            mapExtent: GetViewExtent(viewer).toString(),
+                            imageDisplay: viewer.scene.canvas.width + ',' + viewer.scene.canvas.height + ',96',
+                            returnGeometry: true,
+                            returnFieldName: true,
+                            f: 'json'
+                        }
+                        if (type == 1 || type == 2) {//point
+                            params["geometry"] = JSON.stringify({ "x": parseFloat(point.split(",")[0]), "y": parseFloat(point.split(",")[1]) });
+                            params["geometryType"] = 'esriGeometryPoint'
+                        } else if (type == 3) {//polygon
+                            // params["geometry"] = JSON.stringify({
+                            //     "rings": [pointStringsToArrayForQuery(point)]
+                            // });
+                            params["geometry"] = encodeURIComponent(JSON.stringify({
+                                "rings": [pointStringsToArrayForQuery(point)]
+
+                            }));
+                            params["geometryType"] = 'esriGeometryPolygon'
+
+                        } else if (type == 4) {//polgline
+                            params["geometry"] = encodeURIComponent(JSON.stringify({
+                                "paths": [pointStringsToArrayForQuery(point)]
+                            }));
+                            params["geometryType"] = 'esriGeometryPolyline'
+                        }
+                        break;
+                    case sw_source.sw_wms:
+                        if (type == 1 || type == 2) {
+                            queryUrl = layerUrl + "/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=" + layerInfo.layerid + "&outputFormat=application/json&srsName=" + (layerInfo.srsName ? layerInfo.srsName : "EPSG:3857") + "&filter=<Filter xmlns='http://www.opengis.net/ogc' xmlns:gml='http://www.opengis.net/gml'><Intersects><PropertyName>the_geom</PropertyName><gml:Point srsName='EPSG:4326'><gml:coordinates>" + point + "</gml:coordinates></gml:Point></Intersects></Filter>";
+                        } else if (type == 3) {
+                            queryUrl = layerUrl + "/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=" + layerInfo.layerid + "&outputFormat=application/json&srsName=" + (layerInfo.srsName ? layerInfo.srsName : "EPSG:3857") + "&filter=<Filter xmlns='http://www.opengis.net/ogc' xmlns:gml='http://www.opengis.net/gml'><Intersects><PropertyName>the_geom</PropertyName><gml:Polygon srsName='EPSG:4326'><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>" + point + "</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon></Intersects></Filter>";
+                        } else if (type == 4) {
+                            queryUrl = layerUrl + "/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=" + layerInfo.layerid + "&outputFormat=application/json&srsName=" + (layerInfo.srsName ? layerInfo.srsName : "EPSG:3857") + "&filter=<Filter xmlns='http://www.opengis.net/ogc' xmlns:gml='http://www.opengis.net/gml'><Intersects><PropertyName>the_geom</PropertyName><gml:Polyline srsName='EPSG:4326'><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>" + point + "</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polyline></Intersects></Filter>";
+                        }
+                        break;
+                    default:
+                        break;
+                }
+
+                break;
+            case sw_servicetype.vector://vector
+
+                break;
+            default:
+                break;
+
+        }
+        // 发送请求
+        mapRequest({
+            url: queryUrl,
+            method: 'get',
+            params: params
+        }).then((res) => {
+            if (typeof (res) === "string") {
+                res = JSON.parse(res)
+            }
+            result = handleToGeojson(res.results, "arcgis");
+            if (result && result.features.length > 0) {
+                // addQueryFeatures(viewer, result.features);
+                results.push({
+                    name: layerItem["NAME"],
+                    id: layerIds[i],
+                    data: result
+                });
+            }
+            flag++;
+            if (flag === layerIds.length) {
+                callback(results)
+            }
+        })
+    }
+}
+
+// i查询,过滤查询
+export function FilterQueryLayerInfoByPoint(viewer, point, type, callback) {
+    let layerIds = store.state.resourceTree.checkedNode;
+    let result;
+    if (layerIds.length == 0) {
+        callback([]);
+        // identifyClear();
+        clearScreenSpaceEventHandler();
+        removeSampleLabel();
+        this.$modal.msgWarning('请先打开图层再查询')	
+        return;
+    }
+    if (layerIds.length > 0) {
+        //只查询最顶层图层信息
+        let layerItem = window.treeList[layerIds[0]].imageryLayer;
+        let queryUrl = "";
+        let params = {};
+        let layerUrl = layerItem["URL"];
+        let layerName = layerItem["NAME"];
+        switch (layerItem["SERVICETYPE"]) {
+            case sw_servicetype.sw_tile: //tile
+                switch (layerItem["SOURCE"]) {
+                    case sw_source.sw_arcgis: //arcgis
+                    case sw_source.sw_arcgistile: //arcgis
+                        queryUrl = layerUrl + '/identify';
+                        params = {
+                            sr: 4326,
+                            layers: 'visible',
+                            tolerance: 3,
+                            mapExtent: GetViewExtent(viewer).toString(),
+                            imageDisplay: viewer.scene.canvas.width + ',' + viewer.scene.canvas.height + ',96',
+                            returnGeometry: true,
+                            returnFieldName: true,
+                            f: 'json'
+                        }
+                        if (type == 1) { //point
+                            params["geometry"] = JSON.stringify({
+                                "x": parseFloat(point.split(",")[0]),
+                                "y": parseFloat(point.split(",")[1])
+                            });
+                            params["geometryType"] = 'esriGeometryPoint'
+                        }
+                        break;
+                    case sw_source.sw_wms:
+                        if (type == 1) {
+                            queryUrl = layerUrl + "/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=" + layerInfo.layerid + "&outputFormat=application/json&srsName=" + (layerInfo.srsName ? layerInfo.srsName : "EPSG:3857") + "&filter=<Filter xmlns='http://www.opengis.net/ogc' xmlns:gml='http://www.opengis.net/gml'><Intersects><PropertyName>the_geom</PropertyName><gml:Point srsName='EPSG:4326'><gml:coordinates>" + point + "</gml:coordinates></gml:Point></Intersects></Filter>";
+                        }
+                        break;
+                    default:
+                        break;
+                }
+
+                break;
+            case sw_servicetype.vector: //vector
+
+                break;
+            default:
+                break;
+
+        }
+        // 发送请求
+        mapRequest({
+            url: queryUrl,
+            method: 'get',
+            params: params
+        }).then((res) => {
+            if (typeof (res) === "string") {
+                res = JSON.parse(res);
+            }
+            result = handleToGeojson(res.results, "arcgis");
+            if (result && result.features.length > 0) {
+                addHighlightedFeatures(viewer, result.features, "polyline");
+                filterQueryResult(result.features, layerIds[0], function (e) {
+                    callback(e);
+                });
+            }
+        })
+    }
+}
+/**
+ * 通过配置文件过滤,只显示预先配置好的字段信息
+ * @param {*} features 
+ */
+export function filterQueryResult(features, layerId, callback) {
+    let properties = features[0].properties,
+        result = [];
+    if (!LayerFieldFilterInfo[layerId]) {
+        this.$modal.msgWarning('暂未配置属性字段!')	
+    } else {
+        getFieldsInfo({
+            layerGuid: layerId,
+        }).then((res) => {
+            res = typeof res == "string" ? JSON.parse(res) : res;
+            LayerFieldFilterInfo[layerId].map(function (item) {
+                let resultInfo = {};
+                let value = !properties[item.fieldName] ? "" : properties[item.fieldName]
+                resultInfo.value = value;
+                let alias = item.alias;
+                // 优先使用配置文件里的别名
+                if (alias && alias != "") {
+                    resultInfo.key = item.alias;
+                } else {
+                    //属性字段解译
+                    let obj = {}
+                    if (res.data && res.data.length > 0) {
+                        obj = res.data.find((i) => i.fieldname == item.fieldName)
+                    }
+                    if (Object.keys(obj).length == 0) {
+                        resultInfo.key = item.fieldName;
+                    } else {
+                        resultInfo.key = obj.fieldalias;
+                    }
+                }
+                result.push(resultInfo)
+            });
+            callback(result);
+        });
+    }
+}
+/**
+ * 高亮显示要素
+ * @param {*} features 
+ * @param {string} geomtype "point","polyline","polygon"
+ */
+export function addHighlightedFeatures(viewer, features, geomtype) {
+    for (var m = 0; m < features.length; m++) {
+        var geom = features[m].geometry;
+        // var geomtype = geom.type.toLowerCase();
+        if (geomtype.indexOf("polygon") > -1) {
+            var points = [];
+            for (var i = 0; i < geom.coordinates[0][0].length; i++) {
+                points.push(geom.coordinates[0][0][i][0]);
+                points.push(geom.coordinates[0][0][i][1]);
+            }
+            viewer.entities.add({
+                polygon: {
+                    hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
+                    material: Cesium.Color.RED.withAlpha(0.5)
+                }
+            });
+        } else if (geomtype.indexOf("polyline") > -1) {
+            var points = [];
+            for (var i = 0; i < geom.coordinates[0][0].length; i++) {
+                points.push(geom.coordinates[0][0][i][0]);
+                points.push(geom.coordinates[0][0][i][1]);
+            }
+            viewer.entities.add({
+                polyline: {
+                    clampToGround: true,
+                    positions: Cesium.Cartesian3.fromDegreesArray(points),
+                    material: Cesium.Color.AQUA.withAlpha(1), // Cesium.Color.BLUE.withAlpha(0.5) ,
+                    width: 3,
+                    //distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, updatedPositions[m + 4].height + 12000)
+                }
+            });
+        } else if (geomtype.indexOf("point") > -1) {
+            viewer.entities.add({
+                position: Cesium.Cartesian3.fromDegrees(geom.coordinates[0], geom.coordinates[1]),
+                point: {
+                    color: Cesium.Color.RED.withAlpha(0.5),
+                    pixelSize: 10,
+                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                    outlineColor: Cesium.Color.YELLOW,
+                    outlineWidth: 2,
+                }
+            });
+        }
+    }
+}
+
+//绘制点
+export function createPoint(viewer, worldPosition) {
+    var point = viewer.entities.add({
+        position: worldPosition,
+        point: {
+            color: Cesium.Color.WHITE,
+            pixelSize: 5,
+            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
+        }
+    });
+    return point;
+}
+//绘制形状
+export function drawShape(viewer, positionData) {
+    //当positionData为数组时绘制最终图,如果为function则绘制动态图
+    var arr = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
+    var shape = viewer.entities.add({
+        name: 'Blue translucent, rotated, and extruded ellipse with outline',
+        rectangle: {
+            coordinates: new Cesium.CallbackProperty(function () {
+                var obj = Cesium.Rectangle.fromCartesianArray(arr);
+                return obj;
+            }, false),
+            material: Cesium.Color.RED.withAlpha(0.5)
+        }
+    });
+    return shape;
+}
+export function mapProjectionToWGS84_2(viewer, pointArr) {
+    var thisResult = [];
+    for (var i = 0; i < pointArr.length; i++) {
+        var ellipsoid = viewer.scene.globe.ellipsoid;
+        if (pointArr[i].length === 3)
+            var cartesian3 = new Cesium.Cartesian3(pointArr[i][0], pointArr[i][1], pointArr[i][2]);
+        else
+            var cartesian3 = new Cesium.Cartesian3(pointArr[i][0], pointArr[i][1], 0);
+        var cartographic = ellipsoid.cartesianToCartographic(cartesian3);
+        var lat = Cesium.Math.toDegrees(cartographic.latitude);
+        var lng = Cesium.Math.toDegrees(cartographic.longitude);
+        var alt = cartographic.height;
+        var obj = { longitude: lng, latitude: lat, height: alt };
+        thisResult.push(obj);
+    }
+    return thisResult;
+}
+export function pointArrsToStringForQuery(pointArrs) {
+    var html = ''
+    for (var i = 0; i < pointArrs.length; i++) {
+        html += pointArrs[i][0] + ',' + pointArrs[i][1] + ' '
+    }
+    return html.substring(0, html.length - 1)
+}
+
+export function pointStringsToArrayForQuery(string) {
+    var arr = [];
+    for (var i = 0; i < string.split(" ").length; i++) {
+        arr.push([string.split(" ")[i].split(",")[0], string.split(" ")[i].split(",")[1]]);
+    }
+    return arr;
+}
+
+/**
+ * @Desc: 查询结果高亮显示
+ * @param {*} viewer
+ * @param {*} features
+ * @return {*}
+ */
+export function addQueryFeatures(viewer, features, inSR) {
+    if (!inSR) {
+        inSR = "EPSG:" + features[0].arcgis.spatialReference.latestWkid; //3857
+    }
+    var outSR = "EPSG:4326"
+    for (var m = 0; m < features.length; m++) {
+        var geom = features[m].geometry;
+        var geomtype = geom.type.toLowerCase();
+        if (geomtype.indexOf("polygon") > -1) {
+            var points = [];
+            addProjectionTransform(geom.coordinates[0][0], inSR, outSR, true, false, function (e) {
+                let coordinates = e.result
+                for (var i = 0; i < coordinates.length; i++) {
+                    var lon = coordinates[i][0];
+                    var lat = coordinates[i][1];
+                    points.push(lon);
+                    points.push(lat);
+                }
+                viewer.entities.add({
+                    polygon: {
+                        hierarchy: Cesium.Cartesian3.fromDegreesArray(points),
+                        material: Cesium.Color.RED.withAlpha(0.5)
+                    }
+                });
+            });
+        } else if (geomtype.indexOf("polyline") > -1) {
+            var points = [];
+            addProjectionTransform(geom.coordinates[0][0], inSR, outSR, true, false, function (e) {
+                let coordinates = e.result
+                for (var i = 0; i < coordinates.length; i++) {
+                    var lon = coordinates[i][0];
+                    var lat = coordinates[i][1];
+                    points.push(lon);
+                    points.push(lat);
+                }
+                viewer.entities.add({
+                    polyline: {
+                        positions: Cesium.Cartesian3.fromDegreesArray(points),
+                        material: Cesium.Color.RED.withAlpha(0.5)
+                    }
+                });
+            })
+        } else if (geomtype.indexOf("point") > -1) {
+            addProjectionTransform(geom.coordinates, inSR, outSR, true, false, function (e) {
+                let coordinates = e.result
+                viewer.entities.add({
+                    position: Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]),
+                    point: {
+                        color: Cesium.Color.RED.withAlpha(0.5),
+                        pixelSize: 10,
+                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                        outlineColor: Cesium.Color.YELLOW,
+                        outlineWidth: 2,
+                    }
+                });
+            })
+        }
+    }
+}
+/**
+ * @Desc: 选中结果高亮显示
+ * @param {*} geom
+ * @param {*} isAllAttrQuery
+ * @return {*}
+ */
+export function addSelectedFeatures(viewer, geom, inSR) {
+    var outSR = "EPSG:4326"
+    viewer.entities.removeById("selected_entity");
+    var geomtype = geom.type.toLowerCase();
+    var entity = null;
+    var destination;
+    if (geomtype.indexOf("polygon") > -1) {
+        var points = [];
+        addProjectionTransform(geom.coordinates[0][0], inSR, outSR, true, false, function (e) {
+            let coordinates = e.result
+            for (var i = 0; i < coordinates.length; i++) {
+                var lon = coordinates[i][0];
+                var lat = coordinates[i][1];
+                points.push(lon);
+                points.push(lat);
+            }
+            destination = Cesium.Cartesian3.fromDegreesArray(points);
+            entity = viewer.entities.add({
+                id: 'selected_entity',
+                name: 'selected_entity',
+                polygon: {
+                    hierarchy: destination,
+                    material: Cesium.Color.GREEN.withAlpha(0.7)
+                }
+            });
+            if (entity) {
+                viewer.flyTo(entity, {
+                    offset: {
+                        heading: Cesium.Math.toRadians(0.0),
+                        pitch: Cesium.Math.toRadians(-90),
+                        range: 0
+                    }
+                });
+            }
+        });
+    } else if (geomtype.indexOf("polyline") > -1) {
+        var points = [];
+        addProjectionTransform(geom.coordinates[0][0], inSR, outSR, true, false, function (e) {
+            let coordinates = e.result
+            for (var i = 0; i < coordinates.length; i++) {
+                var lon = coordinates[i][0];
+                var lat = coordinates[i][1];
+                points.push(lon);
+                points.push(lat);
+            }
+            destination = Cesium.Cartesian3.fromDegreesArray(points);
+            entity = viewer.entities.add({
+                id: 'selected_entity',
+                name: 'selected_entity',
+                polyline: {
+                    positions: destination,
+                    material: Cesium.Color.GREEN.withAlpha(0.7)
+                }
+            });
+            if (entity) {
+                viewer.flyTo(entity, {
+                    offset: {
+                        heading: Cesium.Math.toRadians(0.0),
+                        pitch: Cesium.Math.toRadians(-90),
+                        range: 0
+                    }
+                });
+            }
+        })
+    } else if (geomtype.indexOf("point") > -1) {
+        var points = [];
+        addProjectionTransform(geom.coordinates, inSR, outSR, true, false, function (e) {
+            let coordinates = e.result
+            destination = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]);
+            entity = viewer.entities.add({
+                id: 'selected_entity',
+                name: 'selected_entity',
+                position: destination,
+                point: {
+                    color: Cesium.Color.GREEN.withAlpha(0.7),
+                    pixelSize: 10,
+                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+                    outlineColor: Cesium.Color.YELLOW,
+                    outlineWidth: 2,
+                }
+            });
+            if (entity) {
+                viewer.flyTo(entity, {
+                    offset: {
+                        heading: Cesium.Math.toRadians(0.0),
+                        pitch: Cesium.Math.toRadians(-90),
+                        range: 0
+                    }
+                });
+            }
+        })
+    }
+}
+
+/**
+ * 移除xt3d简单标注
+ */
+export function removeSampleLabel() {
+    if (sampleLabel) {
+        sampleLabel.remove()
+        sampleLabel = null;
+    }
+}

+ 285 - 0
src/utils/map/fun/layerScreenshots.js

@@ -0,0 +1,285 @@
+/*
+ * @Descripttion: 地图截屏
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-05 17:49:26
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-10 16:35:08
+ */
+/**
+ * covert canvas to image
+ * and save the image file
+ */
+export function layerScreenshots(viewer) {
+    var canvas = viewer.scene.canvas;
+    var imageWidth = 800;
+    var img = Canvas2Image.convertToImage(canvas, canvas.width, canvas.height, 'png');
+    var loadImg = document.createElement('a')
+    loadImg.href = img.src
+    loadImg.download = 'earth'
+    loadImg.click()
+}
+var Canvas2Image = function () {
+
+    // check if support sth.
+    var $support = function () {
+        var canvas = document.createElement('canvas'),
+            ctx = canvas.getContext('2d');
+
+        return {
+            canvas: !!ctx,
+            imageData: !!ctx.getImageData,
+            dataURL: !!canvas.toDataURL,
+            btoa: !!window.btoa
+        };
+    }();
+
+    var downloadMime = 'image/octet-stream';
+
+    function scaleCanvas(canvas, width, height) {
+        var w = canvas.width,
+            h = canvas.height;
+        if (width == undefined) {
+            width = w;
+        }
+        if (height == undefined) {
+            height = h;
+        }
+
+        var retCanvas = document.createElement('canvas');
+        var retCtx = retCanvas.getContext('2d');
+        retCanvas.width = width;
+        retCanvas.height = height;
+        retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
+        return retCanvas;
+    }
+
+    function getDataURL(canvas, type, width, height) {
+        canvas = scaleCanvas(canvas, width, height);
+        return canvas.toDataURL(type);
+    }
+
+    function saveFile(strData) {
+        document.location.href = strData;
+    }
+
+    function genImage(strData) {
+        var img = document.createElement('img');
+        img.src = strData;
+        return img;
+    }
+
+    function fixType(type) {
+        type = type.toLowerCase().replace(/jpg/i, 'jpeg');
+        var r = type.match(/png|jpeg|bmp|gif/)[0];
+        return 'image/' + r;
+    }
+
+    function encodeData(data) {
+        if (!window.btoa) { throw 'btoa undefined' }
+        var str = '';
+        if (typeof data == 'string') {
+            str = data;
+        } else {
+            for (var i = 0; i < data.length; i++) {
+                str += String.fromCharCode(data[i]);
+            }
+        }
+
+        return btoa(str);
+    }
+
+    function getImageData(canvas) {
+        var w = canvas.width,
+            h = canvas.height;
+        return canvas.getContext('2d').getImageData(0, 0, w, h);
+    }
+
+    function makeURI(strData, type) {
+        return 'data:' + type + ';base64,' + strData;
+    }
+
+
+    /**
+     * create bitmap image
+     * 按照规则生成图片响应头和响应体
+     */
+    var genBitmapImage = function (oData) {
+
+        //
+        // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
+        // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
+        //
+
+        var biWidth = oData.width;
+        var biHeight = oData.height;
+        var biSizeImage = biWidth * biHeight * 3;
+        var bfSize = biSizeImage + 54; // total header size = 54 bytes
+
+        //
+        //  typedef struct tagBITMAPFILEHEADER {
+        //  	WORD bfType;
+        //  	DWORD bfSize;
+        //  	WORD bfReserved1;
+        //  	WORD bfReserved2;
+        //  	DWORD bfOffBits;
+        //  } BITMAPFILEHEADER;
+        //
+        var BITMAPFILEHEADER = [
+            // WORD bfType -- The file type signature; must be "BM"
+            0x42, 0x4D,
+            // DWORD bfSize -- The size, in bytes, of the bitmap file
+            bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
+            // WORD bfReserved1 -- Reserved; must be zero
+            0, 0,
+            // WORD bfReserved2 -- Reserved; must be zero
+            0, 0,
+            // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
+            54, 0, 0, 0
+        ];
+
+        //
+        //  typedef struct tagBITMAPINFOHEADER {
+        //  	DWORD biSize;
+        //  	LONG  biWidth;
+        //  	LONG  biHeight;
+        //  	WORD  biPlanes;
+        //  	WORD  biBitCount;
+        //  	DWORD biCompression;
+        //  	DWORD biSizeImage;
+        //  	LONG  biXPelsPerMeter;
+        //  	LONG  biYPelsPerMeter;
+        //  	DWORD biClrUsed;
+        //  	DWORD biClrImportant;
+        //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
+        //
+        var BITMAPINFOHEADER = [
+            // DWORD biSize -- The number of bytes required by the structure
+            40, 0, 0, 0,
+            // LONG biWidth -- The width of the bitmap, in pixels
+            biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
+            // LONG biHeight -- The height of the bitmap, in pixels
+            biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
+            // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
+            1, 0,
+            // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
+            // has a maximum of 2^24 colors (16777216, Truecolor)
+            24, 0,
+            // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
+            0, 0, 0, 0,
+            // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
+            biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
+            // LONG biXPelsPerMeter, unused
+            0, 0, 0, 0,
+            // LONG biYPelsPerMeter, unused
+            0, 0, 0, 0,
+            // DWORD biClrUsed, the number of color indexes of palette, unused
+            0, 0, 0, 0,
+            // DWORD biClrImportant, unused
+            0, 0, 0, 0
+        ];
+
+        var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
+
+        var aImgData = oData.data;
+
+        var strPixelData = '';
+        var biWidth4 = biWidth << 2;
+        var y = biHeight;
+        var fromCharCode = String.fromCharCode;
+
+        do {
+            var iOffsetY = biWidth4 * (y - 1);
+            var strPixelRow = '';
+            for (var x = 0; x < biWidth; x++) {
+                var iOffsetX = x << 2;
+                strPixelRow += fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
+                    fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
+                    fromCharCode(aImgData[iOffsetY + iOffsetX]);
+            }
+
+            for (var c = 0; c < iPadding; c++) {
+                strPixelRow += String.fromCharCode(0);
+            }
+
+            strPixelData += strPixelRow;
+        } while (--y);
+
+        var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
+
+        return strEncoded;
+    };
+
+    /**
+     * saveAsImage
+     * @param canvasElement
+     * @param {String} image type
+     * @param {Number} [optional] png width
+     * @param {Number} [optional] png height
+     */
+    var saveAsImage = function (canvas, width, height, type) {
+        if ($support.canvas && $support.dataURL) {
+            if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
+            if (type == undefined) { type = 'png'; }
+            type = fixType(type);
+            if (/bmp/.test(type)) {
+                var data = getImageData(scaleCanvas(canvas, width, height));
+                var strData = genBitmapImage(data);
+                saveFile(makeURI(strData, downloadMime));
+            } else {
+                var strData = getDataURL(canvas, type, width, height);
+                saveFile(strData.replace(type, downloadMime));
+            }
+        }
+    };
+
+    var convertToImage = function (canvas, width, height, type) {
+        if ($support.canvas && $support.dataURL) {
+            if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
+            if (type == undefined) { type = 'png'; }
+            type = fixType(type);
+
+            if (/bmp/.test(type)) {
+                var data = getImageData(scaleCanvas(canvas, width, height));
+                var strData = genBitmapImage(data);
+                return genImage(makeURI(strData, 'image/bmp'));
+            } else {
+                var strData = getDataURL(canvas, type, width, height);
+                return genImage(strData);
+            }
+        }
+    };
+
+
+
+    return {
+        saveAsImage: saveAsImage,
+        saveAsPNG: function (canvas, width, height) {
+            return saveAsImage(canvas, width, height, 'png');
+        },
+        saveAsJPEG: function (canvas, width, height) {
+            return saveAsImage(canvas, width, height, 'jpeg');
+        },
+        saveAsGIF: function (canvas, width, height) {
+            return saveAsImage(canvas, width, height, 'gif');
+        },
+        saveAsBMP: function (canvas, width, height) {
+            return saveAsImage(canvas, width, height, 'bmp');
+        },
+
+        convertToImage: convertToImage,
+        convertToPNG: function (canvas, width, height) {
+            return convertToImage(canvas, width, height, 'png');
+        },
+        convertToJPEG: function (canvas, width, height) {
+            return convertToImage(canvas, width, height, 'jpeg');
+        },
+        convertToGIF: function (canvas, width, height) {
+            return convertToImage(canvas, width, height, 'gif');
+        },
+        convertToBMP: function (canvas, width, height) {
+            return convertToImage(canvas, width, height, 'bmp');
+        }
+    };
+
+}();

+ 504 - 0
src/utils/map/layerHelper.js

@@ -0,0 +1,504 @@
+/*
+ * @Descripttion: 
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-07-29 11:20:03
+ * @LastEditors: 郭亚伟 2241880990@qq.com
+ * @LastEditTime: 2022-11-09 14:33:27
+ */
+// import { updateCesiumStore } from '@/utils/updateCesiumStore'
+import * as Cesium from "cesium";
+import { ArcgisService } from "@/utils/menu/map/provider/ArcgisService";
+import { BaiduMapService } from "@/utils/menu/map/provider/BaiduMapService";
+import { GaodeMapService } from "@/utils/menu/map/provider/GaodeMapService";
+import { GeoJsonService } from "@/utils/menu/map/provider/GeoJsonService";
+import { GltfService } from "@/utils/menu/map/provider/GltfService";
+import { GoogleMapService } from "@/utils/menu/map/provider/GoogleMapService";
+import { LGXServer } from "@/utils/menu/map/provider/LGXServer";
+import { LoadJsonServer } from "@/utils/menu/map/provider/LoadJsonServer";
+import { MVTVectorService } from "@/utils/menu/map/provider/MVTVectorService";
+import { NMLWServer } from "@/utils/menu/map/provider/NMLWServer";
+import { ObliqueService } from "@/utils/menu/map/provider/ObliqueService";
+import { OpenJsonService } from "@/utils/menu/map/provider/OpenJsonService";
+import { PoiService } from "@/utils/menu/map/provider/PoiService";
+import { PrimitivePointService } from "@/utils/menu/map/provider/PrimivitePoints";
+import { StreetMapService } from "@/utils/menu/map/provider/StreetMapService";
+import { SWImageMapService } from "@/utils/menu/map/provider/SWImageService";
+import { TemplateMapService } from "@/utils/menu/map/provider/TemplateMapService";
+import { TerrainService } from "@/utils/menu/map/provider/TerrainService";
+import { TiandituMapService } from "@/utils/menu/map/provider/TiandituMapService";
+import { TileArcgisService } from "@/utils/menu/map/provider/TileArcgisService";
+import { TileMongodbService } from "@/utils/menu/map/provider/TileMongodbService";
+import { TileOSMService } from "@/utils/menu/map/provider/TileOSMService";
+import { TileTiandituService } from "@/utils/menu/map/provider/TileTiandituService";
+import { TileWMSService } from "@/utils/menu/map/provider/TileWMSService";
+import { TileWMTSService } from "@/utils/menu/map/provider/TileWMTSService";
+import { TileXYZService } from "@/utils/menu/map/provider/TileXYZService";
+import { VectorService } from "@/utils/menu/map/provider/VectorService";
+import { toRaw } from '@vue/reactivity'
+import store from "@/store";
+
+export const sw_servicetype = {
+    sw_tile: "tile",
+    sw_vector: "vector",
+    sw_terrain: "terrain",
+    sw_oblique: "oblique",
+    sw_gltf: "gltf",
+    sw_poi: "poi",
+    sw_geojson: "geojson",
+    sw_lgx: "lgx",
+    sw_nmlw: "nmlw",
+    sw_nmpoi: "nmpoi",
+    sw_json: "json",
+    sw_jsoninfo: "jsoninfo"
+};
+const sw_servertype = {
+    sw_geoserver: "geoserver",
+    sw_mongodb: "mongodb",
+    sw_iis: "iis",
+    sw_arcgis: "arcgis"
+};
+export const sw_source = {
+    sw_xyz: "xyz",
+    sw_arcgistile: "tilearcgisrest",
+    sw_arcgis: "arcgis",
+    sw_osm: "osm",
+    sw_wms: "tilewms",
+    sw_wmts: "wmts",
+    sw_pbf: "pbftile",
+    sw_mongodb: "mongodb",
+    sw_baidu: "baidu",
+    sw_gaode: "gaode",
+    sw_google: "google",
+    sw_tianditu: "tianditu",
+    sw_template: "template",
+    sw_gdaltile: "gdaltile",
+    sw_streetmap: "streetmap",
+    sw_tianditu_tile: "tianditutile"
+};
+// 配置项
+const sw_source_type = {
+    "0": sw_source.sw_arcgis,
+    "1": sw_source.sw_streetmap,
+    "2": sw_source.sw_tianditu_tile, // 天地图影像注记
+    "4": sw_source.sw_template,
+};
+const sw_service_type = {
+    "9": sw_servicetype.sw_terrain
+}
+// 获取proxy对象中的原始对象
+// let cesium = toRaw(store.state.cesium);
+//地图加载类
+export function LayerHelper(layerInfo, isbasemap, viewer) {
+    var LayerHelper = Object;
+    LayerHelper.layerInfo = layerInfo;
+    LayerHelper.isbasemap = isbasemap;
+    LayerHelper.isLoad = false;
+    LayerHelper.GetLayer = function () {
+        var thisLayerInfo = this.layerInfo;
+        var isLoad = this.isLoad;
+        var id = thisLayerInfo.hasOwnProperty("GUID") ? thisLayerInfo.GUID : "";
+        return window.treeList[id].imageryLayer;
+    }
+    LayerHelper.moveToUp = function () {
+        viewer.imageryLayers.raise(window.treeList[this.layerInfo.GUID].imageryLayer);
+    }
+    LayerHelper.raiseToTop = function () {
+        if (window.treeList[this.layerInfo.GUID].imageryLayer) {
+            viewer.imageryLayers.raiseToTop(window.treeList[this.layerInfo.GUID].imageryLayer);
+        }
+    }
+    LayerHelper.moveToDown = function () {
+        viewer.imageryLayers.lower(window.treeList[this.layerInfo.GUID].imageryLayer);
+    }
+    LayerHelper.lowerToBottom = function () {
+        if (window.treeList[this.layerInfo.GUID].imageryLayer) {
+            viewer.imageryLayers.lowerToBottom(window.treeList[this.layerInfo.GUID].imageryLayer);
+        }
+    }
+    LayerHelper.addLayer = function (visible) {
+        // store.commit('showLoading')
+        // var loading = ElLoading.service({
+        //     // lock: true,
+        //     // text: "加载中",
+        //     // background: "rgba(0, 0, 0, 0.7)",
+        //     background: "transparent",
+        // });
+        try {
+            //#region 获取图层信息
+            var thisLayerInfo = this.layerInfo;
+            var isLoad = this.isLoad;
+            var myLayer = null;
+            var layerCount = 0;
+
+            var id = thisLayerInfo.hasOwnProperty("GUID") ? thisLayerInfo.GUID : "";
+            var layers = viewer.scene.imageryLayers;
+            var primitives = viewer.scene.primitives;
+            if (!window.treeList) {
+                window.treeList = {}
+            }
+            if (!window.treeList[id]) {
+                window.treeList[id] = thisLayerInfo
+                window.treeList[id].imageryLayer = undefined
+            }
+            if (!window.treeList[id].imageryLayer && (typeof (visible) == "undefined" || visible)) {
+                myLayer = createLayer(thisLayerInfo, layerCount);
+                if (myLayer) {
+                    if (this.isbasemap) {
+                        this.lowerToBottom();
+                    }
+                    myLayer.NAME = thisLayerInfo.NAME;
+                    //  cesium.layer3DList[id] = myLayer;
+                    window.treeList[id].imageryLayer = myLayer
+                    isLoad = true;
+                }
+                this.changeLayerTransparent(id, thisLayerInfo)
+            } else if (window.treeList[id].imageryLayer) {
+                if (typeof (visible) != "undefined") {
+                    if (!visible) {
+                        deleteServerTypeMap(id, thisLayerInfo);
+                    }
+                } else {
+                    deleteServerTypeMap(id, thisLayerInfo);
+                }
+            }
+            this.isload = isLoad;
+            // loading.close()
+            return myLayer;
+        } catch (error) {
+
+        }
+
+    }
+
+    LayerHelper.changeLayerTransparent = function (id, thisLayerInfo, opacity) {
+        if (!opacity && opacity != 0) {
+            opacity = 1
+        }
+        layerTransparent[id] = opacity;
+        var thisLayer = window.treeList[id].imageryLayer;
+        var servicetype = thisLayerInfo.hasOwnProperty("SERVICETYPE") ? thisLayerInfo.SERVICETYPE : "tile"; //图层类型
+        var source = thisLayerInfo.hasOwnProperty("SOURCE") ? thisLayerInfo.SOURCE : "";
+        switch (servicetype) {
+            case sw_servicetype.sw_tile: //切片
+                {
+                    switch (source) {
+                        case sw_source.sw_xyz:
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_arcgis:
+                        case sw_source.sw_arcgistile:
+                            //arcgisserver-Arcgis切片服务处理
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_osm:
+                            // osm开源世界地图(OpenStreetMap)服务处理
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_wms:
+                            //wms网络地图服务处理
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_wmts:
+                            //wmts-web地图瓦片服务处理
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_pbf:
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_mongodb:
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_baidu:
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_gaode:
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_google:
+                            //mongodb自定义服务处理
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_tianditu:
+                            //mongodb自定义服务处理
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_template:
+                            thisLayer.alpha = opacity;
+                            break;
+                        case sw_source.sw_gdaltile:
+                            thisLayer.alpha = opacity;
+                            break;
+                        default:
+                            break;
+                    }
+                    break;
+                }
+            case sw_servicetype.sw_terrain: //地形
+                {
+                    //viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider({});
+                    console.log("地形不支持透明度调整!");
+                    break;
+                }
+            case sw_servicetype.sw_oblique: //倾斜模型
+                {
+                    thisLayer.style = new Cesium.Cesium3DTileStyle({
+                        color: "color('rgba(255,255,255," + opacity + ")')",
+                    });
+                    break;
+                }
+            case sw_servicetype.sw_gltf: //倾斜模型
+                {
+                    thisLayer.style = new Cesium.Cesium3DTileStyle({
+                        color: "color('rgba(255,255,255," + opacity + ")')",
+                    });
+                    break;
+                }
+            case "undefined":
+                break;
+            default:
+                break;
+        }
+
+    }
+
+    function createLayer(myLayerInfo, layerIndex) {
+        var layerType = 3;
+        var thisLayer = null;
+        var thisService = null;
+        //属性
+        var servicetype = myLayerInfo.hasOwnProperty("SERVICETYPE") ? myLayerInfo.SERVICETYPE : "tile"; //图层类型
+        var source = myLayerInfo.hasOwnProperty("SOURCE") ? myLayerInfo.SOURCE : "";
+        var status = myLayerInfo.hasOwnProperty("STATUS") ? myLayerInfo.STATUS : "";
+
+        var source_type = myLayerInfo.hasOwnProperty("type") ? myLayerInfo.type : "";
+        if (!source && (source_type == 0 || source_type)) {
+            if (sw_source_type[source_type]) {
+                source = sw_source_type[source_type]
+            } else {
+                servicetype = sw_service_type[source_type]
+            }
+        }
+        var isOrder = true;
+
+        var sw_status = {
+            sw_online: "online",
+            sw_offline: "offline"
+        };
+        switch (servicetype) {
+            case sw_servicetype.sw_tile: //切片
+                //#region 根据不同数据源进行加载设置
+                switch (source) {
+                    case sw_source.sw_xyz:
+                        //xyz-谷歌/高德服务处理
+                        if (status == sw_status.sw_online) {
+                            thisService = new TileXYZService(myLayerInfo);
+                        } else if (status == sw_status.sw_offline) {
+
+                        }
+                        break;
+                    case sw_source.sw_arcgis:
+                        //arcgisserver-Arcgis切片服务处理
+                        thisService = new ArcgisService(myLayerInfo);
+                        break;
+                    case sw_source.sw_arcgistile:
+                        //arcgisserver-Arcgis切片服务处理
+                        thisService = new TileArcgisService(myLayerInfo);
+                        break;
+                    case sw_source.sw_osm:
+                        // osm开源世界地图(OpenStreetMap)服务处理
+                        thisService = new TileOSMService(myLayerInfo);
+                        break;
+                    case sw_source.sw_wms:
+                        //wms网络地图服务处理
+                        thisService = new TileWMSService(myLayerInfo);
+                        break;
+                    case sw_source.sw_wmts:
+                        //wmts-web地图瓦片服务处理
+                        thisService = new TileWMTSService(myLayerInfo);
+                        break;
+                    case sw_source.sw_pbf:
+                        //pbf矢量切片服务处理
+                        thisService = new MVTVectorService(myLayerInfo);
+                        break;
+                    case sw_source.sw_mongodb:
+                        //mongodb自定义服务处理
+                        thisService = new TileMongodbService(myLayerInfo);
+                        break;
+                    case sw_source.sw_baidu:
+                        //百度服务处理
+                        thisService = new BaiduMapService(myLayerInfo);
+                        break;
+                    case sw_source.sw_gaode:
+                        //高德服务处理
+                        thisService = new GaodeMapService(myLayerInfo);
+                        break;
+                    case sw_source.sw_google:
+                        //谷歌服务处理
+                        thisService = new GoogleMapService(myLayerInfo);
+                        break;
+                    case sw_source.sw_tianditu:
+                        //天地图服务处理
+                        thisService = new TiandituMapService(myLayerInfo);
+                        break;
+                    case sw_source.sw_template:
+                        //模板服务处理
+                        thisService = new TemplateMapService(myLayerInfo);
+                        break;
+                    case sw_source.sw_gdaltile:
+                        //gdal
+                        thisService = new SWImageMapService(myLayerInfo);
+                    case sw_source.sw_streetmap:
+                        thisService = new StreetMapService(myLayerInfo);
+                    case sw_source.sw_tianditu_tile:
+                        thisService = new TileTiandituService(myLayerInfo);
+                    default:
+                        break;
+                }
+                break;
+            case sw_servicetype.sw_vector: //矢量
+                thisService = new VectorService(myLayerInfo);
+                break;
+            case sw_servicetype.sw_terrain: //地形
+                thisService = new TerrainService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_oblique: //倾斜
+                thisService = new ObliqueService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_gltf: //gltf
+                thisService = new GltfService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_poi: //poi
+                thisService = new PoiService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_geojson://geojson
+                thisService = new GeoJsonService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_lgx://lgx
+                thisService = new LGXServer(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_nmlw://路网
+                thisService = new NMLWServer(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_nmpoi://兴趣点json
+                thisService = new PrimitivePointService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_json://json
+                thisService = new OpenJsonService(myLayerInfo);
+                isOrder = false;
+                break;
+            case sw_servicetype.sw_jsoninfo://jsoninfo
+                thisService = new LoadJsonServer(myLayerInfo);
+                isOrder = false;
+                break;
+        }
+        if (thisService != null) {
+            thisLayer = thisService.CreateLayer(viewer);
+        }
+
+        //对图层类型进行绑定
+        thisLayer = thisLayer || {};
+        if (myLayerInfo) {
+            thisLayer["NAME"] = myLayerInfo["ALIAS"];
+            thisLayer["URL"] = myLayerInfo["URL"];
+        }
+        thisLayer["SERVICETYPE"] = servicetype;
+        thisLayer["SOURCE"] = source;
+        thisLayer["GLOBALVISIBLE"] = true;
+        return thisLayer;
+    }
+    // /**
+    //  * 删除指定ID的图层
+    //  */
+    function deleteServerTypeMap(id, layerInfo) {
+        var servicetype = layerInfo.hasOwnProperty("SERVICETYPE") ? layerInfo.SERVICETYPE : "tile"; //图层类型
+        var source = layerInfo.hasOwnProperty("SOURCE") ? layerInfo.SOURCE : "";
+        var imageryLayer = window.treeList[id].imageryLayer
+        switch (servicetype) {
+            case sw_servicetype.sw_tile: //切片
+                {
+                    viewer.scene.imageryLayers.remove(imageryLayer);
+                    // window.treeList[id].imageryLayer = null
+
+                    break;
+                }
+            case sw_servicetype.sw_terrain: //地形
+                {
+                    viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider({});
+
+                    break;
+                }
+            case sw_servicetype.sw_oblique: //倾斜模型
+                {
+                    window.treeList[id].imageryLayer.show = false;
+                    window.treeList[id].imageryLayer["GLOBALVISIBLE"] = false;
+                    break;
+                }
+            case sw_servicetype.sw_gltf: //gltf
+                window.treeList[id].imageryLayer.show = false;
+                break;
+            case sw_servicetype.sw_poi: //poi
+                if (window.treeList[id].imageryLayer) {
+                    window.treeList[id].imageryLayer.show = false;
+                    return
+                    var entities = window.treeList[id].imageryLayer.entities.values;
+                    for (var i = 0; i < entities.length; i++) {
+                        entities[i].show = false;
+                    }
+                }
+                break;
+            case sw_servicetype.sw_geojson: //geojson
+                if (window.treeList[id].imageryLayer) {
+                    window.treeList[id].imageryLayer.show = false;
+                    return
+                }
+                break;
+            case sw_servicetype.sw_lgx: //lgx
+                // globleStreamerpath.removeprimitive(id);
+
+
+                break;
+            case sw_servicetype.sw_nmlw: //nmlw
+                var entities = window.treeList[id].imageryLayer._entityCollection._entities._array;
+                for (var i = 0; i < entities.length; i++) {
+                    entities[i].show = false;
+                }
+                break;
+            case sw_servicetype.sw_nmpoi: //nmlw
+                window.treeList[id].imageryLayer.SetVisible(false);
+                break;
+            case sw_servicetype.sw_json: //json
+                if (window.treeList[id].imageryLayer) {
+                    window.treeList[id].imageryLayer.SetVisible(false);
+                }
+                break;
+            case sw_servicetype.sw_jsoninfo: //jsoninfo
+                if (window.treeList[id].imageryLayer) {
+                    window.treeList[id].imageryLayer.SetVisible(false);
+                }
+                break;
+            case "undefined":
+                break;
+            default:
+                break;
+        }
+        window.treeList[id].imageryLayer = null
+    }
+    return LayerHelper;
+}
+var layerTransparent = {};
+export function checkLayerTransparent(layer, id, alpha) {
+    if (layerTransparent[id]) {
+        layer.alpha = layerTransparent[id];
+    } else if (alpha) {
+        layer.alpha = alpha;
+    }
+}

+ 38 - 0
src/utils/map/mapRequest.js

@@ -0,0 +1,38 @@
+/*
+ * @Descripttion: 
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-01 17:33:34
+ * @LastEditors: 郭亚伟 2241880990@qq.com
+ * @LastEditTime: 2022-11-09 14:33:58
+ */
+import axios from 'axios';
+
+const service = axios.create({
+    // baseURL: "",
+    withCredentials: true,
+    timeout: 30000
+})
+
+service.interceptors.request.use((config) => {
+    return config
+}, (error) => {
+    console.log(error);
+    return Promise.reject(error);
+})
+
+service.interceptors.response.use((response) => {
+    const res = response.data
+    return res
+    if (res.code !== '200' && res.code !== 200) {
+        console.log(res.message || res.msg || 'Error');
+        return Promise.reject(new Error(res.message || res.msg || 'Error'))
+    } else {
+        return res
+    }
+}, (error) => {
+    console.log('err' + error)
+    return Promise.reject(error)
+})
+
+export default service;

+ 626 - 0
src/utils/map/mapUtils.js

@@ -0,0 +1,626 @@
+/*
+ * @Descripttion: 
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-07-29 11:00:38
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-16 10:19:39
+ */
+import * as Cesium from "cesium";
+import { removeSampleLabel } from "@/utils/map/fun/layerQuery";
+import { GlobeTooltip } from "@/utils/map/drawPlugin/GlobeTooltip";
+import { clearTrack } from "@/utils/map/fun/layerDraw";
+import { ClearOrbitFlightCamera } from "@/utils/map/fly/fly";
+
+let g_tooltip = undefined;
+export function setTooltip(viewer) {
+    if (!g_tooltip) {
+        g_tooltip = new GlobeTooltip(viewer.container);
+    }
+    return g_tooltip
+}
+let g_cesium_handler = undefined;
+export function setScreenSpaceEventHandler(viewer) {
+    if (!g_cesium_handler) {
+        g_cesium_handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
+    }
+    return g_cesium_handler
+}
+export function clearScreenSpaceEventHandler() {
+    if (g_cesium_handler) {
+        g_cesium_handler.destroy();
+        g_cesium_handler = undefined;
+    }
+}
+let g_onTickEventRemoveCallback = undefined
+export function controlOnTickEvent(func) {
+    if (!g_onTickEventRemoveCallback && func) {
+        g_onTickEventRemoveCallback = func
+    } else if (g_onTickEventRemoveCallback) {
+        // .onTick.addEventListener返回值是一个移除的回调函数,它可以清除onTickCallback事件
+        g_onTickEventRemoveCallback();
+        g_onTickEventRemoveCallback = undefined
+    }
+}
+
+//将鼠标的二维坐标转换为对应椭球体三维坐标
+export function getPickPositionGlobe(position, viewer) {
+    var cartesian = null;
+    if (viewer.scene.globe.depthTestAgainstTerrain) {
+        //cartesian = viewer.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid);
+        cartesian = viewer.scene.pickPosition(position);
+    } else {
+        var ray = viewer.camera.getPickRay(position);
+        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
+    }
+    return cartesian;
+}
+/**
+ * 实时获取鼠标所在位置
+ * @param {*} ele
+ * @return {*}
+ */
+export function getMousePosition(ele, viewer) {
+    ele.style.display = "block";
+    //得到当前三维场景
+    var scene = viewer.scene;
+    //得到当前三维场景的椭球体
+    var ellipsoid = scene.globe.ellipsoid;
+
+    var longitudeString = null;
+    var latitudeString = null;
+    var elevationHeight = null;
+    var height = null;
+    var cartesian = null;
+    // 定义当前场景的画布元素的事件处理
+    var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+    //设置鼠标移动事件的处理函数,这里负责监听x,y坐标值变化
+    handler.setInputAction(function (movement) {
+        //通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
+        //cartesian = viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);
+        cartesian = getPickPositionGlobe(movement.endPosition, viewer);
+        if (cartesian) {
+            //将笛卡尔坐标转换为地理坐标
+            var cartographic =
+                ellipsoid.cartesianToCartographic(cartesian);
+            //将弧度转为度的十进制度表示
+            longitudeString = Cesium.Math.toDegrees(
+                cartographic.longitude
+            );
+            latitudeString = Cesium.Math.toDegrees(
+                cartographic.latitude
+            );
+            //获取相机高度
+            height = Math.ceil(
+                viewer.camera.positionCartographic.height
+            );
+            //海拔高度
+            elevationHeight = viewer.scene.globe.getHeight(cartographic)
+                ? viewer.scene.globe.getHeight(cartographic).toFixed(2)
+                : 0;
+
+            longitudeString = longitudeString.toFixed(6);
+            latitudeString = latitudeString.toFixed(6);
+            ele.innerHTML = `经度:${longitudeString}, 纬度:${latitudeString},视角高度:${height}米,海拔高度:${elevationHeight}米`;
+        }
+    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+    //设置鼠标滚动事件的处理函数,这里负责监听高度值变化
+    handler.setInputAction(function (wheelment) {
+        height = Math.ceil(viewer.camera.positionCartographic.height);
+        ele.innerHTML = `经度:${longitudeString}, 纬度:${latitudeString},视角高度:${height}米,海拔高度:${elevationHeight}米`;
+    }, Cesium.ScreenSpaceEventType.WHEEL);
+}
+/**
+ * 隐藏鼠标位置
+ * @param {*} ele
+ * @return {*}
+ */
+export function removeMousePosition(ele) {
+    ele.style.display = "none";
+}
+/**
+ * Cesium缩放最低高度设置
+ * @return {*}
+ */
+export function forbidDown(viewer) {
+    var scene = viewer.scene;
+    var canvas = viewer.canvas;
+    var camera = viewer.camera;
+    scene.screenSpaceCameraController.minimumZoomDistance = 0; //距离地形的距离?这个值可以多测试几个值,,我这不太好描述
+    viewer.clock.onTick.addEventListener(function () {
+        setMinCamera();
+    });
+    var setMinCamera = function () {
+        if (camera.pitch > 0) {
+            scene.screenSpaceCameraController.enableTilt = false;
+        }
+    };
+    var startMousePosition;
+    var mousePosition;
+    var handler = new Cesium.ScreenSpaceEventHandler(canvas);
+    handler.setInputAction(function (movement) {
+        mousePosition = startMousePosition = Cesium.Cartesian3.clone(
+            movement.position
+        );
+        handler.setInputAction(function (movement) {
+            mousePosition = movement.endPosition;
+            var y = mousePosition.y - startMousePosition.y;
+            if (y > 0) {
+                scene.screenSpaceCameraController.enableTilt = true;
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    }, Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
+}
+export function RemoveAllLayers(viewer) {
+    // 清空所有实体
+    removeAllEntities(viewer);
+    // 移除点选、框选鼠标监听
+    // identifyClear();
+    clearScreenSpaceEventHandler();
+    // 移除xt3d简单标注
+    removeSampleLabel();
+    // 移除绑定在viewer实例上Cesium鼠标事件
+    removeMouseAction(viewer)
+    // 清除绘制
+    clearTrack(viewer)
+    // 清除绕点飞行监听
+    ClearOrbitFlightCamera(viewer)
+    // 移除雨雪雾
+    viewer.scene.postProcessStages.removeAll();
+    // 恢复地形夸张
+    if (viewer.scene.terrainExaggeration != 1) {
+        viewer.scene.terrainExaggeration = 1;
+        viewer.scene.globe.terrainExaggeration = 1;
+    }
+    // 恢复场景颜色控制
+    restorColorSetting(viewer);
+    // 清空onTick监听
+    controlOnTickEvent();
+    // 清除等高线
+    viewer.scene.globe.material = undefined;
+}
+// 清空所有实体
+export function removeAllEntities(viewer) {
+    for (var i = 0; i < viewer.entities.values.length;) {
+        var entityId = viewer.entities.values[i].id;
+        if (entityId && (entityId.indexOf("video_entity_") > -1 || entityId.indexOf("story_") > -1)) {
+            i++;
+        } else {
+            viewer.entities.remove(viewer.entities.values[i]);
+        }
+    }
+}
+// 一键移除Cesium鼠标事件(在viewer实例上)
+export function removeMouseAction(viewer) {
+    viewer.screenSpaceEventHandler.removeInputAction(
+        Cesium.ScreenSpaceEventType.LEFT_CLICK
+    );
+    viewer.screenSpaceEventHandler.removeInputAction(
+        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
+    );
+    viewer.screenSpaceEventHandler.removeInputAction(
+        Cesium.ScreenSpaceEventType.MOUSE_MOVE
+    );
+    viewer.screenSpaceEventHandler.removeInputAction(
+        Cesium.ScreenSpaceEventType.RIGHT_CLICK
+    );
+}
+//获取视图范围
+export function GetViewExtent(viewer) {
+    var extent = {};
+    var scene = viewer.scene;
+    var ellipsoid = scene.globe.ellipsoid;
+    var canvas = scene.canvas;
+
+    var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid); // canvas左上角
+    var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid); // canvas右下角
+
+    // 当canvas左上角和右下角全部在椭球体上
+    if (car3_lt && car3_rb) {
+        var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);
+        var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);
+        extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);
+        extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);
+        extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);
+        extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);
+    } else if (!car3_lt && car3_rb) { // 当canvas左上角不在但右下角在椭球体上
+        var car3_lt2 = null;
+        var yIndex = 0;
+        var xIndex = 0;
+        do {
+            // 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
+            yIndex <= canvas.height ? yIndex += 10 : canvas.height;
+            xIndex <= canvas.width ? xIndex += 10 : canvas.width;
+            car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(xIndex, yIndex), ellipsoid);
+        } while (!car3_lt2);
+        var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
+        var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);
+        extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
+        extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
+        extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
+        extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
+    } else if (car3_lt && !car3_rb) { // 当canvas左上角在但右下角不在椭球体上
+        var car3_rb2 = null;
+        var yIndex = canvas.height;
+        var xIndex = canvas.width;
+        do {
+            // 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
+            yIndex >= 10 ? yIndex -= 10 : 10;
+            xIndex >= 10 ? xIndex -= 10 : 10;
+            car3_rb2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(yIndex, yIndex), ellipsoid);
+        } while (!car3_rb2);
+        var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt);
+        var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb2);
+        extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
+        extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
+        extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
+        extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
+    } else if (!car3_lt && !car3_rb) {
+        var car3_lt2 = null;
+        var yIndex = 0;
+        var xIndex = 0;
+        do {
+            // 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
+            yIndex <= canvas.height ? yIndex += 10 : canvas.height;
+            xIndex <= canvas.width ? xIndex += 10 : canvas.width;
+            car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(xIndex, yIndex), ellipsoid);
+        } while (!car3_lt2);
+
+        var car3_rb2 = null;
+        var yIndex = canvas.height;
+        var xIndex = canvas.width;
+        do {
+            // 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
+            yIndex >= 10 ? yIndex -= 10 : 10;
+            xIndex >= 10 ? xIndex -= 10 : 10;
+            car3_rb2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(yIndex, yIndex), ellipsoid);
+        } while (!car3_rb2);
+
+        var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
+        var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb2);
+        extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
+        extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
+        extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
+        extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
+    }
+
+    // 获取高度
+    //extent.height = Math.ceil(viewer.camera.positionCartographic.height);
+    return [extent.xmin, extent.ymin, extent.xmax, extent.ymax];
+}
+
+/**
+ * @Desc: 将数据转换为Geojson格式
+ * @Author: 牛夏蕊
+ * @Date: 2022-08-01 17:16:24
+ * @param {*} data 源数据
+ * @param {*} type 源数据类型 arcgis
+ * @return {*}
+ */
+export function handleToGeojson(data, type) {
+    var geojson = {
+        "type": "FeatureCollection",
+        "features": []
+    };
+    if (!data) {
+        return geojson;
+    }
+    type = type ? type : "arcgis";
+    switch (type) {
+        case "arcgis":
+            for (var i = 0; i < data.length; i++) {
+                var param = data[i];
+                var arcgis = {
+                    displayFieldName: "",
+                    fieldAliases: {},
+                    fields: [],
+                    features: [param],
+                    geometryType: param.geometryType,
+                    spatialReference: param.geometry.spatialReference
+                }
+                if (param.geometryType == "esriGeometryPolygon" || param.geometry.rings) {
+                    geojson.features.push({
+                        "type": "Feature",
+                        "geometry": {
+                            "type": "Polygon",
+                            "coordinates": [param.geometry.rings]
+                        },
+                        "properties": param.attributes,
+                        "arcgis": arcgis
+                    });
+                } else if (param.geometryType == "esriGeometryPolyline" || param.geometry.path || param.geometry.paths) {
+                    geojson.features.push({
+                        "type": "Feature",
+                        "geometry": {
+                            "type": "Polyline",
+                            "coordinates": [param.geometry.path || param.geometry.paths]
+                        },
+                        "properties": param.attributes,
+                        "arcgis": arcgis
+                    });
+                } else if (param.geometryType == "esriGeometryPoint" || param.geometry.x) {
+                    geojson.features.push({
+                        "type": "Feature",
+                        "geometry": {
+                            "type": "Point",
+                            "coordinates": [param.geometry.x, param.geometry.y]
+                        },
+                        "properties": param.attributes,
+                        "arcgis": arcgis
+                    });
+                }
+            }
+            break;
+        default:
+            break;
+    }
+    return geojson;
+}
+
+/**
+ * 采集高度
+ * @param {*} cartesians:笛卡尔坐标组成的数组
+ * @param {*} type:
+ * @returns 采集结果:笛卡尔坐标组成的数组
+ */
+export function getHeightByType(positions, type) {
+    if (type === 'model') {
+        return new Promise(async resolve => {
+            try {
+                let promise = viewer.scene.clampToHeightMostDetailed(cartesians)
+                promise.then(updatedCartesians => resolve(updatedCartesians))
+            } catch (e) {
+                resolve(false)
+            }
+        })
+    } else if (type = 'terrain') {
+        let terrain = viewer.terrainProvider
+        return new Promise(async resolve => {
+            try {
+                // 当前场景中没有使用地形
+                if (!terrain) resolve(false)
+                let promise = Cesium.sampleTerrain(terrain, 15, positions);
+                promise.then(function (updatedPositions) {
+                    resolve(updatedPositions)
+                });
+            } catch (e) {
+                resolve(false)
+            }
+        })
+    }
+}
+/**
+ * 根据四至坐标进行视图缩放
+ * @param minx
+ * @param miny
+ * @param maxx
+ * @param maxy
+ */
+export function flyByRectangle(params) {
+    // var minx = params["MINX"];
+    // var miny = params["MINY"];
+    // var maxx = params["MAXX"];
+    // var maxy = params["MAXY"];
+    // if(minx && miny && maxx && maxy){
+    //     var rectangle = new Cesium.Rectangle.fromDegrees(minx, miny, maxx, maxy);
+    //     viewer.camera.flyTo({
+    //         destination: rectangle,
+    //         duration: 3,
+    //         //获取canvas截图
+    //         // complete: function (e){
+    //         //     var canvas = viewer.scene.canvas;
+    //         //     var mapURL = canvas.toDataURL("image/png");
+    //         //     overlayVectorFeatureDataURL[params.name] = mapURL.substring(22);
+    //         // }
+    //     });
+    // }
+
+    //2022/3/28 迁移鄂尔多斯方法
+    var minx = params["MINX"];
+    var miny = params["MINY"];
+    var maxx = params["MAXX"];
+    var maxy = params["MAXY"];
+    var isLoadTerrain = false
+    //判断一下是否已加载了地形数据
+    for (var attr in cesium.layer3DList) {
+        var layerItem = cesium.layer3DList[attr];
+        if (layerItem["NAME"] && layerItem["SERVICETYPE"] == sw_servicetype.sw_terrain && layerItem["SOURCE"] == sw_source.sw_mongodb) {
+            isLoadTerrain = true
+        }
+    }
+
+    if (minx && miny && maxx && maxy) {
+        //如果已经加载了地形数据,需要通过terrainProvider获取高程数据
+        //取出面的8个点坐标,拿点坐标去求高度值
+        var slopelineposition = []
+        slopelineposition.push(Cesium.Cartographic.fromDegrees(minx, miny));
+        slopelineposition.push(Cesium.Cartographic.fromDegrees(maxx, maxy));
+        slopelineposition.push(Cesium.Cartographic.fromDegrees(minx, maxy));
+        slopelineposition.push(Cesium.Cartographic.fromDegrees(maxx, miny));
+        if (true) {
+            var terrainProvider = viewer.terrainProvider;
+            var promise = Cesium.sampleTerrain(terrainProvider, 15, slopelineposition);
+            Cesium.when(promise,
+                function (updatedPositions) {
+                    var rect = Cesium.Rectangle.fromCartesianArray(Cesium.Cartesian3.fromDegreesArrayHeights(
+                        [minx, miny, updatedPositions[0].height,
+                            maxx, maxy, updatedPositions[1].height,
+                            minx, maxy, updatedPositions[2].height,
+                            maxx, miny, updatedPositions[3].height
+                        ]))
+                    loactionTectEntity = viewer.entities.add({
+                        name: 'locationRectangle',
+                        // id: 'locationRectangle',
+                        rectangle: {
+                            coordinates: rect,
+                            material: Cesium.Color.BLUE.withAlpha(0),
+                            height: updatedPositions[0].height,
+                            outline: false
+                        }
+                    });
+                    var flyPromise = viewer.flyTo(loactionTectEntity, {
+                        duration: 3,
+                        offset: new Cesium.HeadingPitchRange(0.0, Cesium.Math.toRadians(-90.0))
+                    });
+
+                    flyPromise.then(function () {
+                        setPitch();
+                    });
+
+                    function setPitch() {
+                        var center = Cesium.Rectangle.center(rect);
+                        var car = Cesium.Cartesian3.fromRadians(center.longitude, center.latitude);
+                        var range = Cesium.Cartesian3.distance(car, viewer.camera.position) * Math.cos(20);
+                    }
+                })
+        } else {
+            var cartesian3List = [];
+            var cartesian3 = Cesium.Cartesian3.fromDegrees(minx, miny, 500000);
+            cartesian3List.push(cartesian3);
+            var cartesian32 = Cesium.Cartesian3.fromDegrees(maxx, maxy, 500000);
+            cartesian3List.push(cartesian32);
+            var rectangle = Cesium.Rectangle.fromCartesianArray(cartesian3List);
+            viewer.camera.flyTo({
+                destination: rectangle,
+                duration: 3
+            });
+        }
+    }
+}
+
+/**
+ * 返回uuid
+ */
+export function getUUID() {
+    var s = [];
+    var hexDigits = "0123456789abcdef";
+    for (var i = 0; i < 36; i++) {
+        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
+    }
+    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
+    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
+    s[8] = s[13] = s[18] = s[23] = "-";
+
+    var uuid = s.join("");
+    return uuid;
+}
+// 恢复场景颜色设置
+export function restorColorSetting(viewer) {
+    for (
+        let i = 1;
+        i < viewer.imageryLayers.length;
+        i++
+    ) {
+        let layer = viewer.imageryLayers.get(i);
+        if (layer) {
+            layer.brightness = 1;
+            layer.contrast = 1;
+            layer.hue = 0;
+            layer.saturation = 1;
+            layer.gamma = 1;
+        }
+    }
+}
+//镜头拉近 放大
+export function zoomInViewer(viewer) {
+    // 获取当前镜头位置的笛卡尔坐标
+    let cameraPos = viewer.camera.position;
+    // 获取当前坐标系标准
+    let ellipsoid = viewer.scene.globe.ellipsoid;
+    // 根据坐标系标准,将笛卡尔坐标转换为地理坐标
+    let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
+    // 获取镜头的高度
+    let height = cartographic.height;
+    // 根据上面当前镜头的位置,获取该中心位置的经纬度坐标
+    let centerLon = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(8));
+    let centerLat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(8));
+    viewer.camera.flyTo({
+        destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, height / 1.8),
+        duration: 1.0,
+        orientation: {
+            heading: viewer.camera.heading,
+            pitch: viewer.camera.pitch,
+            roll: viewer.camera.roll
+        }
+    });
+}
+
+//镜头拉远 缩小
+export function zoomOutViewer(viewer) {
+    // 获取当前镜头位置的笛卡尔坐标
+    let cameraPos = viewer.camera.position;
+    // 获取当前坐标系标准
+    let ellipsoid = viewer.scene.globe.ellipsoid;
+    // 根据坐标系标准,将笛卡尔坐标转换为地理坐标
+    let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
+    // 获取镜头的高度
+    let height = cartographic.height;
+    // 根据上面当前镜头的位置,获取该中心位置的经纬度坐标
+    let centerLon = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(8));
+    let centerLat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(8));
+    viewer.camera.flyTo({
+        destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, height * 1.8),
+        duration: 1.0,
+        orientation: {
+            heading: viewer.camera.heading,
+            pitch: viewer.camera.pitch,
+            roll: viewer.camera.roll
+        }
+    });
+}
+/**
+ * 设置罗盘显示及位置
+ * @param params
+ *      top  number
+ *      left number
+ *      size number
+ */
+export function setCompassPosition(viewer, params) {
+    if (typeof (params) == "string") {
+        params = JSON.parse(params);
+    }
+    var options = {};
+    options.enableCompass = true; //罗盘
+    options.enableZoomControls = false; //缩放
+    options.enableDistanceLegend = false; //比例尺
+    options.enableCompassOuterRing = true; //指南针外环
+    viewer.extend(Cesium.viewerCesiumNavigationMixin, options);
+    var left = parseFloat(params.left);
+    var top = parseFloat(params.top);
+    var size = parseFloat(params.size);
+    $(".navigation-controls").hide();
+    $(".compass").animate({
+        top: top + "px",
+        left: left + "px"
+    });
+    if (size) {
+        //调整主面板大小
+        $(".compass, .compass-outer-ring").css("width", size + "px");//主单元块
+        $(".compass, .compass-outer-ring").css("fill", "#156BC0");//主单元块
+        $(".compass, .compass-outer-ring").css("height", size + "px");//主单元块
+
+        $(".compass").css("line-height", size + "px");
+        $(".compass").css("text-align", "center");
+
+        $(".compass-gyro").css("width", size + "px") //主单元内嵌块
+        $(".compass-gyro").css("height", size + "px") //主单元内嵌块
+
+        $(".compass-rotation-marker").css("width", size + "px") //主单元内嵌块
+        $(".compass-rotation-marker").css("height", size + "px") //主单元内嵌块
+
+        $(".compass-outer-ring-background").css("position", "relative") // 蓝色背景圈
+        $(".compass-outer-ring-background").css("display", "none") // 蓝色背景圈
+        $(".compass-outer-ring-background").css("width", (44 * (size / 95)) + "px") // 蓝色背景圈
+        $(".compass-outer-ring-background").css("height", (44 * (size / 95)) + "px") // 蓝色背景圈
+        $(".compass-outer-ring-background").css("left", "0px") // 蓝色背景圈
+        $(".compass-outer-ring-background").css("top", (14 * (size / 44) / 2 + 5) + "px") // 蓝色背景圈
+
+
+        $(".compass-gyro-background").css("width", (33 * (size / 95)) + "px") // 蓝色背景圈
+        $(".compass-gyro-background").css("height", (33 * (size / 95)) + "px") // 蓝色背景圈
+        $(".compass-gyro-background").css("left", (30 * (size / 95)) + "px") // 蓝色背景圈
+        $(".compass-gyro-background").css("top", (30 * (size / 95)) + "px") // 蓝色背景圈
+        $(".compass-gyro-background").css("border-radius", "50px") // 蓝色背景圈
+    }
+}

+ 43 - 0
src/utils/map/provider/ArcgisService.js

@@ -0,0 +1,43 @@
+/*
+ * @Descripttion: 
+ * @version: 
+ * @Author: 牛夏蕊
+ * @Date: 2022-07-29 11:23:34
+ * @LastEditors: 牛夏蕊
+ * @LastEditTime: 2022-08-02 09:30:45
+ */
+import * as Cesium from "cesium";
+import { checkLayerTransparent } from "@/utils/map/layerHelper"
+//arcgis服务
+export function ArcgisService(layerInfo) {
+    var ArcgisService = new Object;
+    ArcgisService.id = layerInfo.hasOwnProperty("GUID") ? layerInfo.GUID : "";
+    ArcgisService.url = layerInfo.hasOwnProperty("URL") ? layerInfo.URL : "";
+    ArcgisService.name = layerInfo.hasOwnProperty("NAME") ? layerInfo.NAME : "";
+    ArcgisService.servertype = layerInfo.hasOwnProperty("SERVERTYPE") ? layerInfo.SERVERTYPE : "";
+    ArcgisService.showLayer = (layerInfo.hasOwnProperty("PARAMETERS") && layerInfo.PARAMETERS != "") ? layerInfo.PARAMETERS : layerInfo.ID;
+    ArcgisService.transparent = (layerInfo.hasOwnProperty("transparent") && layerInfo.transparent != "") ? layerInfo.transparent : "";
+    ArcgisService.layerindex = (layerInfo.hasOwnProperty("layerindex") && layerInfo.layerindex != "") ? layerInfo.layerindex : "";
+
+    ArcgisService.CreateLayer = function (viewer) {
+        var id = this.id;
+        var url = this.url;
+        var name = this.name;
+        var servertype = this.servertype;
+        var showLayer = this.showLayer == "" ? "" : "show:" + this.showLayer;
+        var proxyUrl = "";
+        var layers = viewer.imageryLayers;
+        // var layerindex = layers._layers.length;
+
+        var layerindex = (this.layerindex != "" && this.layerindex > layers._layers.length) ? layers._layers.length : layerindex;
+        var transparent = this.transparent;
+
+        var thisLayer = layers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({
+            url: url,
+            enablePickFeatures: false
+        }), layerindex);
+        checkLayerTransparent(thisLayer, id, transparent);
+        return thisLayer;
+    }
+    return ArcgisService;
+}

+ 62 - 0
src/utils/map/provider/BaiduMapService.js

@@ -0,0 +1,62 @@
+//百度服务
+import * as Cesium from "cesium";
+import {checkLayerTransparent} from "@/utils/map/layerHelper"
+
+export function BaiduMapService(layerInfo) {
+    var BaiduMapService = new Object;
+    BaiduMapService.id = layerInfo.hasOwnProperty("GUID") ? layerInfo.GUID : "";
+    BaiduMapService.url = layerInfo.hasOwnProperty("URL") ? layerInfo.URL : "";
+    BaiduMapService.name = layerInfo.hasOwnProperty("NAME") ? layerInfo.NAME : "";
+    BaiduMapService.servertype = layerInfo.hasOwnProperty("SERVERTYPE") ? layerInfo.SERVERTYPE : "";
+    BaiduMapService.prj = layerInfo.hasOwnProperty("PRJ") ? layerInfo.PRJ : "EPSG:3857";
+    BaiduMapService.tileGrid = layerInfo.hasOwnProperty("TILEGRID") ? layerInfo.TILEGRID : "EPSG:3857";
+    BaiduMapService.CreateLayer = function (viewer) {
+        var id = this.id;
+        var url = this.url;
+        var name = this.name;
+        var prj = this.prj;
+        var servertype = this.servertype;
+        var tileGrid = this.tileGrid;
+        var baiduSource = new ol.source.TileImage({
+            projection: prj,
+            tileGrid: tileGrid,
+            tileUrlFunction: function (tileCoord, pixelRatio, proj) {
+                var z = tileCoord[0];
+                var x = tileCoord[1];
+                var y = tileCoord[2];
+                // 百度瓦片服务url将负数使用M前缀来标识
+                if (x < 0) {
+                    x = 'M' + (-x);
+                }
+                if (y < 0) {
+                    y = 'M' + (-y);
+                }
+                return url + "x=" + x + "&y=" + y + "&z=" + z;
+            },
+            wrapX: false
+        });
+        baiduSource.set("id", id, true);
+        var thisLayer = new ol.layer.Tile({
+            source: baiduSource,
+            name: name
+        });
+        return thisLayer;
+    }
+    function getDefaultTileGrid() {
+        //百度地图
+        // 自定义分辨率和瓦片坐标系
+        var resolutions = [];
+        var maxZoom = 18;
+
+        // 计算百度使用的分辨率
+        for (var i = 0; i <= maxZoom; i++) {
+            resolutions[i] = Math.pow(2, maxZoom - i);
+        }
+        var tilegrid = new ol.tilegrid.TileGrid({
+            origin: [0, 0],    // 设置原点坐标
+            resolutions: resolutions    // 设置分辨率
+        });
+        return tilegrid;
+     }
+    return BaiduMapService;
+}

+ 27 - 0
src/utils/map/provider/GaodeMapService.js

@@ -0,0 +1,27 @@
+//高德服务
+import * as Cesium from "cesium";
+import {checkLayerTransparent} from "@/utils/map/layerHelper"
+
+export function GaodeMapService(layerInfo) {
+    var GaodeMapService = new Object;
+    GaodeMapService.id = layerInfo.hasOwnProperty("GUID") ? layerInfo.GUID : "";
+    GaodeMapService.url = layerInfo.hasOwnProperty("URL") ? layerInfo.URL : "";
+    GaodeMapService.name = layerInfo.hasOwnProperty("NAME") ? layerInfo.NAME : "";
+    GaodeMapService.servertype = layerInfo.hasOwnProperty("SERVERTYPE") ? layerInfo.SERVERTYPE : "";
+    GaodeMapService.CreateLayer = function (viewer) {
+        var id = this.id;
+        var url = this.url;
+        var name = this.name;
+        var servertype = this.servertype;
+        var thisLayer = new ol.layer.Tile({
+            source: new ol.source.XYZ({
+                url: url,
+                id: id,
+                wrapX: false
+            }),
+            name: name
+        });
+        return thisLayer;
+    }
+    return GaodeMapService;
+}

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff