diff --git a/.prettierrc b/.prettierrc
index 280006f..06a96f5 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -4,5 +4,6 @@
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
- "bracketSpacing": false
+ "bracketSpacing": false,
+ "printWidth": 120
}
diff --git a/dist.zip b/dist.zip
new file mode 100644
index 0000000..176ed00
Binary files /dev/null and b/dist.zip differ
diff --git a/package-lock.json b/package-lock.json
index b8e02c5..7f4155f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,13 +12,16 @@
"core-js": "^3.8.3",
"echarts": "^5.4.3",
"element-ui": "2.9.2",
+ "file-saver": "^2.0.5",
"gsap": "^3.13.0",
+ "ini-parser": "^0.0.2",
"js-cookie": "2.2.1",
+ "raw-loader": "^4.0.2",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vuex": "^3.6.2",
- "vxe-pc-ui": "^3.9.21",
- "vxe-table": "^3.18.9"
+ "vxe-pc-ui": "~3.9.21",
+ "vxe-table": "~3.18.9"
},
"devDependencies": {
"@babel/core": "^7.12.16",
@@ -1866,7 +1869,6 @@
"version": "0.3.13",
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -1888,7 +1890,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1898,7 +1899,6 @@
"version": "0.3.11",
"resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -1909,14 +1909,12 @@
"version": "1.5.5",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.30",
"resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz",
"integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -2414,7 +2412,6 @@
"version": "8.56.12",
"resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.56.12.tgz",
"integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "*",
@@ -2425,7 +2422,6 @@
"version": "3.7.7",
"resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/eslint": "*",
@@ -2436,7 +2432,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/express": {
@@ -2506,7 +2501,6 @@
"version": "7.0.15",
"resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/mime": {
@@ -2527,7 +2521,6 @@
"version": "24.3.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.3.1.tgz",
"integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.10.0"
@@ -3300,7 +3293,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz",
"integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/helper-numbers": "1.13.2",
@@ -3311,28 +3303,24 @@
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
"integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
- "dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
"integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
"integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
- "dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
"integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.13.2",
@@ -3344,14 +3332,12 @@
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
"integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
- "dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
"integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
@@ -3364,7 +3350,6 @@
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
"integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
@@ -3374,7 +3359,6 @@
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
"integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@xtuc/long": "4.2.2"
@@ -3384,14 +3368,12 @@
"version": "1.13.2",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
"integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
"integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
@@ -3408,7 +3390,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
"integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
@@ -3422,7 +3403,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
"integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
@@ -3435,7 +3415,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
"integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
@@ -3450,7 +3429,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
"integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
@@ -3461,14 +3439,12 @@
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true,
"license": "Apache-2.0"
},
"node_modules/accepts": {
@@ -3499,7 +3475,6 @@
"version": "8.15.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -3512,7 +3487,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
"integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10.13.0"
@@ -3558,7 +3532,6 @@
"version": "6.12.6",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -3575,7 +3548,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
@@ -3593,7 +3565,6 @@
"version": "8.17.1",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -3610,14 +3581,12 @@
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
"license": "MIT"
},
"node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
"license": "MIT",
"peerDependencies": {
"ajv": "^6.9.1"
@@ -3984,7 +3953,6 @@
"version": "5.2.2",
"resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": "*"
@@ -4110,7 +4078,6 @@
"version": "4.25.4",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.25.4.tgz",
"integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4168,7 +4135,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/bytes": {
@@ -4279,7 +4245,6 @@
"version": "1.0.30001741",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz",
"integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4362,7 +4327,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0"
@@ -5616,7 +5580,6 @@
"version": "1.5.215",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.215.tgz",
"integrity": "sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==",
- "dev": true,
"license": "ISC"
},
"node_modules/element-ui": {
@@ -5647,7 +5610,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
@@ -5677,7 +5639,6 @@
"version": "5.18.3",
"resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
"integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
- "dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -5758,7 +5719,6 @@
"version": "1.7.0",
"resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
- "dev": true,
"license": "MIT"
},
"node_modules/es-object-atoms": {
@@ -5778,7 +5738,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5952,7 +5911,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
@@ -6330,7 +6288,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
@@ -6343,7 +6300,6 @@
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -6353,7 +6309,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -6407,7 +6362,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.x"
@@ -6500,7 +6454,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
"license": "MIT"
},
"node_modules/fast-diff": {
@@ -6544,7 +6497,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
"license": "MIT"
},
"node_modules/fast-levenshtein": {
@@ -6558,7 +6510,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz",
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -6620,6 +6571,12 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
+ "license": "MIT"
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
@@ -6960,7 +6917,6 @@
"version": "0.4.1",
"resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "dev": true,
"license": "BSD-2-Clause"
},
"node_modules/globals": {
@@ -7030,7 +6986,6 @@
"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==",
- "dev": true,
"license": "ISC"
},
"node_modules/gsap": {
@@ -7066,7 +7021,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7501,6 +7455,11 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/ini-parser": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmmirror.com/ini-parser/-/ini-parser-0.0.2.tgz",
+ "integrity": "sha512-HwrdoAGH+GGo9bIwZ8dA2zJ7Mofha9JfiaobkY93WSfYfDC8t6kDTRiNkd2Lv2OOCagv8Z0qdkedasHC8pMQdQ=="
+ },
"node_modules/ipaddr.js": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
@@ -7736,7 +7695,6 @@
"version": "27.5.1",
"resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -7751,7 +7709,6 @@
"version": "8.1.1",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -7845,14 +7802,12 @@
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
"license": "MIT"
},
"node_modules/json-stable-stringify-without-jsonify": {
@@ -7866,7 +7821,6 @@
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -7974,7 +7928,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.11.5"
@@ -8354,7 +8307,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true,
"license": "MIT"
},
"node_modules/merge2": {
@@ -8408,7 +8360,6 @@
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -8418,7 +8369,6 @@
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
@@ -8654,7 +8604,6 @@
"version": "2.6.2",
"resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
- "dev": true,
"license": "MIT"
},
"node_modules/nice-try": {
@@ -8718,7 +8667,6 @@
"version": "2.0.20",
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.20.tgz",
"integrity": "sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==",
- "dev": true,
"license": "MIT"
},
"node_modules/normalize-package-data": {
@@ -10181,7 +10129,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -10228,7 +10175,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "^5.1.0"
@@ -10260,6 +10206,58 @@
"node": ">= 0.8"
}
},
+ "node_modules/raw-loader": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/raw-loader/-/raw-loader-4.0.2.tgz",
+ "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
+ "license": "MIT",
+ "dependencies": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/raw-loader/node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "license": "MIT",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/raw-loader/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "license": "MIT",
+ "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/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz",
@@ -10460,7 +10458,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -10590,7 +10587,6 @@
"version": "5.2.1",
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -10809,7 +10805,6 @@
"version": "6.0.2",
"resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
- "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"randombytes": "^2.1.0"
@@ -11151,7 +11146,6 @@
"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==",
- "dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
@@ -11478,7 +11472,6 @@
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.3.tgz",
"integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -11492,7 +11485,6 @@
"version": "5.44.0",
"resolved": "https://registry.npmmirror.com/terser/-/terser-5.44.0.tgz",
"integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -11511,7 +11503,6 @@
"version": "5.3.14",
"resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
"integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.25",
@@ -11546,7 +11537,6 @@
"version": "8.17.1",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -11563,7 +11553,6 @@
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3"
@@ -11576,14 +11565,12 @@
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
"license": "MIT"
},
"node_modules/terser-webpack-plugin/node_modules/schema-utils": {
"version": "4.3.2",
"resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.3.2.tgz",
"integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.9",
@@ -11603,7 +11590,6 @@
"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==",
- "dev": true,
"license": "MIT"
},
"node_modules/text-table": {
@@ -11798,7 +11784,6 @@
"version": "7.10.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.10.0.tgz",
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
- "dev": true,
"license": "MIT"
},
"node_modules/unicode-canonical-property-names-ecmascript": {
@@ -11869,7 +11854,6 @@
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -11900,7 +11884,6 @@
"version": "4.4.1",
"resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
@@ -12208,7 +12191,6 @@
"version": "2.4.4",
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.4.tgz",
"integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"glob-to-regexp": "^0.4.1",
@@ -12249,7 +12231,6 @@
"version": "5.101.3",
"resolved": "https://registry.npmmirror.com/webpack/-/webpack-5.101.3.tgz",
"integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/eslint-scope": "^3.7.7",
@@ -12598,7 +12579,6 @@
"version": "3.3.3",
"resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.3.3.tgz",
"integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10.13.0"
@@ -12615,7 +12595,6 @@
"version": "8.17.1",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -12632,7 +12611,6 @@
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3"
@@ -12645,14 +12623,12 @@
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
"license": "MIT"
},
"node_modules/webpack/node_modules/schema-utils": {
"version": "4.3.2",
"resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.3.2.tgz",
"integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.9",
diff --git a/package.json b/package.json
index 7f9a28f..73c9c6e 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"core-js": "^3.8.3",
"echarts": "^5.4.3",
"element-ui": "2.9.2",
+ "file-saver": "^2.0.5",
"gsap": "^3.13.0",
"ini-parser": "^0.0.2",
"js-cookie": "2.2.1",
diff --git a/config.ini b/public/config.ini
similarity index 100%
rename from config.ini
rename to public/config.ini
diff --git a/src/App.vue b/src/App.vue
index cd5e97f..6e8a6b9 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -17,7 +17,7 @@ export default {
return {
routerMap: {
1: '/',
- 2: '/residentAnalysis',
+ // 2: '/residentAnalysis ',
},
}
},
diff --git a/src/router/index.js b/src/router/index.js
index b99bb3c..5234950 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -6,13 +6,13 @@ import residentAnalysis from '@/views/residentAnalysis/index.vue'
Vue.use(VueRouter)
const routes = [
+ // {
+ // path: '/',
+ // name: 'home',
+ // component: HomeView,
+ // },
{
path: '/',
- name: 'home',
- component: HomeView,
- },
- {
- path: '/residentAnalysis',
name: 'residentAnalysis',
component: residentAnalysis,
},
diff --git a/src/views/header/index.vue b/src/views/header/index.vue
index 58a5b47..abeabec 100644
--- a/src/views/header/index.vue
+++ b/src/views/header/index.vue
@@ -22,8 +22,8 @@ export default {
data() {
return {
tabList: [
- {id: 1, label: '机动路线规划'},
- // {id: 2, label: '临时部署驻地分析'},
+ // {id: 1, label: '机动路线规划'},
+ {id: 1, label: '临时部署驻地分析'},
],
activeIndex: 1,
}
diff --git a/src/views/home.vue b/src/views/home.vue
index d32ca98..5dc51d4 100644
--- a/src/views/home.vue
+++ b/src/views/home.vue
@@ -81,21 +81,12 @@
-
+
导入json文件
隐蔽添加
-
+
@@ -112,12 +103,7 @@
参与路线规划
-
+
@@ -125,10 +111,7 @@
-
+
数据选择
@@ -156,7 +139,7 @@
inputform.minTurnRadius || 0
}},最大车辆载重{{ inputform.load || 0 }}吨
-
+
@@ -165,23 +148,23 @@
-
+
-
- {{ row.area.toFixed(2)}}
+
+ {{ row.area.toFixed(2) }}
-
- {{ (row.vehicles.map(item => item.name)).join(',')}}
+
+ {{ row.vehicles.map((item) => item.name).join(',') }}
-
+
新增
-
+
{{ row.name }}
-
+
{{ row.long }}
-
+
{{ row.width }}
-
+
{{ row.load }}
-
+
{{ row.minTurnRadius }}
-
+
编辑
保存
删除
@@ -248,7 +231,7 @@
import Cookies from 'js-cookie'
import axios from 'axios'
import iniParser from 'ini-parser'
-import configIni from '/config.ini';
+import configIni from '/public/config.ini'
export default {
data() {
@@ -321,7 +304,7 @@ export default {
.catch((error) => {})
},
async initMap() {
- const parsedData = iniParser.parse(configIni);
+ const parsedData = iniParser.parse(configIni)
this.viewer = new window.mars3d.Map(
'map',
{
@@ -356,7 +339,7 @@ export default {
this.shortestPathLayer = new window.mars3d.layer.GraphicLayer()
this.viewer.addLayer(this.shortestPathLayer)
-
+
this.accordFactoryLayer = new window.mars3d.layer.GraphicLayer()
this.viewer.addLayer(this.accordFactoryLayer)
this.loadShapefile() // 拿到路网数据
@@ -450,7 +433,7 @@ export default {
outline: false,
},
})
- this.graphicLayer.addGraphic(graphicLine);
+ this.graphicLayer.addGraphic(graphicLine)
})
this.roadNetworkGeoJSONBuild = this.buildGraph(this.roadNetworkGeoJSON)
this.loadFactoryGeoJson() // 拿到厂房数据
@@ -500,7 +483,7 @@ export default {
this.accordPoint = graphic
try {
// 创建缓冲区的宽度
- const bufferWidth = this.hideform.radius; // 避让区的宽度(单位:米)
+ const bufferWidth = this.hideform.radius // 避让区的宽度(单位:米)
// 获取绘制的点的坐标
const pointCoordinates = [
graphic.toGeoJSON().geometry.coordinates[0],
@@ -514,12 +497,12 @@ export default {
coordinates: pointCoordinates,
},
properties: {},
- };
+ }
// 使用 Turf.js 计算缓冲区
- let buffered = turf.buffer(pointFeature, bufferWidth / 1000, { units: 'kilometers' });
+ let buffered = turf.buffer(pointFeature, bufferWidth / 1000, {units: 'kilometers'})
// 将缓冲区存储到数组中
- this.bufferLayerList.push(buffered);
+ this.bufferLayerList.push(buffered)
const polygon = new window.mars3d.graphic.PolygonEntity({
positions: buffered.geometry.coordinates[0],
style: {
@@ -529,19 +512,19 @@ export default {
outlineWidth: 1,
outlineColor: '#ffffff',
},
- time: new Date().getTime()
+ time: new Date().getTime(),
})
- this.accordFactoryLayer.addGraphic(polygon);
+ this.accordFactoryLayer.addGraphic(polygon)
// 检查缓冲区内的厂房
- this.checkFactoryInBuffer('point', pointCoordinates);
+ this.checkFactoryInBuffer('point', pointCoordinates)
} catch (error) {
- console.error("缓冲区生成或检查异常:", error);
+ console.error('缓冲区生成或检查异常:', error)
}
},
})
},
// 获取当前路线的缓冲区
- hadBuffer () {
+ hadBuffer() {
if (this.shortestPathList.length == 0) {
this.$message.warning('请先进行路线规划')
return
@@ -551,34 +534,34 @@ export default {
return
}
try {
- // =======检查几何对象的类型 缓冲区========
+ // =======检查几何对象的类型 缓冲区========
for (const feature of this.shortestPathList[0]) {
- // this.shortestPathList[0].forEach((feature) => {
- // 创建缓冲区的宽度
- const bufferWidth = this.hideform.radius; // 避让区的宽度(单位:米)
+ // this.shortestPathList[0].forEach((feature) => {
+ // 创建缓冲区的宽度
+ const bufferWidth = this.hideform.radius // 避让区的宽度(单位:米)
if (feature.geometry.type === 'LineString') {
- const positions = feature.geometry.coordinates[0];
+ const positions = feature.geometry.coordinates[0]
// 确保每条线至少有 2 个点
if (positions.length < 2) {
- console.warn('无效的线,跳过:', feature);
- return;
+ console.warn('无效的线,跳过:', feature)
+ return
}
try {
// 使用 Turf.js 计算缓冲区
- var buffered = turf.buffer(feature, bufferWidth / 1000, { units: 'kilometers' });
+ var buffered = turf.buffer(feature, bufferWidth / 1000, {units: 'kilometers'})
// 将缓冲区存储到数组中
- this.bufferLayerList.push(buffered);
+ this.bufferLayerList.push(buffered)
} catch (error) {
- console.error("缓冲分析异常:", error);
+ console.error('缓冲分析异常:', error)
}
} else if (feature.geometry.type === 'MultiLineString') {
// 遍历每个线段
feature.geometry.coordinates.forEach((lineCoordinates) => {
// 检查每个线段是否有效
if (lineCoordinates.length < 2) {
- console.warn('多线段中的无效的线段,跳过:', lineCoordinates);
- return;
+ console.warn('多线段中的无效的线段,跳过:', lineCoordinates)
+ return
}
// 创建单个线段的 GeoJSON 特征
@@ -588,27 +571,27 @@ export default {
type: 'LineString',
coordinates: lineCoordinates,
},
- properties: feature.properties
- };
+ properties: feature.properties,
+ }
try {
// 使用 Turf.js 计算缓冲区
- var buffered = turf.buffer(lineFeature, bufferWidth / 1000, { units: 'kilometers' });
+ var buffered = turf.buffer(lineFeature, bufferWidth / 1000, {units: 'kilometers'})
// 将缓冲区存储到数组中
- this.bufferLayerList.push(buffered);
+ this.bufferLayerList.push(buffered)
} catch (error) {
- console.error("缓冲分析异常:", error);
+ console.error('缓冲分析异常:', error)
}
- });
+ })
} else {
- console.warn('不支持的几何类型:', feature.geometry.type);
+ console.warn('不支持的几何类型:', feature.geometry.type)
}
- }
-
+ }
+
// 去筛选在缓存区的厂房
- this.checkFactoryInBuffer('line');
- }catch (error) {
- console.error("处理路径列表时发生错误:", error);
+ this.checkFactoryInBuffer('line')
+ } catch (error) {
+ console.error('处理路径列表时发生错误:', error)
}
},
checkFactoryInBuffer(type, pointInfo) {
@@ -629,106 +612,106 @@ export default {
// 检查几何对象的类型
if (factory.geometry.type === 'MultiPolygon') {
// 创建多边形集合(MultiPolygon)
- const factoryMultiPoly = turf.multiPolygon(factory.geometry.coordinates);
+ const factoryMultiPoly = turf.multiPolygon(factory.geometry.coordinates)
// 计算整个多边形集合的面积
- const area = turf.area(factoryMultiPoly);
+ const area = turf.area(factoryMultiPoly)
// 计算工厂多边形集合的边界框
- const [minX, minY, maxX, maxY] = turf.bbox(factoryMultiPoly);
+ const [minX, minY, maxX, maxY] = turf.bbox(factoryMultiPoly)
// 筛选与工厂边界框相交的缓冲区
const candidates = this.bufferLayerList.filter((buffer) => {
- const [bminX, bminY, bmaxX, bmaxY] = turf.bbox(buffer);
- return !(bmaxX < minX || bminX > maxX || bmaxY < minY || bminY > maxY);
- });
+ const [bminX, bminY, bmaxX, bmaxY] = turf.bbox(buffer)
+ return !(bmaxX < minX || bminX > maxX || bmaxY < minY || bminY > maxY)
+ })
// 精确相交检测
- let isInside = false;
+ let isInside = false
for (const buffer of candidates) {
if (turf.booleanIntersects(factoryMultiPoly, buffer)) {
// 如果工厂在缓冲区内,绘制所有多边形
- isInside = true;
- this.drawFactory(factory.geometry.coordinates, factory, area, pointInfo);
- break;
+ isInside = true
+ this.drawFactory(factory.geometry.coordinates, factory, area, pointInfo)
+ break
}
}
// 如果工厂不在任何缓冲区内
- resolve();
+ resolve()
} else {
- reject(new Error('不支持的几何类型'));
+ reject(new Error('不支持的几何类型'))
}
})
- });
+ })
// 确保所有工厂处理完成后进行排序
Promise.allSettled(factoryPromises)
.then(async (results) => {
// 只有路线隐蔽规划需要塞入车辆 点的不需要
// 所有工厂处理完成,进行排序 按照距离近到远
- this.accordFactoryInfo.sort((a, b) => a.distance - b.distance);
+ this.accordFactoryInfo.sort((a, b) => a.distance - b.distance)
// 拿到当前的车队车辆信息 并且算出面积 按照从大到小排序
const areaList = JSON.parse(Cookies.get('minTurnRadius'))
areaList.map((item) => {
item.area = Number(item.long) * Number(item.width)
})
- areaList.sort((a, b) => b.area - a.area);
+ areaList.sort((a, b) => b.area - a.area)
// 初始化每个工厂的剩余面积
- this.accordFactoryInfo.forEach(factory => {
- factory.remainingArea = factory.area; // 记录每个工厂的剩余可用面积
- factory.vehicles = []; // 确保每个工厂都有一个 vehicles 属性
- });
+ this.accordFactoryInfo.forEach((factory) => {
+ factory.remainingArea = factory.area // 记录每个工厂的剩余可用面积
+ factory.vehicles = [] // 确保每个工厂都有一个 vehicles 属性
+ })
// 遍历每个车辆,尝试塞入工厂
areaList.forEach((vehicle) => {
- let isPlaced = false;
+ let isPlaced = false
// 遍历每个工厂,尝试塞入车辆
for (let i = 0; i < this.accordFactoryInfo.length; i++) {
- const factory = this.accordFactoryInfo[i];
+ const factory = this.accordFactoryInfo[i]
// 检查工厂是否还有剩余面积
if (factory.remainingArea >= vehicle.area) {
// 塞入车辆
factory.vehicles.push({
...vehicle,
- remainingArea: factory.remainingArea - vehicle.area // 记录车辆塞入后的工厂剩余面积
- });
+ remainingArea: factory.remainingArea - vehicle.area, // 记录车辆塞入后的工厂剩余面积
+ })
// 更新工厂的剩余面积
- factory.remainingArea -= vehicle.area;
+ factory.remainingArea -= vehicle.area
// 标记车辆已放置
- isPlaced = true;
- break;
+ isPlaced = true
+ break
}
}
// 如果车辆没有被放置,可以在这里处理(例如记录日志或显示警告)
if (!isPlaced) {
- console.warn(`车辆 ${vehicle.id} 无法放置在任何工厂中`);
+ console.warn(`车辆 ${vehicle.id} 无法放置在任何工厂中`)
}
- });
+ })
// 更新 this.accordFactoryInfo
- this.accordFactoryInfo = this.accordFactoryInfo.map(factory => {
+ this.accordFactoryInfo = this.accordFactoryInfo.map((factory) => {
// 确保每个工厂都有 vehicles 属性
if (!factory.vehicles) {
- factory.vehicles = [];
+ factory.vehicles = []
}
// 确保 remainingArea 是一个数字且大于 0
- factory.area = factory.area > 0 ? factory.area : 0;
- return factory;
- });
+ factory.area = factory.area > 0 ? factory.area : 0
+ return factory
+ })
// 过滤出有车辆的工厂
- const factoriesWithVehicles = this.accordFactoryInfo.filter(factory => factory.vehicles.length > 0);
+ const factoriesWithVehicles = this.accordFactoryInfo.filter((factory) => factory.vehicles.length > 0)
this.factoriesWithVehicles = factoriesWithVehicles
- await this.showAreaInfoDialog(factoriesWithVehicles);
+ await this.showAreaInfoDialog(factoriesWithVehicles)
})
.catch((error) => {
console.error('数据有问题', error)
- });
+ })
},
drawFactory(factoryMultiPoly, factory, area, pointInfo) {
// 获取当前多边形集合的中心点
- const center = turf.center(turf.multiPolygon(factory.geometry.coordinates));
+ const center = turf.center(turf.multiPolygon(factory.geometry.coordinates))
// 将中心点转换为 Mars3D 的 LngLatPoint 对象
- const popupPosition = new mars3d.LngLatPoint(center.geometry.coordinates[0], center.geometry.coordinates[1]);
+ const popupPosition = new mars3d.LngLatPoint(center.geometry.coordinates[0], center.geometry.coordinates[1])
// 遍历每个多边形集合
factory.geometry.coordinates[0].forEach((coordGroup) => {
// 创建一个多边形图形
@@ -740,35 +723,39 @@ export default {
outline: true,
outlineWidth: 1,
outlineColor: '#ffffff',
- properties: { ...factory.properties },
+ properties: {...factory.properties},
},
- time: new Date().getTime()
+ time: new Date().getTime(),
})
- this.accordFactoryLayer.addGraphic(graphic);
+ this.accordFactoryLayer.addGraphic(graphic)
// 计算多边形中心与参考点的距离
const point = pointInfo && pointInfo.length > 0 ? pointInfo : this.form.endPoint.split(',').map(Number)
- const distance = turf.distance(center.geometry.coordinates, point, { units: 'kilometers' }) * 1000; // 米
+ const distance = turf.distance(center.geometry.coordinates, point, {units: 'kilometers'}) * 1000 // 米
// 将多边形图形添加到地图层
this.accordFactoryInfo.push({
...graphic,
distance: distance,
popupPosition: popupPosition,
- area: this.hideform.redundancy && this.hideform.redundancy != 0 && area > 0
- ? area * (100 - this.hideform.redundancy) * 0.01
- : area > 0
- ? area
- : 0, // 如果 area 不是有效值,设置为 0 或其他默认值
+ area:
+ this.hideform.redundancy && this.hideform.redundancy != 0 && area > 0
+ ? area * (100 - this.hideform.redundancy) * 0.01
+ : area > 0
+ ? area
+ : 0, // 如果 area 不是有效值,设置为 0 或其他默认值
})
})
},
// 显示面积信息弹框的方法
async showAreaInfoDialog(info) {
- const graphics = this.accordFactoryLayer.getGraphics();
- const promises = [];
+ const graphics = this.accordFactoryLayer.getGraphics()
+ const promises = []
info.forEach((item) => {
graphics.forEach((ele) => {
- if (ele.options.time === item.options.time && ele.options.style.properties.FID_1 === item.options.style.properties.FID_1) {
- const textInfo = `${item.area.toFixed(2)}㎡ \n(${item.vehicles.map(e => e.name).join(',')})`
+ if (
+ ele.options.time === item.options.time &&
+ ele.options.style.properties.FID_1 === item.options.style.properties.FID_1
+ ) {
+ const textInfo = `${item.area.toFixed(2)}㎡ \n(${item.vehicles.map((e) => e.name).join(',')})`
const labelGraphic = new window.mars3d.graphic.LabelEntity({
id: 'label',
position: item.popupPosition,
@@ -781,34 +768,34 @@ export default {
outlineColor: '#000000',
background: true,
backgroundColor: '#2f705f',
- }
+ },
})
// 使用 Promise 确保标签添加完成后继续执行
const promise = new Promise((resolve, reject) => {
this.accordFactoryLayer.addGraphic(labelGraphic, () => {
- resolve();
- });
- });
+ resolve()
+ })
+ })
- promises.push(promise);
+ promises.push(promise)
}
})
})
- this.$message.success("路线隐蔽规划成功")
- const popupPositionList = info.map(item => item.popupPosition)
- let minLng = Infinity;
- let maxLng = -Infinity;
- let minLat = Infinity;
- let maxLat = -Infinity;
+ this.$message.success('路线隐蔽规划成功')
+ const popupPositionList = info.map((item) => item.popupPosition)
+ let minLng = Infinity
+ let maxLng = -Infinity
+ let minLat = Infinity
+ let maxLat = -Infinity
- popupPositionList.forEach(point => {
- if (point.lng < minLng) minLng = point.lng;
- if (point.lng > maxLng) maxLng = point.lng;
- if (point.lat < minLat) minLat = point.lat;
- if (point.lat > maxLat) maxLat = point.lat;
- });
+ popupPositionList.forEach((point) => {
+ if (point.lng < minLng) minLng = point.lng
+ if (point.lng > maxLng) maxLng = point.lng
+ if (point.lat < minLat) minLat = point.lat
+ if (point.lat > maxLat) maxLat = point.lat
+ })
// 创建一个矩形区域,包含所有点
- const rectangle = Cesium.Rectangle.fromDegrees(minLng, minLat, maxLng, maxLat);
+ const rectangle = Cesium.Rectangle.fromDegrees(minLng, minLat, maxLng, maxLat)
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
@@ -819,29 +806,29 @@ export default {
orientation: {
heading: Cesium.Math.toRadians(0), // 方位角
pitch: Cesium.Math.toRadians(-90), // 俯仰角
- roll: 0.0 // 翻滚角
+ roll: 0.0, // 翻滚角
},
- duration: 2 // 飞行动画持续时间,单位为秒
- });
+ duration: 2, // 飞行动画持续时间,单位为秒
+ })
},
// 弹框
async openDialog() {
this.multipleSelection = []
await fetch('./data/minTurnRadius.json')
- .then((response) => {
- return response.json()
- })
- .then(async (data) => {
- this.dialogVisible = true;
- this.tableData = data
- await this.$nextTick(() => {
- this.multipleSelection = JSON.parse(Cookies.get('minTurnRadius'))
- this.multipleSelection.forEach((item) => {
- this.$refs.vxeTable.setCheckboxRowKey(item.id, true)
+ .then((response) => {
+ return response.json()
+ })
+ .then(async (data) => {
+ this.dialogVisible = true
+ this.tableData = data
+ await this.$nextTick(() => {
+ this.multipleSelection = JSON.parse(Cookies.get('minTurnRadius'))
+ this.multipleSelection.forEach((item) => {
+ this.$refs.vxeTable.setCheckboxRowKey(item.id, true)
+ })
})
})
- })
- .catch((error) => {})
+ .catch((error) => {})
},
handleSelectionChange({records}) {
this.multipleSelection = records
@@ -879,35 +866,39 @@ export default {
load: null,
minTurnRadius: null,
editing: true,
- };
- this.tableData.push(newRow);
+ }
+ this.tableData.push(newRow)
},
handleDelete(row) {
- const index = this.tableData.findIndex(item => item.id === row.id);
+ const index = this.tableData.findIndex((item) => item.id === row.id)
if (index !== -1) {
- this.tableData.splice(index, 1);
+ this.tableData.splice(index, 1)
}
},
handleEdit(row) {
- this.$set(row, 'editing', true);
+ this.$set(row, 'editing', true)
},
handleSave(row) {
- this.$set(row, 'editing', false);
+ this.$set(row, 'editing', false)
},
// 保存列表数据
suerCofirm() {
- const parsedData = iniParser.parse(configIni);
- axios.post(`http://${parsedData.http.address}:${parsedData.http.port}/api/equpment`, JSON.stringify(this.tableData), {
- headers: {
- 'Authorization': 'Bearer your_token_here',
- 'Content-Type': 'application/json'
- }
- })
- .then(response => {
- this.$message.success('保存成功')
- })
- .catch(error => {
- });
+ const parsedData = iniParser.parse(configIni)
+ axios
+ .post(
+ `http://${parsedData.http.address}:${parsedData.http.port}/api/equpment`,
+ JSON.stringify(this.tableData),
+ {
+ headers: {
+ Authorization: 'Bearer your_token_here',
+ 'Content-Type': 'application/json',
+ },
+ }
+ )
+ .then((response) => {
+ this.$message.success('保存成功')
+ })
+ .catch((error) => {})
},
// 导入json文件
triggerFileUpload() {
@@ -974,21 +965,12 @@ export default {
}
},
addPointToMap(type, point, time) {
- const coords = time
- ? point.points.split(',').map(Number)
- : point.split(',').map(Number)
+ const coords = time ? point.points.split(',').map(Number) : point.split(',').map(Number)
const graphic = new window.mars3d.graphic.PointEntity({
position: new window.mars3d.LngLatPoint(coords[0], coords[1]),
style: {
pixelSize: 10,
- color:
- type === 'startPoint'
- ? 'red'
- : type === 'endPoint'
- ? 'red'
- : type === 'viaPoints'
- ? 'blue'
- : 'orange',
+ color: type === 'startPoint' ? 'red' : type === 'endPoint' ? 'red' : type === 'viaPoints' ? 'blue' : 'orange',
label: {
text:
type === 'startPoint'
@@ -1022,9 +1004,7 @@ export default {
addPolygonToMap(type, area, time) {
const coords = JSON.parse(area.points)
const graphic = new window.mars3d.graphic.PolygonEntity({
- positions: coords.map(
- (coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])
- ),
+ positions: coords.map((coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])),
style: {
color: 'red',
opacity: 0.4,
@@ -1079,94 +1059,55 @@ export default {
}
} else if (type === 'viaPoints') {
if (!row.points) {
- const graphic = this.viaPoints.find(
- (viaPoint) => viaPoint.style.time === row.time
- )
- if (
- this.form.viaPoints.length === 1 &&
- this.form.viaPoints[0].points === ''
- ) {
+ const graphic = this.viaPoints.find((viaPoint) => viaPoint.style.time === row.time)
+ if (this.form.viaPoints.length === 1 && this.form.viaPoints[0].points === '') {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.viaPoints[0].points = ''
graphic?.remove()
- this.viaPoints = this.viaPoints.filter(
- (viaPoint) => viaPoint.style.time !== row.time
- )
+ this.viaPoints = this.viaPoints.filter((viaPoint) => viaPoint.style.time !== row.time)
} else {
- this.form.viaPoints = this.form.viaPoints.filter(
- (viaPoint) => viaPoint.time !== row.time
- )
+ this.form.viaPoints = this.form.viaPoints.filter((viaPoint) => viaPoint.time !== row.time)
}
graphic?.remove()
- this.viaPoints = this.viaPoints.filter(
- (viaPoint) => viaPoint.style.time !== row.time
- )
+ this.viaPoints = this.viaPoints.filter((viaPoint) => viaPoint.style.time !== row.time)
} else {
- const graphic = this.viaPoints.find(
- (viaPoint) => viaPoint.style.time === row.time
- )
+ const graphic = this.viaPoints.find((viaPoint) => viaPoint.style.time === row.time)
this.updatePointPosition(graphic, row.points)
}
} else if (type === 'avoidPoints') {
if (!row.points) {
- const graphic = this.avoidPoints.find(
- (avoidPoint) => avoidPoint.style.time === row.time
- )
- if (
- this.form.avoidPoints.length === 1 &&
- this.form.avoidPoints[0].points === ''
- ) {
+ const graphic = this.avoidPoints.find((avoidPoint) => avoidPoint.style.time === row.time)
+ if (this.form.avoidPoints.length === 1 && this.form.avoidPoints[0].points === '') {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.avoidPoints[0].points = ''
} else {
- this.form.avoidPoints = this.form.avoidPoints.filter(
- (avoidPoint) => avoidPoint.time !== row.time
- )
+ this.form.avoidPoints = this.form.avoidPoints.filter((avoidPoint) => avoidPoint.time !== row.time)
}
graphic?.remove()
- this.avoidPoints = this.avoidPoints.filter(
- (avoidPoint) => avoidPoint.style.time !== row.time
- )
+ this.avoidPoints = this.avoidPoints.filter((avoidPoint) => avoidPoint.style.time !== row.time)
} else {
- const graphic = this.avoidPoints.find(
- (avoidPoint) => avoidPoint.style.time === row.time
- )
+ const graphic = this.avoidPoints.find((avoidPoint) => avoidPoint.style.time === row.time)
this.updatePointPosition(graphic, row.points)
}
} else if (type === 'avoidAreas') {
if (!row.points) {
- const graphic = this.avoidAreas.find(
- (avoidArea) => avoidArea.style.time === row.time
- )
- if (
- this.form.avoidAreas.length === 1 &&
- this.form.avoidAreas[0].points === ''
- ) {
+ const graphic = this.avoidAreas.find((avoidArea) => avoidArea.style.time === row.time)
+ if (this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.avoidAreas[0].points = ''
} else {
- this.form.avoidAreas = this.form.avoidAreas.filter(
- (avoidArea) => avoidArea.time !== row.time
- )
+ this.form.avoidAreas = this.form.avoidAreas.filter((avoidArea) => avoidArea.time !== row.time)
}
graphic?.remove()
- this.avoidAreas = this.avoidAreas.filter(
- (avoidArea) => avoidArea.style.time !== row.time
- )
+ this.avoidAreas = this.avoidAreas.filter((avoidArea) => avoidArea.style.time !== row.time)
} else {
- const graphic = this.avoidAreas.find(
- (avoidArea) => avoidArea.style.time === row.time
- )
+ const graphic = this.avoidAreas.find((avoidArea) => avoidArea.style.time === row.time)
this.updatePolygonPosition(graphic, row.points)
}
}
},
handleEmptyArray(type) {
- if (
- type === 'viaPoints' &&
- this.form.viaPoints.length === 1 &&
- this.form.viaPoints[0].points === ''
- ) {
+ if (type === 'viaPoints' && this.form.viaPoints.length === 1 && this.form.viaPoints[0].points === '') {
this.form.viaPoints = []
} else if (
type === 'avoidPoints' &&
@@ -1174,11 +1115,7 @@ export default {
this.form.avoidPoints[0].points === ''
) {
this.form.avoidPoints = []
- } else if (
- type === 'avoidAreas' &&
- this.form.avoidAreas.length === 1 &&
- this.form.avoidAreas[0].points === ''
- ) {
+ } else if (type === 'avoidAreas' && this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
this.form.avoidAreas = []
}
},
@@ -1193,9 +1130,7 @@ export default {
if (!graphic) return
try {
const coords = JSON.parse(pointsStr)
- graphic.positions = coords.map(
- (coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])
- )
+ graphic.positions = coords.map((coord) => new window.mars3d.LngLatPoint(coord[0], coord[1]))
} catch (error) {
graphic.remove()
}
@@ -1350,9 +1285,7 @@ export default {
success: (graphic) => {
this.avoidAreas.push(graphic)
const avoidAreasGeoJSON = graphic.toGeoJSON()
- const points = JSON.stringify(
- avoidAreasGeoJSON.geometry.coordinates[0]
- )
+ const points = JSON.stringify(avoidAreasGeoJSON.geometry.coordinates[0])
if (
this.form.avoidAreas.length == 1 &&
this.form.avoidAreas[0].points == '' &&
@@ -1385,11 +1318,8 @@ export default {
}
// 计算边权重(距离,单位:米)
const distance =
- turf.distance(
- turf.point(coords[0][0]),
- turf.point(coords[coords.length - 1][0]),
- {units: 'kilometers'}
- ) * 1000
+ turf.distance(turf.point(coords[0][0]), turf.point(coords[coords.length - 1][0]), {units: 'kilometers'}) *
+ 1000
// 构建邻接表(双向图)
graph[startNode] = graph[startNode] || {}
@@ -1418,22 +1348,17 @@ export default {
return nearestNode
},
// 3. 路径规划主函数(经纬度坐标输入) - 支持途经点 + 避让点/区域
- async planRoute(
- startCoord,
- endCoord,
- viaPoints = [],
- avoidObstacles = null
- ) {
+ async planRoute(startCoord, endCoord, viaPoints = [], avoidObstacles = null) {
const {graph, nodeCoords} = this.roadNetworkGeoJSONBuild
// 按顺序组合点:起点 -> 途经点 -> 终点
- const points = [startCoord];
+ const points = [startCoord]
if (viaPoints && viaPoints.length > 0) {
viaPoints.forEach((viaPoint) => {
- points.push(viaPoint.geometry.coordinates);
- });
+ points.push(viaPoint.geometry.coordinates)
+ })
}
- points.push(endCoord);
+ points.push(endCoord)
const fullPath = []
const infoList = []
for (let i = 0; i < points.length - 1; i++) {
@@ -1457,8 +1382,7 @@ export default {
for (const [node, coord] of Object.entries(nodeCoords)) {
const pt = turf.point(coord)
avoidObstacles.features.forEach((ob) => {
- if (turf.booleanPointInPolygon(pt.geometry, ob.geometry))
- obstacleNodes.push(node)
+ if (turf.booleanPointInPolygon(pt.geometry, ob.geometry)) obstacleNodes.push(node)
})
}
obstacleNodes.forEach((node) => delete tempGraph[node])
@@ -1471,10 +1395,7 @@ export default {
delete tempGraph[node][targetNode]
continue
}
- const line = turf.lineString([
- nodeCoords[node],
- nodeCoords[targetNode],
- ])
+ const line = turf.lineString([nodeCoords[node], nodeCoords[targetNode]])
avoidObstacles.features.forEach((area) => {
if (turf.booleanCrosses(line, area)) {
delete tempGraph[node][targetNode]
@@ -1500,21 +1421,17 @@ export default {
if (!this.join) {
segment = this.roadNetworkGeoJSON.features.find(
(f) =>
- (f.properties.FNODE_ == currentNode &&
- f.properties.TNODE_ == nextNode) ||
- (f.properties.FNODE_ == nextNode &&
- f.properties.TNODE_ == currentNode)
+ (f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
+ (f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)
)
} else {
segment = this.roadNetworkGeoJSON.features.find(
- (f) =>
- ((f.properties.FNODE_ == currentNode &&
- f.properties.TNODE_ == nextNode) ||
- (f.properties.FNODE_ == nextNode &&
- f.properties.TNODE_ == currentNode) ) &&
- f.properties.载重吨 >= this.inputform.load &&
- f.properties.宽度 >= this.inputform.width &&
- f.properties.曲率半 <= this.inputform.minTurnRadius
+ (f) =>
+ ((f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
+ (f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)) &&
+ f.properties.载重吨 >= this.inputform.load &&
+ f.properties.宽度 >= this.inputform.width &&
+ f.properties.曲率半 <= this.inputform.minTurnRadius
)
}
if (segment) {
@@ -1534,20 +1451,13 @@ export default {
this.shortestPathLayer.clear()
this.shortestPathList = []
this.infoList = []
- const startPoint = turf.point(
- this.pointQD.toGeoJSON().geometry.coordinates
- ).geometry.coordinates // 起点
- const endPoint = turf.point(this.pointZD.toGeoJSON().geometry.coordinates)
- .geometry.coordinates // 终点
+ const startPoint = turf.point(this.pointQD.toGeoJSON().geometry.coordinates).geometry.coordinates // 起点
+ const endPoint = turf.point(this.pointZD.toGeoJSON().geometry.coordinates).geometry.coordinates // 终点
// 途经点
- const viaPointsGeoJSON =
- this.viaPoints.map((point) => point.toGeoJSON()) || []
- const viaPointsTurf = viaPointsGeoJSON.map((p) =>
- turf.point(p.geometry.coordinates)
- )
+ const viaPointsGeoJSON = this.viaPoints.map((point) => point.toGeoJSON()) || []
+ const viaPointsTurf = viaPointsGeoJSON.map((p) => turf.point(p.geometry.coordinates))
// 避让点
- const avoidPointsGeoJSON =
- this.avoidPoints.map((point) => point.toGeoJSON()) || []
+ const avoidPointsGeoJSON = this.avoidPoints.map((point) => point.toGeoJSON()) || []
const avoidPointsPolygons = avoidPointsGeoJSON.map((point) => {
return turf.circle(
turf.point(point.geometry.coordinates),
@@ -1556,18 +1466,9 @@ export default {
)
})
// 避让区域
- const avoidAreasGeoJSON =
- this.avoidAreas.map((area) => area.toGeoJSON({closure: true})) || []
- const obstaclesGeoJSON = turf.featureCollection([
- ...avoidPointsPolygons,
- ...avoidAreasGeoJSON,
- ])
- const route = await this.planRoute(
- startPoint,
- endPoint,
- viaPointsTurf,
- obstaclesGeoJSON
- )
+ const avoidAreasGeoJSON = this.avoidAreas.map((area) => area.toGeoJSON({closure: true})) || []
+ const obstaclesGeoJSON = turf.featureCollection([...avoidPointsPolygons, ...avoidAreasGeoJSON])
+ const route = await this.planRoute(startPoint, endPoint, viaPointsTurf, obstaclesGeoJSON)
this.drawPath(route)
},
@@ -1588,9 +1489,7 @@ export default {
this.infoList = path.infoList.map((item) => item.properties)
},
/** 隐蔽规划 */
- concealed() {
-
- },
+ concealed() {},
},
}
@@ -1664,14 +1563,14 @@ export default {
display: flex;
justify-content: space-between;
}
-.control-panel .title .joinCheck {
+.control-panel .title .joinCheck {
font-size: 14px;
color: #555;
}
.el-checkbox {
- margin-right: 5px!important;
+ margin-right: 5px !important;
}
-
+
.importJson {
display: flex;
flex-direction: row;
@@ -1721,6 +1620,4 @@ export default {
.popDiloag .popDiloag-title {
font-weight: 500;
}
-.popDiloag .popDiloag-p {
-}
diff --git a/src/views/home/home.vue b/src/views/home/home.vue
index a1c80ab..db4748c 100644
--- a/src/views/home/home.vue
+++ b/src/views/home/home.vue
@@ -81,21 +81,12 @@
-
+
导入json文件
隐蔽添加
-
+
@@ -112,12 +103,7 @@
参与路线规划
-
+
@@ -125,10 +111,7 @@
-
+
数据选择
@@ -156,7 +139,7 @@
inputform.minTurnRadius || 0
}},最大车辆载重{{ inputform.load || 0 }}吨
-
+
@@ -165,23 +148,23 @@
-
+
-
- {{ row.area.toFixed(2)}}
+
+ {{ row.area.toFixed(2) }}
-
- {{ (row.vehicles.map(item => item.name)).join(',')}}
+
+ {{ row.vehicles.map((item) => item.name).join(',') }}
-
+
新增
-
+
{{ row.name }}
-
+
{{ row.long }}
-
+
{{ row.width }}
-
+
{{ row.load }}
-
+
{{ row.minTurnRadius }}
-
+
编辑
保存
删除
@@ -248,7 +231,7 @@
import Cookies from 'js-cookie'
import axios from 'axios'
import iniParser from 'ini-parser'
-import configIni from '/config.ini';
+import configIni from '/public/config.ini'
export default {
data() {
@@ -321,7 +304,7 @@ export default {
.catch((error) => {})
},
async initMap() {
- const parsedData = iniParser.parse(configIni);
+ const parsedData = iniParser.parse(configIni)
this.viewer = new window.mars3d.Map(
'map',
{
@@ -356,7 +339,7 @@ export default {
this.shortestPathLayer = new window.mars3d.layer.GraphicLayer()
this.viewer.addLayer(this.shortestPathLayer)
-
+
this.accordFactoryLayer = new window.mars3d.layer.GraphicLayer()
this.viewer.addLayer(this.accordFactoryLayer)
this.loadShapefile() // 拿到路网数据
@@ -450,7 +433,7 @@ export default {
outline: false,
},
})
- this.graphicLayer.addGraphic(graphicLine);
+ this.graphicLayer.addGraphic(graphicLine)
})
this.roadNetworkGeoJSONBuild = this.buildGraph(this.roadNetworkGeoJSON)
this.loadFactoryGeoJson() // 拿到厂房数据
@@ -500,7 +483,7 @@ export default {
this.accordPoint = graphic
try {
// 创建缓冲区的宽度
- const bufferWidth = this.hideform.radius; // 避让区的宽度(单位:米)
+ const bufferWidth = this.hideform.radius // 避让区的宽度(单位:米)
// 获取绘制的点的坐标
const pointCoordinates = [
graphic.toGeoJSON().geometry.coordinates[0],
@@ -514,12 +497,12 @@ export default {
coordinates: pointCoordinates,
},
properties: {},
- };
+ }
// 使用 Turf.js 计算缓冲区
- let buffered = turf.buffer(pointFeature, bufferWidth / 1000, { units: 'kilometers' });
+ let buffered = turf.buffer(pointFeature, bufferWidth / 1000, {units: 'kilometers'})
// 将缓冲区存储到数组中
- this.bufferLayerList.push(buffered);
+ this.bufferLayerList.push(buffered)
const polygon = new window.mars3d.graphic.PolygonEntity({
positions: buffered.geometry.coordinates[0],
style: {
@@ -529,19 +512,19 @@ export default {
outlineWidth: 1,
outlineColor: '#ffffff',
},
- time: new Date().getTime()
+ time: new Date().getTime(),
})
- this.accordFactoryLayer.addGraphic(polygon);
+ this.accordFactoryLayer.addGraphic(polygon)
// 检查缓冲区内的厂房
- this.checkFactoryInBuffer('point', pointCoordinates);
+ this.checkFactoryInBuffer('point', pointCoordinates)
} catch (error) {
- console.error("缓冲区生成或检查异常:", error);
+ console.error('缓冲区生成或检查异常:', error)
}
},
})
},
// 获取当前路线的缓冲区
- hadBuffer () {
+ hadBuffer() {
if (this.shortestPathList.length == 0) {
this.$message.warning('请先进行路线规划')
return
@@ -562,30 +545,30 @@ export default {
for (const feature of this.shortestPathList[0]) {
// this.shortestPathList[0].forEach((feature) => {
// 创建缓冲区的宽度
- const bufferWidth = this.hideform.radius; // 避让区的宽度(单位:米)
+ const bufferWidth = this.hideform.radius // 避让区的宽度(单位:米)
if (feature.geometry.type === 'LineString') {
- const positions = feature.geometry.coordinates[0];
+ const positions = feature.geometry.coordinates[0]
// 确保每条线至少有 2 个点
if (positions.length < 2) {
- console.warn('无效的线,跳过:', feature);
- return;
+ console.warn('无效的线,跳过:', feature)
+ return
}
try {
// 使用 Turf.js 计算缓冲区
- var buffered = turf.buffer(feature, bufferWidth / 1000, { units: 'kilometers' });
+ var buffered = turf.buffer(feature, bufferWidth / 1000, {units: 'kilometers'})
// 将缓冲区存储到数组中
- this.bufferLayerList.push(buffered);
+ this.bufferLayerList.push(buffered)
} catch (error) {
- console.error("缓冲分析异常:", error);
+ console.error('缓冲分析异常:', error)
}
} else if (feature.geometry.type === 'MultiLineString') {
// 遍历每个线段
feature.geometry.coordinates.forEach((lineCoordinates) => {
// 检查每个线段是否有效
if (lineCoordinates.length < 2) {
- console.warn('多线段中的无效的线段,跳过:', lineCoordinates);
- return;
+ console.warn('多线段中的无效的线段,跳过:', lineCoordinates)
+ return
}
// 创建单个线段的 GeoJSON 特征
@@ -595,27 +578,27 @@ export default {
type: 'LineString',
coordinates: lineCoordinates,
},
- properties: feature.properties
- };
+ properties: feature.properties,
+ }
try {
// 使用 Turf.js 计算缓冲区
- var buffered = turf.buffer(lineFeature, bufferWidth / 1000, { units: 'kilometers' });
+ var buffered = turf.buffer(lineFeature, bufferWidth / 1000, {units: 'kilometers'})
// 将缓冲区存储到数组中
- this.bufferLayerList.push(buffered);
+ this.bufferLayerList.push(buffered)
} catch (error) {
- console.error("缓冲分析异常:", error);
+ console.error('缓冲分析异常:', error)
}
- });
+ })
} else {
- console.warn('不支持的几何类型:', feature.geometry.type);
+ console.warn('不支持的几何类型:', feature.geometry.type)
}
- }
-
+ }
+
// 去筛选在缓存区的厂房
- this.checkFactoryInBuffer('line');
- }catch (error) {
- console.error("处理路径列表时发生错误:", error);
+ this.checkFactoryInBuffer('line')
+ } catch (error) {
+ console.error('处理路径列表时发生错误:', error)
}
},
checkFactoryInBuffer(type, pointInfo) {
@@ -636,106 +619,106 @@ export default {
// 检查几何对象的类型
if (factory.geometry.type === 'MultiPolygon') {
// 创建多边形集合(MultiPolygon)
- const factoryMultiPoly = turf.multiPolygon(factory.geometry.coordinates);
+ const factoryMultiPoly = turf.multiPolygon(factory.geometry.coordinates)
// 计算整个多边形集合的面积
- const area = turf.area(factoryMultiPoly);
+ const area = turf.area(factoryMultiPoly)
// 计算工厂多边形集合的边界框
- const [minX, minY, maxX, maxY] = turf.bbox(factoryMultiPoly);
+ const [minX, minY, maxX, maxY] = turf.bbox(factoryMultiPoly)
// 筛选与工厂边界框相交的缓冲区
const candidates = this.bufferLayerList.filter((buffer) => {
- const [bminX, bminY, bmaxX, bmaxY] = turf.bbox(buffer);
- return !(bmaxX < minX || bminX > maxX || bmaxY < minY || bminY > maxY);
- });
+ const [bminX, bminY, bmaxX, bmaxY] = turf.bbox(buffer)
+ return !(bmaxX < minX || bminX > maxX || bmaxY < minY || bminY > maxY)
+ })
// 精确相交检测
- let isInside = false;
+ let isInside = false
for (const buffer of candidates) {
if (turf.booleanIntersects(factoryMultiPoly, buffer)) {
// 如果工厂在缓冲区内,绘制所有多边形
- isInside = true;
- this.drawFactory(factory.geometry.coordinates, factory, area, pointInfo);
- break;
+ isInside = true
+ this.drawFactory(factory.geometry.coordinates, factory, area, pointInfo)
+ break
}
}
// 如果工厂不在任何缓冲区内
- resolve();
+ resolve()
} else {
- reject(new Error('不支持的几何类型'));
+ reject(new Error('不支持的几何类型'))
}
})
- });
+ })
// 确保所有工厂处理完成后进行排序
Promise.allSettled(factoryPromises)
.then(async (results) => {
// 只有路线隐蔽规划需要塞入车辆 点的不需要
// 所有工厂处理完成,进行排序 按照距离近到远
- this.accordFactoryInfo.sort((a, b) => a.distance - b.distance);
+ this.accordFactoryInfo.sort((a, b) => a.distance - b.distance)
// 拿到当前的车队车辆信息 并且算出面积 按照从大到小排序
const areaList = JSON.parse(Cookies.get('minTurnRadius'))
areaList.map((item) => {
item.area = Number(item.long) * Number(item.width)
})
- areaList.sort((a, b) => b.area - a.area);
+ areaList.sort((a, b) => b.area - a.area)
// 初始化每个工厂的剩余面积
- this.accordFactoryInfo.forEach(factory => {
- factory.remainingArea = factory.area; // 记录每个工厂的剩余可用面积
- factory.vehicles = []; // 确保每个工厂都有一个 vehicles 属性
- });
+ this.accordFactoryInfo.forEach((factory) => {
+ factory.remainingArea = factory.area // 记录每个工厂的剩余可用面积
+ factory.vehicles = [] // 确保每个工厂都有一个 vehicles 属性
+ })
// 遍历每个车辆,尝试塞入工厂
areaList.forEach((vehicle) => {
- let isPlaced = false;
+ let isPlaced = false
// 遍历每个工厂,尝试塞入车辆
for (let i = 0; i < this.accordFactoryInfo.length; i++) {
- const factory = this.accordFactoryInfo[i];
+ const factory = this.accordFactoryInfo[i]
// 检查工厂是否还有剩余面积
if (factory.remainingArea >= vehicle.area) {
// 塞入车辆
factory.vehicles.push({
...vehicle,
- remainingArea: factory.remainingArea - vehicle.area // 记录车辆塞入后的工厂剩余面积
- });
+ remainingArea: factory.remainingArea - vehicle.area, // 记录车辆塞入后的工厂剩余面积
+ })
// 更新工厂的剩余面积
- factory.remainingArea -= vehicle.area;
+ factory.remainingArea -= vehicle.area
// 标记车辆已放置
- isPlaced = true;
- break;
+ isPlaced = true
+ break
}
}
// 如果车辆没有被放置,可以在这里处理(例如记录日志或显示警告)
if (!isPlaced) {
- console.warn(`车辆 ${vehicle.id} 无法放置在任何工厂中`);
+ console.warn(`车辆 ${vehicle.id} 无法放置在任何工厂中`)
}
- });
+ })
// 更新 this.accordFactoryInfo
- this.accordFactoryInfo = this.accordFactoryInfo.map(factory => {
+ this.accordFactoryInfo = this.accordFactoryInfo.map((factory) => {
// 确保每个工厂都有 vehicles 属性
if (!factory.vehicles) {
- factory.vehicles = [];
+ factory.vehicles = []
}
// 确保 remainingArea 是一个数字且大于 0
- factory.area = factory.area > 0 ? factory.area : 0;
- return factory;
- });
+ factory.area = factory.area > 0 ? factory.area : 0
+ return factory
+ })
// 过滤出有车辆的工厂
- const factoriesWithVehicles = this.accordFactoryInfo.filter(factory => factory.vehicles.length > 0);
+ const factoriesWithVehicles = this.accordFactoryInfo.filter((factory) => factory.vehicles.length > 0)
this.factoriesWithVehicles = factoriesWithVehicles
- await this.showAreaInfoDialog(factoriesWithVehicles);
+ await this.showAreaInfoDialog(factoriesWithVehicles)
})
.catch((error) => {
console.error('数据有问题', error)
- });
+ })
},
drawFactory(factoryMultiPoly, factory, area, pointInfo) {
// 获取当前多边形集合的中心点
- const center = turf.center(turf.multiPolygon(factory.geometry.coordinates));
+ const center = turf.center(turf.multiPolygon(factory.geometry.coordinates))
// 将中心点转换为 Mars3D 的 LngLatPoint 对象
- const popupPosition = new mars3d.LngLatPoint(center.geometry.coordinates[0], center.geometry.coordinates[1]);
+ const popupPosition = new mars3d.LngLatPoint(center.geometry.coordinates[0], center.geometry.coordinates[1])
// 遍历每个多边形集合
factory.geometry.coordinates[0].forEach((coordGroup) => {
// 创建一个多边形图形
@@ -747,35 +730,39 @@ export default {
outline: true,
outlineWidth: 1,
outlineColor: '#ffffff',
- properties: { ...factory.properties },
+ properties: {...factory.properties},
},
- time: new Date().getTime()
+ time: new Date().getTime(),
})
- this.accordFactoryLayer.addGraphic(graphic);
+ this.accordFactoryLayer.addGraphic(graphic)
// 计算多边形中心与参考点的距离
const point = pointInfo && pointInfo.length > 0 ? pointInfo : this.form.endPoint.split(',').map(Number)
- const distance = turf.distance(center.geometry.coordinates, point, { units: 'kilometers' }) * 1000; // 米
+ const distance = turf.distance(center.geometry.coordinates, point, {units: 'kilometers'}) * 1000 // 米
// 将多边形图形添加到地图层
this.accordFactoryInfo.push({
...graphic,
distance: distance,
popupPosition: popupPosition,
- area: this.hideform.redundancy && this.hideform.redundancy != 0 && area > 0
- ? area * (100 - this.hideform.redundancy) * 0.01
- : area > 0
- ? area
- : 0, // 如果 area 不是有效值,设置为 0 或其他默认值
+ area:
+ this.hideform.redundancy && this.hideform.redundancy != 0 && area > 0
+ ? area * (100 - this.hideform.redundancy) * 0.01
+ : area > 0
+ ? area
+ : 0, // 如果 area 不是有效值,设置为 0 或其他默认值
})
})
},
// 显示面积信息弹框的方法
async showAreaInfoDialog(info) {
- const graphics = this.accordFactoryLayer.getGraphics();
- const promises = [];
+ const graphics = this.accordFactoryLayer.getGraphics()
+ const promises = []
info.forEach((item) => {
graphics.forEach((ele) => {
- if (ele.options.time === item.options.time && ele.options.style.properties.FID_1 === item.options.style.properties.FID_1) {
- const textInfo = `${item.area.toFixed(2)}㎡ \n(${item.vehicles.map(e => e.name).join(',')})`
+ if (
+ ele.options.time === item.options.time &&
+ ele.options.style.properties.FID_1 === item.options.style.properties.FID_1
+ ) {
+ const textInfo = `${item.area.toFixed(2)}㎡ \n(${item.vehicles.map((e) => e.name).join(',')})`
const labelGraphic = new window.mars3d.graphic.LabelEntity({
id: 'label',
position: item.popupPosition,
@@ -788,34 +775,34 @@ export default {
outlineColor: '#000000',
background: true,
backgroundColor: '#2f705f',
- }
+ },
})
// 使用 Promise 确保标签添加完成后继续执行
const promise = new Promise((resolve, reject) => {
this.accordFactoryLayer.addGraphic(labelGraphic, () => {
- resolve();
- });
- });
+ resolve()
+ })
+ })
- promises.push(promise);
+ promises.push(promise)
}
})
})
- this.$message.success("路线隐蔽规划成功")
- const popupPositionList = info.map(item => item.popupPosition)
- let minLng = Infinity;
- let maxLng = -Infinity;
- let minLat = Infinity;
- let maxLat = -Infinity;
+ this.$message.success('路线隐蔽规划成功')
+ const popupPositionList = info.map((item) => item.popupPosition)
+ let minLng = Infinity
+ let maxLng = -Infinity
+ let minLat = Infinity
+ let maxLat = -Infinity
- popupPositionList.forEach(point => {
- if (point.lng < minLng) minLng = point.lng;
- if (point.lng > maxLng) maxLng = point.lng;
- if (point.lat < minLat) minLat = point.lat;
- if (point.lat > maxLat) maxLat = point.lat;
- });
+ popupPositionList.forEach((point) => {
+ if (point.lng < minLng) minLng = point.lng
+ if (point.lng > maxLng) maxLng = point.lng
+ if (point.lat < minLat) minLat = point.lat
+ if (point.lat > maxLat) maxLat = point.lat
+ })
// 创建一个矩形区域,包含所有点
- const rectangle = Cesium.Rectangle.fromDegrees(minLng, minLat, maxLng, maxLat);
+ const rectangle = Cesium.Rectangle.fromDegrees(minLng, minLat, maxLng, maxLat)
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
@@ -826,29 +813,29 @@ export default {
orientation: {
heading: Cesium.Math.toRadians(0), // 方位角
pitch: Cesium.Math.toRadians(-90), // 俯仰角
- roll: 0.0 // 翻滚角
+ roll: 0.0, // 翻滚角
},
- duration: 2 // 飞行动画持续时间,单位为秒
- });
+ duration: 2, // 飞行动画持续时间,单位为秒
+ })
},
// 弹框
async openDialog() {
this.multipleSelection = []
await fetch('./data/minTurnRadius.json')
- .then((response) => {
- return response.json()
- })
- .then(async (data) => {
- this.dialogVisible = true;
- this.tableData = data
- await this.$nextTick(() => {
- this.multipleSelection = JSON.parse(Cookies.get('minTurnRadius'))
- this.multipleSelection.forEach((item) => {
- this.$refs.vxeTable.setCheckboxRowKey(item.id, true)
+ .then((response) => {
+ return response.json()
+ })
+ .then(async (data) => {
+ this.dialogVisible = true
+ this.tableData = data
+ await this.$nextTick(() => {
+ this.multipleSelection = JSON.parse(Cookies.get('minTurnRadius'))
+ this.multipleSelection.forEach((item) => {
+ this.$refs.vxeTable.setCheckboxRowKey(item.id, true)
+ })
})
})
- })
- .catch((error) => {})
+ .catch((error) => {})
},
handleSelectionChange({records}) {
this.multipleSelection = records
@@ -886,35 +873,39 @@ export default {
load: null,
minTurnRadius: null,
editing: true,
- };
- this.tableData.push(newRow);
+ }
+ this.tableData.push(newRow)
},
handleDelete(row) {
- const index = this.tableData.findIndex(item => item.id === row.id);
+ const index = this.tableData.findIndex((item) => item.id === row.id)
if (index !== -1) {
- this.tableData.splice(index, 1);
+ this.tableData.splice(index, 1)
}
},
handleEdit(row) {
- this.$set(row, 'editing', true);
+ this.$set(row, 'editing', true)
},
handleSave(row) {
- this.$set(row, 'editing', false);
+ this.$set(row, 'editing', false)
},
// 保存列表数据
suerCofirm() {
- const parsedData = iniParser.parse(configIni);
- axios.post(`http://${parsedData.http.address}:${parsedData.http.port}/api/equpment`, JSON.stringify(this.tableData), {
- headers: {
- 'Authorization': 'Bearer your_token_here',
- 'Content-Type': 'application/json'
- }
- })
- .then(response => {
- this.$message.success('保存成功')
- })
- .catch(error => {
- });
+ const parsedData = iniParser.parse(configIni)
+ axios
+ .post(
+ `http://${parsedData.http.address}:${parsedData.http.port}/api/equpment`,
+ JSON.stringify(this.tableData),
+ {
+ headers: {
+ Authorization: 'Bearer your_token_here',
+ 'Content-Type': 'application/json',
+ },
+ }
+ )
+ .then((response) => {
+ this.$message.success('保存成功')
+ })
+ .catch((error) => {})
},
// 导入json文件
triggerFileUpload() {
@@ -981,21 +972,12 @@ export default {
}
},
addPointToMap(type, point, time) {
- const coords = time
- ? point.points.split(',').map(Number)
- : point.split(',').map(Number)
+ const coords = time ? point.points.split(',').map(Number) : point.split(',').map(Number)
const graphic = new window.mars3d.graphic.PointEntity({
position: new window.mars3d.LngLatPoint(coords[0], coords[1]),
style: {
pixelSize: 10,
- color:
- type === 'startPoint'
- ? 'red'
- : type === 'endPoint'
- ? 'red'
- : type === 'viaPoints'
- ? 'blue'
- : 'orange',
+ color: type === 'startPoint' ? 'red' : type === 'endPoint' ? 'red' : type === 'viaPoints' ? 'blue' : 'orange',
label: {
text:
type === 'startPoint'
@@ -1029,9 +1011,7 @@ export default {
addPolygonToMap(type, area, time) {
const coords = JSON.parse(area.points)
const graphic = new window.mars3d.graphic.PolygonEntity({
- positions: coords.map(
- (coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])
- ),
+ positions: coords.map((coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])),
style: {
color: 'red',
opacity: 0.4,
@@ -1086,94 +1066,55 @@ export default {
}
} else if (type === 'viaPoints') {
if (!row.points) {
- const graphic = this.viaPoints.find(
- (viaPoint) => viaPoint.style.time === row.time
- )
- if (
- this.form.viaPoints.length === 1 &&
- this.form.viaPoints[0].points === ''
- ) {
+ const graphic = this.viaPoints.find((viaPoint) => viaPoint.style.time === row.time)
+ if (this.form.viaPoints.length === 1 && this.form.viaPoints[0].points === '') {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.viaPoints[0].points = ''
graphic?.remove()
- this.viaPoints = this.viaPoints.filter(
- (viaPoint) => viaPoint.style.time !== row.time
- )
+ this.viaPoints = this.viaPoints.filter((viaPoint) => viaPoint.style.time !== row.time)
} else {
- this.form.viaPoints = this.form.viaPoints.filter(
- (viaPoint) => viaPoint.time !== row.time
- )
+ this.form.viaPoints = this.form.viaPoints.filter((viaPoint) => viaPoint.time !== row.time)
}
graphic?.remove()
- this.viaPoints = this.viaPoints.filter(
- (viaPoint) => viaPoint.style.time !== row.time
- )
+ this.viaPoints = this.viaPoints.filter((viaPoint) => viaPoint.style.time !== row.time)
} else {
- const graphic = this.viaPoints.find(
- (viaPoint) => viaPoint.style.time === row.time
- )
+ const graphic = this.viaPoints.find((viaPoint) => viaPoint.style.time === row.time)
this.updatePointPosition(graphic, row.points)
}
} else if (type === 'avoidPoints') {
if (!row.points) {
- const graphic = this.avoidPoints.find(
- (avoidPoint) => avoidPoint.style.time === row.time
- )
- if (
- this.form.avoidPoints.length === 1 &&
- this.form.avoidPoints[0].points === ''
- ) {
+ const graphic = this.avoidPoints.find((avoidPoint) => avoidPoint.style.time === row.time)
+ if (this.form.avoidPoints.length === 1 && this.form.avoidPoints[0].points === '') {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.avoidPoints[0].points = ''
} else {
- this.form.avoidPoints = this.form.avoidPoints.filter(
- (avoidPoint) => avoidPoint.time !== row.time
- )
+ this.form.avoidPoints = this.form.avoidPoints.filter((avoidPoint) => avoidPoint.time !== row.time)
}
graphic?.remove()
- this.avoidPoints = this.avoidPoints.filter(
- (avoidPoint) => avoidPoint.style.time !== row.time
- )
+ this.avoidPoints = this.avoidPoints.filter((avoidPoint) => avoidPoint.style.time !== row.time)
} else {
- const graphic = this.avoidPoints.find(
- (avoidPoint) => avoidPoint.style.time === row.time
- )
+ const graphic = this.avoidPoints.find((avoidPoint) => avoidPoint.style.time === row.time)
this.updatePointPosition(graphic, row.points)
}
} else if (type === 'avoidAreas') {
if (!row.points) {
- const graphic = this.avoidAreas.find(
- (avoidArea) => avoidArea.style.time === row.time
- )
- if (
- this.form.avoidAreas.length === 1 &&
- this.form.avoidAreas[0].points === ''
- ) {
+ const graphic = this.avoidAreas.find((avoidArea) => avoidArea.style.time === row.time)
+ if (this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
// 如果只剩下一个空项,不删除图形,清空输入框值
this.form.avoidAreas[0].points = ''
} else {
- this.form.avoidAreas = this.form.avoidAreas.filter(
- (avoidArea) => avoidArea.time !== row.time
- )
+ this.form.avoidAreas = this.form.avoidAreas.filter((avoidArea) => avoidArea.time !== row.time)
}
graphic?.remove()
- this.avoidAreas = this.avoidAreas.filter(
- (avoidArea) => avoidArea.style.time !== row.time
- )
+ this.avoidAreas = this.avoidAreas.filter((avoidArea) => avoidArea.style.time !== row.time)
} else {
- const graphic = this.avoidAreas.find(
- (avoidArea) => avoidArea.style.time === row.time
- )
+ const graphic = this.avoidAreas.find((avoidArea) => avoidArea.style.time === row.time)
this.updatePolygonPosition(graphic, row.points)
}
}
},
handleEmptyArray(type) {
- if (
- type === 'viaPoints' &&
- this.form.viaPoints.length === 1 &&
- this.form.viaPoints[0].points === ''
- ) {
+ if (type === 'viaPoints' && this.form.viaPoints.length === 1 && this.form.viaPoints[0].points === '') {
this.form.viaPoints = []
} else if (
type === 'avoidPoints' &&
@@ -1181,11 +1122,7 @@ export default {
this.form.avoidPoints[0].points === ''
) {
this.form.avoidPoints = []
- } else if (
- type === 'avoidAreas' &&
- this.form.avoidAreas.length === 1 &&
- this.form.avoidAreas[0].points === ''
- ) {
+ } else if (type === 'avoidAreas' && this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
this.form.avoidAreas = []
}
},
@@ -1200,9 +1137,7 @@ export default {
if (!graphic) return
try {
const coords = JSON.parse(pointsStr)
- graphic.positions = coords.map(
- (coord) => new window.mars3d.LngLatPoint(coord[0], coord[1])
- )
+ graphic.positions = coords.map((coord) => new window.mars3d.LngLatPoint(coord[0], coord[1]))
} catch (error) {
graphic.remove()
}
@@ -1357,9 +1292,7 @@ export default {
success: (graphic) => {
this.avoidAreas.push(graphic)
const avoidAreasGeoJSON = graphic.toGeoJSON()
- const points = JSON.stringify(
- avoidAreasGeoJSON.geometry.coordinates[0]
- )
+ const points = JSON.stringify(avoidAreasGeoJSON.geometry.coordinates[0])
if (
this.form.avoidAreas.length == 1 &&
this.form.avoidAreas[0].points == '' &&
@@ -1392,11 +1325,8 @@ export default {
}
// 计算边权重(距离,单位:米)
const distance =
- turf.distance(
- turf.point(coords[0][0]),
- turf.point(coords[coords.length - 1][0]),
- {units: 'kilometers'}
- ) * 1000
+ turf.distance(turf.point(coords[0][0]), turf.point(coords[coords.length - 1][0]), {units: 'kilometers'}) *
+ 1000
// 构建邻接表(双向图)
graph[startNode] = graph[startNode] ? graph[startNode] : {}
@@ -1430,22 +1360,23 @@ export default {
// 构建临时 graph
const tempGraph = JSON.parse(JSON.stringify(graph))
-
+
// 删除避让的边
if (avoidObstacles) {
for (const [node, edges] of Object.entries(tempGraph)) {
for (const targetNode of Object.keys(edges)) {
- const line = turf.lineString([nodeCoords[node], nodeCoords[targetNode]]);
- const intersectsObstacle = avoidObstacles.features.some(area => {
- return turf.booleanIntersects(line, area.geometry) || // 线段与面相交
- turf.booleanWithin(line, area.geometry) || // 线段在面内
- turf.booleanContains(area.geometry, line) // 面包含线段(冗余判断,覆盖边界场景)
- }
- );
+ const line = turf.lineString([nodeCoords[node], nodeCoords[targetNode]])
+ const intersectsObstacle = avoidObstacles.features.some((area) => {
+ return (
+ turf.booleanIntersects(line, area.geometry) || // 线段与面相交
+ turf.booleanWithin(line, area.geometry) || // 线段在面内
+ turf.booleanContains(area.geometry, line)
+ ) // 面包含线段(冗余判断,覆盖边界场景)
+ })
if (intersectsObstacle) {
- delete tempGraph[node][targetNode];
+ delete tempGraph[node][targetNode]
if (tempGraph[targetNode] && tempGraph[targetNode][node]) {
- delete tempGraph[targetNode][node];
+ delete tempGraph[targetNode][node]
}
}
}
@@ -1453,71 +1384,71 @@ export default {
}
// 按顺序组合点:起点 -> 途经点 -> 终点(保留途经点原始信息,而非仅坐标)
const points = [
- { type: 'start', coord: startCoord }, // 标记点类型:起点
- ...viaPoints.map(p => ({ type: 'via', coord: p.geometry.coordinates, raw: p })), // 途经点
- { type: 'end', coord: endCoord } // 终点
+ {type: 'start', coord: startCoord}, // 标记点类型:起点
+ ...viaPoints.map((p) => ({type: 'via', coord: p.geometry.coordinates, raw: p})), // 途经点
+ {type: 'end', coord: endCoord}, // 终点
]
-
+
const fullPath = []
const infoList = []
- let prevSegmentEndNode = null; // 存储上一个途经点的衔接点(用于下一段复用)
-
+ let prevSegmentEndNode = null // 存储上一个途经点的衔接点(用于下一段复用)
+
for (let i = 0; i < points.length - 1; i++) {
- const currPoint = points[i]; // 当前点(起点/途经点)
- const nextPoint = points[i + 1]; // 下一个点(途经点/终点)
- const segmentStart = currPoint.coord;
- const segmentEnd = nextPoint.coord;
+ const currPoint = points[i] // 当前点(起点/途经点)
+ const nextPoint = points[i + 1] // 下一个点(途经点/终点)
+ const segmentStart = currPoint.coord
+ const segmentEnd = nextPoint.coord
// 匹配最近节点:关键修改——若当前是“途经点之后的段”,复用前一段的衔接点作为起点
- let startNode, endNode;
- if (currPoint.type === 'via' && prevSegmentEndNode ) {
+ let startNode, endNode
+ if (currPoint.type === 'via' && prevSegmentEndNode) {
// 直接使用上一段的结束节点作为起点(确保路径连续性)
- startNode = prevSegmentEndNode;
+ startNode = prevSegmentEndNode
} else {
// 情况2:起点/第一段,正常匹配最近节点
- startNode = this.findNearestNode(segmentStart, nodeCoords);
+ startNode = this.findNearestNode(segmentStart, nodeCoords)
}
- endNode = this.findNearestNodeWithReturn(segmentEnd, nodeCoords, tempGraph, startNode);
+ endNode = this.findNearestNodeWithReturn(segmentEnd, nodeCoords, tempGraph, startNode)
if (!startNode || !endNode) {
console.error('无法匹配到路网节点')
- prevSegmentEndNode = null; // 重置衔接点,避免后续复用错误
+ prevSegmentEndNode = null // 重置衔接点,避免后续复用错误
continue
}
-
+
// 检查路径可行性
if (!this.isPathPossible(tempGraph, startNode, endNode)) {
- this.$message.warning(`无法匹配到路网节点`);
- continue;
+ this.$message.warning(`无法匹配到路网节点`)
+ continue
}
-
+
// 检查路径可行性(考虑死胡同原路返回)
- const {pathNodes, isDeadEnd} = await this.findPathWithReturn(tempGraph, startNode, endNode, nodeCoords);
-
+ const {pathNodes, isDeadEnd} = await this.findPathWithReturn(tempGraph, startNode, endNode, nodeCoords)
+
if (!pathNodes || pathNodes.length === 0) {
- this.$message.warning(`第${i+1}段路径未找到!`)
- prevSegmentEndNode = null;
+ this.$message.warning(`第${i + 1}段路径未找到!`)
+ prevSegmentEndNode = null
continue
}
// 生成当前段的路径(处理死胡同原路返回)
const segmentResult = await this.generatePathWithReturn(
- pathNodes,
- segmentStart,
- segmentEnd,
+ pathNodes,
+ segmentStart,
+ segmentEnd,
i,
points.length,
currPoint.type,
nextPoint.type,
isDeadEnd,
prevSegmentEndNode
- );
-
+ )
+
if (segmentResult.path.length > 0) {
// 合并路径段
- this.mergePathSegments(fullPath, segmentResult.path);
- infoList.push(...segmentResult.segments);
+ this.mergePathSegments(fullPath, segmentResult.path)
+ infoList.push(...segmentResult.segments)
// 记录当前段的结束节点,供下一段使用
- prevSegmentEndNode = pathNodes[pathNodes.length - 1];
+ prevSegmentEndNode = pathNodes[pathNodes.length - 1]
// if (i === 0) {
// // 第一段:直接添加
// fullPath.push(...segmentResult.path);
@@ -1525,7 +1456,7 @@ export default {
// // 后续段:需要检查连接点,避免重复
// this.mergePathSegments(fullPath, segmentResult.path);
// }
-
+
// infoList.push(...segmentResult.segments);
// 关键:若当前段的终点是“途经点”,记录其衔接点,供下一段复用
// if (nextPoint.type === 'via' && segmentResult.viaConnectPoint) {
@@ -1534,7 +1465,7 @@ export default {
// prevSegmentEndNode = null; // 非途经点,重置
// }
} else {
- prevSegmentEndNode = null;
+ prevSegmentEndNode = null
}
}
@@ -1542,226 +1473,249 @@ export default {
},
// 改进:查找最近节点,考虑死胡同情况
findNearestNodeWithReturn(coord, nodeCoords, graph, fromNode = null) {
- const nearestNode = this.findNearestNode(coord, nodeCoords);
-
+ const nearestNode = this.findNearestNode(coord, nodeCoords)
+
// 如果没有起点节点或不是死胡同,直接返回最近节点
if (!fromNode || !this.isDeadEnd(nearestNode, graph)) {
- return nearestNode;
+ return nearestNode
}
-
+
// 如果是死胡同,找到死胡同的入口节点(原路返回点)
- return this.findDeadEndEntry(nearestNode, graph, fromNode, nodeCoords);
+ return this.findDeadEndEntry(nearestNode, graph, fromNode, nodeCoords)
},
// 判断节点是否是死胡同(只有一个连接)
isDeadEnd(node, graph) {
- if (!graph[node]) return true;
- const connections = Object.keys(graph[node]);
- return connections.length === 1;
+ if (!graph[node]) return true
+ const connections = Object.keys(graph[node])
+ return connections.length === 1
},
// 找到死胡同的入口节点(原路返回的衔接点)
findDeadEndEntry(deadEndNode, graph, fromNode, nodeCoords) {
// 从死胡同节点开始,沿着唯一路径往回找,直到找到分支点或起点
- let currentNode = deadEndNode;
- let visited = new Set([currentNode]);
-
+ let currentNode = deadEndNode
+ let visited = new Set([currentNode])
+
while (currentNode) {
- const connections = graph[currentNode] ? Object.keys(graph[currentNode]) : [];
-
+ const connections = graph[currentNode] ? Object.keys(graph[currentNode]) : []
+
// 如果当前节点有多个连接,或者是从起点过来的节点,作为入口点
if (connections.length > 1 || currentNode === fromNode) {
- return currentNode;
+ return currentNode
}
-
+
// 继续往回找(排除已访问的节点)
- const nextNode = connections.find(node => !visited.has(node));
- if (!nextNode) break;
-
- visited.add(nextNode);
- currentNode = nextNode;
+ const nextNode = connections.find((node) => !visited.has(node))
+ if (!nextNode) break
+
+ visited.add(nextNode)
+ currentNode = nextNode
}
-
+
// 如果找不到合适的入口,返回原始最近节点
- return deadEndNode;
+ return deadEndNode
},
// 改进的路径查找,支持原路返回
async findPathWithReturn(graph, startNode, endNode, nodeCoords) {
try {
// 先尝试直接路径
- const directPath = dijkstra.find_path(graph, startNode, endNode);
+ const directPath = dijkstra.find_path(graph, startNode, endNode)
if (directPath && directPath.length > 0) {
- return {pathNodes: directPath, isDeadEnd: false};
+ return {pathNodes: directPath, isDeadEnd: false}
}
-
+
// 如果直接路径失败,检查是否是死胡同情况
if (this.isDeadEnd(endNode, graph)) {
// 找到死胡同入口作为替代终点
- const entryNode = this.findDeadEndEntry(endNode, graph, startNode, nodeCoords);
+ const entryNode = this.findDeadEndEntry(endNode, graph, startNode, nodeCoords)
if (entryNode && entryNode !== endNode) {
- const alternativePath = dijkstra.find_path(graph, startNode, entryNode);
+ const alternativePath = dijkstra.find_path(graph, startNode, entryNode)
if (alternativePath && alternativePath.length > 0) {
return {
- pathNodes: alternativePath,
+ pathNodes: alternativePath,
isDeadEnd: true,
actualEndNode: endNode,
- entryNode: entryNode
- };
+ entryNode: entryNode,
+ }
}
}
}
-
- return {pathNodes: null, isDeadEnd: false};
+
+ return {pathNodes: null, isDeadEnd: false}
} catch (error) {
- console.error('路径查找错误:', error);
- return {pathNodes: null, isDeadEnd: false};
+ console.error('路径查找错误:', error)
+ return {pathNodes: null, isDeadEnd: false}
}
},
// 通过坐标反向查找对应的路网节点(处理浮点数精度)
findNodeByCoord(coord, nodeCoords) {
- const tolerance = 0.000001; // 与findPointIndex保持一致的容差
+ const tolerance = 0.000001 // 与findPointIndex保持一致的容差
for (const [nodeId, nodeCoord] of Object.entries(nodeCoords)) {
- if (
- Math.abs(nodeCoord[0] - coord[0]) < tolerance &&
- Math.abs(nodeCoord[1] - coord[1]) < tolerance
- ) {
- return nodeId;
+ if (Math.abs(nodeCoord[0] - coord[0]) < tolerance && Math.abs(nodeCoord[1] - coord[1]) < tolerance) {
+ return nodeId
}
}
// 若未找到完全匹配的节点,返回最近的节点(降级处理)
- return this.findNearestNode(coord, nodeCoords);
+ return this.findNearestNode(coord, nodeCoords)
},
// 改进的路径生成,支持原路返回
async generatePathWithReturn(
- pathNodes,
- segmentStart,
- segmentEnd,
- segmentIndex,
+ pathNodes,
+ segmentStart,
+ segmentEnd,
+ segmentIndex,
totalPoints,
currPointType,
nextPointType,
isDeadEnd = false,
prevSegmentEndNode = null
) {
- const segmentPath = [];
- const segments = [];
-
+ const segmentPath = []
+ const segments = []
+
// 生成主要路径段
for (let j = 0; j < pathNodes.length - 1; j++) {
- const currentNode = pathNodes[j];
- const nextNode = pathNodes[j + 1];
-
- let segment = null;
+ const currentNode = pathNodes[j]
+ const nextNode = pathNodes[j + 1]
+
+ let segment = null
if (!this.join) {
segment = this.roadNetworkGeoJSON.features.find(
(f) =>
(f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
(f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)
- );
+ )
} else {
segment = this.roadNetworkGeoJSON.features.find(
(f) =>
((f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
- (f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)) &&
+ (f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)) &&
f.properties.载重吨 >= this.inputform.load &&
f.properties.宽度 >= this.inputform.width &&
f.properties.曲率半 <= this.inputform.minTurnRadius
- );
+ )
}
-
- if (!segment) continue;
-
- segments.push(segment);
- const segmentCoords = segment.geometry.coordinates[0];
-
+
+ if (!segment) continue
+
+ segments.push(segment)
+ const segmentCoords = segment.geometry.coordinates[0]
+
// 处理段内连接
if (j === 0) {
await this.handleSegmentStartWithReturn(
- segmentPath, segmentStart, segmentCoords, segmentIndex, currPointType, prevSegmentEndNode
- );
+ segmentPath,
+ segmentStart,
+ segmentCoords,
+ segmentIndex,
+ currPointType,
+ prevSegmentEndNode
+ )
} else {
- this.connectSegmentInternally(segmentPath, segmentCoords);
+ this.connectSegmentInternally(segmentPath, segmentCoords)
}
}
-
+
// 处理段结束连接(支持死胡同原路返回)
await this.handleSegmentEndWithReturn(
- segmentPath, segmentEnd, pathNodes, segmentIndex, totalPoints, nextPointType, isDeadEnd
- );
-
- return { path: segmentPath, segments };
+ segmentPath,
+ segmentEnd,
+ pathNodes,
+ segmentIndex,
+ totalPoints,
+ nextPointType,
+ isDeadEnd
+ )
+
+ return {path: segmentPath, segments}
},
// 改进的段起始处理
- async handleSegmentStartWithReturn(segmentPath, segmentStart, segmentCoords, segmentIndex, currPointType, prevSegmentEndNode) {
+ async handleSegmentStartWithReturn(
+ segmentPath,
+ segmentStart,
+ segmentCoords,
+ segmentIndex,
+ currPointType,
+ prevSegmentEndNode
+ ) {
if (segmentIndex === 0 || currPointType === 'start') {
// 第一段或起点:从实际起点开始
- segmentPath.push(segmentStart);
- const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords);
- segmentPath.push(nearestPoint);
-
- const startIndex = this.findPointIndex(segmentCoords, nearestPoint);
+ segmentPath.push(segmentStart)
+ const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords)
+ segmentPath.push(nearestPoint)
+
+ const startIndex = this.findPointIndex(segmentCoords, nearestPoint)
if (startIndex !== -1 && startIndex < segmentCoords.length - 1) {
- segmentPath.push(...segmentCoords.slice(startIndex + 1));
+ segmentPath.push(...segmentCoords.slice(startIndex + 1))
}
} else {
// 途经点之后的段:确保路径连续性
- segmentPath.push(segmentStart);
-
+ segmentPath.push(segmentStart)
+
// 找到与上一段衔接的最佳点
- const connectionPoint = this.findContinuationPoint(segmentCoords, prevSegmentEndNode);
+ const connectionPoint = this.findContinuationPoint(segmentCoords, prevSegmentEndNode)
if (connectionPoint) {
- segmentPath.push(connectionPoint);
- const connectionIndex = this.findPointIndex(segmentCoords, connectionPoint);
+ segmentPath.push(connectionPoint)
+ const connectionIndex = this.findPointIndex(segmentCoords, connectionPoint)
if (connectionIndex !== -1 && connectionIndex < segmentCoords.length - 1) {
- segmentPath.push(...segmentCoords.slice(connectionIndex + 1));
+ segmentPath.push(...segmentCoords.slice(connectionIndex + 1))
}
} else {
// 降级处理:使用最近点
- const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords);
- segmentPath.push(nearestPoint);
- const startIndex = this.findPointIndex(segmentCoords, nearestPoint);
+ const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords)
+ segmentPath.push(nearestPoint)
+ const startIndex = this.findPointIndex(segmentCoords, nearestPoint)
if (startIndex !== -1 && startIndex < segmentCoords.length - 1) {
- segmentPath.push(...segmentCoords.slice(startIndex + 1));
+ segmentPath.push(...segmentCoords.slice(startIndex + 1))
}
}
}
},
// 改进的段结束处理(支持死胡同)
- async handleSegmentEndWithReturn(segmentPath, segmentEnd, pathNodes, segmentIndex, totalPoints, nextPointType, isDeadEnd) {
+ async handleSegmentEndWithReturn(
+ segmentPath,
+ segmentEnd,
+ pathNodes,
+ segmentIndex,
+ totalPoints,
+ nextPointType,
+ isDeadEnd
+ ) {
if (isDeadEnd) {
// 死胡同情况:先到达目标点,然后原路返回到入口点
- const lastRoadNode = pathNodes[pathNodes.length - 1];
- const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode);
-
+ const lastRoadNode = pathNodes[pathNodes.length - 1]
+ const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode)
+
if (nearestPoint) {
// 前往目标点
- segmentPath.push(nearestPoint);
- segmentPath.push(segmentEnd);
-
+ segmentPath.push(nearestPoint)
+ segmentPath.push(segmentEnd)
+
// 原路返回到入口点(反向路径)
- this.retracePath(segmentPath, pathNodes);
+ this.retracePath(segmentPath, pathNodes)
}
} else {
// 正常情况
if (segmentIndex === totalPoints - 2) {
// 最后一段:连接到实际终点
- const lastRoadNode = pathNodes[pathNodes.length - 1];
- const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode);
-
+ const lastRoadNode = pathNodes[pathNodes.length - 1]
+ const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode)
+
if (nearestPoint) {
- segmentPath.push(nearestPoint);
- segmentPath.push(segmentEnd);
+ segmentPath.push(nearestPoint)
+ segmentPath.push(segmentEnd)
}
} else {
// 中间段:途经点处理
- const lastRoadNode = pathNodes[pathNodes.length - 1];
- const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode);
-
+ const lastRoadNode = pathNodes[pathNodes.length - 1]
+ const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode)
+
if (nearestPoint) {
- segmentPath.push(nearestPoint);
- segmentPath.push(segmentEnd);
+ segmentPath.push(nearestPoint)
+ segmentPath.push(segmentEnd)
}
}
}
@@ -1771,63 +1725,63 @@ export default {
retracePath(segmentPath, pathNodes) {
// 从路径节点反向生成返回路径
for (let i = pathNodes.length - 2; i >= 0; i--) {
- const currentNode = pathNodes[i];
- const nextNode = pathNodes[i + 1];
-
+ const currentNode = pathNodes[i]
+ const nextNode = pathNodes[i + 1]
+
let segment = this.roadNetworkGeoJSON.features.find(
(f) =>
(f.properties.FNODE_ == currentNode && f.properties.TNODE_ == nextNode) ||
(f.properties.FNODE_ == nextNode && f.properties.TNODE_ == currentNode)
- );
-
- if (!segment) continue;
-
- const segmentCoords = [...segment.geometry.coordinates[0]].reverse();
- this.connectSegmentInternally(segmentPath, segmentCoords);
+ )
+
+ if (!segment) continue
+
+ const segmentCoords = [...segment.geometry.coordinates[0]].reverse()
+ this.connectSegmentInternally(segmentPath, segmentCoords)
}
},
// 找到路径延续点(确保路径连续性)
findContinuationPoint(segmentCoords, prevEndNode) {
- if (!prevEndNode) return null;
-
- const nodeCoords = this.roadNetworkGeoJSONBuild.nodeCoords[prevEndNode];
- if (!nodeCoords) return null;
-
+ if (!prevEndNode) return null
+
+ const nodeCoords = this.roadNetworkGeoJSONBuild.nodeCoords[prevEndNode]
+ if (!nodeCoords) return null
+
// 在路段上找到与上一段结束点最近的点
- return this.findNearestPointOnLine(nodeCoords, segmentCoords);
+ return this.findNearestPointOnLine(nodeCoords, segmentCoords)
},
// 处理段起始连接
async handleSegmentStart(segmentPath, segmentStart, segmentCoords, segmentIndex) {
if (segmentIndex === 0) {
// 第一段:从实际起点开始
- segmentPath.push(segmentStart);
-
+ segmentPath.push(segmentStart)
+
// 找到距离起点最近的道路点
- const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords);
- segmentPath.push(nearestPoint);
-
+ const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords)
+ segmentPath.push(nearestPoint)
+
// 添加从最近点到路径的剩余部分
- const startIndex = this.findPointIndex(segmentCoords, nearestPoint);
+ const startIndex = this.findPointIndex(segmentCoords, nearestPoint)
if (startIndex !== -1 && startIndex < segmentCoords.length - 1) {
- segmentPath.push(...segmentCoords.slice(startIndex + 1));
+ segmentPath.push(...segmentCoords.slice(startIndex + 1))
}
} else {
// 中间段(途经点之后):从途经点开始
- segmentPath.push(segmentStart);
-
+ segmentPath.push(segmentStart)
+
// 找到距离途经点最近的道路点
- const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords);
- segmentPath.push(nearestPoint);
-
+ const nearestPoint = this.findNearestPointOnLine(segmentStart, segmentCoords)
+ segmentPath.push(nearestPoint)
+
// 添加从最近点到路径的剩余部分
- const startIndex = this.findPointIndex(segmentCoords, nearestPoint);
+ const startIndex = this.findPointIndex(segmentCoords, nearestPoint)
if (startIndex !== -1 && startIndex < segmentCoords.length - 1) {
- segmentPath.push(...segmentCoords.slice(startIndex + 1));
+ segmentPath.push(...segmentCoords.slice(startIndex + 1))
} else {
// 如果找不到索引,直接添加整段路径
- segmentPath.push(...segmentCoords);
+ segmentPath.push(...segmentCoords)
}
}
},
@@ -1836,214 +1790,213 @@ export default {
async handleSegmentEnd(segmentPath, segmentEnd, pathNodes, segmentIndex, totalPoints) {
if (segmentIndex === totalPoints - 2) {
// 最后一段:连接到实际终点
- const lastRoadNode = pathNodes[pathNodes.length - 1];
- const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode);
-
+ const lastRoadNode = pathNodes[pathNodes.length - 1]
+ const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode)
+
if (nearestPoint) {
- segmentPath.push(nearestPoint);
- segmentPath.push(segmentEnd);
+ segmentPath.push(nearestPoint)
+ segmentPath.push(segmentEnd)
}
} else {
// 中间段:途经点处理 - 确保正确连接到途经点
- const lastRoadNode = pathNodes[pathNodes.length - 1];
- const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode);
-
+ const lastRoadNode = pathNodes[pathNodes.length - 1]
+ const nearestPoint = this.findBestConnectionPoint(segmentEnd, lastRoadNode)
+
if (nearestPoint) {
// 先连接到路径上的最近点
- segmentPath.push(nearestPoint);
+ segmentPath.push(nearestPoint)
// 然后连接到途经点本身
- segmentPath.push(segmentEnd);
+ segmentPath.push(segmentEnd)
}
}
},
// 合并路径段(避免重复点)
mergePathSegments(fullPath, newSegment) {
- if (newSegment.length === 0) return;
-
+ if (newSegment.length === 0) return
+
if (fullPath.length === 0) {
- fullPath.push(...newSegment);
- return;
+ fullPath.push(...newSegment)
+ return
}
-
- const lastPoint = fullPath[fullPath.length - 1];
- const firstNewPoint = newSegment[0];
-
+
+ const lastPoint = fullPath[fullPath.length - 1]
+ const firstNewPoint = newSegment[0]
+
// 检查是否需要连接(如果点不重复)
if (lastPoint[0] !== firstNewPoint[0] || lastPoint[1] !== firstNewPoint[1]) {
// 点不重复,直接添加
- fullPath.push(...newSegment);
+ fullPath.push(...newSegment)
} else {
// 点重复,跳过第一个点
if (newSegment.length > 1) {
- fullPath.push(...newSegment.slice(1));
+ fullPath.push(...newSegment.slice(1))
}
}
},
// 在线段上找到最近的点
findNearestPointOnLine(point, lineCoords) {
- let nearestPoint = lineCoords[0];
- let minDistance = this.calculateDistance(point, nearestPoint);
-
+ let nearestPoint = lineCoords[0]
+ let minDistance = this.calculateDistance(point, nearestPoint)
+
for (let i = 1; i < lineCoords.length; i++) {
- const coord = lineCoords[i];
- const distance = this.calculateDistance(point, coord);
+ const coord = lineCoords[i]
+ const distance = this.calculateDistance(point, coord)
if (distance < minDistance) {
- minDistance = distance;
- nearestPoint = coord;
+ minDistance = distance
+ nearestPoint = coord
}
}
-
- return nearestPoint;
+
+ return nearestPoint
},
// 查找点在数组中的索引
findPointIndex(coords, point) {
- const tolerance = 0.000001; // 容差,处理浮点数精度问题
-
+ const tolerance = 0.000001 // 容差,处理浮点数精度问题
+
for (let i = 0; i < coords.length; i++) {
- if (Math.abs(coords[i][0] - point[0]) < tolerance &&
- Math.abs(coords[i][1] - point[1]) < tolerance) {
- return i;
+ if (Math.abs(coords[i][0] - point[0]) < tolerance && Math.abs(coords[i][1] - point[1]) < tolerance) {
+ return i
}
}
- return -1;
+ return -1
},
// 找到最佳连接点
findBestConnectionPoint(actualPoint, roadNode) {
- const roadNodeCoord = this.roadNetworkGeoJSONBuild.nodeCoords[roadNode];
- if (!roadNodeCoord) return null;
-
+ const roadNodeCoord = this.roadNetworkGeoJSONBuild.nodeCoords[roadNode]
+ if (!roadNodeCoord) return null
+
// 查找连接到该节点的所有道路段
- const connectedRoads = this.roadNetworkGeoJSON.features.filter(road =>
- road.properties.FNODE_ === roadNode || road.properties.TNODE_ === roadNode
- );
-
- if (connectedRoads.length === 0) return roadNodeCoord;
-
- let bestPoint = roadNodeCoord;
- let minDistance = this.calculateDistance(actualPoint, roadNodeCoord);
-
+ const connectedRoads = this.roadNetworkGeoJSON.features.filter(
+ (road) => road.properties.FNODE_ === roadNode || road.properties.TNODE_ === roadNode
+ )
+
+ if (connectedRoads.length === 0) return roadNodeCoord
+
+ let bestPoint = roadNodeCoord
+ let minDistance = this.calculateDistance(actualPoint, roadNodeCoord)
+
// 在所有连接的道路段上寻找最佳连接点
- connectedRoads.forEach(road => {
- const coords = road.geometry.coordinates[0];
-
+ connectedRoads.forEach((road) => {
+ const coords = road.geometry.coordinates[0]
+
// 检查道路段的每个点
- coords.forEach(coord => {
- const distance = this.calculateDistance(actualPoint, coord);
+ coords.forEach((coord) => {
+ const distance = this.calculateDistance(actualPoint, coord)
if (distance < minDistance) {
- minDistance = distance;
- bestPoint = coord;
+ minDistance = distance
+ bestPoint = coord
}
- });
- });
-
- return bestPoint;
+ })
+ })
+
+ return bestPoint
},
// 段内小段连接
connectSegmentInternally(segmentPath, segmentCoords) {
if (segmentPath.length === 0) {
- segmentPath.push(...segmentCoords);
- return;
+ segmentPath.push(...segmentCoords)
+ return
}
-
- const lastPoint = segmentPath[segmentPath.length - 1];
-
+
+ const lastPoint = segmentPath[segmentPath.length - 1]
+
// 找到与上一段终点最接近的点
- const nearestPointInfo = this.findNearestPointWithIndex(segmentCoords, lastPoint);
-
+ const nearestPointInfo = this.findNearestPointWithIndex(segmentCoords, lastPoint)
+
if (nearestPointInfo.index === 0) {
// 最近点是段首,正向连接
if (segmentCoords.length > 1) {
- segmentPath.push(...segmentCoords.slice(1));
+ segmentPath.push(...segmentCoords.slice(1))
}
} else if (nearestPointInfo.index === segmentCoords.length - 1) {
// 最近点是段尾,反向连接
- const reversedCoords = [...segmentCoords].reverse();
+ const reversedCoords = [...segmentCoords].reverse()
if (reversedCoords.length > 1) {
- segmentPath.push(...reversedCoords.slice(1));
+ segmentPath.push(...reversedCoords.slice(1))
}
} else {
// 最近点在中间,需要分割处理
- this.handleMidpointConnection(segmentPath, segmentCoords, nearestPointInfo);
+ this.handleMidpointConnection(segmentPath, segmentCoords, nearestPointInfo)
}
},
// 找到线上最近的点及其索引
findNearestPointWithIndex(coords, point) {
- let nearestIndex = 0;
- let nearestPoint = coords[0];
- let minDistance = this.calculateDistance(point, nearestPoint);
-
+ let nearestIndex = 0
+ let nearestPoint = coords[0]
+ let minDistance = this.calculateDistance(point, nearestPoint)
+
for (let i = 1; i < coords.length; i++) {
- const distance = this.calculateDistance(point, coords[i]);
+ const distance = this.calculateDistance(point, coords[i])
if (distance < minDistance) {
- minDistance = distance;
- nearestIndex = i;
- nearestPoint = coords[i];
+ minDistance = distance
+ nearestIndex = i
+ nearestPoint = coords[i]
}
}
-
- return { index: nearestIndex, point: nearestPoint, distance: minDistance };
+
+ return {index: nearestIndex, point: nearestPoint, distance: minDistance}
},
// 处理中间点连接
handleMidpointConnection(segmentPath, segmentCoords, nearestPointInfo) {
- const { index, point } = nearestPointInfo;
-
+ const {index, point} = nearestPointInfo
+
// 添加最近点
- segmentPath.push(point);
-
+ segmentPath.push(point)
+
// 决定连接方向(选择较短的部分)
- const distanceToStart = this.calculateDistance(point, segmentCoords[0]);
- const distanceToEnd = this.calculateDistance(point, segmentCoords[segmentCoords.length - 1]);
-
+ const distanceToStart = this.calculateDistance(point, segmentCoords[0])
+ const distanceToEnd = this.calculateDistance(point, segmentCoords[segmentCoords.length - 1])
+
if (distanceToStart <= distanceToEnd) {
// 向起点方向连接
if (index > 0) {
- const toStart = segmentCoords.slice(0, index).reverse();
- segmentPath.push(...toStart);
+ const toStart = segmentCoords.slice(0, index).reverse()
+ segmentPath.push(...toStart)
}
} else {
// 向终点方向连接
if (index < segmentCoords.length - 1) {
- const toEnd = segmentCoords.slice(index + 1);
- segmentPath.push(...toEnd);
+ const toEnd = segmentCoords.slice(index + 1)
+ segmentPath.push(...toEnd)
}
}
},
// 计算距离(使用更精确的方法)
calculateDistance(coord1, coord2) {
- const point1 = turf.point(coord1);
- const point2 = turf.point(coord2);
- return turf.distance(point1, point2, { units: 'meters' });
+ const point1 = turf.point(coord1)
+ const point2 = turf.point(coord2)
+ return turf.distance(point1, point2, {units: 'meters'})
},
// 检查路径可行性
isPathPossible(graph, startNode, endNode) {
// 使用广度优先搜索(BFS)检查路径可行性
- const visited = new Set();
- const queue = [startNode];
- visited.add(startNode);
+ const visited = new Set()
+ const queue = [startNode]
+ visited.add(startNode)
while (queue.length > 0) {
- const currentNode = queue.shift();
+ const currentNode = queue.shift()
if (currentNode === endNode) {
- return true;
+ return true
}
- const neighbors = graph[currentNode];
+ const neighbors = graph[currentNode]
if (neighbors) {
for (const neighbor in neighbors) {
if (!visited.has(neighbor)) {
- visited.add(neighbor);
- queue.push(neighbor);
+ visited.add(neighbor)
+ queue.push(neighbor)
}
}
}
}
- return false;
+ return false
},
async calculateShortestPath() {
if (!this.pointQD || !this.pointZD || !this.roadNetworkGeoJSON) {
@@ -2053,20 +2006,13 @@ export default {
this.shortestPathLayer.clear()
this.shortestPathList = []
this.infoList = []
- const startPoint = turf.point(
- this.pointQD.toGeoJSON().geometry.coordinates
- ).geometry.coordinates // 起点
- const endPoint = turf.point(this.pointZD.toGeoJSON().geometry.coordinates)
- .geometry.coordinates // 终点
+ const startPoint = turf.point(this.pointQD.toGeoJSON().geometry.coordinates).geometry.coordinates // 起点
+ const endPoint = turf.point(this.pointZD.toGeoJSON().geometry.coordinates).geometry.coordinates // 终点
// 途经点
- const viaPointsGeoJSON =
- this.viaPoints.map((point) => point.toGeoJSON()) || []
- const viaPointsTurf = viaPointsGeoJSON.map((p) =>
- turf.point(p.geometry.coordinates)
- )
+ const viaPointsGeoJSON = this.viaPoints.map((point) => point.toGeoJSON()) || []
+ const viaPointsTurf = viaPointsGeoJSON.map((p) => turf.point(p.geometry.coordinates))
// 避让点 算成有半径的圆 方便去和线去调整
- const avoidPointsGeoJSON =
- this.avoidPoints.map((point) => point.toGeoJSON()) || []
+ const avoidPointsGeoJSON = this.avoidPoints.map((point) => point.toGeoJSON()) || []
const avoidPointsPolygons = avoidPointsGeoJSON.map((point) => {
return turf.circle(
turf.point(point.geometry.coordinates),
@@ -2074,7 +2020,7 @@ export default {
{
steps: 64,
units: 'meters',
- properties: { type: 'avoid_point' } // 给圆添加属性,方便后续调试区分“点转圆”和“原生区域”
+ properties: {type: 'avoid_point'}, // 给圆添加属性,方便后续调试区分“点转圆”和“原生区域”
} // 显式指定单位
)
})
@@ -2094,17 +2040,10 @@ export default {
// })
// 避让区域
const avoidAreasGeoJSON =
- this.avoidAreas.map((area) => turf.feature(area.toGeoJSON({closure: true}.geometry, { type: 'avoid_area' }))) || []
- const obstaclesGeoJSON = turf.featureCollection([
- ...avoidPointsPolygons,
- ...avoidAreasGeoJSON,
- ])
- const route = await this.planRoute(
- startPoint,
- endPoint,
- viaPointsTurf,
- obstaclesGeoJSON
- )
+ this.avoidAreas.map((area) => turf.feature(area.toGeoJSON({closure: true}.geometry, {type: 'avoid_area'}))) ||
+ []
+ const obstaclesGeoJSON = turf.featureCollection([...avoidPointsPolygons, ...avoidAreasGeoJSON])
+ const route = await this.planRoute(startPoint, endPoint, viaPointsTurf, obstaclesGeoJSON)
this.drawPath(route)
},
@@ -2128,7 +2067,7 @@ export default {
drawPath(path) {
const positions = path
if (positions.fullPath.length == 0) return
-
+
// 1. 绘制主要路径
const polyline = new window.mars3d.graphic.PolylinePrimitive({
positions: positions.fullPath,
@@ -2139,92 +2078,89 @@ export default {
},
})
this.shortestPathLayer.addGraphic(polyline)
-
+
// 2. 添加方向箭头
this.addDirectionArrows(positions.fullPath)
-
+
this.shortestPathList.push(path.infoList)
this.infoList = path.infoList.map((item) => item.properties)
},
// 添加方向箭头
addDirectionArrows(pathCoords) {
- if (pathCoords.length < 2) return;
-
- const arrowLayer = this.shortestPathLayer;
- const baseArrowSpacing = 10000; // 基础间距(米)
- const minArrowSpacing = 1000; // 最小间距(避免过密,可根据需求调整)
- const minSegmentLength = 500; // 最小线段长度(短于该值的线段合并,可调整)
+ if (pathCoords.length < 2) return
+
+ const arrowLayer = this.shortestPathLayer
+ const baseArrowSpacing = 10000 // 基础间距(米)
+ const minArrowSpacing = 1000 // 最小间距(避免过密,可根据需求调整)
+ const minSegmentLength = 500 // 最小线段长度(短于该值的线段合并,可调整)
// 预处理:合并过近的连续点
- const filteredCoords = this.filterClosePoints(pathCoords, minSegmentLength);
+ const filteredCoords = this.filterClosePoints(pathCoords, minSegmentLength)
for (let i = 0; i < filteredCoords.length - 1; i++) {
- const startCoord = filteredCoords[i];
- const endCoord = filteredCoords[i + 1];
- const segmentDistance = this.calculateDistance(startCoord, endCoord);
+ const startCoord = filteredCoords[i]
+ const endCoord = filteredCoords[i + 1]
+ const segmentDistance = this.calculateDistance(startCoord, endCoord)
// 跳过过短的线段(已合并但仍可能存在的极短线段)
- if (segmentDistance < minSegmentLength) continue;
+ if (segmentDistance < minSegmentLength) continue
// 动态计算当前线段的箭头间距:
// 线段越长,间距越接近基础值;线段越短,间距按比例缩小,但不小于最小间距
const dynamicSpacing = Math.max(
minArrowSpacing,
Math.min(baseArrowSpacing, segmentDistance / 5) // 最多在该线段放5个箭头
- );
+ )
// 在当前段上放置箭头(从起点开始,按动态间距排列)
- let segmentAccumulated = 0;
+ let segmentAccumulated = 0
while (segmentAccumulated < segmentDistance) {
- const ratio = segmentAccumulated / segmentDistance;
- const arrowPosition = this.interpolatePoint(startCoord, endCoord, ratio);
- const arrowDirection = this.calculateDirection(startCoord, endCoord);
- this.createArrow(arrowLayer, arrowPosition, arrowDirection);
+ const ratio = segmentAccumulated / segmentDistance
+ const arrowPosition = this.interpolatePoint(startCoord, endCoord, ratio)
+ const arrowDirection = this.calculateDirection(startCoord, endCoord)
+ this.createArrow(arrowLayer, arrowPosition, arrowDirection)
- segmentAccumulated += dynamicSpacing;
+ segmentAccumulated += dynamicSpacing
}
}
// 终点箭头(基于过滤后的坐标)
if (filteredCoords.length >= 2) {
- const lastPoint = filteredCoords[filteredCoords.length - 1];
- const secondLastPoint = filteredCoords[filteredCoords.length - 2];
- const finalDirection = this.calculateDirection(secondLastPoint, lastPoint);
- this.createArrow(arrowLayer, lastPoint, finalDirection);
+ const lastPoint = filteredCoords[filteredCoords.length - 1]
+ const secondLastPoint = filteredCoords[filteredCoords.length - 2]
+ const finalDirection = this.calculateDirection(secondLastPoint, lastPoint)
+ this.createArrow(arrowLayer, lastPoint, finalDirection)
}
},
// 辅助方法:过滤过近的连续点(保留关键转折点)
filterClosePoints(coords, minDistance) {
- if (coords.length <= 1) return coords;
- const filtered = [coords[0]];
- let lastCoord = coords[0];
+ if (coords.length <= 1) return coords
+ const filtered = [coords[0]]
+ let lastCoord = coords[0]
for (let i = 1; i < coords.length; i++) {
- const currentCoord = coords[i];
- const distance = this.calculateDistance(lastCoord, currentCoord);
+ const currentCoord = coords[i]
+ const distance = this.calculateDistance(lastCoord, currentCoord)
// 只有当当前点与上一个保留点的距离超过阈值时,才保留当前点
if (distance >= minDistance) {
- filtered.push(currentCoord);
- lastCoord = currentCoord;
+ filtered.push(currentCoord)
+ lastCoord = currentCoord
}
}
// 确保终点被保留(避免因最后一段过短而丢失终点)
if (filtered[filtered.length - 1] !== coords[coords.length - 1]) {
- filtered.push(coords[coords.length - 1]);
+ filtered.push(coords[coords.length - 1])
}
- return filtered;
+ return filtered
},
// 插值计算点位置
interpolatePoint(start, end, ratio) {
- return [
- start[0] + (end[0] - start[0]) * ratio,
- start[1] + (end[1] - start[1]) * ratio
- ]
+ return [start[0] + (end[0] - start[0]) * ratio, start[1] + (end[1] - start[1]) * ratio]
},
// 计算方向(角度)
@@ -2245,8 +2181,8 @@ export default {
extrudedHeight: 10, // 稍微抬升避免重叠
outline: true,
outlineColor: Cesium.Color.WHITE,
- outlineWidth: 1
- }
+ outlineWidth: 1,
+ },
})
layer.addGraphic(arrow)
},
@@ -2255,23 +2191,20 @@ export default {
calculateArrowShape(center, direction) {
const size = 0.0001 // 箭头大小(经纬度)
const angle = direction * (Math.PI / 180) // 转换为弧度
-
+
// 箭头三角形的三个点
- const tip = [
- center[0] + Math.cos(angle) * size * 2,
- center[1] + Math.sin(angle) * size * 2
- ]
-
+ const tip = [center[0] + Math.cos(angle) * size * 2, center[1] + Math.sin(angle) * size * 2]
+
const left = [
center[0] + Math.cos(angle + Math.PI * 0.8) * size,
- center[1] + Math.sin(angle + Math.PI * 0.8) * size
+ center[1] + Math.sin(angle + Math.PI * 0.8) * size,
]
-
+
const right = [
center[0] + Math.cos(angle - Math.PI * 0.8) * size,
- center[1] + Math.sin(angle - Math.PI * 0.8) * size
+ center[1] + Math.sin(angle - Math.PI * 0.8) * size,
]
-
+
return [tip, left, right, tip] // 闭合三角形
},
},
@@ -2347,14 +2280,14 @@ export default {
display: flex;
justify-content: space-between;
}
-.control-panel .title .joinCheck {
+.control-panel .title .joinCheck {
font-size: 14px;
color: #555;
}
.el-checkbox {
- margin-right: 5px!important;
+ margin-right: 5px !important;
}
-
+
.importJson {
display: flex;
flex-direction: row;
@@ -2404,6 +2337,4 @@ export default {
.popDiloag .popDiloag-title {
font-weight: 500;
}
-.popDiloag .popDiloag-p {
-}
diff --git a/src/views/residentAnalysis/index.vue b/src/views/residentAnalysis/index.vue
index 86d0c59..36c10a6 100644
--- a/src/views/residentAnalysis/index.vue
+++ b/src/views/residentAnalysis/index.vue
@@ -3,13 +3,8 @@
@@ -20,21 +15,14 @@
范围
-
+
-
+
-
-
- 导入json文件
-
+
+
导入json文件
@@ -72,71 +60,232 @@
+
+
-
+
-
- 道路附属点
-
-
+ 道路附属点
+
-
+
道路附属线
-
+
-
+
-
- 水系附属点
-
-
+ 水系附属点
+
-
+
+
-
- 水系附属线
-
-
+ 水系附属线
+
-
+
+
+
+
+
+
+
+
+ 道路附属点
+ 新增
+
+
+
+
+
+
+ {{ row.编码 }}
+
+
+
+
+
+ {{ row.名称 }}
+
+
+
+
+
+ {{ row.A }}
+
+
+
+
+ 编辑
+ 保存
+ 删除
+
+
+
+
+
+
+
+
+ 道路附属线
+ 新增
+
+
+
+
+
+
+ {{ row.编码 }}
+
+
+
+
+
+ {{ row.名称 }}
+
+
+
+
+
+ {{ row.A }}
+
+
+
+
+ 编辑
+ 保存
+ 删除
+
+
+
+
+
+
+
+
+
+
+ 水系附属点
+ 新增
+
+
+
+
+
+
+ {{ row.编码 }}
+
+
+
+
+
+ {{ row.名称 }}
+
+
+
+
+
+ {{ row.A }}
+
+
+
+
+ 编辑
+ 保存
+ 删除
+
+
+
+
+
+
+
+
+ 水系附属线
+ 新增
+
+
+
+
+
+
+ {{ row.编码 }}
+
+
+
+
+
+ {{ row.名称 }}
+
+
+
+
+
+ {{ row.A }}
+
+
+
+
+ 编辑
+ 保存
+ 删除
+
+
+
+
+
+
+
+
@@ -145,6 +294,8 @@
import {getStorage} from '@/utils/localStorage'
import plantJson from '/public/config/plant.json'
import soilJson from '/public/config/soil.json'
+import axios from 'axios'
+import iniParser from 'ini-parser'
export default {
name: '',
@@ -192,6 +343,16 @@ export default {
validBlocks: [],
colorList: [],
roadWaterLock: false,
+
+ dialogVisible: false,
+ rectTotalScore: '0.31',
+ exportList: {
+ roadPointList: [],
+ roadLineList: [],
+ waterPointList: [],
+ waterLineList: [],
+ },
+ tableHeight: 280,
}
},
created() {
@@ -270,10 +431,7 @@ export default {
return
}
// 清除现有矩形
- if (
- this.polygon &&
- (uploadedJson?.leftTop || uploadedJson?.rightBottom)
- ) {
+ if (this.polygon && (uploadedJson?.leftTop || uploadedJson?.rightBottom)) {
window.graphicLayer.removeGraphic(this.polygon)
}
@@ -293,17 +451,13 @@ export default {
// 初始化地图
initMarsMap() {
- window.viewer = new window.mars3d.Map(
- 'cesiumContainer',
- this.viewerOptions
- )
+ window.viewer = new window.mars3d.Map('cesiumContainer', this.viewerOptions)
window.graphicLayer = new window.mars3d.layer.GraphicLayer()
window.viewer.addLayer(window.graphicLayer)
window.shortestPathLayer = new window.mars3d.layer.GraphicLayer()
window.viewer.addLayer(window.shortestPathLayer)
- // this.drawInitialArea()
this.loadGeoJson()
},
@@ -313,26 +467,10 @@ export default {
people: this.createLayerConfig('./config/people.geojson', '#ff0000'),
plant: this.createLayerConfig('./config/plant.geojson', '#00ff00'),
soil: this.createLayerConfig('./config/soil.geojson', '#0000ff'),
- roadPoint: this.createLayerConfig(
- './config/road_points.geojson',
- '#ff0ff0',
- 'point'
- ),
- roadLine: this.createLayerConfig(
- './config/road_lines.geojson',
- '#ff0ff0',
- 'polyline'
- ),
- waterPoint: this.createLayerConfig(
- './config/water_points.geojson',
- '#ff0ff0',
- 'point'
- ),
- waterLine: this.createLayerConfig(
- './config/water_lines.geojson',
- '#ff0ff0',
- 'polyline'
- ),
+ roadPoint: this.createLayerConfig('./config/road_points.geojson', '#ff0ff0', 'point'),
+ roadLine: this.createLayerConfig('./config/road_lines.geojson', '#ff0ff0', 'polyline'),
+ waterPoint: this.createLayerConfig('./config/water_points.geojson', '#ff0ff0', 'point'),
+ waterLine: this.createLayerConfig('./config/water_lines.geojson', '#ff0ff0', 'polyline'),
}
// 默认只加载一个,其他按需加载
@@ -418,9 +556,7 @@ export default {
return
}
- this.layers[layerName].layer = new mars3d.layer.GeoJsonLayer(
- this.layers[layerName].config
- )
+ this.layers[layerName].layer = new mars3d.layer.GeoJsonLayer(this.layers[layerName].config)
isLoad ? await window.viewer.addLayer(this.layers[layerName].layer) : null
},
@@ -463,17 +599,12 @@ export default {
let minDist = Infinity
let inside = false
- const polygons = geoJSONLayer
- .getGraphics()
- .filter((g) => g.type === 'polygon')
+ const polygons = geoJSONLayer.getGraphics().filter((g) => g.type === 'polygon')
polygons.forEach((g) => {
const lnglats = g.positions.map((p) => {
const carto = Cesium.Cartographic.fromCartesian(p)
- return [
- Cesium.Math.toDegrees(carto.longitude),
- Cesium.Math.toDegrees(carto.latitude),
- ]
+ return [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)]
})
lnglats.push(lnglats[0])
const poly = turf.polygon([lnglats])
@@ -486,21 +617,17 @@ export default {
const polyLine = turf.lineString(lnglats)
rectLine.geometry.coordinates.forEach((pt) => {
const closest = turf.nearestPointOnLine(polyLine, pt)
- const d = turf.distance(pt, closest, {units: 'kilometers'}) * 1000
+ const d = turf.distance(pt, closest, {units: 'metres'})
minDist = Math.min(minDist, d)
})
polyLine.geometry.coordinates.forEach((pt) => {
const closest = turf.nearestPointOnLine(rectLine, pt)
- const d = turf.distance(pt, closest, {units: 'kilometers'}) * 1000
+ const d = turf.distance(pt, closest, {units: 'metres'})
minDist = Math.min(minDist, d)
})
})
- console.log(
- '矩形 → polygonP 边界最短距离(米)',
- inside ? -1 : false,
- minDist
- )
+ console.log('矩形 → polygonP 边界最短距离(米)', inside, minDist)
// 5. 面内直接返回 -1
return inside ? -1 : minDist
@@ -530,10 +657,7 @@ export default {
if (g.type === 'polygon') {
const coords = g.positions.map((p) => {
const carto = Cesium.Cartographic.fromCartesian(p)
- return [
- Cesium.Math.toDegrees(carto.longitude),
- Cesium.Math.toDegrees(carto.latitude),
- ]
+ return [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)]
})
coords.push(coords[0]) // 闭合
features.push({
@@ -546,10 +670,7 @@ export default {
else if (g.type === 'polyline') {
const coords = g.positions.map((p) => {
const carto = Cesium.Cartographic.fromCartesian(p)
- return [
- Cesium.Math.toDegrees(carto.longitude),
- Cesium.Math.toDegrees(carto.latitude),
- ]
+ return [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)]
})
features.push({
type: 'Feature',
@@ -560,10 +681,7 @@ export default {
// 处理点要素
else if (g.type === 'point') {
const carto = Cesium.Cartographic.fromCartesian(g.position)
- const coord = [
- Cesium.Math.toDegrees(carto.longitude),
- Cesium.Math.toDegrees(carto.latitude),
- ]
+ const coord = [Cesium.Math.toDegrees(carto.longitude), Cesium.Math.toDegrees(carto.latitude)]
features.push({
type: 'Feature',
geometry: {type: 'Point', coordinates: coord},
@@ -629,13 +747,11 @@ export default {
},
// 绘制矩形区域
- drawInitialArea(val) {
+ drawInitialArea() {
// 如果多边形尚未创建,则创建它
if (!this.polygon) {
this.polygon = new mars3d.graphic.PolygonEntity({
- positions: this.positions.map((p) =>
- Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)
- ),
+ positions: this.positions.map((p) => Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)),
style: {
color: '#ffff00',
opacity: 0.3,
@@ -654,13 +770,11 @@ export default {
},
})
- console.log(' this.polygon===>', this.polygon)
-
window.graphicLayer.addGraphic(this.polygon)
this.isInitialized = true
} else {
// 如果多边形已存在,则更新它的位置
- this.updateArea(val)
+ this.updateArea()
}
},
@@ -669,12 +783,15 @@ export default {
this.isHand = false
return
}
- if (!this.polygon) return
+
+ if (!this.form.leftTop || !this.form.rightBottom) return
+
+ if (this.form.leftTop && this.form.rightBottom && !this.polygon) {
+ this.drawInitialArea()
+ }
// 将经纬度转换为笛卡尔坐标
- const cartesianPositions = this.positions.map((p) =>
- Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)
- )
+ const cartesianPositions = this.positions.map((p) => Cesium.Cartesian3.fromDegrees(p[0], p[1], 0))
// 更新多边形位置
this.polygon.positions = cartesianPositions
@@ -778,48 +895,26 @@ export default {
]
const slope = slopes[index]
- const distance = this.calcMinDistance(
- rectPos,
- this.layers['people'].layer
- )
+ const distance = this.calcMinDistance(rectPos, this.layers['people'].layer)
- if (
- slope < this.form.maxSlope &&
- distance > this.form.minPeopleDis
- ) {
- console.log('111===>', slope, distance)
-
- const soilGeoId = this.getIntersectId(
- rectPos,
- this.layers['soil'].layer
- )
- const plantGeoId = this.getIntersectId(
- rectPos,
- this.layers['plant'].layer
- )
+ if (slope < this.form.maxSlope && distance > this.form.minPeopleDis) {
+ const soilGeoId = this.getIntersectId(rectPos, this.layers['soil'].layer)
+ const plantGeoId = this.getIntersectId(rectPos, this.layers['plant'].layer)
const plantScore = plantGeoId
? this.getScore(
- this.layers['plant'].layer.getGraphicById(plantGeoId)
- .options.attr['编码'],
+ this.layers['plant'].layer.getGraphicById(plantGeoId).options.attr['编码'],
this.plantJson
)
: 0
const soilScore = soilGeoId
- ? this.getScore(
- this.layers['soil'].layer.getGraphicById(soilGeoId).options
- .attr['编码'],
- this.soilJson
- )
+ ? this.getScore(this.layers['soil'].layer.getGraphicById(soilGeoId).options.attr['编码'], this.soilJson)
: 1
/* 2. 合并成一条记录 */
this.validBlocks.push({
id: `rect_${index + 1}`,
positions: rectPos,
- center: [
- (rectInfo.minLng + rectInfo.maxLng) / 2,
- (rectInfo.minLat + rectInfo.maxLat) / 2,
- ],
+ center: [(rectInfo.minLng + rectInfo.maxLng) / 2, (rectInfo.minLat + rectInfo.maxLat) / 2],
slope,
distance,
plantScore,
@@ -844,7 +939,10 @@ export default {
/* 1. 计算总分(保持原逻辑) */
const list = this.calcTotalScore(this.validBlocks)
const len = list.length
- if (!len) return
+ if (!len) {
+ this.$message.success('计算结束,暂无符合条件的区域!')
+ return
+ }
/* 2. 一次性构造 options 数组,不 new Graphic */
const rectOpts = []
@@ -907,9 +1005,7 @@ export default {
}
/* 3. 批量创建 Graphic(底层一次性构造,避免反复 new) */
- this.rectangles = rectOpts.map(
- (opt) => new mars3d.graphic.PolygonEntity(opt)
- )
+ this.rectangles = rectOpts.map((opt) => new mars3d.graphic.PolygonEntity(opt))
this.labels = labelOpts.map((opt) => new mars3d.graphic.LabelEntity(opt))
/* 4. 一次性添加到图层(mars3d 支持数组)*/
@@ -934,7 +1030,7 @@ export default {
this.selectRectangle(graphic)
}
}
- this.$message.success('计算成功!')
+ this.$message.success(`计算成功!共有${len}个符合条件的区域`)
},
/**
@@ -979,10 +1075,7 @@ export default {
const item = data[i]
// 计算slope分数
- const slopeScore =
- slopeRange > 0
- ? ((item.slope - minSlope) / slopeRange) * slopePer
- : 0.5 * slopePer // 处理slope范围很小的情况
+ const slopeScore = slopeRange > 0 ? ((item.slope - minSlope) / slopeRange) * slopePer : 0.5 * slopePer // 处理slope范围很小的情况
// 计算distance分数
const peopleScore = isDistanceRangeSmall
@@ -993,12 +1086,7 @@ export default {
const plantScore = (item.plantScore || 0) * plantPer
const soilScore = item.soilScore * soilPer
- const totalScore = (
- slopeScore +
- peopleScore +
- plantScore +
- soilScore
- ).toFixed(2)
+ const totalScore = (slopeScore + peopleScore + plantScore + soilScore).toFixed(2)
results[i] = {
...item,
@@ -1024,9 +1112,7 @@ export default {
if (!targetCode) {
return 0
}
- const hit = list.find(
- (item) => Array.isArray(item.code) && item.code.includes(targetCode)
- )
+ const hit = list.find((item) => Array.isArray(item.code) && item.code.includes(targetCode))
if (hit) return hit.score
const fallback = list.find((item) => item.code === null)
@@ -1051,67 +1137,102 @@ export default {
this.waterPointList = []
this.waterLineList = []
+ this.exportList.roadPointList = []
+ this.exportList.roadLineList = []
+ this.exportList.waterPointList = []
+ this.exportList.waterLineList = []
+
if (!this.roadWaterLock) {
- this.loadLayers(
- ['roadPoint', 'roadLine', 'waterPoint', 'waterLine'],
- (results) => {
- this.roadWaterLock = true
- this.getRoadWaterIds(rect)
- }
- )
+ this.loadLayers(['roadPoint', 'roadLine', 'waterPoint', 'waterLine'], (results) => {
+ this.roadWaterLock = true
+ this.getRoadWaterIds(rect)
+ })
} else {
this.getRoadWaterIds(rect)
}
+ this.rectTotalScore = rect.attr.originalData.totalScore
},
getRoadWaterIds(rect) {
const positions = rect.points.map((d) => [d.lng, d.lat])
- let roadPointId = this.getIntersectId(
- positions,
- this.layers['roadPoint'].layer
- )
- let roadLineId = this.getIntersectId(
- positions,
- this.layers['roadLine'].layer
- )
- let waterPointId = this.getIntersectId(
- positions,
- this.layers['waterPoint'].layer
- )
- let waterLineId = this.getIntersectId(
- positions,
- this.layers['waterLine'].layer
- )
+ let roadPointId = this.getIntersectId(positions, this.layers['roadPoint'].layer)
+ let roadLineId = this.getIntersectId(positions, this.layers['roadLine'].layer)
+ let waterPointId = this.getIntersectId(positions, this.layers['waterPoint'].layer)
+ let waterLineId = this.getIntersectId(positions, this.layers['waterLine'].layer)
if (roadPointId) {
- this.roadPointList.push(
- this.layers['roadPoint'].layer.getGraphicById(roadPointId).options
- .attr
- )
+ this.roadPointList.push(this.layers['roadPoint'].layer.getGraphicById(roadPointId).options.attr)
+ this.exportList.roadPointList.push(this.layers['roadPoint'].layer.getGraphicById(roadPointId).options.attr)
} else if (roadLineId) {
- this.roadLineList.push(
- this.layers['roadLine'].layer.getGraphicById(roadLineId).options.attr
- )
+ this.roadLineList.push(this.layers['roadLine'].layer.getGraphicById(roadLineId).options.attr)
+ this.exportList.roadLineList.push(this.layers['roadLine'].layer.getGraphicById(roadLineId).options.attr)
} else if (waterPointId) {
- this.waterPointList.push(
- this.layers['waterPoint'].layer.getGraphicById(waterPointId).options
- .attr
- )
+ this.waterPointList.push(this.layers['waterPoint'].layer.getGraphicById(waterPointId).options.attr)
+ this.exportList.waterPointList.push(this.layers['waterPoint'].layer.getGraphicById(waterPointId).options.attr)
} else if (waterLineId) {
- this.waterLineList.push(
- this.layers['waterLine'].layer.getGraphicById(waterLineId).options
- .attr
- )
+ this.waterLineList.push(this.layers['waterLine'].layer.getGraphicById(waterLineId).options.attr)
+ this.exportList.waterLineList.push(this.layers['waterLine'].layer.getGraphicById(waterLineId).options.attr)
}
+ },
- console.log(
- 'roadPointId===>',
- this.roadPointList,
- this.roadLineList,
- this.waterPointList,
- this.waterLineList
- )
+ // 导出为 JSON文件
+ exportJSON() {
+ try {
+ let file = {
+ id: 1,
+ [this.rectTotalScore]: this.exportList,
+ }
+ fetch('./config.ini')
+ .then((r) => r.text())
+ .then((res) => {
+ const parsedData = iniParser.parse(res)
+ this.$alert(parsedData)
+ axios
+ .post(`http://${parsedData.http.address}:${parsedData.http.port}/api/area`, JSON.stringify(file), {
+ headers: {'Content-Type': 'application/json'},
+ })
+ .then((res) => {
+ this.$alert(res)
+ // this.$message.success(res)
+ // this.$message.success('导出成功!')
+ })
+ .catch((error) => {
+ this.$message.error(error)
+ })
+ })
+ } catch (error) {
+ console.error(error)
+ }
+ },
+
+ // 新增
+ handleAdd(type) {
+ const newRow = {
+ seq: this.exportList[type].length + 1,
+ 编码: '',
+ 名称: '',
+ A: '',
+ editing: true,
+ }
+ this.exportList[type].push(newRow)
+ setTimeout(() => {
+ this.$refs[`${type}REF`].refreshScroll()
+ this.$refs[`${type}REF`].scrollToRow(newRow, 'id')
+ }, 50)
+ },
+
+ handleEdit(row) {
+ this.$set(row, 'editing', true)
+ },
+ handleSave(row) {
+ this.$set(row, 'editing', false)
+ },
+ handleDelete(type, row) {
+ const index = this.exportList[type].findIndex((item) => item.id === row.id)
+ if (index !== -1) {
+ this.exportList[type].splice(index, 1)
+ }
},
// 清除所有矩形
@@ -1172,6 +1293,10 @@ export default {
transform: translateY(-50%);
right: 32px;
}
+ .right {
+ position: absolute;
+ right: 30px;
+ }
}
.content {
@@ -1223,14 +1348,32 @@ export default {
.item {
margin-bottom: 10px;
}
-
- .table-title {
- font-size: 16px;
- font-family: 'Pingfang';
- font-weight: bold;
- letter-spacing: 0.1em;
- margin-bottom: 10px;
- }
}
}
+.table-title {
+ font-size: 16px;
+ font-family: 'Pingfang';
+ font-weight: bold;
+ letter-spacing: 0.1em;
+ margin-bottom: 10px;
+ span {
+ margin-right: 10px;
+ }
+}
+
+.export {
+ position: relative;
+ top: -20px;
+}
+.road,
+.water {
+ width: 100%;
+ .point,
+ .line {
+ width: 49%;
+ }
+}
+.road {
+ margin-bottom: 20px;
+}