@wenle_2523097/agri-map 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/components/ColorSwatch/__tests__/index.test.d.ts +5 -0
  2. package/dist/components/FullscreenControl/__tests__/index.test.d.ts +5 -0
  3. package/dist/components/Marker/useEditHandlers.d.ts +2 -2
  4. package/dist/components/Measurement/__tests__/toolbar.test.d.ts +2 -2
  5. package/dist/components/Notification/__tests__/index.test.d.ts +1 -1
  6. package/dist/components/PerformanceDashboard/__tests__/index.test.d.ts +1 -1
  7. package/dist/components/PlotLayer/__tests__/index.test.d.ts +2 -3
  8. package/dist/components/Popup/__tests__/index.test.d.ts +5 -0
  9. package/dist/components/Road/hooks/useRoadEvents.d.ts +4 -0
  10. package/dist/components/SelectIcon/__tests__/index.test.d.ts +4 -0
  11. package/dist/components/StyleSelector/__tests__/index.test.d.ts +5 -0
  12. package/dist/components/TrackPlayer/__tests__/index.test.d.ts +5 -0
  13. package/dist/components/irrigation.esm.js +12 -2
  14. package/dist/components/irrigation.esm.js.map +1 -1
  15. package/dist/components/marker.esm.js.map +1 -1
  16. package/dist/components/plotgrouplayer.esm.js +3 -1
  17. package/dist/components/plotgrouplayer.esm.js.map +1 -1
  18. package/dist/components/road.esm.js +41 -13
  19. package/dist/components/road.esm.js.map +1 -1
  20. package/dist/hooks/__tests__/useRenderOptimization.test.d.ts +0 -1
  21. package/dist/hooks/index.esm.js +3 -2
  22. package/dist/hooks/index.esm.js.map +1 -1
  23. package/dist/hooks/usePolylineDraw.d.ts +75 -0
  24. package/dist/hooks/usePolylineEdit.d.ts +70 -0
  25. package/dist/hooks/usePolylineRenderer.d.ts +1 -1
  26. package/dist/hooks/useSnapManager.d.ts +50 -0
  27. package/dist/hooks/useVertexMarkers.d.ts +51 -0
  28. package/dist/index.esm.js +53 -14
  29. package/dist/index.esm.js.map +1 -1
  30. package/dist/index.js +53 -14
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.umd.js +53 -14
  33. package/dist/index.umd.js.map +1 -1
  34. package/dist/tests/setup/antd-mock.d.ts +34 -0
  35. package/dist/tests/setup/browser-mock.d.ts +53 -0
  36. package/dist/tests/setup/index.d.ts +22 -0
  37. package/dist/tests/setup/leaflet-mock.d.ts +28 -0
  38. package/dist/types/index.d.ts +1 -0
  39. package/dist/types/irrigation.d.ts +4 -123
  40. package/dist/types/marker.d.ts +12 -113
  41. package/dist/types/mixins/DataSourceMixin.d.ts +56 -0
  42. package/dist/types/mixins/EditableMixin.d.ts +124 -0
  43. package/dist/types/mixins/InteractionMixin.d.ts +43 -0
  44. package/dist/types/mixins/LifecycleMixin.d.ts +23 -0
  45. package/dist/types/mixins/LoadingMixin.d.ts +44 -0
  46. package/dist/types/mixins/SelectableMixin.d.ts +52 -0
  47. package/dist/types/mixins/StyleMixin.d.ts +49 -0
  48. package/dist/types/mixins/ViewControlMixin.d.ts +36 -0
  49. package/dist/types/mixins/index.d.ts +13 -0
  50. package/dist/types/plot.d.ts +13 -67
  51. package/dist/types/road.d.ts +11 -157
  52. package/dist/types/track.d.ts +5 -15
  53. package/dist/utils/__tests__/RTreeIndex.test.d.ts +0 -1
  54. package/dist/utils/drawContext.d.ts +65 -0
  55. package/package.json +1 -1
@@ -0,0 +1,75 @@
1
+ /**
2
+ * 折线绘制 Hook
3
+ * @description 实现折线绘制功能,替代 @geoman-io/leaflet-geoman-free 的 map.pm.enableDraw('Line')
4
+ *
5
+ * 支持功能:
6
+ * - 点击添加顶点
7
+ * - 双击完成绘制
8
+ * - Shift+Click 开始绘制
9
+ * - Escape 取消绘制
10
+ * - 临时线预览
11
+ * - 提示线(指向鼠标位置)
12
+ * - 顶点样式自定义
13
+ * - 吸附功能(可选)
14
+ *
15
+ * @since 2.1.0 移除 @geoman-io/leaflet-geoman-free 依赖重构
16
+ */
17
+ import L from 'leaflet';
18
+ export interface UsePolylineDrawOptions {
19
+ /** Leaflet 地图实例 */
20
+ map: L.Map;
21
+ /** 绘制完成的回调 */
22
+ onComplete?: (points: L.LatLng[]) => void;
23
+ /** 开始绘制的回调 */
24
+ onStart?: () => void;
25
+ /** 取消绘制的回调 */
26
+ onCancel?: () => void;
27
+ /** 顶点添加时的回调 */
28
+ onVertexAdd?: (latlng: L.LatLng, index: number) => void;
29
+ /** 顶点移除时的回调 */
30
+ onVertexRemove?: (index: number) => void;
31
+ /** 临时线样式 */
32
+ tempLineStyle?: L.PathOptions;
33
+ /** 提示线样式 */
34
+ hintLineStyle?: L.PathOptions;
35
+ /** 顶点标记样式 */
36
+ vertexStyle?: {
37
+ radius?: number;
38
+ color?: string;
39
+ fillColor?: string;
40
+ fillOpacity?: number;
41
+ weight?: number;
42
+ };
43
+ /** 是否启用吸附 */
44
+ snappable?: boolean;
45
+ /** 吸附距离(像素) */
46
+ snapDistance?: number;
47
+ /** 最少顶点数(完成绘制所需) */
48
+ minVertices?: number;
49
+ /** 单击靠近最后一个顶点时是否完成绘制(闭合) */
50
+ closeOnLastVertexClick?: boolean;
51
+ /** 闭合检测距离(像素) */
52
+ closeDistance?: number;
53
+ }
54
+ export interface UsePolylineDrawReturn {
55
+ /** 是否正在绘制 */
56
+ isDrawing: boolean;
57
+ /** 当前顶点列表 */
58
+ points: L.LatLng[];
59
+ /** 开始绘制 */
60
+ startDraw: () => void;
61
+ /** 取消绘制 */
62
+ cancelDraw: () => void;
63
+ /** 完成绘制 */
64
+ completeDraw: () => void;
65
+ /** 获取最后一个顶点 */
66
+ getLastVertex: () => L.LatLng | null;
67
+ /** 获取临时线图层 */
68
+ getTempLine: () => L.Polyline | null;
69
+ /** 移除最后一个顶点(Undo) */
70
+ undo: () => void;
71
+ }
72
+ /**
73
+ * 折线绘制 Hook
74
+ */
75
+ export declare function usePolylineDraw(options: UsePolylineDrawOptions): UsePolylineDrawReturn;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 折线顶点编辑 Hook
3
+ * @description 实现折线顶点的拖拽编辑功能,替代 @geoman-io/leaflet-geoman-free 的 layer.pm.enable()
4
+ *
5
+ * 支持功能:
6
+ * - 顶点拖拽移动
7
+ * - 顶点添加(在边上点击添加)
8
+ * - 顶点删除(点击顶点删除)
9
+ * - 样式自定义
10
+ *
11
+ * @since 2.1.0 移除 @geoman-io/leaflet-geoman-free 依赖重构
12
+ */
13
+ import L from 'leaflet';
14
+ export interface UsePolylineEditOptions {
15
+ /** Leaflet 地图实例 */
16
+ map: L.Map;
17
+ /** 要编辑的折线图层引用(可在后续设置) */
18
+ layerRef: React.MutableRefObject<L.Polyline | null>;
19
+ /** 编辑完成时的回调 */
20
+ onComplete?: (points: L.LatLng[]) => void;
21
+ /** 编辑取消时的回调 */
22
+ onCancel?: () => void;
23
+ /** 顶点开始拖拽的回调 */
24
+ onVertexDragStart?: (index: number, latlng: L.LatLng) => void;
25
+ /** 顶点拖拽中的回调 */
26
+ onVertexDrag?: (index: number, latlng: L.LatLng) => void;
27
+ /** 顶点拖拽结束的回调 */
28
+ onVertexDragEnd?: (index: number, latlng: L.LatLng) => void;
29
+ /** 顶点添加时的回调 */
30
+ onVertexAdd?: (index: number, latlng: L.LatLng) => void;
31
+ /** 顶点删除时的回调 */
32
+ onVertexRemove?: (index: number, latlng: L.LatLng) => void;
33
+ /** 顶点样式 */
34
+ vertexStyle?: {
35
+ radius?: number;
36
+ color?: string;
37
+ fillColor?: string;
38
+ fillOpacity?: number;
39
+ weight?: number;
40
+ hoverRadius?: number;
41
+ hoverColor?: string;
42
+ hoverFillColor?: string;
43
+ };
44
+ /** 是否支持在边上添加顶点 */
45
+ addVertexOnEdge?: boolean;
46
+ /** 边上添加顶点的触发距离(像素) */
47
+ edgeSnapDistance?: number;
48
+ }
49
+ export interface UsePolylineEditReturn {
50
+ /** 是否正在编辑 */
51
+ isEditing: boolean;
52
+ /** 当前顶点列表 */
53
+ points: L.LatLng[];
54
+ /** 开始编辑模式 */
55
+ enableEdit: () => void;
56
+ /** 结束编辑模式 */
57
+ disableEdit: (cancel?: boolean) => void;
58
+ /** 获取当前顶点列表 */
59
+ getPoints: () => L.LatLng[];
60
+ /** 添加顶点到指定索引 */
61
+ addVertex: (index: number, latlng: L.LatLng) => void;
62
+ /** 删除指定索引的顶点 */
63
+ removeVertex: (index: number) => void;
64
+ /** 更新指定索引的顶点位置 */
65
+ updateVertex: (index: number, latlng: L.LatLng) => void;
66
+ }
67
+ /**
68
+ * 折线顶点编辑 Hook
69
+ */
70
+ export declare function usePolylineEdit(options: UsePolylineEditOptions): UsePolylineEditReturn;
@@ -23,7 +23,7 @@ interface UsePolylineRendererOptions<T = unknown> {
23
23
  * 管理线要素图层的创建与清理
24
24
  *
25
25
  * 负责:
26
- * 1. 编辑模式下过滤数据(create/edit 模式不渲染已有要素)
26
+ * 1. 编辑模式下过滤数据(create/redraw 模式不渲染已有要素)
27
27
  * 2. 创建 LayerGroup 并将数据渲染进去
28
28
  * 3. 组件卸载时移除 editingLayerRef
29
29
  *
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 吸附管理 Hook
3
+ * @description 实现折线绘制时的吸附功能:
4
+ * - 点到点吸附:当鼠标靠近已有顶点时,吸附到该顶点
5
+ * - 点到线吸附:当鼠标靠近已有线段时,吸附到线段上的最近点
6
+ *
7
+ * @since 2.1.0 移除 @geoman-io/leaflet-geoman-free 依赖重构
8
+ */
9
+ import L from 'leaflet';
10
+ export interface SnapTarget {
11
+ latlng: L.LatLng;
12
+ type: 'vertex' | 'edge';
13
+ edgeIndex?: number;
14
+ vertexIndex?: number;
15
+ distance: number;
16
+ }
17
+ export interface UseSnapManagerOptions {
18
+ /** Leaflet 地图实例 */
19
+ map: L.Map;
20
+ /** 吸附距离阈值(像素) */
21
+ snapDistance?: number;
22
+ /** 是否启用吸附 */
23
+ enabled?: boolean;
24
+ /** 是否吸附到顶点 */
25
+ snapToVertices?: boolean;
26
+ /** 是否吸附到边 */
27
+ snapToEdges?: boolean;
28
+ }
29
+ export interface UseSnapManagerReturn {
30
+ /** 设置吸附目标点(已存在的顶点或线段上的点) */
31
+ setSnapTargets: (points: L.LatLng[], edges?: [L.LatLng, L.LatLng][]) => void;
32
+ /** 清除吸附目标 */
33
+ clearSnapTargets: () => void;
34
+ /** 获取吸附后的坐标(如果鼠标位置在吸附范围内) */
35
+ getSnapLatlng: (mouseLatlng: L.LatLng) => L.LatLng;
36
+ /** 查找最近的吸附目标 */
37
+ findSnapTarget: (mouseLatlng: L.LatLng) => SnapTarget | null;
38
+ /** 判断是否在吸附范围内 */
39
+ isInSnapRange: (mouseLatlng: L.LatLng) => boolean;
40
+ /** 添加吸附目标点 */
41
+ addSnapTarget: (latlng: L.LatLng) => void;
42
+ /** 移除吸附目标点 */
43
+ removeSnapTarget: (index: number) => void;
44
+ }
45
+ /**
46
+ * 吸附管理 Hook
47
+ */
48
+ export declare function useSnapManager(options: UseSnapManagerOptions): UseSnapManagerReturn;
49
+ export declare function setSnapMap(map: L.Map): void;
50
+ export declare function getSnapMap(): L.Map | null;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 顶点标记管理 Hook
3
+ * @description 管理折线/多边形顶点的标记,支持:
4
+ * - 顶点标记的创建、更新、删除
5
+ * - 顶点拖拽功能(使用 Marker + divIcon 实现)
6
+ * - 样式自定义
7
+ *
8
+ * 注意:Leaflet 的 CircleMarker 不支持原生拖拽,因此当 draggable=true 时,
9
+ * 使用 L.Marker + divIcon 替代方案来实现拖拽功能。
10
+ *
11
+ * @since 2.1.0 移除 @geoman-io/leaflet-geoman-free 依赖重构
12
+ */
13
+ import L from 'leaflet';
14
+ export interface VertexMarkerStyle {
15
+ radius?: number;
16
+ color?: string;
17
+ fillColor?: string;
18
+ fillOpacity?: number;
19
+ weight?: number;
20
+ }
21
+ export interface UseVertexMarkersOptions {
22
+ map: L.Map;
23
+ style?: VertexMarkerStyle;
24
+ draggable?: boolean;
25
+ onVertexDragStart?: (index: number, latlng: L.LatLng) => void;
26
+ onVertexDrag?: (index: number, latlng: L.LatLng) => void;
27
+ onVertexDragEnd?: (index: number, latlng: L.LatLng) => void;
28
+ onVertexClick?: (index: number, latlng: L.LatLng, event: L.LeafletMouseEvent) => void;
29
+ }
30
+ export interface UseVertexMarkersReturn {
31
+ /** 创建顶点标记 */
32
+ createMarkers: (points: L.LatLng[]) => L.Marker[];
33
+ /** 更新所有标记的位置 */
34
+ updateMarkers: (points: L.LatLng[]) => void;
35
+ /** 添加单个标记 */
36
+ addMarker: (latlng: L.LatLng, index: number) => L.Marker;
37
+ /** 移除指定索引的标记 */
38
+ removeMarker: (index: number) => void;
39
+ /** 清除所有标记 */
40
+ clearMarkers: () => void;
41
+ /** 获取所有标记 */
42
+ getMarkers: () => L.Marker[];
43
+ /** 获取指定索引的标记 */
44
+ getMarker: (index: number) => L.Marker | undefined;
45
+ /** 获取标记数量 */
46
+ getCount: () => number;
47
+ }
48
+ /**
49
+ * 顶点标记管理 Hook
50
+ */
51
+ export declare function useVertexMarkers(options: UseVertexMarkersOptions): UseVertexMarkersReturn;
package/dist/index.esm.js CHANGED
@@ -5360,7 +5360,7 @@ function useEditMode(editModeProp, defaultButtons) {
5360
5360
  * 管理线要素图层的创建与清理
5361
5361
  *
5362
5362
  * 负责:
5363
- * 1. 编辑模式下过滤数据(create/edit 模式不渲染已有要素)
5363
+ * 1. 编辑模式下过滤数据(create/redraw 模式不渲染已有要素)
5364
5364
  * 2. 创建 LayerGroup 并将数据渲染进去
5365
5365
  * 3. 组件卸载时移除 editingLayerRef
5366
5366
  *
@@ -5413,7 +5413,8 @@ function usePolylineRenderer(options) {
5413
5413
  return renderItem(item, layerGroup, index);
5414
5414
  });
5415
5415
  // 数据变化时清理编辑图层(新建保存后数据源更新时,移除临时的编辑图层避免重复)
5416
- if (dataChanged && editingLayerRef.current) {
5416
+ // 注意:在 redraw 模式下 editingLayerRef 不应被清理(可能在编辑过程中)
5417
+ if (dataChanged && editingLayerRef.current && currentMode !== 'redraw') {
5417
5418
  currentMap.removeLayer(editingLayerRef.current);
5418
5419
  editingLayerRef.current = null;
5419
5420
  }
@@ -16073,7 +16074,9 @@ var PlotGroupLayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
16073
16074
  mode: mode,
16074
16075
  value: getSelectedIdsForType(plotType),
16075
16076
  onSelect: handleSelect(plotType),
16076
- onClick: handleClick(plotType),
16077
+ onClick: function onClick(item) {
16078
+ return handleClick(plotType)(item, undefined);
16079
+ },
16077
16080
  onHover: handleHover(plotType),
16078
16081
  onContextMenu: handleContextMenu(plotType),
16079
16082
  groupKey: groupKey,
@@ -23762,6 +23765,10 @@ var RoadEditToolbar = function RoadEditToolbar(_ref) {
23762
23765
  * - click 模式:点击道路切换 Popup 显示/隐藏(toggle)
23763
23766
  * - hover 模式:鼠标进入道路延迟显示 Popup,离开立即隐藏(带防抖)
23764
23767
  * - 地图点击:点击地图空白区域自动关闭 Popup
23768
+ *
23769
+ * 【稳定性优化】
23770
+ * handleRoadClick 和 handleRoadHover 通过 useRef 保持稳定引用,
23771
+ * 避免因内部状态变化导致回调函数引用改变。
23765
23772
  */
23766
23773
  /**
23767
23774
  * 计算 Popup 位置参数(用于 usePopupTrigger)
@@ -23817,6 +23824,11 @@ function useRoadEvents(options) {
23817
23824
  },
23818
23825
  canClose: popupTrigger.canClosePopup
23819
23826
  });
23827
+ // ========== 稳定性优化:使用 ref 保持 popupTrigger 稳定引用 ==========
23828
+ // popupTrigger 来自 usePopupState,其内部状态变化会导致函数引用改变
23829
+ // 通过 ref 缓存,避免 handleRoadClick/handleRoadHover 依赖变化
23830
+ var popupTriggerLocalRef = useRef(popupTrigger);
23831
+ popupTriggerLocalRef.current = popupTrigger;
23820
23832
  // ========== 业务逻辑 ==========
23821
23833
  /** 计算 Popup 参数的辅助函数 */
23822
23834
  var getPopupParams = useCallback(function (road, layer) {
@@ -23826,30 +23838,30 @@ function useRoadEvents(options) {
23826
23838
  // 处理道路点击
23827
23839
  var handleRoadClick = useCallback(function (roadId, road, layer) {
23828
23840
  // Popup 处理(仅 click 模式)
23829
- if ((popupTriggerRef === null || popupTriggerRef === void 0 ? void 0 : popupTriggerRef.current) === 'click' && onPopupOpenRef !== null && onPopupOpenRef !== void 0 && onPopupOpenRef.current) {
23841
+ if (popupTriggerRef.current === 'click' && onPopupOpenRef !== null && onPopupOpenRef !== void 0 && onPopupOpenRef.current) {
23830
23842
  var _getPopupParams = getPopupParams(road, layer),
23831
23843
  position = _getPopupParams.position,
23832
23844
  bounds = _getPopupParams.bounds;
23833
- popupTrigger.handleItemClick(roadId, road, layer, position, bounds);
23845
+ popupTriggerLocalRef.current.handleItemClick(roadId, road, layer, position, bounds);
23834
23846
  }
23835
- }, [popupTriggerRef, onPopupOpenRef, popupTrigger, getPopupParams]);
23847
+ }, [onPopupOpenRef, getPopupParams, popupTriggerRef]);
23836
23848
  // 处理道路悬停进入
23837
23849
  var handleRoadHover = useCallback(function (roadId, road, layer, type) {
23838
23850
  if (type === 'mouseover') {
23839
23851
  // Popup 处理(仅 hover 模式)
23840
- if ((popupTriggerRef === null || popupTriggerRef === void 0 ? void 0 : popupTriggerRef.current) === 'hover' && onPopupOpenRef !== null && onPopupOpenRef !== void 0 && onPopupOpenRef.current) {
23852
+ if (popupTriggerRef.current === 'hover' && onPopupOpenRef !== null && onPopupOpenRef !== void 0 && onPopupOpenRef.current) {
23841
23853
  var _getPopupParams2 = getPopupParams(road, layer),
23842
23854
  position = _getPopupParams2.position,
23843
23855
  bounds = _getPopupParams2.bounds;
23844
- popupTrigger.handleMouseOver(roadId, road, layer, position, bounds);
23856
+ popupTriggerLocalRef.current.handleMouseOver(roadId, road, layer, position, bounds);
23845
23857
  }
23846
23858
  } else {
23847
23859
  // mouseout: 清除防抖定时器
23848
- if ((popupTriggerRef === null || popupTriggerRef === void 0 ? void 0 : popupTriggerRef.current) === 'hover') {
23849
- popupTrigger.handleMouseOut();
23860
+ if (popupTriggerRef.current === 'hover') {
23861
+ popupTriggerLocalRef.current.handleMouseOut();
23850
23862
  }
23851
23863
  }
23852
- }, [popupTriggerRef, onPopupOpenRef, popupTrigger, getPopupParams]);
23864
+ }, [onPopupOpenRef, getPopupParams, popupTriggerRef]);
23853
23865
  // 处理道路右键
23854
23866
  var handleRoadContextMenu = useCallback(function (_roadId, _road, _layer, _event) {
23855
23867
  // 右键默认行为由外层处理,这里仅提供基础支持
@@ -24230,6 +24242,16 @@ var Road = /*#__PURE__*/forwardRef(function RoadComponent(props, ref) {
24230
24242
  }, [map, editEnabled]);
24231
24243
  var renderItem = useCallback(function (road, layerGroup, index) {
24232
24244
  var _onRowRef$current, _onRowRef$current2;
24245
+ // ========== 方案一修复:redraw 模式下跳过正在编辑的道路 ==========
24246
+ // 修复描述:当进入重绘模式时,被选中的道路(id === value)不应该被 renderItem 渲染
24247
+ // 原因:被选中的道路已经通过 editingLayerRef 在地图上以编辑样式(绿色)渲染
24248
+ // 如果 renderItem 仍然渲染,会导致同一道路以两种样式(红色原始样式 + 绿色编辑样式)同时显示
24249
+ // 撤销方法:删除以下 if 块及其注释即可恢复到修改前的状态
24250
+ // 问题根因:usePolylineRenderer 在 currentMode === 'redraw' 时仍然渲染了所有数据,包括被编辑的道路
24251
+ // ========== 方案一修复结束 ==========================================
24252
+ if (currentModeRef.current === 'redraw' && road.id === valueRef.current) {
24253
+ return; // 跳过渲染,由 editingLayerRef 处理该道路的显示
24254
+ }
24233
24255
  var isSelected = road.id === value;
24234
24256
  var style = getRoadStyle(road, isSelected);
24235
24257
  var rowEvents = (_onRowRef$current = (_onRowRef$current2 = onRowRef.current) === null || _onRowRef$current2 === void 0 ? void 0 : _onRowRef$current2.call(onRowRef, road, index)) !== null && _onRowRef$current !== void 0 ? _onRowRef$current : {};
@@ -24398,8 +24420,10 @@ var Road = /*#__PURE__*/forwardRef(function RoadComponent(props, ref) {
24398
24420
  }
24399
24421
  }, [value, normalizedData, onEditRef, enabledButtonsRef]);
24400
24422
  var handleRedraw = useCallback(function () {
24401
- var _editingPath$vertexBo3, _editingPath$vertexFi3, _editingPath$vertexFi4, _editLayer$pm;
24402
- if (!map || !enabledButtonsRef.current.includes('redraw') || !value || !map.pm) return;
24423
+ var _editingPath$vertexBo3, _editingPath$vertexFi3, _editingPath$vertexFi4, _map$pm, _map$pm$globalEditMod, _editLayer$pm;
24424
+ if (!map || !enabledButtonsRef.current.includes('redraw') || !value || !map.pm) {
24425
+ return;
24426
+ }
24403
24427
  var layer = layerByIdRef.current[value];
24404
24428
  if (!layer) return;
24405
24429
  var road = normalizedData.find(function (r) {
@@ -24419,6 +24443,10 @@ var Road = /*#__PURE__*/forwardRef(function RoadComponent(props, ref) {
24419
24443
  map.removeLayer(layerGroupRef.current);
24420
24444
  layerGroupRef.current = null;
24421
24445
  }
24446
+ // 禁用全局编辑模式
24447
+ if ((_map$pm = map.pm) !== null && _map$pm !== void 0 && (_map$pm$globalEditMod = _map$pm.globalEditModeEnabled) !== null && _map$pm$globalEditMod !== void 0 && _map$pm$globalEditMod.call(_map$pm)) {
24448
+ map.pm.disableGlobalEditMode();
24449
+ }
24422
24450
  var editLayer = L$1.polyline(road.points, _objectSpread2(_objectSpread2({}, editingPath), {}, {
24423
24451
  className: 'road-line'
24424
24452
  })).addTo(map);
@@ -24440,7 +24468,9 @@ var Road = /*#__PURE__*/forwardRef(function RoadComponent(props, ref) {
24440
24468
  }, [value, normalizedData, map, editingPath, enabledButtonsRef]);
24441
24469
  useEffect(function () {
24442
24470
  var _editingPath$vertexBo4, _editingPath$vertexFi5, _editingPath$vertexFi6;
24443
- if (currentMode !== 'redraw' || !editingLayerRef.current || !map) return;
24471
+ if (currentMode !== 'redraw' || !editingLayerRef.current || !map) {
24472
+ return;
24473
+ }
24444
24474
  editingLayerRef.current.setStyle(editingPath);
24445
24475
  // 设置顶点样式 CSS 变量(与 PlotLayer 保持一致)
24446
24476
  var vertexBorderColor = (_editingPath$vertexBo4 = editingPath.vertexBorderColor) !== null && _editingPath$vertexBo4 !== void 0 ? _editingPath$vertexBo4 : ROAD_STYLE.editing.vertexBorderColor;
@@ -25372,6 +25402,15 @@ var Irrigation = /*#__PURE__*/forwardRef(function (props, ref) {
25372
25402
  }, animated, detected.type === 'svg' ? detected.config : null, detected.type === 'url' ? detected.src : null, 'irrigation-port-marker');
25373
25403
  }, []);
25374
25404
  var renderItem = useCallback(function (channel, layerGroup, _index) {
25405
+ // ========== 方案一修复:redraw 模式下跳过正在编辑的渠道 ==========
25406
+ // 修复描述:当进入重绘模式时,被选中的渠道(id === value)不应该被 renderItem 渲染
25407
+ // 原因:被选中的渠道已经通过 editingLayerRef 在地图上以编辑样式渲染
25408
+ // 如果 renderItem 仍然渲染,会导致同一渠道以两种样式同时显示
25409
+ // 撤销方法:删除以下 if 块及其注释即可恢复到修改前的状态
25410
+ // ========== 方案一修复结束 ==========================================
25411
+ if (currentModeRef.current === 'redraw' && channel.id === valueRef.current) {
25412
+ return; // 跳过渲染,由 editingLayerRef 处理该渠道的显示
25413
+ }
25375
25414
  var isSelected = channel.id === value;
25376
25415
  var style = getChannelStyle(channel, isSelected);
25377
25416
  var hitArea = L$1.polyline(channel.points, {