fix: avoid map refresh on road selection

This commit is contained in:
2026-08-26 15:39:17 +08:00
parent 89e0a9ce37
commit 02c3a4d3e4
6 changed files with 59 additions and 4 deletions

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}

View File

@@ -0,0 +1,16 @@
# 修复工作台选择与保存回归
## Goal
道路选择只更新选择高亮,不重置地图数据或视图;保存修改后可靠保留并重新编译 overrides。
## Confirmed Cause
`MapCanvas` 使用 `[state, selected]` 更新全量 source 和 fit view选择道路会触发全图重载。Road override 的前后端 schema 一致,因此保存回归需在 UI 操作后验证其状态同步和编译调用。
## Acceptance Criteria
- 选择道路不会清空 source、重新 fit 地图或改变视图。
- 仅选择高亮 layer 更新;选择相关 OSM 线条样式仍刷新。
- 暂存、保存、重新编译的 overrides 正确发送并以服务端响应更新状态。
- 格式化、类型检查和构建通过。

View File

@@ -0,0 +1,26 @@
{
"id": "workbench-selection-save-fix",
"name": "workbench-selection-save-fix",
"title": "修复工作台选择与保存回归",
"description": "修复道路选择触发全图层重建,并排查修复 React 工作台保存 overrides 回归",
"status": "in_progress",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "dingkang",
"assignee": "dingkang",
"createdAt": "2026-08-26",
"completedAt": null,
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": null,
"relatedFiles": [],
"notes": "",
"meta": {}
}

View File

@@ -4,7 +4,7 @@ import View from 'ol/View';
import Select from 'ol/interaction/Select'; import Select from 'ol/interaction/Select';
import { click } from 'ol/events/condition'; import { click } from 'ol/events/condition';
import type { Road, WorkbenchState } from '../types/state'; import type { Road, WorkbenchState } from '../types/state';
import { createLayers, updateLayers, type LayerName } from '../map/layers'; import { createLayers, updateLayers, updateSelectedRoad, type LayerName } from '../map/layers';
interface Props { interface Props {
state: WorkbenchState; state: WorkbenchState;
@@ -72,7 +72,13 @@ export function MapCanvas({ state, selected, visible, scene, onSelectRoad, onFea
updateLayers(layers, state, selected); updateLayers(layers, state, selected);
const extent = layers.osm.getSource()!.getExtent(); const extent = layers.osm.getSource()!.getExtent();
if (extent && Number.isFinite(extent[0])) map.getView().fit(extent, { padding: [48, 48, 48, 48], maxZoom: 19 }); if (extent && Number.isFinite(extent[0])) map.getView().fit(extent, { padding: [48, 48, 48, 48], maxZoom: 19 });
}, [state, selected]); }, [state]);
useEffect(() => {
const layers = layersRef.current;
if (!layers) return;
updateSelectedRoad(layers, selected);
layers.osm.changed();
}, [selected]);
useEffect(() => { useEffect(() => {
const layers = layersRef.current; const layers = layersRef.current;
if (!layers) return; if (!layers) return;

View File

@@ -157,9 +157,14 @@ export function updateLayers(layers: ReturnType<typeof createLayers>, state: Wor
.filter((item) => item.geometry) .filter((item) => item.geometry)
.map(({ geometry, ...properties }) => ({ type: 'Feature', properties, geometry: geometry! })), .map(({ geometry, ...properties }) => ({ type: 'Feature', properties, geometry: geometry! })),
}); });
put('selectedRoad', { type: 'FeatureCollection', features: [] }); updateSelectedRoad(layers, selected);
}
export function updateSelectedRoad(layers: ReturnType<typeof createLayers>, selected: Road | null) {
const source = layers.selectedRoad.getSource()!;
source.clear();
if (selected) if (selected)
get('selectedRoad').addFeature( source.addFeature(
new Feature({ geometry: new LineString(selected.centerline).transform('EPSG:4326', 'EPSG:3857') }), new Feature({ geometry: new LineString(selected.centerline).transform('EPSG:4326', 'EPSG:3857') }),
); );
} }