Compare commits

..

15 Commits

Author SHA1 Message Date
964ce7cede fix bug修复 2025-10-16 16:02:23 +08:00
ce70fd98ec add json编辑功能 2025-10-15 09:27:20 +08:00
7d22506f18 add json 编辑 2025-10-14 17:23:54 +08:00
328700ec89 fix 2025-10-10 18:31:44 +08:00
2ad6bc1b47 add 导出 2025-10-10 15:32:47 +08:00
41f9034f54 ## 机动路线规划 2025-10-10 11:38:34 +08:00
ae2f9d94e1 fix 路线规划 隐蔽 2025-10-10 11:35:42 +08:00
c1876d23bd add 隐蔽规划 2025-09-24 11:15:23 +08:00
e2b73640df Merge branch 'main' of https://work.rangutech.cn:85/yiqiuyang/kxfx 2025-09-10 09:44:48 +08:00
f084fc92e9 代码提交 2025-09-10 09:44:44 +08:00
3e7ccea682 fix 2025-09-10 09:34:52 +08:00
935846d7f2 fix 2025-09-10 09:13:58 +08:00
cc774db444 fix 2025-09-10 08:55:33 +08:00
c1370dcbc0 Merge branch 'main' of https://work.rangutech.cn:85/yiqiuyang/kxfx 2025-09-10 08:48:38 +08:00
8ea0f436b1 1 2025-09-10 08:47:28 +08:00
15 changed files with 7868 additions and 485 deletions

View File

@ -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/).

View File

@ -9,12 +9,15 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@babel/preset-env": "^7.28.3",
"axios": "0.21.0", "axios": "0.21.0",
"core-js": "^3.8.3",
"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",

6
public/config.ini Normal file
View File

@ -0,0 +1,6 @@
[http]
port=8083
address=127.0.0.1
[title]
msg=道路堪选分析

File diff suppressed because it is too large Load Diff

View File

@ -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
} }

View File

@ -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
} }
] ]

View File

@ -1,38 +1,22 @@
{ {
"startPoint": "114.262694,27.786216", "startPoint": "114.26344,27.800982",
"endPoint": "114.274729,27.777062", "endPoint": "114.284668,27.794961",
"viaPoints": [ "viaPoints": [
{ {
"time": "1694352000000", "time": "1694352000000",
"points": "114.263233,27.777047" "points": "114.272329,27.797299"
},
{
"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": "114.27882,27.792857"
},
{
"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]]"
} }
] ]
} }

4
public/data/road.json Normal file
View File

@ -0,0 +1,4 @@
{
"leftTop": "114.33,27.8",
"rightBottom": "114.34,27.79"
}

View File

@ -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)

View File

@ -23,7 +23,7 @@ export default {
return { return {
tabList: [ tabList: [
{id: 1, label: '机动路线规划'}, {id: 1, label: '机动路线规划'},
{id: 2, label: '临时部署驻地分析'}, // {id: 2, label: '临时部署驻地分析'},
], ],
activeIndex: 1, activeIndex: 1,
} }
@ -31,6 +31,10 @@ export default {
mounted() { mounted() {
this.activeIndex = getStorage('activeIndex') || 1 this.activeIndex = getStorage('activeIndex') || 1
}, },
beforeDestroy() {
setStorage('activeIndex', 1)
},
methods: { methods: {
setActiveIndex(id) { setActiveIndex(id) {
if (this.activeIndex !== id) { if (this.activeIndex !== id) {

File diff suppressed because it is too large Load Diff

2683
src/views/home/home.vue Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -1,30 +1,52 @@
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: { devServer: {client: {overlay: false}},
client: {
overlay: false, configureWebpack(config) {
}, // 调试
},
configureWebpack: (config) => {
//调试JS
config.devtool = 'source-map' config.devtool = 'source-map'
config.resolve = { // 别名
alias: { config.resolve.alias['@'] = path.resolve(__dirname, 'src')
'@': 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',
},
],
],
},
}, },
} })
}, },
css: { css: {
/* 你的 px-to-viewport 配置不动 */
loaderOptions: { loaderOptions: {
postcss: { postcss: {
postcssOptions: { postcssOptions: {
// 增加这一层 postcssOptions
plugins: [ plugins: [
postcssPxToViewport({ postcssPxToViewport({
unitToConvert: 'px', unitToConvert: 'px',
@ -37,7 +59,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,
}), }),