Compare commits
22
Commits
0c59002bd4
...
pathPlan
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e606513f5 | ||
|
|
1c76c7d23c | ||
|
|
802df4d446 | ||
|
|
46c6b952fc | ||
|
|
a562e2cea8 | ||
|
|
af252cd65e | ||
|
|
444bded88f | ||
|
|
964ce7cede | ||
|
|
ce70fd98ec | ||
|
|
7d22506f18 | ||
|
|
328700ec89 | ||
|
|
2ad6bc1b47 | ||
|
|
41f9034f54 | ||
|
|
ae2f9d94e1 | ||
|
|
c1876d23bd | ||
|
|
e2b73640df | ||
|
|
f084fc92e9 | ||
|
|
3e7ccea682 | ||
|
|
935846d7f2 | ||
|
|
cc774db444 | ||
|
|
c1370dcbc0 | ||
|
|
8ea0f436b1 |
@@ -1,29 +1,3 @@
|
|||||||
# kxfx
|
# kxfx
|
||||||
|
|
||||||
## Project setup
|
## 机动路线规划
|
||||||
|
|
||||||
```
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compiles and hot-reloads for development
|
|
||||||
|
|
||||||
```
|
|
||||||
npm run serve
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compiles and minifies for production
|
|
||||||
|
|
||||||
```
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lints and fixes files
|
|
||||||
|
|
||||||
```
|
|
||||||
npm run lint
|
|
||||||
```
|
|
||||||
|
|
||||||
### Customize configuration
|
|
||||||
|
|
||||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
|
||||||
|
|||||||
+8
-3
@@ -9,12 +9,15 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "0.21.0",
|
"@babel/preset-env": "^7.28.3",
|
||||||
"core-js": "^3.8.3",
|
"axios": "^1.13.2",
|
||||||
"echarts": "^5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-ui": "2.9.2",
|
"element-ui": "2.9.2",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
|
"ini-parser": "^0.0.2",
|
||||||
"js-cookie": "2.2.1",
|
"js-cookie": "2.2.1",
|
||||||
|
"raw-loader": "^4.0.2",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-router": "^3.5.1",
|
"vue-router": "^3.5.1",
|
||||||
"vuex": "^3.6.2",
|
"vuex": "^3.6.2",
|
||||||
@@ -22,13 +25,15 @@
|
|||||||
"vxe-table": "~3.18.9"
|
"vxe-table": "~3.18.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@babel/core": "^7.28.4",
|
||||||
"@babel/eslint-parser": "^7.12.16",
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
"@vue/cli-plugin-router": "~5.0.0",
|
"@vue/cli-plugin-router": "~5.0.0",
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
|
"babel-loader": "^10.0.0",
|
||||||
|
"core-js": "^3.46.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[http]
|
||||||
|
port=8381
|
||||||
|
address=192.168.3.35
|
||||||
|
|
||||||
|
[title]
|
||||||
|
msg=道路堪选分析
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
window.config = {
|
||||||
|
// baseUrl: 'http://192.168.3.35:8381',
|
||||||
|
baseUrl: '/api'
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
|||||||
"scene3DOnly": false,
|
"scene3DOnly": false,
|
||||||
"shadows": false,
|
"shadows": false,
|
||||||
"removeDblClick": true,
|
"removeDblClick": true,
|
||||||
"sceneMode": 3,
|
"sceneMode": 2,
|
||||||
"showSun": true,
|
"showSun": true,
|
||||||
"showMoon": true,
|
"showMoon": true,
|
||||||
"showSkyBox": true,
|
"showSkyBox": true,
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
"id": "image-tdss",
|
"id": "image-tdss",
|
||||||
"name": "影像图",
|
"name": "影像图",
|
||||||
"type": "xyz",
|
"type": "xyz",
|
||||||
"url": "http:/www.tdss.website:280/tiles/img_c/{z}/{x}/{y}",
|
"url": "http://www.tdss.website:280/tiles/img_c/{z}/{x}/{y}",
|
||||||
"crs": "EPSG:4490",
|
"crs": "EPSG:4490",
|
||||||
"show": true
|
"show": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,34 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"width": 30,
|
"name": "车1",
|
||||||
"load": 500,
|
"long": 10,
|
||||||
|
"width": 7,
|
||||||
|
"load": 3,
|
||||||
"minTurnRadius": 5
|
"minTurnRadius": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"width": 10,
|
"name": "车2",
|
||||||
"load": 600,
|
"long": 10,
|
||||||
|
"width": 11,
|
||||||
|
"load": 1,
|
||||||
"minTurnRadius": 6
|
"minTurnRadius": 6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"width": 40,
|
"name": "车3",
|
||||||
"load": 700,
|
"long": 10,
|
||||||
|
"width": 8,
|
||||||
|
"load": 7,
|
||||||
"minTurnRadius": 10
|
"minTurnRadius": 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"width": 20,
|
"name": "车4",
|
||||||
"load": 700,
|
"long": 10,
|
||||||
|
"width": 10,
|
||||||
|
"load": 5,
|
||||||
"minTurnRadius": 2
|
"minTurnRadius": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
+5
-21
@@ -1,38 +1,22 @@
|
|||||||
{
|
{
|
||||||
"startPoint": "114.262694,27.786216",
|
"startPoint": "114.312888,27.796612",
|
||||||
"endPoint": "114.274729,27.777062",
|
"endPoint": "114.336525,27.767989",
|
||||||
"viaPoints": [
|
"viaPoints": [
|
||||||
{
|
{
|
||||||
"time": "1694352000000",
|
"time": "1694352000000",
|
||||||
"points": "114.263233,27.777047"
|
"points": "114.334239,27.779261"
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": "1694352001000",
|
|
||||||
"points": "114.265512,27.789935"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": "1694352002000",
|
|
||||||
"points": "114.256863,27.780437"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"avoidPoints": [
|
"avoidPoints": [
|
||||||
{
|
{
|
||||||
"time": "1694352003000",
|
"time": "1694352003000",
|
||||||
"points": "114.261166,27.800982"
|
"points": ""
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": "1694352004000",
|
|
||||||
"points": "114.251312,27.786932"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"avoidAreas": [
|
"avoidAreas": [
|
||||||
{
|
{
|
||||||
"time": "1694352005000",
|
"time": "1694352005000",
|
||||||
"points": "[[114.267217,27.777566,0],[114.276695,27.78048,0],[114.276001,27.772547,0],[114.276001,27.772486,0]]"
|
"points": "[[114.272797,27.7935,0],[114.27268,27.794201,0],[114.27537,27.795838,0]]"
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": "1694352006000",
|
|
||||||
"points": "[[114.272317,27.786501,0],[114.281341,27.79818,0],[114.290389,27.779594,0],[114.284888,27.773934,0]]"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"leftTop": "114.33,27.8",
|
||||||
|
"rightBottom": "114.34,27.79"
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
type="text/css"
|
type="text/css"
|
||||||
/>
|
/>
|
||||||
|
<script src="./config/config.js" type="text/javascript"></script>
|
||||||
<script src="./map/Cesium/Cesium.js" type="text/javascript"></script>
|
<script src="./map/Cesium/Cesium.js" type="text/javascript"></script>
|
||||||
<link href="./map/mars3d/mars3d.css" rel="stylesheet" type="text/css" />
|
<link href="./map/mars3d/mars3d.css" rel="stylesheet" type="text/css" />
|
||||||
<script src="./map/mars3d/mars3d.js" type="text/javascript"></script>
|
<script src="./map/mars3d/mars3d.js" type="text/javascript"></script>
|
||||||
|
|||||||
Binary file not shown.
@@ -1,11 +1,57 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Dengxian';
|
||||||
|
src: url('@/assets/scss/Dengxian.ttf') format('truetype');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
/* 全局强制继承 */
|
||||||
|
html, body, #app, .cesium-widget, .mars3d-container,
|
||||||
|
.mars3d-popup, .mars3d-tooltip, .mars3d-contextmenu,
|
||||||
|
.mars3d-measure-result, .cesium-credit-text,
|
||||||
|
.el-button, .el-input, .el-select, .el-table, .el-form, .el-dialog,
|
||||||
|
.el-message, .el-notification, .el-tooltip,
|
||||||
|
.el-menu, .el-breadcrumb, .el-pagination,
|
||||||
|
.el-radio, .el-checkbox, .el-tag, .el-badge,
|
||||||
|
.el-alert, .el-steps, .el-tabs, .el-calendar,
|
||||||
|
.el-date-picker, .el-cascader, .el-transfer,
|
||||||
|
.el-slider, .el-upload,
|
||||||
|
.el-empty, .el-result,
|
||||||
|
.el-loading-text,.el-table,
|
||||||
|
.el-table__body-wrapper span,
|
||||||
|
.el-table__footer-wrapper span,
|
||||||
|
.el-table__header-wrapper span,
|
||||||
|
.el-table__fixed span,
|
||||||
|
.el-table__fixed-right span,
|
||||||
|
.vxe-table--render-default .vxe-cell--title,
|
||||||
|
.vxe-table--render-default .vxe-cell--label,
|
||||||
|
.vxe-toolbar *,
|
||||||
|
.vxe-pager *,
|
||||||
|
.vxe-modal--wrapper *,
|
||||||
|
.vxe-tooltip--wrapper * {
|
||||||
|
font-family: 'DengXian', sans-serif !important;
|
||||||
|
}
|
||||||
|
/* 覆盖 mars3d 所有内部 UI */
|
||||||
|
.mars3d-draw-tooltip,
|
||||||
|
.mars3d-measure-tooltip,
|
||||||
|
.mars3d-contextmenu *,
|
||||||
|
.mars3d-popup *,
|
||||||
|
.mars3d-measure-result *,
|
||||||
|
.mars3d-control-btn {
|
||||||
|
font-family: 'DengXian', sans-serif !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dengxian {
|
||||||
|
font-family: 'Dengxian' !important;
|
||||||
|
}
|
||||||
|
|
||||||
body,
|
body,
|
||||||
html {
|
html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
|
font-family: 'Dengxian' !important;
|
||||||
Microsoft YaHei, Arial, sans-serif;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
@@ -33,3 +79,20 @@ html {
|
|||||||
.flex-warp {
|
.flex-warp {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
.el-form-item {
|
||||||
|
display: flex!important;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px!important;
|
||||||
|
}
|
||||||
|
.el-form-item__label {
|
||||||
|
letter-spacing: -1px;
|
||||||
|
min-width: 130px!important;
|
||||||
|
padding: 0!important;
|
||||||
|
white-space: nowrap; /* 强制不换行 */
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 16px!important;
|
||||||
|
}
|
||||||
|
.el-input__inner {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
@@ -10,6 +10,9 @@ import 'vxe-pc-ui/es/style.css'
|
|||||||
|
|
||||||
import VxeUITable from 'vxe-table'
|
import VxeUITable from 'vxe-table'
|
||||||
import 'vxe-table/es/style.css'
|
import 'vxe-table/es/style.css'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
Vue.prototype.$http = axios
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
import HomeView from '../views/home.vue'
|
import HomeView from '../views/home/home.vue'
|
||||||
import residentAnalysis from '@/views/residentAnalysis/index.vue'
|
import residentAnalysis from '@/views/residentAnalysis/index.vue'
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/**
|
||||||
|
* 极简 WKT -> GeoJSON
|
||||||
|
* 支持 POINT / LINESTRING / POLYGON
|
||||||
|
* @param {String} wkt
|
||||||
|
* @return {Object} GeoJSON
|
||||||
|
*/
|
||||||
|
function wktToGeoJSON (wkt) {
|
||||||
|
const trim = str => str.trim()
|
||||||
|
const split = (str, d) => str.split(d).map(trim)
|
||||||
|
|
||||||
|
// 1. 提取类型 + 坐标字符串
|
||||||
|
const [head, coords] = split(wkt, '(')
|
||||||
|
const type = trim(head).toUpperCase()
|
||||||
|
const coordStr = coords.replace(/\)$/, '')
|
||||||
|
|
||||||
|
// 2. 通用“数字对”解析
|
||||||
|
const parseRing = ring =>
|
||||||
|
split(ring, ',').map(p => {
|
||||||
|
const [x, y] = split(p, ' ').map(Number)
|
||||||
|
return [x, y] // GeoJSON 里经度在前
|
||||||
|
})
|
||||||
|
|
||||||
|
// 3. 按类型组装
|
||||||
|
switch (type) {
|
||||||
|
case 'POINT': {
|
||||||
|
const [x, y] = split(coordStr, ' ').map(Number)
|
||||||
|
return { type: 'Point', coordinates: [x, y] }
|
||||||
|
}
|
||||||
|
case 'LINESTRING':
|
||||||
|
return { type: 'LineString', coordinates: parseRing(coordStr) }
|
||||||
|
case 'POLYGON': {
|
||||||
|
// 可能带孔,先按“), (”切
|
||||||
|
const rings = coordStr.split(/\s*\),\s*\(/).map(parseRing)
|
||||||
|
return { type: 'Polygon', coordinates: rings }
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error('暂不支持该 WKT 类型:' + type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 拿当前视野四至(容错版) */
|
||||||
|
function getBounds(map) {
|
||||||
|
let rect = map.camera.computeViewRectangle()
|
||||||
|
|
||||||
|
if (!rect) {
|
||||||
|
// 高空/2D 模式下 computeViewRectangle 会失效,用四个角点兜底
|
||||||
|
const canvas = map.scene.canvas
|
||||||
|
const ellipsoid = Cesium.Ellipsoid.WGS84
|
||||||
|
const cv = (x, y) => map.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(x, y), ellipsoid
|
||||||
|
)
|
||||||
|
|
||||||
|
const ptNW = cv(0, 0)
|
||||||
|
const ptSE = cv(canvas.clientWidth, canvas.clientHeight)
|
||||||
|
|
||||||
|
// 如果仍 pick 不到,就缩小范围再试(再不行就返回一个默认矩形)
|
||||||
|
if (!ptNW || !ptSE) {
|
||||||
|
rect = map.camera.computeViewRectangle(
|
||||||
|
ellipsoid,
|
||||||
|
Cesium.Math.toRadians(0.1) // 0.1° 容差
|
||||||
|
)
|
||||||
|
if (!rect) {
|
||||||
|
// 终极保底:以相机位置为中心 ±0.1°
|
||||||
|
const c = map.camera.positionCartographic
|
||||||
|
const d = 0.1
|
||||||
|
return {
|
||||||
|
west : Cesium.Math.toDegrees(c.longitude) - d,
|
||||||
|
east : Cesium.Math.toDegrees(c.longitude) + d,
|
||||||
|
south: Cesium.Math.toDegrees(c.latitude) - d,
|
||||||
|
north: Cesium.Math.toDegrees(c.latitude) + d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// pick 成功
|
||||||
|
const nw = Cesium.Cartographic.fromCartesian(ptNW)
|
||||||
|
const se = Cesium.Cartographic.fromCartesian(ptSE)
|
||||||
|
return {
|
||||||
|
west : Cesium.Math.toDegrees(nw.longitude),
|
||||||
|
north: Cesium.Math.toDegrees(nw.latitude),
|
||||||
|
east : Cesium.Math.toDegrees(se.longitude),
|
||||||
|
south: Cesium.Math.toDegrees(se.latitude)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正常能算到
|
||||||
|
return {
|
||||||
|
west : Cesium.Math.toDegrees(rect.west),
|
||||||
|
south: Cesium.Math.toDegrees(rect.south),
|
||||||
|
east : Cesium.Math.toDegrees(rect.east),
|
||||||
|
north: Cesium.Math.toDegrees(rect.north)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 计算当前地图层级(zoom) */
|
||||||
|
function getZoom(map) {
|
||||||
|
const height = map.camera.positionCartographic.height
|
||||||
|
// 经验公式:Cesium 高度 -> WebMercator zoom
|
||||||
|
return Math.floor(29.5 - Math.log(height) / Math.LN2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 画布像素边界 */
|
||||||
|
function getViewportPxBounds(map) {
|
||||||
|
const cvs = map.scene.canvas
|
||||||
|
return { left: 0, top: 0, right: cvs.clientWidth, bottom: cvs.clientHeight }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 像素 -> 经纬度四至 */
|
||||||
|
function pxToLatLngBounds(px, map) {
|
||||||
|
const pick = (x, y) => {
|
||||||
|
const cart = map.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(x, y),
|
||||||
|
Cesium.Ellipsoid.WGS84
|
||||||
|
)
|
||||||
|
if (!cart) return null
|
||||||
|
const c = Cesium.Cartographic.fromCartesian(cart)
|
||||||
|
return { lng: Cesium.Math.toDegrees(c.longitude), lat: Cesium.Math.toDegrees(c.latitude) }
|
||||||
|
}
|
||||||
|
const nw = pick(px.left, px.top)
|
||||||
|
const se = pick(px.right, px.bottom)
|
||||||
|
// 兜底:高空 pick 不到就用相机矩形
|
||||||
|
if (!nw || !se) {
|
||||||
|
const rect = map.camera.computeViewRectangle() || {}
|
||||||
|
return {
|
||||||
|
west : Cesium.Math.toDegrees(rect.west || 0),
|
||||||
|
south: Cesium.Math.toDegrees(rect.south || 0),
|
||||||
|
east : Cesium.Math.toDegrees(rect.east || 0),
|
||||||
|
north: Cesium.Math.toDegrees(rect.north || 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { west: nw.lng, north: nw.lat, east: se.lng, south: se.lat }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var GRID_SIZE_DEG = 0.05 // 0.05° ≈ 5 km 一格
|
||||||
|
var CACHE_MIN = 30 * 60 * 1000 // 30 min
|
||||||
|
/* 经纬度 → 格子 key */
|
||||||
|
function lonLatToGridKey (lon, lat) {
|
||||||
|
const x = Math.floor(lon / GRID_SIZE_DEG)
|
||||||
|
const y = Math.floor(lat / GRID_SIZE_DEG)
|
||||||
|
return `${x}_${y}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 取格子中心点(方便防抖) */
|
||||||
|
function gridKeyToCenter (key) {
|
||||||
|
const [x, y] = key.split('_').map(Number)
|
||||||
|
return {
|
||||||
|
lon: (x + 0.5) * GRID_SIZE_DEG,
|
||||||
|
lat: (y + 0.5) * GRID_SIZE_DEG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
wktToGeoJSON,
|
||||||
|
getBounds,
|
||||||
|
getZoom,
|
||||||
|
getViewportPxBounds,
|
||||||
|
pxToLatLngBounds,
|
||||||
|
lonLatToGridKey,
|
||||||
|
gridKeyToCenter,
|
||||||
|
}
|
||||||
@@ -16,22 +16,41 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {setStorage, getStorage} from '@/utils/localStorage.js'
|
import {setStorage, getStorage} from '@/utils/localStorage.js'
|
||||||
|
import iniParser from 'ini-parser'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: '',
|
name: '',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabList: [
|
tabList: [
|
||||||
{id: 1, label: '机动路线规划'},
|
{id: 1, label: '道路通过性分析'},
|
||||||
{id: 2, label: '临时部署驻地分析'},
|
// {id: 2, label: '临时部署驻地分析'},
|
||||||
],
|
],
|
||||||
activeIndex: 1,
|
activeIndex: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.getTitle()
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.activeIndex = getStorage('activeIndex') || 1
|
this.activeIndex = getStorage('activeIndex') || 1
|
||||||
},
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
setStorage('activeIndex', 1)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getTitle() {
|
||||||
|
fetch('./config.ini')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(text => {
|
||||||
|
const parsedData = iniParser.parse(text);
|
||||||
|
this.tabList[0].label = parsedData.title.msg || '道路通过性分析'
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.tabList[0].label = '道路通过性分析'
|
||||||
|
})
|
||||||
|
},
|
||||||
setActiveIndex(id) {
|
setActiveIndex(id) {
|
||||||
if (this.activeIndex !== id) {
|
if (this.activeIndex !== id) {
|
||||||
this.activeIndex = id
|
this.activeIndex = id
|
||||||
@@ -60,7 +79,7 @@ $label_height: 50px;
|
|||||||
line-height: $label_height;
|
line-height: $label_height;
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
font-family: 'HarmonyOS Sans';
|
// font-family: 'HarmonyOS Sans';
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
+949
-221
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
<div id="page">
|
<div id="page">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="images flex a-c" v-for="item in imagesList" :key="item.id">
|
<div class="images flex a-c" v-for="item in imagesList" :key="item.id">
|
||||||
<img :src="item.src" />
|
<img :src="item.src" @click="drawRectangle" />
|
||||||
<el-button
|
<el-button
|
||||||
class="form-btn"
|
class="form-btn"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
>确定</el-button
|
>确定</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<el-button class="btn" type="primary" size="mini">确定</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content flex j-s a-c">
|
<div class="content flex j-s a-c">
|
||||||
@@ -21,12 +20,21 @@
|
|||||||
<div class="control-panel">
|
<div class="control-panel">
|
||||||
<div class="title">范围</div>
|
<div class="title">范围</div>
|
||||||
<el-form-item label="左上角">
|
<el-form-item label="左上角">
|
||||||
<el-input v-model="form.leftTop"></el-input>
|
<el-input v-model="form.leftTop" @blur="updateArea"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="右下角">
|
<el-form-item label="右下角">
|
||||||
<el-input v-model="form.rightBottom"></el-input>
|
<el-input v-model="form.rightBottom" @blur="updateArea">
|
||||||
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div class="importJson flex j-c a-c">导入json文件</div>
|
<input
|
||||||
|
type="file"
|
||||||
|
ref="fileInput"
|
||||||
|
@change="handleFileUpload"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
|
<div class="importJson flex j-c a-c" @click="triggerFileUpload">
|
||||||
|
导入json文件
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 权重 -->
|
<!-- 权重 -->
|
||||||
@@ -66,50 +74,67 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="center" id="cesiumContainer"></div>
|
<div class="center" id="cesiumContainer"></div>
|
||||||
|
|
||||||
<div class="right flex column j-s">
|
<div
|
||||||
|
class="right flex column"
|
||||||
|
v-loading="showLoading"
|
||||||
|
element-loading-text="数据加载中"
|
||||||
|
>
|
||||||
<!-- 路点 -->
|
<!-- 路点 -->
|
||||||
|
<div class="table-title" v-if="roadPointList.length > 0">
|
||||||
|
道路附属点
|
||||||
|
</div>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
class="item"
|
class="item"
|
||||||
:data="roadPointList"
|
:data="roadPointList"
|
||||||
v-if="roadPointList.length > 0"
|
v-if="roadPointList.length > 0"
|
||||||
>
|
>
|
||||||
<vxe-column type="seq" width="70"></vxe-column>
|
<vxe-column type="seq" width="70"></vxe-column>
|
||||||
<vxe-column field="name" title="Name"></vxe-column>
|
<vxe-column field="编码" title="编码"></vxe-column>
|
||||||
<vxe-column field="sex" title="Sex"></vxe-column>
|
<vxe-column field="名称" title="名称"></vxe-column>
|
||||||
<vxe-column field="age" title="Age"></vxe-column>
|
<vxe-column field="A" title="A"></vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
|
|
||||||
<!-- 路线 -->
|
<!-- 路线 -->
|
||||||
|
<div class="table-title" v-if="roadLineList.length > 0">道路附属线</div>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
class="item"
|
class="item"
|
||||||
:data="roadLineList"
|
:data="roadLineList"
|
||||||
v-if="roadLineList.length > 0"
|
v-if="roadLineList.length > 0"
|
||||||
>
|
>
|
||||||
<vxe-column type="seq" width="70"></vxe-column>
|
<vxe-column type="seq" width="70"></vxe-column>
|
||||||
<vxe-column field="name" title="Name"></vxe-column>
|
<vxe-column field="编码" title="编码"></vxe-column>
|
||||||
<vxe-column field="sex" title="Sex"></vxe-column>
|
<vxe-column field="名称" title="名称"></vxe-column>
|
||||||
<vxe-column field="age" title="Age"></vxe-column>
|
<vxe-column field="A" title="A"></vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
|
|
||||||
<!-- 水点 -->
|
<!-- 水点 -->
|
||||||
|
<div class="table-title" v-if="waterPointList.length > 0">
|
||||||
|
水系附属点
|
||||||
|
</div>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
class="item"
|
class="item"
|
||||||
:data="waterPointList"
|
:data="waterPointList"
|
||||||
v-if="waterPointList.length > 0"
|
v-if="waterPointList.length > 0"
|
||||||
>
|
>
|
||||||
<vxe-column type="seq" width="70"></vxe-column>
|
<vxe-column type="seq" width="70"></vxe-column>
|
||||||
<vxe-column field="name" title="Name"></vxe-column>
|
<vxe-column field="编码" title="编码"></vxe-column>
|
||||||
<vxe-column field="sex" title="Sex"></vxe-column>
|
<vxe-column field="名称" title="名称"></vxe-column>
|
||||||
<vxe-column field="age" title="Age"></vxe-column>
|
<vxe-column field="A" title="A"></vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
|
|
||||||
<!-- 水线 -->
|
<!-- 水线 -->
|
||||||
|
<div class="table-title" v-if="waterLineList.length > 0">
|
||||||
|
水系附属线
|
||||||
|
</div>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
class="item"
|
class="item"
|
||||||
:data="waterLineList"
|
:data="waterLineList"
|
||||||
v-if="waterLineList.length > 0"
|
v-if="waterLineList.length > 0"
|
||||||
>
|
>
|
||||||
<vxe-column type="seq" width="70"></vxe-column>
|
<vxe-column type="seq" width="70"></vxe-column>
|
||||||
<vxe-column field="name" title="Name"></vxe-column>
|
<vxe-column field="编码" title="编码"></vxe-column>
|
||||||
<vxe-column field="sex" title="Sex"></vxe-column>
|
<vxe-column field="名称" title="名称"></vxe-column>
|
||||||
<vxe-column field="age" title="Age"></vxe-column>
|
<vxe-column field="A" title="A"></vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,115 +150,16 @@ export default {
|
|||||||
name: '',
|
name: '',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
showLoading: false,
|
||||||
imagesList: [{id: 1, src: require('@/assets/image/crop.png')}],
|
imagesList: [{id: 1, src: require('@/assets/image/crop.png')}],
|
||||||
roadPointList: [
|
roadPointList: [],
|
||||||
{
|
roadLineList: [],
|
||||||
id: 10001,
|
waterPointList: [],
|
||||||
name: 'Test1',
|
waterLineList: [],
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
roadLineList: [
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
waterPointList: [
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
waterLineList: [
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10001,
|
|
||||||
name: 'Test1',
|
|
||||||
role: 'Develop',
|
|
||||||
sex: 'Man',
|
|
||||||
age: 28,
|
|
||||||
address: 'test abc',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
form: {
|
form: {
|
||||||
leftTop: '114.33,27.8',
|
leftTop: '',
|
||||||
rightBottom: '114.34, 27.79',
|
rightBottom: '',
|
||||||
slopePer: 0.5,
|
slopePer: 0.5,
|
||||||
peoplePer: 0.2,
|
peoplePer: 0.2,
|
||||||
plantPer: 0.2,
|
plantPer: 0.2,
|
||||||
@@ -245,9 +171,12 @@ export default {
|
|||||||
},
|
},
|
||||||
analyzing: false,
|
analyzing: false,
|
||||||
rectCount: 0,
|
rectCount: 0,
|
||||||
|
isHand: false,
|
||||||
|
|
||||||
selectedRect: null,
|
selectedRect: null,
|
||||||
rectangles: [],
|
rectangles: [],
|
||||||
|
labels: [],
|
||||||
|
|
||||||
peopleGeo: null,
|
peopleGeo: null,
|
||||||
plantGeo: null,
|
plantGeo: null,
|
||||||
soilGeo: null,
|
soilGeo: null,
|
||||||
@@ -283,22 +212,14 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
|
||||||
positions: {
|
|
||||||
deep: true,
|
|
||||||
handler(val) {
|
|
||||||
this.drawInitialArea(val)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getMapJson()
|
this.getMapJson()
|
||||||
this.getColorList()
|
this.getColorList()
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
delete window.mars3d
|
delete window.viewer
|
||||||
|
delete window.graphicLayer
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -321,6 +242,46 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 导入json文件
|
||||||
|
triggerFileUpload() {
|
||||||
|
this.$refs.fileInput.click()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleFileUpload(event) {
|
||||||
|
const file = event.target.files[0]
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
try {
|
||||||
|
const uploadedJson = JSON.parse(e.target.result)
|
||||||
|
this.importJson(uploadedJson)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析 JSON 文件失败:', error)
|
||||||
|
this.$message.error('解析 JSON 文件失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsText(file)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async importJson(uploadedJson) {
|
||||||
|
if (!uploadedJson) {
|
||||||
|
this.$message.warning('请先选择一个 JSON 文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 清除现有矩形
|
||||||
|
if (
|
||||||
|
this.polygon &&
|
||||||
|
(uploadedJson?.leftTop || uploadedJson?.rightBottom)
|
||||||
|
) {
|
||||||
|
window.graphicLayer.removeGraphic(this.polygon)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form.leftTop = uploadedJson.leftTop
|
||||||
|
this.form.rightBottom = uploadedJson.rightBottom
|
||||||
|
this.drawInitialArea()
|
||||||
|
},
|
||||||
|
|
||||||
getColorList() {
|
getColorList() {
|
||||||
this.colorList = colorMap.createColormap({
|
this.colorList = colorMap.createColormap({
|
||||||
colormap: 'jet',
|
colormap: 'jet',
|
||||||
@@ -342,7 +303,7 @@ export default {
|
|||||||
window.shortestPathLayer = new window.mars3d.layer.GraphicLayer()
|
window.shortestPathLayer = new window.mars3d.layer.GraphicLayer()
|
||||||
window.viewer.addLayer(window.shortestPathLayer)
|
window.viewer.addLayer(window.shortestPathLayer)
|
||||||
|
|
||||||
this.drawInitialArea()
|
// this.drawInitialArea()
|
||||||
this.loadGeoJson()
|
this.loadGeoJson()
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -375,10 +336,12 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 默认只加载一个,其他按需加载
|
// 默认只加载一个,其他按需加载
|
||||||
this.loadLayers(['people', 'plant', 'soil'], (results) => {
|
// this.loadLayers(['people', 'plant', 'soil'], (results) => {
|
||||||
console.log('所有图层加载完成', results)
|
// console.log('所有图层加载完成', results)
|
||||||
})
|
// })
|
||||||
// this.loadLayer('people')
|
this.loadLayer('people')
|
||||||
|
this.loadLayer('plant', false)
|
||||||
|
this.loadLayer('soil', false)
|
||||||
},
|
},
|
||||||
|
|
||||||
createLayerConfig(url, color, type = 'polygon') {
|
createLayerConfig(url, color, type = 'polygon') {
|
||||||
@@ -449,7 +412,7 @@ export default {
|
|||||||
return baseConfig
|
return baseConfig
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadLayer(layerName) {
|
async loadLayer(layerName, isLoad = true) {
|
||||||
if (this.layers[layerName].layer) {
|
if (this.layers[layerName].layer) {
|
||||||
this.layers[layerName].layer.show = !this.layers[layerName].layer.show
|
this.layers[layerName].layer.show = !this.layers[layerName].layer.show
|
||||||
return
|
return
|
||||||
@@ -459,11 +422,11 @@ export default {
|
|||||||
this.layers[layerName].config
|
this.layers[layerName].config
|
||||||
)
|
)
|
||||||
|
|
||||||
await window.viewer.addLayer(this.layers[layerName].layer)
|
isLoad ? await window.viewer.addLayer(this.layers[layerName].layer) : null
|
||||||
},
|
},
|
||||||
|
|
||||||
// 新增方法:同时加载多个图层
|
// 新增方法:同时加载多个图层
|
||||||
async loadLayers(names = [], cb) {
|
async loadLayers(names = [], cb, show = true) {
|
||||||
const tasks = names.map((name) => {
|
const tasks = names.map((name) => {
|
||||||
const cfg = this.layers[name]
|
const cfg = this.layers[name]
|
||||||
if (!cfg) return Promise.resolve(null) // 无配置直接过
|
if (!cfg) return Promise.resolve(null) // 无配置直接过
|
||||||
@@ -544,14 +507,20 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 判断矩形与 mars3d GeoJSON 图层是否相交(不转 GeoJSON)
|
// 判断矩形与 mars3d GeoJSON 图层是否相交(不转 GeoJSON)
|
||||||
getIntersectId(position, layer, bufferDistance = 0.001) {
|
getIntersectId(position, layer) {
|
||||||
console.log('position===>', position, layer)
|
console.log('position===>', position, layer)
|
||||||
if (!position || !layer || !layer.graphics) return null
|
if (!position || !layer || !layer.graphics) return null
|
||||||
|
|
||||||
const rectCoords = position.concat([position[0]]) // 闭合
|
const rectCoords = position.concat([position[0]]) // 闭合
|
||||||
|
|
||||||
|
console.log('rectCoords===>', rectCoords)
|
||||||
|
|
||||||
const rectPoly = turf.polygon([rectCoords])
|
const rectPoly = turf.polygon([rectCoords])
|
||||||
|
console.log('rectPoly===>', rectPoly)
|
||||||
const [minX, minY, maxX, maxY] = turf.bbox(rectPoly) // 矩形 bbox
|
const [minX, minY, maxX, maxY] = turf.bbox(rectPoly) // 矩形 bbox
|
||||||
|
|
||||||
|
console.log('minX, minY, maxX, maxY===>', minX, minY, maxX, maxY)
|
||||||
|
|
||||||
let fc = this._polyCache.get(layer)
|
let fc = this._polyCache.get(layer)
|
||||||
|
|
||||||
if (!fc) {
|
if (!fc) {
|
||||||
@@ -636,7 +605,13 @@ export default {
|
|||||||
|
|
||||||
// 手动绘制矩形
|
// 手动绘制矩形
|
||||||
async drawRectangle(clampToGround) {
|
async drawRectangle(clampToGround) {
|
||||||
const graphic = await window.graphicLayer.startDraw({
|
this.clearRectangles()
|
||||||
|
if (this.polygon) {
|
||||||
|
window.graphicLayer.removeGraphic(this.polygon)
|
||||||
|
}
|
||||||
|
this.isHand = true
|
||||||
|
let isEntityGraphic = false
|
||||||
|
this.polygon = await window.graphicLayer.startDraw({
|
||||||
type: isEntityGraphic ? 'rectangle' : 'rectangleP',
|
type: isEntityGraphic ? 'rectangle' : 'rectangleP',
|
||||||
style: {
|
style: {
|
||||||
color: clampToGround ? '#ffff00' : '#3388ff',
|
color: clampToGround ? '#ffff00' : '#3388ff',
|
||||||
@@ -648,7 +623,9 @@ export default {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('标绘完成', graphic.toJSON())
|
let positions = this.polygon.toJSON().positions
|
||||||
|
this.form.leftTop = positions[0][0] + ',' + positions[0][1]
|
||||||
|
this.form.rightBottom = positions[1][0] + ',' + positions[1][1]
|
||||||
},
|
},
|
||||||
|
|
||||||
// 绘制矩形区域
|
// 绘制矩形区域
|
||||||
@@ -660,7 +637,7 @@ export default {
|
|||||||
Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)
|
Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)
|
||||||
),
|
),
|
||||||
style: {
|
style: {
|
||||||
color: '#00ff00',
|
color: '#ffff00',
|
||||||
opacity: 0.3,
|
opacity: 0.3,
|
||||||
outline: true,
|
outline: true,
|
||||||
outlineColor: '#ffffff',
|
outlineColor: '#ffffff',
|
||||||
@@ -687,11 +664,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateArea(val) {
|
updateArea() {
|
||||||
|
if (this.isHand) {
|
||||||
|
this.isHand = false
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!this.polygon) return
|
if (!this.polygon) return
|
||||||
|
|
||||||
// 将经纬度转换为笛卡尔坐标
|
// 将经纬度转换为笛卡尔坐标
|
||||||
const cartesianPositions = val.map((p) =>
|
const cartesianPositions = this.positions.map((p) =>
|
||||||
Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)
|
Cesium.Cartesian3.fromDegrees(p[0], p[1], 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -703,11 +684,15 @@ export default {
|
|||||||
this.polygon.update()
|
this.polygon.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('区域已更新', val)
|
console.log('区域已更新', this.positions)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 分析平均坡度
|
// 分析平均坡度
|
||||||
async analyzeAverageSlope() {
|
async analyzeAverageSlope() {
|
||||||
|
if (!this.form.leftTop || !this.form.rightBottom) {
|
||||||
|
return this.$message.warning('请选择范围!')
|
||||||
|
}
|
||||||
|
|
||||||
console.log('开始坡度分析')
|
console.log('开始坡度分析')
|
||||||
this.analyzing = true
|
this.analyzing = true
|
||||||
this.selectedRect = null
|
this.selectedRect = null
|
||||||
@@ -715,6 +700,8 @@ export default {
|
|||||||
// 清除之前的矩形
|
// 清除之前的矩形
|
||||||
this.clearRectangles()
|
this.clearRectangles()
|
||||||
|
|
||||||
|
console.log('this.rectangles===>', this.rectangles)
|
||||||
|
|
||||||
// 获取分割参数
|
// 获取分割参数
|
||||||
const xSplit = parseInt(this.form.xLength) || 3
|
const xSplit = parseInt(this.form.xLength) || 3
|
||||||
const ySplit = parseInt(this.form.yLength) || 3
|
const ySplit = parseInt(this.form.yLength) || 3
|
||||||
@@ -844,8 +831,9 @@ export default {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('坡度分析失败', e)
|
console.error('坡度分析失败', e)
|
||||||
alert('坡度分析失败,请检查地形数据')
|
this.$message.error('坡度分析失败,请检查地形数据')
|
||||||
} finally {
|
} finally {
|
||||||
|
rectInfoMap.clear()
|
||||||
this.drawLabelAndRec()
|
this.drawLabelAndRec()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -919,32 +907,26 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 3. 批量创建 Graphic(底层一次性构造,避免反复 new) */
|
/* 3. 批量创建 Graphic(底层一次性构造,避免反复 new) */
|
||||||
const rectGraphics = rectOpts.map(
|
this.rectangles = rectOpts.map(
|
||||||
(opt) => new mars3d.graphic.PolygonEntity(opt)
|
(opt) => new mars3d.graphic.PolygonEntity(opt)
|
||||||
)
|
)
|
||||||
const labelGraphics = labelOpts.map(
|
this.labels = labelOpts.map((opt) => new mars3d.graphic.LabelEntity(opt))
|
||||||
(opt) => new mars3d.graphic.LabelEntity(opt)
|
|
||||||
)
|
|
||||||
|
|
||||||
/* 4. 一次性添加到图层(mars3d 支持数组)*/
|
/* 4. 一次性添加到图层(mars3d 支持数组)*/
|
||||||
window.graphicLayer.addGraphic(rectGraphics)
|
window.graphicLayer.addGraphic(this.rectangles)
|
||||||
window.graphicLayer.addGraphic(labelGraphics)
|
window.graphicLayer.addGraphic(this.labels)
|
||||||
|
|
||||||
/* 5. 图层级事件委托:只监听矩形图形的点击事件 */
|
/* 5. 图层级事件委托:只监听矩形图形的点击事件 */
|
||||||
window.graphicLayer.off(mars3d.EventType.click, this._selectRect, this) // 先清旧监听
|
window.graphicLayer.off(mars3d.EventType.click, this._selectRect, this) // 先清旧监听
|
||||||
|
|
||||||
// 为每个矩形图形单独绑定点击事件
|
// 为每个矩形图形单独绑定点击事件
|
||||||
rectGraphics.forEach((rectGraphic) => {
|
this.rectangles.forEach((rectGraphic) => {
|
||||||
rectGraphic.on(mars3d.EventType.click, (event) => {
|
rectGraphic.on(mars3d.EventType.click, (event) => {
|
||||||
this._selectRect(event)
|
this._selectRect(event)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/* 6. 保存引用 */
|
/* 6. 事件处理函数 */
|
||||||
this.rectangles = rectGraphics
|
|
||||||
this.labels = labelGraphics
|
|
||||||
|
|
||||||
/* 7. 事件处理函数 */
|
|
||||||
this._selectRect = (event) => {
|
this._selectRect = (event) => {
|
||||||
const graphic = event.graphic
|
const graphic = event.graphic
|
||||||
// 确保只有矩形图形会触发选择
|
// 确保只有矩形图形会触发选择
|
||||||
@@ -952,6 +934,7 @@ export default {
|
|||||||
this.selectRectangle(graphic)
|
this.selectRectangle(graphic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.$message.success('计算成功!')
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1052,21 +1035,21 @@ export default {
|
|||||||
|
|
||||||
// 选择矩形
|
// 选择矩形
|
||||||
selectRectangle(rect) {
|
selectRectangle(rect) {
|
||||||
console.log('rect===>', rect)
|
this.showLoading = true
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showLoading = false
|
||||||
|
}, 500)
|
||||||
|
|
||||||
if (this.selectedRect?.id === rect.id) return
|
if (this.selectedRect?.id === rect.id) return
|
||||||
this.selectedRect = {
|
this.selectedRect = {
|
||||||
id: rect.id,
|
id: rect.id,
|
||||||
center: rect.center,
|
center: rect.center,
|
||||||
}
|
}
|
||||||
if (!this.roadPointGeo) {
|
|
||||||
this.loadLayer('roadPoint')
|
this.roadPointList = []
|
||||||
} else if (!this.roadLineGeo) {
|
this.roadLineList = []
|
||||||
this.loadLayer('roadLine')
|
this.waterPointList = []
|
||||||
} else if (!this.waterPointGeo) {
|
this.waterLineList = []
|
||||||
this.loadLayer('waterPoint')
|
|
||||||
} else if (!this.waterLineGeo) {
|
|
||||||
this.loadLayer('waterLine')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.roadWaterLock) {
|
if (!this.roadWaterLock) {
|
||||||
this.loadLayers(
|
this.loadLayers(
|
||||||
@@ -1082,38 +1065,69 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getRoadWaterIds(rect) {
|
getRoadWaterIds(rect) {
|
||||||
|
const positions = rect.points.map((d) => [d.lng, d.lat])
|
||||||
|
|
||||||
let roadPointId = this.getIntersectId(
|
let roadPointId = this.getIntersectId(
|
||||||
rect.points,
|
positions,
|
||||||
this.layers['roadPoint'].layer
|
this.layers['roadPoint'].layer
|
||||||
)
|
)
|
||||||
let roadLineId = this.getIntersectId(
|
let roadLineId = this.getIntersectId(
|
||||||
rect.points,
|
positions,
|
||||||
this.layers['roadLine'].layer
|
this.layers['roadLine'].layer
|
||||||
)
|
)
|
||||||
let waterPointId = this.getIntersectId(
|
let waterPointId = this.getIntersectId(
|
||||||
rect.points,
|
positions,
|
||||||
this.layers['waterPoint'].layer
|
this.layers['waterPoint'].layer
|
||||||
)
|
)
|
||||||
let waterLineId = this.getIntersectId(
|
let waterLineId = this.getIntersectId(
|
||||||
rect.points,
|
positions,
|
||||||
this.layers['waterLine'].layer
|
this.layers['waterLine'].layer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (roadPointId) {
|
||||||
|
this.roadPointList.push(
|
||||||
|
this.layers['roadPoint'].layer.getGraphicById(roadPointId).options
|
||||||
|
.attr
|
||||||
|
)
|
||||||
|
} else if (roadLineId) {
|
||||||
|
this.roadLineList.push(
|
||||||
|
this.layers['roadLine'].layer.getGraphicById(roadLineId).options.attr
|
||||||
|
)
|
||||||
|
} else if (waterPointId) {
|
||||||
|
this.waterPointList.push(
|
||||||
|
this.layers['waterPoint'].layer.getGraphicById(waterPointId).options
|
||||||
|
.attr
|
||||||
|
)
|
||||||
|
} else if (waterLineId) {
|
||||||
|
this.waterLineList.push(
|
||||||
|
this.layers['waterLine'].layer.getGraphicById(waterLineId).options
|
||||||
|
.attr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
'roadPointId===>',
|
'roadPointId===>',
|
||||||
roadPointId,
|
this.roadPointList,
|
||||||
roadLineId,
|
this.roadLineList,
|
||||||
waterPointId,
|
this.waterPointList,
|
||||||
waterLineId
|
this.waterLineList
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 清除所有矩形
|
// 清除所有矩形
|
||||||
clearRectangles() {
|
clearRectangles() {
|
||||||
this.rectangles.forEach((rect) => {
|
if (this.rectangles.length > 0) {
|
||||||
window.graphicLayer.removeGraphic(rect)
|
this.rectangles.forEach((item) => item.remove())
|
||||||
})
|
window.graphicLayer.removeGraphic(this.rectangles)
|
||||||
this.rectangles = []
|
this.rectangles = []
|
||||||
|
this.rectCount = 0
|
||||||
|
this.validBlocks = []
|
||||||
|
}
|
||||||
|
if (this.labels.length > 0) {
|
||||||
|
this.labels.forEach((item) => item.remove())
|
||||||
|
window.graphicLayer.removeGraphic(this.labels)
|
||||||
|
this.labels = []
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1202,11 +1216,21 @@ export default {
|
|||||||
width: 452px;
|
width: 452px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #d4e5db;
|
background-color: #d4e5db;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 10px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: 'Pingfang';
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+47
-15
@@ -1,30 +1,62 @@
|
|||||||
const {defineConfig} = require('@vue/cli-service')
|
const {defineConfig} = require('@vue/cli-service')
|
||||||
const postcssPxToViewport = require('postcss-px-to-viewport')
|
const postcssPxToViewport = require('postcss-px-to-viewport')
|
||||||
const path = require('path') // 需要引入 path 模块
|
const path = require('path')
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
publicPath: './',
|
publicPath: './',
|
||||||
transpileDependencies: false,
|
transpileDependencies: false, // 我们自己管,不让 CLI 插手
|
||||||
lintOnSave: false,
|
lintOnSave: false,
|
||||||
|
devServer: {client: {overlay: false}},
|
||||||
|
|
||||||
|
configureWebpack(config) {
|
||||||
|
// 调试
|
||||||
|
config.devtool = 'source-map'
|
||||||
|
// 别名
|
||||||
|
config.resolve.alias['@'] = path.resolve(__dirname, 'src')
|
||||||
|
|
||||||
|
/* 1. 追加 ini 规则 */
|
||||||
|
config.module.rules.push({
|
||||||
|
test: /\.ini$/,
|
||||||
|
use: 'raw-loader',
|
||||||
|
})
|
||||||
|
|
||||||
|
/* 2. 追加 ES5 规则(只转 src,不转 node_modules) */
|
||||||
|
// config.module.rules.push({
|
||||||
|
// test: /\.js$/,
|
||||||
|
// include: path.resolve(__dirname, 'src'),
|
||||||
|
// use: {
|
||||||
|
// loader: 'babel-loader',
|
||||||
|
// options: {
|
||||||
|
// presets: [
|
||||||
|
// [
|
||||||
|
// '@babel/preset-env',
|
||||||
|
// {
|
||||||
|
// targets: {ie: '11'}, // 强制 ES5
|
||||||
|
// corejs: 3,
|
||||||
|
// useBuiltIns: 'entry',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
client: {
|
client: { overlay: false },
|
||||||
overlay: false,
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://192.168.3.35:8381',
|
||||||
|
changeOrigin: true,
|
||||||
|
pathRewrite: { '^/api': '' },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
configureWebpack: (config) => {
|
|
||||||
//调试JS
|
|
||||||
config.devtool = 'source-map'
|
|
||||||
config.resolve = {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, 'src'),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
css: {
|
css: {
|
||||||
|
/* 你的 px-to-viewport 配置不动 */
|
||||||
loaderOptions: {
|
loaderOptions: {
|
||||||
postcss: {
|
postcss: {
|
||||||
postcssOptions: {
|
postcssOptions: {
|
||||||
// 增加这一层 postcssOptions
|
|
||||||
plugins: [
|
plugins: [
|
||||||
postcssPxToViewport({
|
postcssPxToViewport({
|
||||||
unitToConvert: 'px',
|
unitToConvert: 'px',
|
||||||
@@ -37,7 +69,7 @@ module.exports = defineConfig({
|
|||||||
minPixelValue: 1,
|
minPixelValue: 1,
|
||||||
mediaQuery: false,
|
mediaQuery: false,
|
||||||
replace: true,
|
replace: true,
|
||||||
exclude: /(\/|\\)(node_modules)(\/|\\)/,
|
exclude: /node_modules/,
|
||||||
include: [],
|
include: [],
|
||||||
landscape: false,
|
landscape: false,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user