|
|
@ -244,6 +244,7 @@ import { useDeviceStore } from '@/stores/modules/devicesStore' |
|
|
import * as urls from '@/config/urls' |
|
|
import * as urls from '@/config/urls' |
|
|
import commonRefs from '@/utils/commonRefs' |
|
|
import commonRefs from '@/utils/commonRefs' |
|
|
import mapHelper from '@/core/mapHelper' |
|
|
import mapHelper from '@/core/mapHelper' |
|
|
|
|
|
import mapboxgl from 'mapbox-gl' |
|
|
import RouteCard from '@/components/RouteCard.vue' |
|
|
import RouteCard from '@/components/RouteCard.vue' |
|
|
|
|
|
|
|
|
const ROUTE_SOURCE = 'task-route' |
|
|
const ROUTE_SOURCE = 'task-route' |
|
|
@ -286,6 +287,7 @@ const routeMapReady = ref(false) |
|
|
let routeMapInstance = null |
|
|
let routeMapInstance = null |
|
|
let routeMapAttached = false |
|
|
let routeMapAttached = false |
|
|
let pendingStyleHandler = null |
|
|
let pendingStyleHandler = null |
|
|
|
|
|
let pendingFitRoute = false |
|
|
|
|
|
|
|
|
const routeForm = reactive({ name: '', altitude: 50, speed: 10, turnMode: 'auto' }) |
|
|
const routeForm = reactive({ name: '', altitude: 50, speed: 10, turnMode: 'auto' }) |
|
|
const routePoints = ref([]) |
|
|
const routePoints = ref([]) |
|
|
@ -638,7 +640,7 @@ function ensureTaskLayers(map) { |
|
|
return true |
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function syncRouteLayer() { |
|
|
|
|
|
|
|
|
function syncRouteLayer({ fit = false } = {}) { |
|
|
if (!routeMapInstance || !routeMapInstance.isStyleLoaded()) return |
|
|
if (!routeMapInstance || !routeMapInstance.isStyleLoaded()) return |
|
|
if (!ensureTaskLayers(routeMapInstance)) return |
|
|
if (!ensureTaskLayers(routeMapInstance)) return |
|
|
const coords = routePoints.value |
|
|
const coords = routePoints.value |
|
|
@ -669,6 +671,25 @@ function syncRouteLayer() { |
|
|
} |
|
|
} |
|
|
routeMapInstance.getSource(ROUTE_SOURCE)?.setData(lineData) |
|
|
routeMapInstance.getSource(ROUTE_SOURCE)?.setData(lineData) |
|
|
routeMapInstance.getSource(WP_SOURCE)?.setData(wpData) |
|
|
routeMapInstance.getSource(WP_SOURCE)?.setData(wpData) |
|
|
|
|
|
|
|
|
|
|
|
if (fit && coords.length) fitRouteInView(coords) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function fitRouteInView(coords) { |
|
|
|
|
|
if (!routeMapInstance || !coords?.length) return |
|
|
|
|
|
if (coords.length === 1) { |
|
|
|
|
|
routeMapInstance.easeTo({ |
|
|
|
|
|
center: coords[0], |
|
|
|
|
|
zoom: Math.max(routeMapInstance.getZoom(), 16), |
|
|
|
|
|
duration: 400, |
|
|
|
|
|
}) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
const bounds = coords.reduce( |
|
|
|
|
|
(b, c) => b.extend(c), |
|
|
|
|
|
new mapboxgl.LngLatBounds(coords[0], coords[0]), |
|
|
|
|
|
) |
|
|
|
|
|
routeMapInstance.fitBounds(bounds, { padding: 80, duration: 400, maxZoom: 17 }) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function onRouteMapClick(e) { |
|
|
function onRouteMapClick(e) { |
|
|
@ -729,7 +750,9 @@ async function attachRouteMap() { |
|
|
routeMapReady.value = true |
|
|
routeMapReady.value = true |
|
|
requestAnimationFrame(() => { |
|
|
requestAnimationFrame(() => { |
|
|
map.resize() |
|
|
map.resize() |
|
|
syncRouteLayer() |
|
|
|
|
|
|
|
|
const shouldFit = pendingFitRoute |
|
|
|
|
|
pendingFitRoute = false |
|
|
|
|
|
syncRouteLayer({ fit: shouldFit }) |
|
|
}) |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -757,6 +780,7 @@ function teardownRouteMap() { |
|
|
} |
|
|
} |
|
|
routeMapInstance = null |
|
|
routeMapInstance = null |
|
|
routeMapReady.value = false |
|
|
routeMapReady.value = false |
|
|
|
|
|
pendingFitRoute = false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function openRouteEditor() { |
|
|
function openRouteEditor() { |
|
|
@ -787,10 +811,11 @@ async function openRouteEditorForEdit(route) { |
|
|
speed: first ? first.speed : 10, |
|
|
speed: first ? first.speed : 10, |
|
|
turnMode: first ? first.turnMode : 'auto', |
|
|
turnMode: first ? first.turnMode : 'auto', |
|
|
}) |
|
|
}) |
|
|
|
|
|
pendingFitRoute = routePoints.value.length > 0 |
|
|
routeEditorOpen.value = true |
|
|
routeEditorOpen.value = true |
|
|
await attachRouteMap() |
|
|
await attachRouteMap() |
|
|
// boot already syncs; optional extra if ready: |
|
|
|
|
|
if (routeMapReady.value) syncRouteLayer() |
|
|
|
|
|
|
|
|
// boot already syncs+fits when pendingFitRoute; ready 兜底再 fit 一次 |
|
|
|
|
|
if (routeMapReady.value) syncRouteLayer({ fit: routePoints.value.length > 0 }) |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
ui.toast(e.message || '加载航线详情失败') |
|
|
ui.toast(e.message || '加载航线详情失败') |
|
|
} |
|
|
} |
|
|
|