add 首页
This commit is contained in:
5
.eslintrc.js
Normal file
5
.eslintrc.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
rules: {
|
||||||
|
"prettier/prettier": "off"
|
||||||
|
}
|
||||||
|
};
|
||||||
0
public/data.json
Normal file
0
public/data.json
Normal file
26
public/data/minTurnRadius.json
Normal file
26
public/data/minTurnRadius.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"width": 30,
|
||||||
|
"load": 500,
|
||||||
|
"minTurnRadius": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"width": 10,
|
||||||
|
"load": 600,
|
||||||
|
"minTurnRadius": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"width": 40,
|
||||||
|
"load": 700,
|
||||||
|
"minTurnRadius": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"width": 20,
|
||||||
|
"load": 700,
|
||||||
|
"minTurnRadius": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
38
public/data/points.json
Normal file
38
public/data/points.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"startPoint": "114.262694,27.786216",
|
||||||
|
"endPoint": "114.274729,27.777062",
|
||||||
|
"viaPoints": [
|
||||||
|
{
|
||||||
|
"time": "1694352000000",
|
||||||
|
"points": "114.263233,27.777047"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694352001000",
|
||||||
|
"points": "114.265512,27.789935"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694352002000",
|
||||||
|
"points": "114.256863,27.780437"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avoidPoints": [
|
||||||
|
{
|
||||||
|
"time": "1694352003000",
|
||||||
|
"points": "114.261166,27.800982"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694352004000",
|
||||||
|
"points": "114.251312,27.786932"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avoidAreas": [
|
||||||
|
{
|
||||||
|
"time": "1694352005000",
|
||||||
|
"points": "[[114.267217,27.777566,0],[114.276695,27.78048,0],[114.276001,27.772547,0],[114.276001,27.772486,0]]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694352006000",
|
||||||
|
"points": "[[114.272317,27.786501,0],[114.281341,27.79818,0],[114.290389,27.779594,0],[114.284888,27.773934,0]]"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@
|
|||||||
<img @click="drawViaPoint" src="@/assets/image/add.png" />
|
<img @click="drawViaPoint" src="@/assets/image/add.png" />
|
||||||
<img @click="drawAvoidPoint" src="@/assets/image/avoidP.png" />
|
<img @click="drawAvoidPoint" src="@/assets/image/avoidP.png" />
|
||||||
<img @click="drawAvoidArea" src="@/assets/image/updown.png" />
|
<img @click="drawAvoidArea" src="@/assets/image/updown.png" />
|
||||||
|
<div @click="clear" class="sure">清除</div>
|
||||||
<div @click="calculateShortestPath" class="sure">确定</div>
|
<div @click="calculateShortestPath" class="sure">确定</div>
|
||||||
<!-- <div class="control-panel">
|
<!-- <div class="control-panel">
|
||||||
<button @click="drawStartPoint">绘制起点</button>
|
<button @click="drawStartPoint">绘制起点</button>
|
||||||
@ -23,98 +24,144 @@
|
|||||||
<div class="title">参数</div>
|
<div class="title">参数</div>
|
||||||
<el-form
|
<el-form
|
||||||
@submit.native.prevent="calculateShortestPath"
|
@submit.native.prevent="calculateShortestPath"
|
||||||
label-width="80px"
|
label-width="100px"
|
||||||
label-position="left"
|
label-position="left"
|
||||||
size="small"
|
size="mini"
|
||||||
|
:model="form"
|
||||||
>
|
>
|
||||||
<el-form-item label="起点">
|
<el-form-item label="起点">
|
||||||
<el-input v-model="form.startPoint"></el-input>
|
<el-input v-model="form.startPoint" @blur="pointsChange('startPoint')"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="终点">
|
<el-form-item label="终点">
|
||||||
<el-input v-model="form.endPoint"></el-input>
|
<el-input v-model="form.endPoint" @blur="pointsChange('endPoint')"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="途径点">
|
<el-form-item label="途径点">
|
||||||
<el-input v-model="form.viaPoints" placeholder=""></el-input>
|
<div v-for="(item, index) in form.viaPoints" :key="index">
|
||||||
|
<el-input v-model="item.points" placeholder="" @blur="pointsChange('viaPoints', item)"></el-input>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="避让点">
|
<el-form-item label="避让点">
|
||||||
<el-input v-model="form.avoidPoints" placeholder=""></el-input>
|
<div v-for="(item, index) in form.avoidPoints" :key="index">
|
||||||
|
<el-input v-model="item.points" placeholder="" @blur="pointsChange('avoidPoints', item)"></el-input>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="避让区域">
|
<el-form-item label="避让区域">
|
||||||
<el-input
|
<div v-for="(item, index) in form.avoidAreas" :key="index">
|
||||||
type="textarea"
|
<el-input
|
||||||
v-model="form.avoidAreas"
|
type="textarea"
|
||||||
:rows="4"
|
v-model="item.points"
|
||||||
placeholder=""
|
:rows="4"
|
||||||
></el-input>
|
placeholder=""
|
||||||
|
@blur="pointsChange('avoidAreas', item)"
|
||||||
|
></el-input>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item>
|
<!-- <el-form-item>
|
||||||
<el-button type="primary" @click="calculateShortestPath">计算最短路径</el-button>
|
<el-button type="primary" @click="calculateShortestPath">计算最短路径</el-button>
|
||||||
<el-button @click="clear">清除所有</el-button>
|
<el-button @click="clear">清除所有</el-button>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="importJson">导入json文件</div>
|
<input type="file" ref="fileInput" @change="handleFileUpload" style="display: none;" />
|
||||||
|
<div class="importJson" @click="triggerFileUpload">导入json文件</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-panel">
|
<div class="control-panel">
|
||||||
<div class="title">机动属性</div>
|
<div class="title">机动属性</div>
|
||||||
<el-form
|
<el-form
|
||||||
@submit.native.prevent="calculateShortestPath"
|
@submit.native.prevent="calculateShortestPath"
|
||||||
label-width="80px"
|
label-width="100px"
|
||||||
label-position="left"
|
label-position="left"
|
||||||
size="small"
|
size="mini"
|
||||||
>
|
>
|
||||||
<el-form-item label="长">
|
<el-form-item label="宽度">
|
||||||
<el-input v-model="form.startPoint"></el-input>
|
<el-input v-model="inputform.width"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="宽">
|
<el-form-item label="载重(吨)">
|
||||||
<el-input v-model="form.endPoint"></el-input>
|
<el-input v-model="inputform.load" placeholder=""></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="高">
|
<el-form-item label="最小转弯半径">
|
||||||
<el-input v-model="form.viaPoints" placeholder=""></el-input>
|
<el-input v-model="inputform.minTurnRadius" placeholder=""></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="载重">
|
|
||||||
<el-input v-model="form.avoidPoints" placeholder=""></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="避让区域">
|
|
||||||
<el-input
|
|
||||||
type="textarea"
|
|
||||||
v-model="form.avoidAreas"
|
|
||||||
:rows="4"
|
|
||||||
placeholder=""
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- <el-form-item>
|
|
||||||
<el-button type="primary" @click="calculateShortestPath">计算最短路径</el-button>
|
|
||||||
<el-button @click="clear">清除所有</el-button>
|
|
||||||
</el-form-item> -->
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="importJson">导入json文件</div>
|
<div class="importJson" @click="openDialog">数据选择</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div id="map"></div> -->
|
<div id="map"></div>
|
||||||
<div id="mapbox"></div>
|
<!-- <div id="mapbox"></div> -->
|
||||||
<div class="main-container">
|
<div class="main-container" style="width: 452px;">
|
||||||
<div class="control-panel"></div>
|
<div class="control-panel" style="width: 452px;">
|
||||||
|
<div style="font-size: 14px;margin-bottom: 10px;">
|
||||||
|
详细路线:<br/>
|
||||||
|
起点({{form.startPoint}}),
|
||||||
|
途径点({{form.viaPoints.length > 0 && form.viaPoints[0].points ? form.viaPoints.map(item => item.points).join(";") : ''}}),
|
||||||
|
避让点({{form.avoidPoints.length > 0 && form.avoidPoints[0].points ? form.avoidPoints.map(item => item.points).join(";") : ''}}),
|
||||||
|
终点({{form.endPoint}}),
|
||||||
|
避让区域({{form.avoidAreas.length > 0 && form.avoidAreas[0].points ? form.avoidAreas.map(item => item.points).join(";") : ''}})。<br/>
|
||||||
|
装备参数:最大车辆宽度{{inputform.width || 0}},最小转弯半径{{inputform.minTurnRadius || 0}},最大车辆载重{{inputform.load || 0}}吨
|
||||||
|
</div>
|
||||||
|
<vxe-table
|
||||||
|
ref="xTable"
|
||||||
|
:data="infoList"
|
||||||
|
>
|
||||||
|
<vxe-column field="编码" title="编码" width="65px"></vxe-column>
|
||||||
|
<vxe-column field="名称" title="名称" width="80px"></vxe-column>
|
||||||
|
<vxe-column field="宽度" title="路宽"></vxe-column>
|
||||||
|
<vxe-column field="曲率半" title="曲率"></vxe-column>
|
||||||
|
<vxe-column field="载重吨" title="载重"></vxe-column>
|
||||||
|
<vxe-column field="水深" title="水深"></vxe-column>
|
||||||
|
<vxe-column field="净空高" title="净空高" width="65px"></vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<el-dialog :visible.sync="dialogVisible" title="机动属性" width="600px">
|
||||||
|
<vxe-table
|
||||||
|
height="300px"
|
||||||
|
:data="tableData"
|
||||||
|
:row-config="{ isCurrent: true, isHover: true }"
|
||||||
|
:checkbox-config="{ checkField: 'checked', highlight: true }"
|
||||||
|
@checkbox-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<vxe-column type="checkbox" width="50"></vxe-column>
|
||||||
|
<vxe-column field="width" title="宽度"></vxe-column>
|
||||||
|
<vxe-column field="load" title="载重(吨)"></vxe-column>
|
||||||
|
<vxe-column field="minTurnRadius" title="最小转弯半径"></vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmSelection">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Header from './header/index.vue'
|
import router from '@/router';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: '',
|
|
||||||
components: {
|
|
||||||
Header,
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
dialogVisible: false,
|
||||||
|
tableData: [],
|
||||||
|
multipleSelection: [],
|
||||||
|
inputform: {
|
||||||
|
width: '',
|
||||||
|
load: '',
|
||||||
|
minTurnRadius: ''
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
startPoint: '',
|
||||||
|
endPoint: '',
|
||||||
|
viaPoints: [{ points: '', time: '' }],
|
||||||
|
avoidPoints: [{ points: '', time: '' }],
|
||||||
|
avoidAreas: [{ points: '', time: '' }],
|
||||||
|
},
|
||||||
viewer: null,
|
viewer: null,
|
||||||
graphicLayer: null,
|
graphicLayer: null,
|
||||||
polygonZAM: null,
|
polygonZAM: null,
|
||||||
pointQD: null,
|
pointQD: null,
|
||||||
pointZD: null,
|
pointZD: null,
|
||||||
shortestPathLayer: null,
|
shortestPathLayer: null,
|
||||||
|
infoList: [],
|
||||||
roadNetworkLayer: null,
|
roadNetworkLayer: null,
|
||||||
roadNetworkGeoJSON: null,
|
roadNetworkGeoJSON: null,
|
||||||
mapOptions: null,
|
mapOptions: null,
|
||||||
@ -125,12 +172,26 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
console.log('go')
|
||||||
|
this.viewer = null
|
||||||
await this.getMapOption()
|
await this.getMapOption()
|
||||||
// this.initMap()
|
this.$nextTick(async () => {
|
||||||
|
await this.initMap()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.destroyMap()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
destroyMap() {
|
||||||
|
// if (this.viewer) {
|
||||||
|
// this.viewer.destroy();
|
||||||
|
// this.viewer = null;
|
||||||
|
// }
|
||||||
|
this.clear()
|
||||||
|
},
|
||||||
async getMapOption() {
|
async getMapOption() {
|
||||||
await fetch('./config/map.json')
|
await fetch('/config/map.json')
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return response.json()
|
return response.json()
|
||||||
})
|
})
|
||||||
@ -140,7 +201,18 @@ export default {
|
|||||||
.catch((error) => {})
|
.catch((error) => {})
|
||||||
},
|
},
|
||||||
async initMap() {
|
async initMap() {
|
||||||
this.viewer = new window.mars3d.Map('map', this.mapOptions || {})
|
this.viewer = new window.mars3d.Map('map', {
|
||||||
|
...this.mapOptions,
|
||||||
|
scene: {
|
||||||
|
center: {
|
||||||
|
lat: 27.729862392917948,
|
||||||
|
lng: 114.27980291774088,
|
||||||
|
alt: 3808,
|
||||||
|
heading: 5,
|
||||||
|
pitch: -35
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} || {})
|
||||||
this.graphicLayer = new window.mars3d.layer.GraphicLayer()
|
this.graphicLayer = new window.mars3d.layer.GraphicLayer()
|
||||||
this.viewer.addLayer(this.graphicLayer)
|
this.viewer.addLayer(this.graphicLayer)
|
||||||
|
|
||||||
@ -154,47 +226,50 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
clear() {
|
clear() {
|
||||||
// 清除障碍面
|
|
||||||
if (this.polygonZAM) {
|
|
||||||
this.polygonZAM.remove()
|
|
||||||
this.polygonZAM = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清除起点
|
// 清除起点
|
||||||
if (this.pointQD) {
|
if (this.pointQD) {
|
||||||
this.pointQD.remove()
|
this.pointQD.remove()
|
||||||
this.pointQD = null
|
this.pointQD = null
|
||||||
|
this.form.startPoint = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除终点
|
// 清除终点
|
||||||
if (this.pointZD) {
|
if (this.pointZD) {
|
||||||
this.pointZD.remove()
|
this.pointZD.remove()
|
||||||
this.pointZD = null
|
this.pointZD = null
|
||||||
|
this.form.endPoint = ''
|
||||||
|
}
|
||||||
|
if (this.viaPoints.length > 0) {
|
||||||
|
// 清除途径点
|
||||||
|
this.viaPoints.forEach((point) => {
|
||||||
|
point.remove()
|
||||||
|
})
|
||||||
|
this.viaPoints = []
|
||||||
|
this.form.viaPoints = [{ points: '', time: '' }]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除途径点
|
if (this.avoidPoints.length > 0) {
|
||||||
this.viaPoints.forEach((point) => {
|
// 清除避让点
|
||||||
point.remove()
|
this.avoidPoints.forEach((point) => {
|
||||||
})
|
point.remove()
|
||||||
this.viaPoints = []
|
})
|
||||||
|
this.avoidPoints = []
|
||||||
|
this.form.avoidPoints = [{ points: '', time: '' }]
|
||||||
|
}
|
||||||
|
|
||||||
// 清除避让点
|
if (this.avoidAreas.length > 0) {
|
||||||
this.avoidPoints.forEach((point) => {
|
// 清除避让区域
|
||||||
point.remove()
|
this.avoidAreas.forEach((area) => {
|
||||||
})
|
area.remove()
|
||||||
this.avoidPoints = []
|
})
|
||||||
|
this.avoidAreas = []
|
||||||
// 清除避让区域
|
this.form.avoidAreas = [{ points: '', time: '' }]
|
||||||
this.avoidAreas.forEach((area) => {
|
}
|
||||||
area.remove()
|
if (this.shortestPathLayer) {
|
||||||
})
|
// 清除最短路径图层
|
||||||
this.avoidAreas = []
|
this.shortestPathLayer.clear()
|
||||||
|
this.infoList = []
|
||||||
// 清除最短路径图层
|
}
|
||||||
this.shortestPathLayer.clear()
|
|
||||||
|
|
||||||
// 清除路网数据图层
|
|
||||||
// this.graphicLayer.clear();
|
|
||||||
},
|
},
|
||||||
async loadShapefile() {
|
async loadShapefile() {
|
||||||
try {
|
try {
|
||||||
@ -203,7 +278,7 @@ export default {
|
|||||||
// const shpJson = await shp(shpBuffer); // {features: [...]}
|
// const shpJson = await shp(shpBuffer); // {features: [...]}
|
||||||
|
|
||||||
// 1. 读取本地 jeojson
|
// 1. 读取本地 jeojson
|
||||||
const shpBuffer = await fetch('./config/map/data/dao.geojson')
|
const shpBuffer = await fetch('/config/dao.geojson')
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return response.json()
|
return response.json()
|
||||||
})
|
})
|
||||||
@ -233,27 +308,247 @@ export default {
|
|||||||
console.error('加载 Shapefile 数据失败:', error)
|
console.error('加载 Shapefile 数据失败:', error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async drawPolygon() {
|
// 弹框
|
||||||
if (this.polygonZAM) {
|
async openDialog() {
|
||||||
this.polygonZAM.remove()
|
await fetch('/data/minTurnRadius.json')
|
||||||
this.polygonZAM = null
|
.then((response) => {
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.tableData = data
|
||||||
|
})
|
||||||
|
.catch((error) => {})
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
|
handleSelectionChange({ records }) {
|
||||||
|
this.multipleSelection = records;
|
||||||
|
},
|
||||||
|
confirmSelection() {
|
||||||
|
if (this.multipleSelection.length === 0) {
|
||||||
|
this.$message.warning('请至少选择一行数据');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
this.polygonZAM = await this.graphicLayer.startDraw({
|
const maxValues = this.multipleSelection.reduce((acc, item) => {
|
||||||
type: 'polygon',
|
acc.width = Math.max(acc.width, item.width);
|
||||||
|
acc.load = Math.max(acc.load, item.load);
|
||||||
|
acc.minTurnRadius = Math.max(acc.minTurnRadius, item.minTurnRadius);
|
||||||
|
return acc;
|
||||||
|
}, { width: 0, load: 0, minTurnRadius: 0 });
|
||||||
|
this.inputform.width = maxValues.width;
|
||||||
|
this.inputform.load = maxValues.load;
|
||||||
|
this.inputform.minTurnRadius = maxValues.minTurnRadius;
|
||||||
|
this.dialogVisible = false;
|
||||||
|
},
|
||||||
|
// 导入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;
|
||||||
|
};
|
||||||
|
// 清除现有数据
|
||||||
|
this.clear();
|
||||||
|
// 加载起点
|
||||||
|
if (uploadedJson.startPoint) {
|
||||||
|
this.form.startPoint = uploadedJson.startPoint
|
||||||
|
this.addPointToMap('startPoint', this.form.startPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载终点
|
||||||
|
if (uploadedJson.endPoint) {
|
||||||
|
this.form.endPoint = uploadedJson.endPoint
|
||||||
|
this.addPointToMap('endPoint', this.form.endPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载途径点
|
||||||
|
if (uploadedJson.viaPoints) {
|
||||||
|
this.form.viaPoints = uploadedJson.viaPoints
|
||||||
|
uploadedJson.viaPoints.forEach(viaPoint => {
|
||||||
|
this.addPointToMap('viaPoints', viaPoint, viaPoint.time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载避让点
|
||||||
|
if (uploadedJson.avoidPoints) {
|
||||||
|
this.form.avoidPoints = uploadedJson.avoidPoints
|
||||||
|
uploadedJson.avoidPoints.forEach(avoidPoint => {
|
||||||
|
this.addPointToMap('avoidPoints', avoidPoint, avoidPoint.time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载避让区域
|
||||||
|
if (uploadedJson.avoidAreas) {
|
||||||
|
this.form.avoidAreas = uploadedJson.avoidAreas
|
||||||
|
uploadedJson.avoidAreas.forEach(avoidArea => {
|
||||||
|
const time = Date.now();
|
||||||
|
this.addPolygonToMap('avoidAreas', avoidArea, avoidArea.time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
addPointToMap(type, point, time) {
|
||||||
|
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: {
|
style: {
|
||||||
color: '#00ffff',
|
pixelSize: 10,
|
||||||
|
color: type === 'startPoint' ? 'red' : type === 'endPoint' ? 'red' : type === 'viaPoints' ? 'blue' : 'orange',
|
||||||
|
label: {
|
||||||
|
text: type === 'startPoint' ? '起点' : type === 'endPoint' ? '终点' : type === 'viaPoints' ? '途径点' : '避让点',
|
||||||
|
font_size: 20,
|
||||||
|
color: '#ffffff',
|
||||||
|
outline: true,
|
||||||
|
outlineColor: '#000000',
|
||||||
|
pixelOffsetY: -20,
|
||||||
|
},
|
||||||
|
time: time
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.graphicLayer.addGraphic(graphic);
|
||||||
|
|
||||||
|
if (type === 'startPoint') {
|
||||||
|
this.pointQD = graphic;
|
||||||
|
} else if (type === 'endPoint') {
|
||||||
|
this.pointZD = graphic;
|
||||||
|
} else if (type === 'viaPoints') {
|
||||||
|
this.viaPoints.push(graphic);
|
||||||
|
} else if (type === 'avoidPoints') {
|
||||||
|
this.avoidPoints.push(graphic);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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])),
|
||||||
|
style: {
|
||||||
|
color: 'red',
|
||||||
opacity: 0.4,
|
opacity: 0.4,
|
||||||
clampToGround: true,
|
clampToGround: true,
|
||||||
outline: true,
|
outline: true,
|
||||||
outlineWidth: 1,
|
outlineWidth: 1,
|
||||||
outlineColor: '#ffffff',
|
outlineColor: '#ffffff',
|
||||||
|
time: time
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
this.graphicLayer.addGraphic(graphic);
|
||||||
|
|
||||||
|
if (type === 'avoidAreas') {
|
||||||
|
this.avoidAreas.push(graphic);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 输入框失去焦点 反向编辑点
|
||||||
|
pointsChange(type, row) {
|
||||||
|
if (type === 'startPoint') {
|
||||||
|
if ((!this.form.startPoint || this.form.startPoint == '' || this.form.startPoint == null || this.form.startPoint == undefined) && this.pointQD) {
|
||||||
|
this.pointQD.remove()
|
||||||
|
this.pointQD = null;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.updatePointPosition(this.pointQD, this.form.startPoint);
|
||||||
|
} else if (type === 'endPoint') {
|
||||||
|
if ((!this.form.endPoint || this.form.endPoint == '' || this.form.endPoint == null || this.form.endPoint == undefined) && this.pointZD) {
|
||||||
|
this.pointZD.remove()
|
||||||
|
this.pointZD = null;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.updatePointPosition(this.pointZD, this.form.endPoint);
|
||||||
|
} 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 === '') {
|
||||||
|
// 如果只剩下一个空项,不删除图形,清空输入框值
|
||||||
|
this.form.viaPoints[0].points = '';
|
||||||
|
graphic?.remove();
|
||||||
|
this.viaPoints = this.viaPoints.filter(viaPoint => viaPoint.style.time !== row.time);
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
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 === '') {
|
||||||
|
// 如果只剩下一个空项,不删除图形,清空输入框值
|
||||||
|
this.form.avoidPoints[0].points = '';
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
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 === '') {
|
||||||
|
// 如果只剩下一个空项,不删除图形,清空输入框值
|
||||||
|
this.form.avoidAreas[0].points = '';
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
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 === '') {
|
||||||
|
this.form.viaPoints = [];
|
||||||
|
} else if (type === 'avoidPoints' && this.form.avoidPoints.length === 1 && this.form.avoidPoints[0].points === '') {
|
||||||
|
this.form.avoidPoints = [];
|
||||||
|
} else if (type === 'avoidAreas' && this.form.avoidAreas.length === 1 && this.form.avoidAreas[0].points === '') {
|
||||||
|
this.form.avoidAreas = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updatePointPosition(graphic, pointsStr) {
|
||||||
|
if (!graphic) return;
|
||||||
|
const coords = pointsStr.split(',').map(Number);
|
||||||
|
if (coords.length === 2) {
|
||||||
|
graphic.position = new window.mars3d.LngLatPoint(coords[0], coords[1]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updatePolygonPosition(graphic, pointsStr) {
|
||||||
|
if (!graphic) return;
|
||||||
|
try {
|
||||||
|
const coords = JSON.parse(pointsStr);
|
||||||
|
graphic.positions = coords.map(coord => new window.mars3d.LngLatPoint(coord[0], coord[1]));
|
||||||
|
} catch (error) {
|
||||||
|
graphic.remove();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
drawStartPoint() {
|
drawStartPoint() {
|
||||||
if (this.pointQD) {
|
if (this.pointQD) {
|
||||||
this.pointQD.remove()
|
this.pointQD.remove()
|
||||||
this.pointQD = null
|
this.pointQD = null
|
||||||
|
this.form.startPoint = ''
|
||||||
}
|
}
|
||||||
this.graphicLayer.startDraw({
|
this.graphicLayer.startDraw({
|
||||||
type: 'point',
|
type: 'point',
|
||||||
@ -271,7 +566,7 @@ export default {
|
|||||||
},
|
},
|
||||||
success: (graphic) => {
|
success: (graphic) => {
|
||||||
this.pointQD = graphic
|
this.pointQD = graphic
|
||||||
this.graphicLayer.stopDraw()
|
this.form.startPoint = [graphic.toGeoJSON().geometry.coordinates[0],graphic.toGeoJSON().geometry.coordinates[1]].join(",");
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -279,6 +574,7 @@ export default {
|
|||||||
if (this.pointZD) {
|
if (this.pointZD) {
|
||||||
this.pointZD.remove()
|
this.pointZD.remove()
|
||||||
this.pointZD = null
|
this.pointZD = null
|
||||||
|
this.form.endPoint = ''
|
||||||
}
|
}
|
||||||
this.graphicLayer.startDraw({
|
this.graphicLayer.startDraw({
|
||||||
type: 'point',
|
type: 'point',
|
||||||
@ -296,12 +592,13 @@ export default {
|
|||||||
},
|
},
|
||||||
success: (graphic) => {
|
success: (graphic) => {
|
||||||
this.pointZD = graphic
|
this.pointZD = graphic
|
||||||
this.graphicLayer.stopDraw()
|
this.form.endPoint = [graphic.toGeoJSON().geometry.coordinates[0],graphic.toGeoJSON().geometry.coordinates[1]].join(",");
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 途径点
|
// 途径点
|
||||||
drawViaPoint() {
|
drawViaPoint() {
|
||||||
|
const time = Date.now();
|
||||||
this.graphicLayer.startDraw({
|
this.graphicLayer.startDraw({
|
||||||
type: 'point',
|
type: 'point',
|
||||||
style: {
|
style: {
|
||||||
@ -315,15 +612,23 @@ export default {
|
|||||||
outlineColor: '#000000',
|
outlineColor: '#000000',
|
||||||
pixelOffsetY: -20,
|
pixelOffsetY: -20,
|
||||||
},
|
},
|
||||||
|
time: time
|
||||||
},
|
},
|
||||||
success: (graphic) => {
|
success: (graphic) => {
|
||||||
this.viaPoints.push(graphic)
|
this.viaPoints.push(graphic)
|
||||||
this.graphicLayer.stopDraw()
|
const points = [graphic.toGeoJSON().geometry.coordinates[0],graphic.toGeoJSON().geometry.coordinates[1]].join(",")
|
||||||
|
if(this.form.viaPoints.length == 1 && this.form.viaPoints[0].points == '' && !this.form.viaPoints[0].points){
|
||||||
|
this.form.viaPoints[0].points = points
|
||||||
|
this.form.viaPoints[0].time = time
|
||||||
|
} else {
|
||||||
|
this.form.viaPoints.push({points,time})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 避让点
|
// 避让点
|
||||||
drawAvoidPoint() {
|
drawAvoidPoint() {
|
||||||
|
const time = Date.now();
|
||||||
this.graphicLayer.startDraw({
|
this.graphicLayer.startDraw({
|
||||||
type: 'point',
|
type: 'point',
|
||||||
style: {
|
style: {
|
||||||
@ -337,15 +642,23 @@ export default {
|
|||||||
outlineColor: '#000000',
|
outlineColor: '#000000',
|
||||||
pixelOffsetY: -20,
|
pixelOffsetY: -20,
|
||||||
},
|
},
|
||||||
|
time: time
|
||||||
},
|
},
|
||||||
success: (graphic) => {
|
success: (graphic) => {
|
||||||
this.avoidPoints.push(graphic)
|
this.avoidPoints.push(graphic)
|
||||||
this.graphicLayer.stopDraw()
|
const points = [graphic.toGeoJSON().geometry.coordinates[0],graphic.toGeoJSON().geometry.coordinates[1]].join(",")
|
||||||
|
if(this.form.avoidPoints.length == 1 && this.form.avoidPoints[0].points == '' && !this.form.avoidPoints[0].points){
|
||||||
|
this.form.avoidPoints[0].points = points
|
||||||
|
this.form.avoidPoints[0].time = time
|
||||||
|
} else {
|
||||||
|
this.form.avoidPoints.push({points, time})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 避让区域
|
// 避让区域
|
||||||
drawAvoidArea() {
|
drawAvoidArea() {
|
||||||
|
const time = Date.now();
|
||||||
this.graphicLayer.startDraw({
|
this.graphicLayer.startDraw({
|
||||||
type: 'polygon',
|
type: 'polygon',
|
||||||
drawEndEventType: window.mars3d.EventType.dblClick,
|
drawEndEventType: window.mars3d.EventType.dblClick,
|
||||||
@ -356,10 +669,18 @@ export default {
|
|||||||
outline: true,
|
outline: true,
|
||||||
outlineWidth: 1,
|
outlineWidth: 1,
|
||||||
outlineColor: '#ffffff',
|
outlineColor: '#ffffff',
|
||||||
|
time: time
|
||||||
},
|
},
|
||||||
success: (graphic) => {
|
success: (graphic) => {
|
||||||
this.avoidAreas.push(graphic)
|
this.avoidAreas.push(graphic)
|
||||||
this.graphicLayer.stopDraw()
|
const avoidAreasGeoJSON = graphic.toGeoJSON()
|
||||||
|
const points = JSON.stringify(avoidAreasGeoJSON.geometry.coordinates[0])
|
||||||
|
if(this.form.avoidAreas.length == 1 && this.form.avoidAreas[0].points == '' && !this.form.avoidAreas[0].points){
|
||||||
|
this.form.avoidAreas[0].points = points
|
||||||
|
this.form.avoidAreas[0].time = time
|
||||||
|
} else {
|
||||||
|
this.form.avoidAreas.push({points, time})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -395,7 +716,6 @@ export default {
|
|||||||
graph[endNode] = graph[endNode] || {}
|
graph[endNode] = graph[endNode] || {}
|
||||||
graph[endNode][startNode] = distance
|
graph[endNode][startNode] = distance
|
||||||
})
|
})
|
||||||
|
|
||||||
return {graph, nodeCoords}
|
return {graph, nodeCoords}
|
||||||
},
|
},
|
||||||
// 2. 匹配最近路网节点(经纬度坐标)
|
// 2. 匹配最近路网节点(经纬度坐标)
|
||||||
@ -430,6 +750,7 @@ export default {
|
|||||||
? [startCoord, viaPoints[0].geometry.coordinates, endCoord]
|
? [startCoord, viaPoints[0].geometry.coordinates, endCoord]
|
||||||
: [startCoord, endCoord]
|
: [startCoord, endCoord]
|
||||||
const fullPath = []
|
const fullPath = []
|
||||||
|
const infoList = []
|
||||||
|
|
||||||
for (let i = 0; i < points.length - 1; i++) {
|
for (let i = 0; i < points.length - 1; i++) {
|
||||||
const segmentStart = points[i]
|
const segmentStart = points[i]
|
||||||
@ -499,11 +820,12 @@ export default {
|
|||||||
)
|
)
|
||||||
if (segment) {
|
if (segment) {
|
||||||
fullPath.push(...segment.geometry.coordinates[0])
|
fullPath.push(...segment.geometry.coordinates[0])
|
||||||
|
infoList.push(segment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullPath
|
return {fullPath, infoList}
|
||||||
},
|
},
|
||||||
async calculateShortestPath() {
|
async calculateShortestPath() {
|
||||||
if (!this.pointQD || !this.pointZD || !this.roadNetworkGeoJSON) {
|
if (!this.pointQD || !this.pointZD || !this.roadNetworkGeoJSON) {
|
||||||
@ -511,6 +833,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.shortestPathLayer.clear()
|
this.shortestPathLayer.clear()
|
||||||
|
this.infoList = []
|
||||||
const startPoint = turf.point(
|
const startPoint = turf.point(
|
||||||
this.pointQD.toGeoJSON().geometry.coordinates
|
this.pointQD.toGeoJSON().geometry.coordinates
|
||||||
).geometry.coordinates // 起点
|
).geometry.coordinates // 起点
|
||||||
@ -552,7 +875,7 @@ export default {
|
|||||||
drawPath(path) {
|
drawPath(path) {
|
||||||
const positions = path
|
const positions = path
|
||||||
const polyline = new window.mars3d.graphic.PolylinePrimitive({
|
const polyline = new window.mars3d.graphic.PolylinePrimitive({
|
||||||
positions: positions,
|
positions: positions.fullPath,
|
||||||
style: {
|
style: {
|
||||||
clampToGround: true,
|
clampToGround: true,
|
||||||
color: '#55ff33',
|
color: '#55ff33',
|
||||||
@ -560,6 +883,7 @@ export default {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
this.shortestPathLayer.addGraphic(polyline)
|
this.shortestPathLayer.addGraphic(polyline)
|
||||||
|
this.infoList = path.infoList.map(item => item.properties)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -579,6 +903,7 @@ export default {
|
|||||||
height: 24px;
|
height: 24px;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.sure {
|
.sure {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -594,8 +919,11 @@ export default {
|
|||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
position: absolute;
|
margin-right: 10px;
|
||||||
right: 30px;
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.dialog-body {
|
||||||
|
max-height: 500px;
|
||||||
}
|
}
|
||||||
.home {
|
.home {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -603,23 +931,35 @@ export default {
|
|||||||
background: #abc6bc;
|
background: #abc6bc;
|
||||||
}
|
}
|
||||||
.main-container {
|
.main-container {
|
||||||
width: 100%;
|
width: 340px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: #d4e5db;
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: none; /* 隐藏滚动条(Firefox) */
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-container::-webkit-scrollbar {
|
||||||
|
display: none; /* 隐藏滚动条(Chrome, Safari, Edge) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel {
|
.control-panel {
|
||||||
width: 340px;
|
width: 340px;
|
||||||
padding: 20px 26px;
|
padding: 20px 26px;
|
||||||
margin-left: 4px;
|
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background: #d4e5db;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel .title {
|
.control-panel .title {
|
||||||
|
/* text-align: center; */
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
color: #1c1c1c;
|
color: #1c1c1c;
|
||||||
}
|
}
|
||||||
.importJson {
|
.importJson {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
background: #2f705f;
|
background: #2f705f;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -627,7 +967,8 @@ export default {
|
|||||||
height: 24px;
|
height: 24px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-left: 40px;
|
margin-left: 20px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
@ -651,8 +992,7 @@ export default {
|
|||||||
#mapbox,
|
#mapbox,
|
||||||
.el-main {
|
.el-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: calc(100vw- 792px);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 1px solid #333;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user