PanelHxhs.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. <!-- 航线划设面板 -->
  2. <template>
  3. <div class="panel-hxhs flex flex-col aside-left-inner">
  4. <div class="title-main">航线划设</div>
  5. <el-steps :active="currentStep" finish-status="success" align-center>
  6. <el-step title="航线划设" />
  7. <el-step title="航线评估" />
  8. </el-steps>
  9. <div class="flex-1 relative mb-4">
  10. <Transition name="emerge-left">
  11. <el-form
  12. ref="formRef"
  13. v-show="currentStep === 0"
  14. :model="form"
  15. :rules="rules"
  16. label-position="left"
  17. size="large"
  18. class="p-form p-main"
  19. hide-required-asterisk>
  20. <el-form-item label="名称" prop="name">
  21. <el-input v-model="form.name" clearable></el-input>
  22. </el-form-item>
  23. <el-form-item label="任务类型" prop="taskType">
  24. <el-select v-model="form.taskType" placeholder="">
  25. <el-option label="短途运输" value="01" />
  26. <el-option label="外卖配送" value="02" />
  27. </el-select>
  28. </el-form-item>
  29. <el-form-item label="飞行器" prop="uavType">
  30. <el-select v-model="form.uavType" placeholder="">
  31. <el-option label="微型无人机" value="01" />
  32. <el-option label="轻型无人机" value="02" />
  33. <el-option label="小型无人机" value="03" />
  34. <el-option label="中型无人机" value="04" />
  35. <el-option label="大型无人机" value="05" />
  36. </el-select>
  37. </el-form-item>
  38. <el-form-item label="航线选择" prop="dataType">
  39. <el-radio-group v-model="form.dataType" @change="changeDataType()" size="large">
  40. <el-radio label="起降场规划" value="02" />
  41. <el-radio label="手动划设" value="01" />
  42. <el-radio label="导入航线" value="03" />
  43. </el-radio-group>
  44. </el-form-item>
  45. <div v-if="form.dataType === '01'" @click="changeDataType()" class="msg-draw">
  46. <img src="../../../assets/images/page/icon-draw.png" alt="" />
  47. <span>重新绘制</span>
  48. </div>
  49. <template v-if="form.dataType === '02'">
  50. <el-form-item label="起飞场" prop="fromPort">
  51. <el-select v-model="form.fromPort" @change="showPort('fromPort')" placeholder="">
  52. <el-option
  53. v-for="item in portOptions"
  54. :key="item.value"
  55. :label="item.label"
  56. :value="item.value"
  57. :disabled="item.value === form.toPort" />
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item label="降落场" prop="toPort">
  61. <el-select v-model="form.toPort" @change="showPort('toPort')" placeholder="">
  62. <el-option
  63. v-for="item in portOptions"
  64. :key="item.value"
  65. :label="item.label"
  66. :value="item.value"
  67. :disabled="item.value === form.fromPort" />
  68. </el-select>
  69. </el-form-item>
  70. </template>
  71. <el-form-item label="上传文件" prop="file" v-if="form.dataType === '03'">
  72. <el-upload v-model:file-list="form.file" action="" class="single-uplaod">
  73. <div class="upload-trigger">点击上传文件</div>
  74. </el-upload>
  75. </el-form-item>
  76. <el-form-item label="保持半径" prop="radius">
  77. <el-input v-model="form.radius" type="number" class="flex-1">
  78. <template #suffix>
  79. <span>米</span>
  80. </template>
  81. </el-input>
  82. </el-form-item>
  83. <el-form-item label="飞行高度" prop="height">
  84. <el-input v-model="form.height1" type="number" class="flex-1">
  85. <template #suffix>
  86. <span>米</span>
  87. </template>
  88. </el-input>
  89. <div class="mx-3">--</div>
  90. <el-input v-model="form.height2" type="number" class="flex-1">
  91. <template #suffix>
  92. <span>米</span>
  93. </template>
  94. </el-input>
  95. </el-form-item>
  96. <el-form-item label="日期" prop="startDate">
  97. <el-date-picker
  98. v-model="form.startDate"
  99. value-format="YYYY-MM-DD"
  100. type="date"
  101. class="flex-1"></el-date-picker>
  102. <div class="mx-3">--</div>
  103. <el-date-picker
  104. v-model="form.endDate"
  105. value-format="YYYY-MM-DD"
  106. type="date"
  107. class="flex-1"></el-date-picker>
  108. </el-form-item>
  109. <el-form-item label="时间" prop="startTime">
  110. <el-time-select
  111. v-model="form.startTime"
  112. :max-time="form.endTime"
  113. placeholder=""
  114. start="00:00"
  115. step="00:15"
  116. end="23:45"
  117. class="flex-1" />
  118. <div class="mx-3">--</div>
  119. <el-time-select
  120. v-model="form.endTime"
  121. :min-time="form.startTime"
  122. placeholder=""
  123. start="00:00"
  124. step="00:15"
  125. end="23:45"
  126. class="flex-1" />
  127. </el-form-item>
  128. <el-form-item label="网格查询">
  129. <!-- <el-checkbox v-model="form.grade">评分</el-checkbox>-->
  130. <el-button class="btn-secondary ml-4" @click="queryCube()">查询网格</el-button>
  131. <el-button class="btn-secondary ml-4" @click="closeCube()">关闭网格</el-button>
  132. </el-form-item>
  133. <!-- <el-form-item label="辅助规划">-->
  134. <!-- <el-button class="btn-secondary" @click="getAutoPath()" >辅助规划</el-button>-->
  135. <!-- </el-form-item>-->
  136. </el-form>
  137. </Transition>
  138. <Transition name="emerge-right">
  139. <div v-show="currentStep === 1" class="p-main">
  140. <ul class="list-plans flex justify-evenly mb-4">
  141. <li
  142. v-for="item in plans"
  143. class="pt-7 cursor-pointer hover:brightness-125"
  144. :class="{ active: item.id === currentPlan }"
  145. @click="handlePickPlan(item)">
  146. <div class="text-base">
  147. <span class="tuli" :style="{ backgroundColor: item.color }"></span>{{ item.feature }}
  148. </div>
  149. <div class="text-sm py-1">
  150. 距离&nbsp;<span class="num">{{ item.distance }}</span
  151. >&nbsp;公里
  152. </div>
  153. <div class="text-sm">
  154. 风险度:<span class="num">{{ item.risk }}</span>
  155. </div>
  156. </li>
  157. </ul>
  158. <el-form-item label="网格查询">
  159. <!-- <el-checkbox v-model="form.grade">评分</el-checkbox>-->
  160. <el-button class="btn-secondary ml-4" @click="queryCube24()">查询网格</el-button>
  161. <el-button class="btn-secondary ml-4" @click="closeCube()">关闭网格</el-button>
  162. </el-form-item>
  163. <div v-if="isSafe" class="msg-safe mb-2">当前计划无冲突!</div>
  164. <template v-else>
  165. <div v-for="item in results" :key="item.title" class="mb-3">
  166. <div class="title-sub">
  167. {{ item.title }}
  168. <div class="flex-1 flex justify-between items-center pl-2">
  169. <span
  170. v-if="item.level"
  171. class="risk-label"
  172. :class="riskTypes.find((i) => i.value === item.level).color"
  173. >{{ riskTypes.find((i) => i.value === item.level).label }}</span
  174. >
  175. <i v-else></i>
  176. <span class="btn-inline" @click="handleReInspect">重新评估</span>
  177. </div>
  178. </div>
  179. <table class="table-default stripe mt-2">
  180. <thead>
  181. <tr>
  182. <th v-for="th in item.cols">{{ th }}</th>
  183. <th class="w-20">地图显示</th>
  184. </tr>
  185. </thead>
  186. <tbody>
  187. <tr v-for="row in item.details">
  188. <td v-for="key in Object.keys(item.cols)">{{ row[key] }}</td>
  189. <td class="w-20">
  190. <el-checkbox
  191. size="large"
  192. v-model="row.display"
  193. :disabled="
  194. (row.id !== '3-3' && !row.cubes.length) ||
  195. (row.id === '3-3' && item.details.every((r) => r.cubes.length === 0))
  196. "
  197. @change="(val) => toggleCubeDetail(row, val)"></el-checkbox>
  198. </td>
  199. </tr>
  200. </tbody>
  201. </table>
  202. </div>
  203. </template>
  204. </div>
  205. </Transition>
  206. </div>
  207. <div class="text-center">
  208. <el-button v-if="currentStep === 0" :disabled="!hasDraw" class="btn-main" @click="toNext">下一步</el-button>
  209. <template v-if="currentStep === 1">
  210. <el-button class="btn-main" @click="toPrev">上一步</el-button>
  211. <el-button class="btn-main" @click="handlePreview">计划预演</el-button>
  212. <el-button class="btn-main" @click="handleSave">保存</el-button>
  213. </template>
  214. </div>
  215. </div>
  216. </template>
  217. <script setup>
  218. import { ref, onMounted, watch, onBeforeUnmount, computed, onBeforeMount } from 'vue'
  219. import { routePlanAll, saveRoute, searchQJCList } from '@/service/panelHxhs.js'
  220. import { geometryMeshEffect, getPathCube, getPathCube24, showAndRedrawPath } from '@/utils/map/addTool.js'
  221. import { InspectPathCube } from '@/utils/map/addLayer'
  222. import useLayoutStore from '@/store/layout'
  223. import { useMapStore } from '@/store/map.js'
  224. import { riskTypes } from '@/utils/options'
  225. import { useDateFormat } from '@vueuse/core'
  226. import { getInspectionData } from '@/service/map.js'
  227. const currentStep = ref(0)
  228. let currentPath = [] // 当前规划路径
  229. let allPathArr = [] // 所有路径
  230. let autoHeight = false //手动规划
  231. const layoutStore = useLayoutStore()
  232. const mapStore = useMapStore()
  233. const form = ref({
  234. taskType: '01',
  235. uavType: '01',
  236. dataType: '02',
  237. height1: 60,
  238. height2: 80,
  239. radius: 5,
  240. startDate: '',
  241. endDate: '',
  242. startTime: '',
  243. endTime: '',
  244. })
  245. onBeforeMount(() => {
  246. form.value.startDate = useDateFormat(new Date(), 'YYYY-MM-DD').value
  247. form.value.endDate = useDateFormat(new Date().getTime() + 24 * 60 * 60 * 1000, 'YYYY-MM-DD').value
  248. form.value.startTime = useDateFormat(new Date(), 'HH:mm').value
  249. form.value.endTime = useDateFormat(new Date().getTime() + 60 * 60 * 1000, 'HH:mm').value
  250. })
  251. const portOptions = []
  252. const rules = {
  253. name: [{ required: true, message: '请输入空域名称', trigger: 'none' }],
  254. }
  255. const formRef = ref(null)
  256. const results = ref([
  257. {
  258. title: '空域评估',
  259. level: null,
  260. cols: { areaName: '冲突空域', time: '冲突时段', height: '冲突高度' },
  261. details: [],
  262. },
  263. {
  264. title: '计划冲突',
  265. level: null,
  266. cols: { areaName: '冲突空域', time: '冲突时段', height: '冲突高度' },
  267. details: [],
  268. },
  269. {
  270. title: '障碍物分析',
  271. level: null,
  272. cols: { object: '冲突空域', height: '冲突高度' },
  273. details: [],
  274. },
  275. {
  276. title: '地面安全评估',
  277. level: null,
  278. cols: { element: '要素', coverage: '覆盖率' },
  279. details: [],
  280. },
  281. ])
  282. function handleReInspect() {
  283. closeCube()
  284. setTimeout(() => {
  285. queryCube()
  286. }, 500)
  287. }
  288. let addedCubeDetailIds = []
  289. function toggleCubeDetail(row, status) {
  290. console.log(row, status)
  291. if (row.id === '3-3') {
  292. // 处理综合占比
  293. results.value[3].details.forEach((gRow) => {
  294. if (gRow.display !== status && gRow.cubes.length) {
  295. gRow.display = status
  296. toggleCubeDetail(gRow, status)
  297. }
  298. })
  299. } else {
  300. if (!row.cubes.length) return
  301. const id = 'hxhs_' + row.id
  302. if (status) {
  303. addedCubeDetailIds.push(id)
  304. } else {
  305. const targetIndex = addedCubeDetailIds.findIndex((i) => i === id)
  306. addedCubeDetailIds.splice(targetIndex, 1)
  307. }
  308. InspectPathCube({
  309. id,
  310. show: status,
  311. points: row.cubes.map((c) => ({
  312. x: c.x,
  313. y: c.y,
  314. z: c.z,
  315. color: c.color,
  316. gridCode: c.gridCode,
  317. })),
  318. size: {
  319. x: row.cubes[0].boxSize.latLength,
  320. y: row.cubes[0].boxSize.lonLength,
  321. z: row.cubes[0].boxSize.height,
  322. },
  323. })
  324. }
  325. }
  326. function clearAllCubeDetail() {
  327. addedCubeDetailIds.forEach((id) => {
  328. InspectPathCube({
  329. id,
  330. show: false,
  331. })
  332. })
  333. addedCubeDetailIds = []
  334. }
  335. let plans = ref([
  336. { id: '1', name: 'originalPath', feature: '接近原方案', color: '#FFA500', distance: '', risk: '50' },
  337. { id: '2', name: 'safePath', feature: '地面风险较低', color: '#00FF00', distance: '', risk: '10' },
  338. { id: '3', name: 'shortestPath', feature: '距离最短', color: '#FFA5FF', distance: '', risk: '50' },
  339. ])
  340. const isSafe = computed(() => {
  341. return results.value.every((i) => i.level === 1)
  342. })
  343. const hasDraw = ref(false)
  344. function clearResults() {
  345. results.value.forEach((v) => {
  346. v.details = []
  347. v.level = null
  348. })
  349. }
  350. function formatResult(res) {
  351. clearResults()
  352. debugger
  353. if (res != null && res != undefined) {
  354. const { groundSafety, lineConflictArray, obstacle, spaceConflictArray, spaceRisk, lineRisk } = res
  355. results.value[0].level = spaceRisk
  356. results.value[1].level = lineRisk
  357. results.value[2].level = obstacle.risk
  358. results.value[3].level = groundSafety.risk
  359. results.value[0].details = spaceConflictArray.map((i, index) => ({
  360. id: `0-${index}`,
  361. areaName: i.gridName,
  362. height: i.heightRange,
  363. time: i.conflictTime,
  364. cubes: i.gridEntityList,
  365. display: false,
  366. }))
  367. results.value[1].details = lineConflictArray.map((i, index) => ({
  368. id: `1-${index}`,
  369. areaName: i.gridName,
  370. height: i.heightRange,
  371. time: i.conflictTime,
  372. cubes: i.gridEntityList,
  373. display: false,
  374. }))
  375. results.value[2].details = [
  376. {
  377. id: '2-0',
  378. time: '01-249:00-01-25 10-00',
  379. object: '建筑物',
  380. height: obstacle.buildingConflictHeight,
  381. cubes: obstacle.buildingsConflictArray,
  382. display: false,
  383. },
  384. {
  385. id: '2-1',
  386. time: '01-249:00-01-25 10-00',
  387. object: '建筑物缓冲区',
  388. height: obstacle.buildingBufferConflictHeight,
  389. cubes: obstacle.buildingsBufferConflictArray,
  390. display: false,
  391. },
  392. ]
  393. const toPercent = (num) => {
  394. return Math.round(num * 100) + '%'
  395. }
  396. results.value[3].details = [
  397. {
  398. id: '3-0',
  399. element: '道路',
  400. coverage: toPercent(groundSafety.road),
  401. cubes: groundSafety.gridGoupMap.road,
  402. display: false,
  403. },
  404. {
  405. id: '3-1',
  406. element: '河流',
  407. coverage: toPercent(groundSafety.river),
  408. cubes: groundSafety.gridGoupMap.river,
  409. display: false,
  410. },
  411. {
  412. id: '3-2',
  413. element: '绿化',
  414. coverage: toPercent(groundSafety.green),
  415. cubes: groundSafety.gridGoupMap.green,
  416. display: false,
  417. },
  418. {
  419. id: '3-3',
  420. element: '综合占比',
  421. coverage: toPercent(groundSafety.road + groundSafety.river + groundSafety.green),
  422. display: false,
  423. },
  424. ]
  425. } else {
  426. ElMessage({ type: 'error', message: '核查结果为空' })
  427. }
  428. layoutStore.toggleGlobalLoading(false)
  429. }
  430. function handlePickPlan(plan) {
  431. currentPlan.value = plan.id
  432. showAllPathByType()
  433. const conflicts = allPathArr[plan.name]?.conflicts
  434. if (!conflicts) {
  435. clearResults()
  436. return
  437. }
  438. clearAllCubeDetail()
  439. formatResult(conflicts.gridConflict)
  440. }
  441. const currentPlan = ref('1')
  442. function toNext() {
  443. formRef.value.validate((valid) => {
  444. if (valid) {
  445. currentStep.value = 1
  446. getAutoPath()
  447. }
  448. })
  449. }
  450. function toPrev() {
  451. currentStep.value = 0
  452. formRef.value.resetFields()
  453. allPathArr = {}
  454. clearResults()
  455. clearAllCubeDetail()
  456. getPathCube({
  457. status: 'hide',
  458. })
  459. hasDraw.value = false
  460. showAndRedrawPath({
  461. status: 'hide',
  462. })
  463. geometryMeshEffect({
  464. id: 'fromPort',
  465. status: 'hide',
  466. })
  467. geometryMeshEffect({
  468. id: 'toPort',
  469. status: 'hide',
  470. })
  471. geometryMeshEffect({
  472. status: 'hide',
  473. id: 'drawAllPathOne',
  474. })
  475. }
  476. //保存网格结果
  477. function handleSave() {
  478. saveRoute({
  479. ...form.value,
  480. shape: JSON.stringify({ paths: [currentPath] }),
  481. })
  482. .then((res) => {
  483. if (res.data.code == 200 && res.data.msg == 'success') {
  484. ElMessage({
  485. type: 'success',
  486. message: '保存成功',
  487. })
  488. } else {
  489. ElMessage({
  490. type: 'error',
  491. message: '保存失败',
  492. })
  493. }
  494. })
  495. .catch(() => {
  496. ElMessage({
  497. type: 'error',
  498. message: '保存失败',
  499. })
  500. })
  501. }
  502. function handlePreview() {}
  503. //获取起降数据
  504. function getQJCList() {
  505. searchQJCList().then((res) => {
  506. let data = res.data.data
  507. data.forEach((item) => {
  508. portOptions.push({
  509. label: item.name,
  510. value: item.id,
  511. shape: item.shape,
  512. geoType: item.geoType,
  513. })
  514. })
  515. })
  516. }
  517. function showPort(id) {
  518. geometryMeshEffect({
  519. id: id,
  520. status: 'show',
  521. data: [
  522. {
  523. type: portOptions.find((item) => item.value == form.value[id]).geoType,
  524. shape: {
  525. ...JSON.parse(portOptions.find((item) => item.value == form.value[id]).shape),
  526. color: [0, 255, 0, 0.7],
  527. },
  528. },
  529. ],
  530. })
  531. showOriginPath()
  532. }
  533. //起降场选择完成生成原始直线
  534. function showOriginPath() {
  535. if (form.value.fromPort && form.value.toPort) {
  536. let formPoint = JSON.parse(portOptions.find((item) => item.value == form.value.fromPort).shape).point
  537. let toPoint = JSON.parse(portOptions.find((item) => item.value == form.value.toPort).shape).point
  538. debugger
  539. currentPath = [
  540. [formPoint.x, formPoint.y, formPoint.z],
  541. [formPoint.x, formPoint.y, (form.value.height1 * 1 + form.value.height2 * 1) / 2],
  542. [
  543. (formPoint.x + toPoint.x) / 2,
  544. (formPoint.y + toPoint.y) / 2,
  545. (form.value.height1 * 1 + form.value.height2 * 1) / 2,
  546. ],
  547. [toPoint.x, toPoint.y, (form.value.height1 * 1 + form.value.height2 * 1) / 2],
  548. [toPoint.x, toPoint.y, toPoint.z],
  549. ]
  550. hasDraw.value = true
  551. showAndRedrawPath({
  552. status: 'show',
  553. path: currentPath,
  554. })
  555. }
  556. }
  557. function handleInspect(level) {
  558. let tempPath = []
  559. currentPath.forEach((item) => {
  560. tempPath.push({
  561. x: item[0],
  562. y: item[1],
  563. z: item[2],
  564. })
  565. })
  566. const params = {
  567. paths: tempPath,
  568. radius: 5,
  569. level,
  570. }
  571. getInspectionData(params, 'polyline')
  572. .then((res) => {
  573. const conflict = res.data?.data?.gridConflict
  574. if (!conflict) {
  575. clearResults()
  576. }
  577. formatResult(conflict)
  578. })
  579. .finally(() => {
  580. layoutStore.toggleGlobalLoading(false)
  581. })
  582. }
  583. //查询网格
  584. function queryCube() {
  585. getPathCube({
  586. status: 'show',
  587. paths: [currentPath],
  588. })
  589. }
  590. //查询网格
  591. function queryCube24() {
  592. layoutStore.toggleGlobalLoading(true)
  593. getPathCube24({
  594. status: 'show',
  595. paths: [currentPath],
  596. })
  597. handleInspect('24')
  598. }
  599. //关闭网格
  600. function closeCube() {
  601. getPathCube({
  602. status: 'hide',
  603. })
  604. }
  605. //辅助规划
  606. function getAutoPath() {
  607. let paramsPaths = []
  608. currentPath.forEach((item) => {
  609. paramsPaths.push({
  610. x: item[0],
  611. y: item[1],
  612. z: item[2],
  613. })
  614. })
  615. layoutStore.toggleGlobalLoading(true)
  616. routePlanAll({
  617. height1: form.value.height1,
  618. height2: form.value.height2,
  619. paths: paramsPaths,
  620. })
  621. .then((res) => {
  622. debugger
  623. if (res.data.code !== 200) {
  624. ElMessage({ type: 'error', message: res.data.msg })
  625. currentStep.value = 0
  626. } else {
  627. let data = res.data.data
  628. allPathArr = data
  629. plans.value.forEach((item) => {
  630. item.distance = (data[item.name].length / 1000).toFixed(2)
  631. })
  632. handlePickPlan(plans.value[0])
  633. }
  634. })
  635. .catch(() => {
  636. ElMessage({ type: 'error', message: '路径规划请求失败' })
  637. currentStep.value = 0
  638. })
  639. .finally(() => {
  640. layoutStore.toggleGlobalLoading(false)
  641. })
  642. }
  643. function showAllPathByType() {
  644. let otherPathArr = []
  645. if (currentPlan.value == 1) {
  646. //接近原路线
  647. if (allPathArr.safePath.path.length > 0) {
  648. otherPathArr.push({
  649. name: '安全路径',
  650. type: 'polyline',
  651. shape: {
  652. radius: 10,
  653. paths: allPathArr.safePath.path,
  654. color: [0, 255, 0, 0.3],
  655. },
  656. })
  657. }
  658. if (allPathArr.shortestPath.path.length > 0) {
  659. otherPathArr.push({
  660. name: '贴合路径',
  661. type: 'polyline',
  662. shape: {
  663. radius: 10,
  664. paths: allPathArr.shortestPath.path,
  665. color: [255, 165, 255, 0.3],
  666. },
  667. })
  668. }
  669. showAndRedrawPath({
  670. status: 'show',
  671. path: allPathArr.originalPath.path,
  672. color: [255, 234, 0, 0.7],
  673. })
  674. currentPath = allPathArr.shortestPath.path
  675. } else if (currentPlan.value == 2) {
  676. //安全
  677. if (allPathArr.shortestPath.path.length > 0) {
  678. otherPathArr.push({
  679. name: '最短路径',
  680. type: 'polyline',
  681. shape: {
  682. radius: 10,
  683. paths: allPathArr.shortestPath.path,
  684. color: [255, 165, 255, 0.3],
  685. },
  686. })
  687. }
  688. if (allPathArr.originalPath.path.length > 0) {
  689. otherPathArr.push({
  690. name: '贴合路径',
  691. type: 'polyline',
  692. shape: {
  693. radius: 10,
  694. paths: allPathArr.originalPath.path,
  695. color: [255, 234, 0, 0.3],
  696. },
  697. })
  698. }
  699. showAndRedrawPath({
  700. status: 'show',
  701. path: allPathArr.safePath.path,
  702. color: [0, 255, 0, 0.7],
  703. })
  704. currentPath = allPathArr.safePath.path
  705. } else if (currentPlan.value == 3) {
  706. //最短
  707. if (allPathArr.safePath.path.length > 0) {
  708. otherPathArr.push({
  709. name: '安全路径',
  710. type: 'polyline',
  711. shape: {
  712. radius: 10,
  713. paths: allPathArr.safePath.path,
  714. color: [0, 255, 0, 0.3],
  715. },
  716. })
  717. }
  718. if (allPathArr.originalPath.path.length > 0) {
  719. otherPathArr.push({
  720. name: '贴合路径',
  721. type: 'polyline',
  722. shape: {
  723. radius: 10,
  724. paths: allPathArr.originalPath.path,
  725. color: [255, 234, 0, 0.3],
  726. },
  727. })
  728. }
  729. showAndRedrawPath({
  730. status: 'show',
  731. path: allPathArr.shortestPath.path,
  732. color: [225, 165, 255, 0.7],
  733. })
  734. currentPath = allPathArr.shortestPath.path
  735. }
  736. geometryMeshEffect({
  737. status: 'show',
  738. id: 'drawAllPathOne',
  739. data: otherPathArr,
  740. })
  741. }
  742. function getDrawGeometry() {
  743. if (mapStore.draw_geometry) {
  744. if (autoHeight) {
  745. let path = mapStore.draw_geometry.paths[0]
  746. let flyPathArr = [path[0]]
  747. path.forEach((item) => {
  748. flyPathArr.push([item[0], item[1], (form.value.height1 * 1 + form.value.height2 * 1) / 2])
  749. })
  750. flyPathArr.push([path[path.length - 1][0], path[path.length - 1][1], 0])
  751. hasDraw.value = true
  752. showAndRedrawPath({
  753. status: 'show',
  754. path: flyPathArr,
  755. })
  756. autoHeight = false
  757. currentPath = flyPathArr
  758. } else {
  759. if (currentPlan.value == 1) {
  760. //最接近原航线,替换原航线数据
  761. allPathArr.originalPath.path = mapStore.draw_geometry.paths[0]
  762. } else if (currentPlan.value == 2) {
  763. //最安全
  764. allPathArr.safePath.path = mapStore.draw_geometry.paths[0]
  765. } else if (currentPlan.value == 3) {
  766. //最短
  767. allPathArr.shortestPath.path = mapStore.draw_geometry.paths[0]
  768. }
  769. currentPath = mapStore.draw_geometry.paths[0]
  770. }
  771. }
  772. }
  773. function changeDataType() {
  774. if (form.value.dataType == '01') {
  775. //手动
  776. autoHeight = true
  777. hasDraw.value = true
  778. showAndRedrawPath({
  779. status: 'show',
  780. radius: form.value.radius,
  781. })
  782. geometryMeshEffect({
  783. id: 'fromPort',
  784. status: 'hide',
  785. })
  786. geometryMeshEffect({
  787. id: 'toPort',
  788. status: 'hide',
  789. })
  790. } else if (form.value.dataType == '02') {
  791. //自动
  792. autoHeight = false
  793. hasDraw.value = false
  794. showAndRedrawPath({
  795. status: 'hide',
  796. })
  797. } else if (form.value.dataType == '03') {
  798. //导入航线
  799. autoHeight = false
  800. hasDraw.value = false
  801. showAndRedrawPath({
  802. status: 'hide',
  803. })
  804. geometryMeshEffect({
  805. id: 'fromPort',
  806. status: 'hide',
  807. })
  808. geometryMeshEffect({
  809. id: 'toPort',
  810. status: 'hide',
  811. })
  812. }
  813. }
  814. //展示冲突结果
  815. onMounted(() => {
  816. getQJCList()
  817. })
  818. watch(
  819. () => mapStore.draw_geometry,
  820. (val) => {
  821. getDrawGeometry()
  822. },
  823. {
  824. deep: true,
  825. }
  826. )
  827. // watch(
  828. // () => mapStore.cubeResult,
  829. // (val) => {
  830. // formatResult(val.data)
  831. // layoutStore.toggleGlobalLoading(false)
  832. // },
  833. // { deep: true }
  834. // )
  835. onBeforeUnmount(() => {
  836. toPrev()
  837. })
  838. </script>
  839. <style lang="scss">
  840. @use '../../../assets/styles/panel-form.scss';
  841. </style>
  842. <style lang="scss" scoped>
  843. .panel-hxhs {
  844. :deep(.p-form) {
  845. .el-form-item__label {
  846. width: 105px;
  847. }
  848. }
  849. .msg-draw {
  850. height: 38px;
  851. margin: -5px 0 25px;
  852. background: #62729486;
  853. display: flex;
  854. justify-content: center;
  855. align-items: center;
  856. font-size: 16px;
  857. img {
  858. width: 14px;
  859. height: 14px;
  860. margin-right: 5px;
  861. }
  862. }
  863. .list-plans {
  864. li {
  865. width: 134px;
  866. height: 117px;
  867. background: url('../../../assets/images/page/bg-plan.png');
  868. background-size: 100% !important;
  869. text-align: center;
  870. .tuli {
  871. display: inline-block;
  872. margin-right: 4px;
  873. width: 10px;
  874. height: 10px;
  875. }
  876. .num {
  877. color: #8cbcff;
  878. }
  879. &.active {
  880. background: url('../../../assets/images/page/bg-plan-h.png');
  881. }
  882. }
  883. }
  884. }
  885. </style>