From 127c4ea1950f48a3c41a8a4db80d944c4b05eb99 Mon Sep 17 00:00:00 2001 From: xiaosi <2652281683@qq.com> Date: Fri, 4 Sep 2026 09:45:12 +0800 Subject: [PATCH] fix: fit route editor map to waypoints on edit Route points were synced into Mapbox sources, but the shared map camera stayed on the overview, so edited routes looked missing. --- src/views/TasksView/TasksView.vue | 33 +++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/views/TasksView/TasksView.vue b/src/views/TasksView/TasksView.vue index fe1b1ef..b059249 100644 --- a/src/views/TasksView/TasksView.vue +++ b/src/views/TasksView/TasksView.vue @@ -244,6 +244,7 @@ import { useDeviceStore } from '@/stores/modules/devicesStore' import * as urls from '@/config/urls' import commonRefs from '@/utils/commonRefs' import mapHelper from '@/core/mapHelper' +import mapboxgl from 'mapbox-gl' import RouteCard from '@/components/RouteCard.vue' const ROUTE_SOURCE = 'task-route' @@ -286,6 +287,7 @@ const routeMapReady = ref(false) let routeMapInstance = null let routeMapAttached = false let pendingStyleHandler = null +let pendingFitRoute = false const routeForm = reactive({ name: '', altitude: 50, speed: 10, turnMode: 'auto' }) const routePoints = ref([]) @@ -638,7 +640,7 @@ function ensureTaskLayers(map) { return true } -function syncRouteLayer() { +function syncRouteLayer({ fit = false } = {}) { if (!routeMapInstance || !routeMapInstance.isStyleLoaded()) return if (!ensureTaskLayers(routeMapInstance)) return const coords = routePoints.value @@ -669,6 +671,25 @@ function syncRouteLayer() { } routeMapInstance.getSource(ROUTE_SOURCE)?.setData(lineData) 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) { @@ -729,7 +750,9 @@ async function attachRouteMap() { routeMapReady.value = true requestAnimationFrame(() => { map.resize() - syncRouteLayer() + const shouldFit = pendingFitRoute + pendingFitRoute = false + syncRouteLayer({ fit: shouldFit }) }) } @@ -757,6 +780,7 @@ function teardownRouteMap() { } routeMapInstance = null routeMapReady.value = false + pendingFitRoute = false } function openRouteEditor() { @@ -787,10 +811,11 @@ async function openRouteEditorForEdit(route) { speed: first ? first.speed : 10, turnMode: first ? first.turnMode : 'auto', }) + pendingFitRoute = routePoints.value.length > 0 routeEditorOpen.value = true 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) { ui.toast(e.message || '加载航线详情失败') }