@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,23 @@
1
+ /**
2
+ * @fileoverview 生命周期 Mixin
3
+ * @description 统一的组件生命周期回调
4
+ * @module types/mixins
5
+ */
6
+ import type { AgriculturalComponentType, LifecycleConfig } from '../lifecycle';
7
+ /**
8
+ * 生命周期 Mixin
9
+ * @description 提供统一的生命周期回调配置
10
+ * @example
11
+ * ```typescript
12
+ * interface MarkerProps extends LifecycleMixin<'Marker'> {
13
+ * lifecycle?: LifecycleConfig<'Marker'>;
14
+ * }
15
+ * ```
16
+ */
17
+ export interface LifecycleMixin<T extends AgriculturalComponentType = AgriculturalComponentType> {
18
+ /**
19
+ * 生命周期回调配置
20
+ * @description 组件挂载、渲染、卸载等关键节点的回调
21
+ */
22
+ lifecycle?: LifecycleConfig<T>;
23
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview 加载状态 Mixin
3
+ * @description 统一的加载状态和遮罩配置
4
+ * @module types/mixins
5
+ */
6
+ /**
7
+ * 加载遮罩配置
8
+ * @description 统一的加载遮罩层配置
9
+ */
10
+ export interface LoadingMaskConfig {
11
+ /** 是否启用遮罩 */
12
+ enabled?: boolean;
13
+ /** 遮罩背景色 */
14
+ background?: string;
15
+ /** 遮罩层级 */
16
+ zIndex?: number;
17
+ }
18
+ /**
19
+ * 加载状态 Mixin
20
+ * @description 提供统一的加载状态控制
21
+ * @example
22
+ * ```typescript
23
+ * interface MarkerProps extends LoadingMixin {
24
+ * loading?: boolean;
25
+ * loadingMask?: LoadingMaskConfig;
26
+ * }
27
+ * ```
28
+ */
29
+ export interface LoadingMixin {
30
+ /**
31
+ * 是否显示加载状态
32
+ * @default false
33
+ */
34
+ loading?: boolean;
35
+ /**
36
+ * 加载遮罩配置
37
+ * @description 自定义加载遮罩的样式和行为
38
+ */
39
+ loadingMask?: LoadingMaskConfig;
40
+ }
41
+ /**
42
+ * 加载图标名称
43
+ */
44
+ export type LoadingIconName = 'loading-spinner' | 'loading-circle' | 'loading bars' | 'loading bars' | 'spinning' | 'spinning (SLOW)';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @fileoverview 选择 Mixin
3
+ * @description 支持单选/多选,受控/非受控模式
4
+ * @module types/mixins
5
+ */
6
+ /**
7
+ * 选择模式
8
+ */
9
+ export type SelectionMode = 'single' | 'multiple';
10
+ /**
11
+ * 选择 Mixin
12
+ * @description 提供统一的选择状态管理
13
+ * @example
14
+ * ```typescript
15
+ * // 单选
16
+ * interface MarkerProps extends SelectableMixin<string | number> {
17
+ * value?: string | number | null;
18
+ * onSelect?: (id: string | number | null) => void;
19
+ * }
20
+ *
21
+ * // 多选
22
+ * interface PlotLayerProps extends SelectableMixin<string | number | (string | number)[]> {
23
+ * value?: (string | number)[];
24
+ * onSelect?: (ids: (string | number)[], plotId?: string | number) => void;
25
+ * }
26
+ * ```
27
+ */
28
+ export interface SelectableMixin<T = string | number> {
29
+ /**
30
+ * 当前选中的值(受控模式)
31
+ * @description 当需要完全控制选择状态时使用
32
+ */
33
+ value?: T | null;
34
+ /**
35
+ * 默认选中的值(非受控模式)
36
+ * @description 组件内部管理状态,仅在首次渲染时使用
37
+ */
38
+ defaultValue?: T;
39
+ /**
40
+ * 选择变化时的回调
41
+ * @param id - 被选中或取消选中的 ID(单选),或 null(取消选中)
42
+ */
43
+ onSelect?: (id: T | null) => void;
44
+ }
45
+ /**
46
+ * 选择变化事件参数
47
+ */
48
+ export interface SelectChangeEvent<T> {
49
+ value: T;
50
+ previousValue: T;
51
+ source: 'user' | 'programmatic';
52
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview 样式 Mixin
3
+ * @description 动态样式支持
4
+ * @module types/mixins
5
+ */
6
+ import type { PathOptions } from '../basic';
7
+ /**
8
+ * 样式 Mixin
9
+ * @description 提供统一的样式配置
10
+ * @example
11
+ * ```typescript
12
+ * interface RoadProps extends StyleMixin<RoadData> {
13
+ * style?: (data: RoadData) => PathOptions;
14
+ * path?: PathOptions | null | false;
15
+ * selectedPath?: PathOptions | null | false;
16
+ * }
17
+ * ```
18
+ */
19
+ export interface StyleMixin<T = unknown> {
20
+ /**
21
+ * 动态样式函数
22
+ * @description 根据数据项动态返回样式配置,优先级最高
23
+ * @param data - 数据项
24
+ * @returns 样式配置
25
+ */
26
+ style?: (data: T) => PathOptions;
27
+ /**
28
+ * 默认路径样式
29
+ * @description
30
+ * - `undefined | null | false`: 使用默认样式
31
+ * - `object`: 使用自定义样式
32
+ */
33
+ path?: PathOptions | null | false;
34
+ /**
35
+ * 选中状态的路径样式
36
+ * @description
37
+ * - `undefined | null | false`: 使用默认选中样式
38
+ * - `object`: 使用自定义选中样式
39
+ */
40
+ selectedPath?: PathOptions | null | false;
41
+ }
42
+ /**
43
+ * 样式覆盖优先级
44
+ * 1. 数据级样式(data.options.path)
45
+ * 2. style 函数返回的样式
46
+ * 3. Props 级 path/selectedPath
47
+ * 4. 组件默认样式
48
+ */
49
+ export type StylePriority = 'data' | 'function' | 'props' | 'default';
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @fileoverview 视图控制 Mixin
3
+ * @description 统一的地图视图控制配置
4
+ * @module types/mixins
5
+ */
6
+ /**
7
+ * 自动适应边界配置
8
+ * @description 配置地图自动适应边界的参数
9
+ */
10
+ export interface AutoFitConfig {
11
+ /** 最大缩放级别 */
12
+ maxZoom?: number;
13
+ /** 内边距 */
14
+ padding?: number | [number, number];
15
+ }
16
+ /**
17
+ * 视图控制 Mixin
18
+ * @description 提供统一的地图视图控制
19
+ * @example
20
+ * ```typescript
21
+ * interface MarkerProps extends ViewControlMixin {
22
+ * autoFit?: boolean | AutoFitConfig;
23
+ * }
24
+ * ```
25
+ */
26
+ export interface ViewControlMixin {
27
+ /**
28
+ * 是否在首次加载数据后自动适应边界
29
+ * @description
30
+ * - `true`: 启用,使用默认配置
31
+ * - `false`: 禁用(默认)
32
+ * - `object`: 自定义配置
33
+ * @default false
34
+ */
35
+ autoFit?: boolean | AutoFitConfig;
36
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Mixin 接口统一导出
3
+ * @description 导出所有 Mixin 接口,供组件类型组合使用
4
+ * @module types/mixins
5
+ */
6
+ export type { DataSourceMixin, RequiredDataFields, CoordinateDataItem, DataValidationResult, } from './DataSourceMixin';
7
+ export type { LoadingMixin, LoadingMaskConfig, LoadingIconName } from './LoadingMixin';
8
+ export type { ViewControlMixin, AutoFitConfig } from './ViewControlMixin';
9
+ export type { SelectableMixin, SelectionMode, SelectChangeEvent } from './SelectableMixin';
10
+ export type { StyleMixin, StylePriority } from './StyleMixin';
11
+ export type { InteractionMixin, RowEventHandler, HoverEvent } from './InteractionMixin';
12
+ export type { LifecycleMixin } from './LifecycleMixin';
13
+ export type { EditableMixin, EditModeConfig, ToolbarButton, ToolbarColor, ToolbarSize, EditAction, BaseEditResult, } from './EditableMixin';
@@ -5,6 +5,7 @@ import type React from 'react';
5
5
  import type L from 'leaflet';
6
6
  import type { Coordinate, PathOptions } from './basic';
7
7
  import type { LifecycleConfig } from './lifecycle';
8
+ import type { DataSourceMixin, StyleMixin, LoadingMixin, LifecycleMixin, ViewControlMixin, InteractionMixin, EditableMixin } from './mixins';
8
9
  export type { Boundaries, BBox } from './basic';
9
10
  export type { LifecycleConfig };
10
11
  /**
@@ -191,35 +192,19 @@ export interface AreaUnitConfig {
191
192
  }
192
193
  /**
193
194
  * 地块图层组件属性
194
- * @description PlotLayer 组件的 Props 定义
195
+ * @description PlotLayer 组件的 Props 定义,使用 Mixin 组合重构
195
196
  */
196
- export interface PlotLayerProps {
197
- /** 地块数据数组 */
197
+ export interface PlotLayerProps extends DataSourceMixin<PlotData>, StyleMixin<PlotData>, LoadingMixin, LifecycleMixin<'PlotLayer'>, ViewControlMixin, InteractionMixin<PlotData>, EditableMixin<'redraw' | 'clip' | 'move' | 'create' | 'delete'> {
198
+ /** 地块数据数组(必需) */
198
199
  dataSource: PlotData[];
199
- /** 字段名映射,用于自定义 dataSource 中的字段名 */
200
- fieldNames?: PlotFieldNames;
201
200
  /** 面积单位,用于计算新建地块的面积,默认 'mu'(亩) */
202
201
  areaUnit?: AreaUnit;
203
- /** 点击地块时的回调函数 */
204
- onClick?: (item: PlotData, layer?: L.Layer) => void;
205
- /** 右键点击地块时的回调函数 */
206
- onContextMenu?: (item: PlotData, layer?: L.Layer, event?: L.LeafletMouseEvent) => void;
207
202
  /** 鼠标悬停事件回调 */
208
203
  onHover?: (data: PlotData, type: 'mouseover' | 'mouseout') => void;
209
204
  /** 最小显示缩放级别 */
210
205
  minZoom?: number;
211
206
  /** 最大显示缩放级别 */
212
207
  maxZoom?: number;
213
- /** 动态样式函数,根据地块数据返回样式 */
214
- style?: (data: PlotData) => PlotStyle;
215
- /**
216
- * 是否在首次渲染数据后自动 fitBounds 适配地图视图
217
- * @default false
218
- */
219
- autoFit?: boolean | {
220
- maxZoom?: number;
221
- padding?: number | [number, number];
222
- };
223
208
  /**
224
209
  * 虚拟化渲染配置
225
210
  * @default false
@@ -231,10 +216,6 @@ export interface PlotLayerProps {
231
216
  minZoom?: number;
232
217
  maxZoom?: number;
233
218
  };
234
- /** 默认选中的地块 ID(非受控模式) */
235
- defaultValue?: string | number | (string | number)[];
236
- /** 选中的地块 ID(受控模式) */
237
- value?: string | number | (string | number)[];
238
219
  /** 选择模式:单选或多选 */
239
220
  mode?: 'single' | 'multiple';
240
221
  /**
@@ -246,27 +227,27 @@ export interface PlotLayerProps {
246
227
  path?: PathOptions;
247
228
  /** 选中状态的路径样式 */
248
229
  selectedPath?: PathOptions;
230
+ /** 选中的地块 ID(受控模式) */
231
+ value?: string | number | (string | number)[];
232
+ /** 默认选中的地块 ID(非受控模式) */
233
+ defaultValue?: string | number | (string | number)[];
249
234
  /** 选中变化时的回调 */
250
235
  onSelect?: (ids: (string | number)[], plotId?: string | number) => void;
251
- /** 编辑模式,可开启全部或指定功能,或使用对象配置自定义工具栏 */
252
- editMode?: boolean | ('redraw' | 'clip' | 'move' | 'create' | 'delete')[] | PlotEditModeConfig;
253
236
  /** 编辑按钮回调,用于打开编辑抽屉 */
254
237
  onEdit?: (result: {
255
238
  plotId: string | number;
256
239
  plot: PlotData;
257
240
  }) => void;
258
- /** 重绘完成回调 */
241
+ /** 覆盖编辑模式回调 */
242
+ onCreate?: (result: PlotCreateResult) => void;
243
+ /** 删除完成回调 */
244
+ onDelete?: (result: PlotDeleteResult) => void;
245
+ /** 覆盖重绘回调 */
259
246
  onRedraw?: (result: PlotEditResult) => void;
260
247
  /** 剪辑完成回调 */
261
248
  onClip?: (result: PlotClipResult) => void;
262
249
  /** 移动完成回调 */
263
250
  onMove?: (result: PlotMoveResult) => void;
264
- /** 新建完成回调,包含计算后的面积 */
265
- onCreate?: (result: PlotCreateResult) => void;
266
- /** 删除完成回调 */
267
- onDelete?: (result: PlotDeleteResult) => void;
268
- /** 保存回调(统一处理各种编辑结果) */
269
- onSave?: (result: PlotEditResult | PlotClipResult | PlotMoveResult | PlotCreateResult) => void;
270
251
  /** 渲染统计回调 */
271
252
  onRenderStats?: (stats: RenderStats) => void;
272
253
  /** 是否显示地块标签 */
@@ -276,8 +257,6 @@ export interface PlotLayerProps {
276
257
  };
277
258
  /** 标签显示的字段列表 */
278
259
  labelFields?: string[];
279
- /** 是否显示编辑模式提示,默认 false */
280
- showEditHint?: boolean;
281
260
  /**
282
261
  * 分组字段名,用于构建字段值索引,支持 O(1) 快速查找同组地块
283
262
  * @default undefined
@@ -288,39 +267,6 @@ export interface PlotLayerProps {
288
267
  * @default { color: '#fa8c16', fillColor: '#fa8c16', fillOpacity: 0.4, weight: 2 }
289
268
  */
290
269
  highlightPath?: PathOptions;
291
- /**
292
- * 是否显示加载状态
293
- * @description 当为 true 时,在地图上显示加载动画覆盖层
294
- * @default false
295
- */
296
- loading?: boolean;
297
- /**
298
- * 加载遮罩配置
299
- * @description 自定义加载遮罩的样式
300
- */
301
- loadingMask?: {
302
- /** 是否显示遮罩,默认 true */
303
- enabled?: boolean;
304
- /** 遮罩背景色,默认 'rgba(0, 0, 0, 0.5)' */
305
- background?: string;
306
- /** 遮罩层级,默认 1000 */
307
- zIndex?: number;
308
- };
309
- /**
310
- * 生命周期回调配置
311
- * @description 管理组件的挂载、渲染、状态变化、卸载等生命周期节点
312
- * @since 1.4.0
313
- * @example
314
- * ```tsx
315
- * lifecycle={{
316
- * onBeforeMount: (data) => validatePlotData(data),
317
- * onFirstRender: (stats) => reportPerformance(stats),
318
- * onStateChange: (payload) => trackEditAction(payload),
319
- * onBeforeUnmount: () => saveDraft(),
320
- * }}
321
- * ```
322
- */
323
- lifecycle?: LifecycleConfig<'PlotLayer'>;
324
270
  /** 子组件 */
325
271
  children?: React.ReactNode;
326
272
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { Coordinate, PathOptions } from './basic';
5
5
  import type { ReactNode } from 'react';
6
- import type { LifecycleConfig } from './lifecycle';
6
+ import type { DataSourceMixin, SelectableMixin, StyleMixin, LoadingMixin, LifecycleMixin, ViewControlMixin, InteractionMixin, EditableMixin } from './mixins';
7
7
  /**
8
8
  * 编辑模式对象配置(Road)
9
9
  */
@@ -220,46 +220,9 @@ export interface RoadRef {
220
220
  }
221
221
  /**
222
222
  * 道路组件属性
223
- * @description Road 组件的 Props 定义
223
+ * @description Road 组件的 Props 定义,使用 Mixin 组合重构
224
224
  */
225
- export interface RoadProps<T = Record<string, unknown>> {
226
- /**
227
- * 道路数据数组
228
- * @description 每个道路对象包含 id、name、points、distance、options 等字段
229
- * @example
230
- * ```ts
231
- * const roads = [
232
- * {
233
- * id: 'road-1',
234
- * name: '主干道',
235
- * points: [[29.95, 117.98], [29.96, 117.99]],
236
- * distance: 500,
237
- * options: { default: { color: '#1668dc', weight: 10, opacity: 1 } }
238
- * }
239
- * ];
240
- * ```
241
- */
242
- dataSource?: T[];
243
- /**
244
- * 自定义字段名映射
245
- * @description 当数据源字段名与默认字段名不同时,可通过此配置映射
246
- * @example
247
- * ```ts
248
- * fieldNames={{ id: 'roadId', name: 'roadName', points: 'coordinates' }}
249
- * ```
250
- */
251
- fieldNames?: RoadFieldNames;
252
- /**
253
- * 点击道路时的回调
254
- * @param item - 被点击的道路数据
255
- */
256
- onClick?: (item: RoadData) => void;
257
- /**
258
- * 右键点击道路时的回调
259
- * @param item - 被右键点击的道路数据
260
- * @param event - Leaflet 鼠标事件
261
- */
262
- onContextMenu?: (item: RoadData, event: L.LeafletMouseEvent) => void;
225
+ export interface RoadProps<T = Record<string, unknown>> extends DataSourceMixin<T>, SelectableMixin<string | number>, StyleMixin<T>, LoadingMixin, LifecycleMixin<'Road'>, ViewControlMixin, InteractionMixin<T>, EditableMixin<'create' | 'edit' | 'redraw' | 'delete'> {
263
226
  /**
264
227
  * 道路默认态样式配置
265
228
  * @description undefined | null | false | {} 时使用 ROAD_DEFAULT_PATH
@@ -270,64 +233,6 @@ export interface RoadProps<T = Record<string, unknown>> {
270
233
  * @description undefined | null | false | {} 时使用 ROAD_DEFAULT_SELECTED_PATH
271
234
  */
272
235
  selectedPath?: PathOptions | null | false;
273
- /**
274
- * 动态样式函数
275
- * @description 根据道路数据动态返回样式,优先级:数据级 path > style 函数 > Props 级 path
276
- */
277
- style?: (data: T) => PathOptions;
278
- /**
279
- * 编辑模式
280
- * @description 开启道路编辑功能,可传入 true 开启全部功能,或数组指定开启的功能,或对象配置
281
- * @example
282
- * ```ts
283
- * editMode={true} // 开启全部编辑功能
284
- * editMode={['create', 'edit', 'redraw']} // 仅开启新建、编辑和重绘
285
- * editMode={{ enabled: ['create', 'edit'], toolbar: <ToolbarButton>自定义</ToolbarButton> }} // 对象配置
286
- * ```
287
- */
288
- editMode?: boolean | ('create' | 'edit' | 'redraw' | 'delete')[] | RoadEditModeConfig;
289
- /**
290
- * 新建道路回调
291
- * @param result - 新建结果,包含 points 和 name
292
- */
293
- onCreate?: (result: RoadCreateResult) => void;
294
- /**
295
- * 编辑道路回调(点击编辑按钮触发,用于打开编辑抽屉)
296
- * @param result - 编辑结果,包含 roadId 和 road 数据
297
- */
298
- onEdit?: (result: RoadEditDrawerResult) => void;
299
- /**
300
- * 重绘道路回调
301
- * @param result - 重绘结果,包含 roadId、oldPoints、newPoints
302
- */
303
- onRedraw?: (result: RoadEditResult) => void;
304
- /**
305
- * 删除道路回调
306
- * @param result - 删除结果,包含 roadId
307
- */
308
- onDelete?: (result: RoadDeleteResult) => void;
309
- /**
310
- * 保存回调
311
- * @description 新建或编辑保存时触发,mode 字段区分操作类型
312
- */
313
- onSave?: (result: {
314
- mode: string;
315
- } & (RoadCreateResult | RoadEditResult)) => void;
316
- /**
317
- * 选中变化回调
318
- * @param id - 新选中的道路 ID,null 表示取消选中
319
- */
320
- onSelect?: (id: string | number | null) => void;
321
- /**
322
- * 选中的道路 ID(受控模式)
323
- * @description 传入此属性时,组件进入受控模式,选中状态由父组件管理
324
- */
325
- value?: string | number | null;
326
- /**
327
- * 默认选中的道路 ID(非受控模式)
328
- * @description 组件初始化时默认选中的道路
329
- */
330
- defaultValue?: string | number;
331
236
  /**
332
237
  * 蚁行动画配置
333
238
  * @description 显示道路方向箭头动画
@@ -351,70 +256,19 @@ export interface RoadProps<T = Record<string, unknown>> {
351
256
  */
352
257
  showSelectedDistance?: boolean;
353
258
  /**
354
- * 是否显示编辑模式提示
355
- * @description 开启后,进入编辑模式时会显示操作提示
356
- * @default false
357
- */
358
- showEditHint?: boolean;
359
- /**
360
- * 统一的声明式事件管理(类似 Ant Design Table 的 onRow)
361
- * @description 返回一个事件回调对象,可按需绑定事件,支持基于数据项的条件化事件处理
362
- * @param item - 当前道路数据
363
- * @param index - 当前道路在数据源中的索引
364
- * @returns RoadEvents 事件回调对象
365
- * @example
366
- * ```tsx
367
- * <Road
368
- * dataSource={roads}
369
- * onRow={(item, index) => ({
370
- * onClick: () => console.log('点击了', item.name),
371
- * onContextMenu: (item, e) => { e.originalEvent.preventDefault(); },
372
- * })}
373
- * />
374
- * ```
259
+ * 覆盖编辑模式回调:重绘道路
375
260
  */
376
- onRow?: (item: RoadData, index: number) => RoadEvents;
377
- /**
378
- * 是否显示加载状态
379
- * @description 当为 true 时,在地图上显示加载动画覆盖层
380
- * @default false
381
- */
382
- loading?: boolean;
383
- /**
384
- * 加载遮罩配置
385
- * @description 自定义加载遮罩的样式
386
- */
387
- loadingMask?: {
388
- /** 是否显示遮罩,默认 true */
389
- enabled?: boolean;
390
- /** 遮罩背景色,默认 'rgba(0, 0, 0, 0.5)' */
391
- background?: string;
392
- /** 遮罩层级,默认 1000 */
393
- zIndex?: number;
394
- };
261
+ onRedraw?: (result: RoadEditResult) => void;
395
262
  /**
396
- * 生命周期回调配置
397
- * @description 管理组件的挂载、渲染、状态变化、卸载等生命周期节点
398
- * @since 1.4.0
399
- * @example
400
- * ```tsx
401
- * lifecycle={{
402
- * onBeforeMount: (data) => validateRoadData(data),
403
- * onFirstRender: (stats) => reportPerformance(stats),
404
- * onStateChange: (payload) => trackEditAction(payload),
405
- * onBeforeUnmount: () => saveDraft(),
406
- * }}
407
- * ```
263
+ * 覆盖保存回调类型
408
264
  */
409
- lifecycle?: LifecycleConfig<'Road'>;
265
+ onSave?: (result: {
266
+ mode: string;
267
+ } & (RoadCreateResult | RoadEditResult)) => void;
410
268
  /**
411
- * 是否在首次加载数据后自动 fitBounds 适配地图视图
412
- * @default false
269
+ * 统一的声明式事件管理(替代 InteractionMixin 的 onClick/onContextMenu)
413
270
  */
414
- autoFit?: boolean | {
415
- maxZoom?: number;
416
- padding?: number | [number, number];
417
- };
271
+ onRow?: (item: T, index: number) => RoadEvents;
418
272
  /**
419
273
  * 子组件
420
274
  * @description 用于嵌套 Popup 等子组件
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import type { FilterResult, ParsedTrack } from '../components/Track/types';
6
6
  import type { IconConfig } from './icon';
7
+ import type { SelectableMixin, ViewControlMixin } from './mixins';
7
8
  export type { IconConfig } from './icon';
8
9
  export type { ParsedTrack } from '../components/Track/types';
9
10
  export type { PolylineStyle as TrackStyle } from './polyline';
@@ -150,21 +151,18 @@ export interface DisplayModeConfig {
150
151
  }
151
152
  /**
152
153
  * Track 组件属性
154
+ * @description 使用 Mixin 组合重构,支持选择和视图控制
153
155
  */
154
- export interface TrackProps {
156
+ export interface TrackProps extends SelectableMixin<string | string[]>, ViewControlMixin {
155
157
  /** 轨迹数据,key为 imei|date 组合 */
156
158
  dataSource: TrackData;
157
159
  /** 自定义数据字段名映射 */
158
160
  fieldNames?: TrackFieldNames;
159
161
  /** 选择模式 */
160
162
  mode?: 'single' | 'multiple';
161
- /** 选中的轨迹key(受控模式) */
162
- value?: string | string[];
163
- /** 默认选中的轨迹key(非受控模式) */
164
- defaultValue?: string | string[];
165
- /** 轨迹点击回调 */
163
+ /** 轨迹点击回调(组件特定签名) */
166
164
  onClick?: (key: string, track: ParsedTrack) => void;
167
- /** 选中值变化回调 */
165
+ /** 选中值变化回调(组件特定) */
168
166
  onChange?: (value: string | string[]) => void;
169
167
  /**
170
168
  * 性能优化配置
@@ -238,14 +236,6 @@ export interface TrackProps {
238
236
  * @default false
239
237
  */
240
238
  end?: boolean | 'selected';
241
- /**
242
- * 是否在首次加载数据后自动 fitBounds 适配地图视图
243
- * @default false
244
- */
245
- autoFit?: boolean | {
246
- maxZoom?: number;
247
- padding?: number | [number, number];
248
- };
249
239
  /** 子组件,通常放置 Popup 组件 */
250
240
  children?: React.ReactNode;
251
241
  }
@@ -1,5 +1,4 @@
1
1
  /**
2
2
  * @fileoverview RTreeIndex 性能测试
3
- * @description 测试 R-Tree 空间索引的性能表现
4
3
  */
5
4
  export {};
@@ -0,0 +1,65 @@
1
+ /**
2
+ * 折线绘制上下文状态管理
3
+ * @description 管理折线绘制过程中的所有状态,包括:
4
+ * - 当前是否正在绘制
5
+ * - 当前已添加的顶点列表
6
+ * - 临时线(绘制过程中的预览线)
7
+ * - 提示线(指向下一个顶点位置的虚线)
8
+ * - 顶点标记列表
9
+ *
10
+ * @since 2.1.0 移除 @geoman-io/leaflet-geoman-free 依赖重构
11
+ */
12
+ import L from 'leaflet';
13
+ export interface DrawContextState {
14
+ /** 是否正在绘制 */
15
+ isDrawing: boolean;
16
+ /** 当前已添加的顶点列表 */
17
+ points: L.LatLng[];
18
+ /** 临时线图层(连接所有已添加的顶点 + 当前鼠标位置) */
19
+ tempLine: L.Polyline | null;
20
+ /** 提示线图层(从最后一个顶点指向预测的下一个位置) */
21
+ hintLine: L.Polyline | null;
22
+ /** 顶点标记列表 */
23
+ vertexMarkers: L.CircleMarker[];
24
+ /** 当前绘制模式 */
25
+ mode: 'Line' | 'Polygon' | null;
26
+ }
27
+ export interface DrawContextOptions {
28
+ /** 临时线样式 */
29
+ tempLineStyle?: L.PathOptions;
30
+ /** 提示线样式 */
31
+ hintLineStyle?: L.PathOptions;
32
+ /** 顶点标记样式 */
33
+ vertexStyle?: {
34
+ radius?: number;
35
+ color?: string;
36
+ fillColor?: string;
37
+ fillOpacity?: number;
38
+ weight?: number;
39
+ };
40
+ /** 是否启用吸附 */
41
+ snappable?: boolean;
42
+ /** 吸附距离(像素) */
43
+ snapDistance?: number;
44
+ }
45
+ /**
46
+ * 创建并返回一个绘制上下文对象
47
+ */
48
+ export declare function createDrawContext(map: L.Map, options?: DrawContextOptions): {
49
+ state: DrawContextState;
50
+ startDraw: (mode?: "Line" | "Polygon") => void;
51
+ stopDraw: (keepElements?: boolean) => void;
52
+ addVertex: (latlng: L.LatLng) => void;
53
+ removeLastVertex: () => void;
54
+ updateTempLine: () => void;
55
+ updateHintLine: (targetLatlng: L.LatLng) => void;
56
+ clearHintLine: () => void;
57
+ addVertexMarker: (latlng: L.LatLng, index: number) => void;
58
+ updateVertexMarkers: (points: L.LatLng[]) => void;
59
+ getPoints: () => L.LatLng[];
60
+ getTempLine: () => L.Polyline | null;
61
+ getLastVertex: () => L.LatLng | null;
62
+ getState: () => DrawContextState;
63
+ reset: () => void;
64
+ };
65
+ export type DrawContext = ReturnType<typeof createDrawContext>;