@wenle_2523097/agri-map 1.0.2 → 1.0.4
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.
- package/dist/components/ConfigProvider/index.d.ts +15 -0
- package/dist/components/DualScaleControl/index.d.ts +10 -0
- package/dist/components/Icons/SelectIcon.d.ts +68 -0
- package/dist/components/Icons/index.d.ts +43 -0
- package/dist/components/Irrigation/index.d.ts +8 -0
- package/dist/components/Irrigation/toolbar.d.ts +6 -0
- package/dist/components/Loading/index.d.ts +40 -0
- package/dist/components/MapContent/index.d.ts +17 -0
- package/dist/components/MapSizeHandler/index.d.ts +24 -0
- package/dist/components/Marker/ClusterView.d.ts +29 -0
- package/dist/components/Marker/MapClickHandler.d.ts +25 -0
- package/dist/components/Marker/index.d.ts +61 -0
- package/dist/components/Marker/parseClusterConfig.d.ts +25 -0
- package/dist/components/Marker/toolbar.d.ts +6 -0
- package/dist/components/Marker/useEditHandlers.d.ts +44 -0
- package/dist/components/Marker/useIconConfig.d.ts +23 -0
- package/dist/components/Marker/useMarkerCommands.d.ts +30 -0
- package/dist/components/Measurement/toolbar.d.ts +20 -0
- package/dist/components/MiniMap/index.d.ts +16 -0
- package/dist/components/Notification/index.d.ts +12 -0
- package/dist/components/PlotGroupLayer/index.d.ts +8 -0
- package/dist/components/PlotLayer/index.d.ts +7 -0
- package/dist/components/PlotLayer/label.d.ts +12 -0
- package/dist/components/PlotLayer/leaflet-types.d.ts +59 -0
- package/dist/components/PlotLayer/parseConfig.d.ts +15 -0
- package/dist/components/PlotLayer/toolbar.d.ts +6 -0
- package/dist/components/PlotLayer/types.d.ts +10 -0
- package/dist/components/PlotLayer/usePlotCommands.d.ts +33 -0
- package/dist/components/PlotLayer/usePlotData.d.ts +32 -0
- package/dist/components/PlotLayer/usePlotEditMode.d.ts +92 -0
- package/dist/components/Road/index.d.ts +8 -0
- package/dist/components/Road/toolbar.d.ts +6 -0
- package/dist/components/TianDiTuLayer/index.d.ts +15 -0
- package/dist/components/Track/ClusterView.d.ts +20 -0
- package/dist/components/Track/TrackView.d.ts +24 -0
- package/dist/components/Track/commands.d.ts +53 -0
- package/dist/components/Track/constants.d.ts +34 -0
- package/dist/components/Track/index.d.ts +54 -0
- package/dist/components/Track/parseConfig.d.ts +40 -0
- package/dist/components/Track/types.d.ts +38 -0
- package/dist/components/Track/useMarkerIcon.d.ts +14 -0
- package/dist/components/Track/useTrackCommands.d.ts +56 -0
- package/dist/components/shared/BaseEditToolbar.d.ts +100 -0
- package/dist/components/shared/ToolbarButton.d.ts +49 -0
- package/dist/components/shared/index.d.ts +5 -0
- package/dist/constants/device.d.ts +14 -0
- package/dist/constants/index.d.ts +20 -0
- package/dist/constants/map.d.ts +13 -0
- package/dist/constants/plot.d.ts +33 -0
- package/dist/constants/road.d.ts +12 -0
- package/dist/constants/styles.d.ts +57 -0
- package/dist/constants/theme.d.ts +47 -0
- package/dist/constants/unit.d.ts +11 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/useEditMode.d.ts +75 -0
- package/dist/hooks/useLatestRef.d.ts +17 -0
- package/dist/hooks/usePolylineEditor.d.ts +65 -0
- package/dist/hooks/usePolylineRenderer.d.ts +34 -0
- package/dist/hooks/useTheme.d.ts +13 -0
- package/dist/index.d.ts +312 -0
- package/dist/index.esm.js +30 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +30 -0
- package/dist/index.umd.js.map +1 -1
- package/dist/types/basic.d.ts +57 -0
- package/dist/types/components.d.ts +56 -0
- package/dist/types/config.d.ts +112 -0
- package/dist/types/decorator.d.ts +26 -0
- package/dist/types/icon.d.ts +52 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/irrigation.d.ts +315 -0
- package/dist/types/layer.d.ts +40 -0
- package/dist/types/loading.d.ts +62 -0
- package/dist/types/marker.d.ts +299 -0
- package/dist/types/measurement.d.ts +121 -0
- package/dist/types/notification.d.ts +50 -0
- package/dist/types/plot.d.ts +479 -0
- package/dist/types/road.d.ts +382 -0
- package/dist/types/toolbar.d.ts +176 -0
- package/dist/types/track.d.ts +386 -0
- package/dist/utils/area.d.ts +57 -0
- package/dist/utils/clusterIcon.d.ts +16 -0
- package/dist/utils/createAntPath.d.ts +13 -0
- package/dist/utils/geometry.d.ts +41 -0
- package/dist/utils/iconCache.d.ts +49 -0
- package/dist/utils/iconUtils.d.ts +46 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/leafletIcons.d.ts +40 -0
- package/dist/utils/mapAnimation.d.ts +14 -0
- package/dist/utils/markerSvg.d.ts +19 -0
- package/dist/utils/pulseIcon.d.ts +28 -0
- package/dist/utils/spatialIndex.d.ts +56 -0
- package/dist/utils/toggleItemState.d.ts +15 -0
- package/dist/utils/trackSimplify.d.ts +23 -0
- package/package.json +7 -3
- package/dist/index.css +0 -4635
- package/dist/index.css.map +0 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地块编辑工具栏组件
|
|
3
|
+
*/
|
|
4
|
+
import type { PlotEditToolbarProps } from '../../types';
|
|
5
|
+
declare const PlotEditToolbar: ({ visible, selectedPlotId, currentMode, enabledButtons, hintMessage, showHint, warningHint, color, size, iconOnly, children, onEdit, onRedraw, onClip, onMove, onCreate, onCancel, onSave, onDelete, }: PlotEditToolbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default PlotEditToolbar;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview PlotLayer 命令式方法 hook
|
|
3
|
+
* @description 将 useImperativeHandle 中的方法逻辑提取为独立 hook
|
|
4
|
+
* @module components/PlotLayer/usePlotCommands
|
|
5
|
+
*/
|
|
6
|
+
import L from 'leaflet';
|
|
7
|
+
import type { PlotData, PlotRef } from '../../types';
|
|
8
|
+
interface UsePlotCommandsOptions {
|
|
9
|
+
map: L.Map;
|
|
10
|
+
selectedPlotId: string | number | null;
|
|
11
|
+
selectedIds: (string | number)[];
|
|
12
|
+
isControlled: boolean;
|
|
13
|
+
virtualMaxZoom: number;
|
|
14
|
+
normalizedDataSourceRef: React.MutableRefObject<PlotData[]>;
|
|
15
|
+
groupIndexRef: React.MutableRefObject<Map<string, (string | number)[]>>;
|
|
16
|
+
highlightedGroupRef: React.MutableRefObject<string | null>;
|
|
17
|
+
normalizePlot: (plot: PlotData) => {
|
|
18
|
+
boundaries: any[];
|
|
19
|
+
bounds: number[];
|
|
20
|
+
} & PlotData;
|
|
21
|
+
updateLayerSelectionStyles: () => void;
|
|
22
|
+
rebuildGeoJSONLayer: () => void;
|
|
23
|
+
onSelectRef: React.MutableRefObject<((selectedIds: (string | number)[], plotId?: string | number) => void) | undefined>;
|
|
24
|
+
setInternalSelectedIds: React.Dispatch<React.SetStateAction<(string | number)[]>>;
|
|
25
|
+
startEdit: (editType: 'redraw' | 'clip' | 'move', plotId?: string | number) => boolean;
|
|
26
|
+
startCreate: () => void;
|
|
27
|
+
clearTempLayer: () => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* PlotLayer 命令式方法 hook
|
|
31
|
+
*/
|
|
32
|
+
export declare function usePlotCommands(ref: React.Ref<PlotRef>, options: UsePlotCommandsOptions): void;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview PlotLayer 数据处理 hook
|
|
3
|
+
* @description 负责数据标准化、GeoJSON 转换、分组索引构建
|
|
4
|
+
* @module components/PlotLayer/usePlotData
|
|
5
|
+
*/
|
|
6
|
+
import type { PlotData, PlotFieldNames, Coordinate } from '../../types';
|
|
7
|
+
interface UsePlotDataOptions {
|
|
8
|
+
fieldNames?: Partial<PlotFieldNames>;
|
|
9
|
+
dataSource: PlotData[] | undefined;
|
|
10
|
+
groupKey?: string;
|
|
11
|
+
}
|
|
12
|
+
interface UsePlotDataResult {
|
|
13
|
+
/** 合并后的字段名配置 */
|
|
14
|
+
mergedFieldNames: Required<PlotFieldNames>;
|
|
15
|
+
/** 标准化后的数据源 */
|
|
16
|
+
normalizedDataSource: PlotData[];
|
|
17
|
+
/** 标准化地块数据:统一 boundaries 为二维数组 */
|
|
18
|
+
normalizePlot: (plot: PlotData) => PlotData & {
|
|
19
|
+
boundaries: Coordinate[];
|
|
20
|
+
bounds: number[];
|
|
21
|
+
};
|
|
22
|
+
/** 从原始数据中推导孔洞坐标 */
|
|
23
|
+
getHoles: (plot: PlotData) => Coordinate[][];
|
|
24
|
+
/** 将 PlotData[] 转换为 GeoJSON FeatureCollection */
|
|
25
|
+
convertToGeoJSON: (plotData: PlotData[]) => GeoJSON.FeatureCollection;
|
|
26
|
+
/** 分组索引 ref(fieldValue → id[]) */
|
|
27
|
+
groupIndexRef: React.MutableRefObject<Map<string, (string | number)[]>>;
|
|
28
|
+
/** 当前高亮分组 ref */
|
|
29
|
+
highlightedGroupRef: React.MutableRefObject<string | null>;
|
|
30
|
+
}
|
|
31
|
+
export declare function usePlotData({ fieldNames, dataSource, groupKey }: UsePlotDataOptions): UsePlotDataResult;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview PlotLayer 编辑模式 hook
|
|
3
|
+
* @description 管理编辑模式的完整状态机:
|
|
4
|
+
* - 绘制事件监听(pm:drawvertex, pm:create, pm:cut)
|
|
5
|
+
* - 编辑模式切换(create, redraw, clip, move)
|
|
6
|
+
* - 保存/取消/删除等操作处理
|
|
7
|
+
* - 剪切碎片选择
|
|
8
|
+
* - 编辑面积标签
|
|
9
|
+
* @module components/PlotLayer/usePlotEditMode
|
|
10
|
+
*/
|
|
11
|
+
import L from 'leaflet';
|
|
12
|
+
import type { PlotData, PlotEditMode, PlotEditResult, PlotClipResult, PlotMoveResult, PlotCreateResult, PlotDeleteResult, Coordinate, AreaUnit } from '../../types';
|
|
13
|
+
import type { PlotLayer as PlotLayerType } from './leaflet-types';
|
|
14
|
+
/** usePlotEditMode 输入参数 */
|
|
15
|
+
export interface UsePlotEditModeOptions {
|
|
16
|
+
map: L.Map;
|
|
17
|
+
selectedPlotId: string | number | null;
|
|
18
|
+
enabledButtons: string[];
|
|
19
|
+
areaUnit: AreaUnit;
|
|
20
|
+
/** 编辑路径样式(绘制图层、剪切图层使用此样式) */
|
|
21
|
+
editPath: L.PathOptions;
|
|
22
|
+
/** 编辑模式 ref(指向 editMode state 的最新值) */
|
|
23
|
+
editModeStateRef: React.MutableRefObject<PlotEditMode>;
|
|
24
|
+
/** 编辑中的图层 ref(与主组件共享) */
|
|
25
|
+
editingLayerRef: React.MutableRefObject<PlotLayerType | null>;
|
|
26
|
+
/** 选中地块 ID ref */
|
|
27
|
+
selectedPlotIdRef: React.MutableRefObject<string | number | null>;
|
|
28
|
+
/** 标准化数据源 ref(用于 handleEdit 查找地块数据) */
|
|
29
|
+
normalizedDataSourceRef: React.MutableRefObject<PlotData[]>;
|
|
30
|
+
/** 图层 ID 映射 ref(用于 idle 清理和 startEdit) */
|
|
31
|
+
layerByIdRef: React.MutableRefObject<Record<string | number, PlotLayerType>>;
|
|
32
|
+
/** 图层重建函数 ref(clearTempLayer 使用) */
|
|
33
|
+
rebuildGeoJSONLayerRef: React.MutableRefObject<(() => void) | null>;
|
|
34
|
+
/** 编辑回调(通过 ref 传入避免闭包过期) */
|
|
35
|
+
onRedrawRef: React.MutableRefObject<((result: PlotEditResult) => void) | undefined>;
|
|
36
|
+
onClipRef: React.MutableRefObject<((result: PlotClipResult) => void) | undefined>;
|
|
37
|
+
onMoveRef: React.MutableRefObject<((result: PlotMoveResult) => void) | undefined>;
|
|
38
|
+
onCreateRef: React.MutableRefObject<((result: PlotCreateResult) => void) | undefined>;
|
|
39
|
+
onSaveRef: React.MutableRefObject<((result: PlotEditResult) => void) | undefined>;
|
|
40
|
+
onDeleteRef: React.MutableRefObject<((result: PlotDeleteResult) => void) | undefined>;
|
|
41
|
+
onEditRef: React.MutableRefObject<((result: {
|
|
42
|
+
plotId: string | number;
|
|
43
|
+
plot: PlotData;
|
|
44
|
+
}) => void) | undefined>;
|
|
45
|
+
}
|
|
46
|
+
/** usePlotEditMode 返回值 */
|
|
47
|
+
export interface UsePlotEditModeResult {
|
|
48
|
+
/** 当前编辑模式 */
|
|
49
|
+
editMode: PlotEditMode;
|
|
50
|
+
/** 设置编辑模式 */
|
|
51
|
+
setEditMode: React.Dispatch<React.SetStateAction<PlotEditMode>>;
|
|
52
|
+
/** 是否处于预览模式(新建绘制完成但未保存) */
|
|
53
|
+
isPreviewMode: boolean;
|
|
54
|
+
/** 剪切提示信息 */
|
|
55
|
+
clipHintMessage: string;
|
|
56
|
+
/** 绘制中的坐标 ref */
|
|
57
|
+
drawingCoordinatesRef: React.MutableRefObject<Coordinate[] | Coordinate[][]>;
|
|
58
|
+
/** 是否保留临时图层 ref */
|
|
59
|
+
preserveTempLayerRef: React.MutableRefObject<boolean>;
|
|
60
|
+
/** 移除编辑面积标签 */
|
|
61
|
+
removeEditAreaMarker: () => void;
|
|
62
|
+
/** 清理编辑事件 */
|
|
63
|
+
cleanupEditEvents: (layer: L.Layer | null) => void;
|
|
64
|
+
/** 清理剪切碎片图层 */
|
|
65
|
+
cleanupFragmentLayers: () => void;
|
|
66
|
+
/** 保存 */
|
|
67
|
+
handleSave: () => void;
|
|
68
|
+
/** 取消 */
|
|
69
|
+
handleCancel: () => void;
|
|
70
|
+
/** 重绘 */
|
|
71
|
+
handleRedraw: () => void;
|
|
72
|
+
/** 剪切 */
|
|
73
|
+
handleClip: () => void;
|
|
74
|
+
/** 移动 */
|
|
75
|
+
handleMove: () => void;
|
|
76
|
+
/** 新建 */
|
|
77
|
+
handleCreate: () => void;
|
|
78
|
+
/** 编辑属性 */
|
|
79
|
+
handleEdit: () => void;
|
|
80
|
+
/** 删除 */
|
|
81
|
+
handleDelete: () => void;
|
|
82
|
+
/** 命令式:进入编辑模式 */
|
|
83
|
+
startEdit: (editType: 'redraw' | 'clip' | 'move', plotId?: string | number) => boolean;
|
|
84
|
+
/** 命令式:进入新建模式 */
|
|
85
|
+
startCreate: () => void;
|
|
86
|
+
/** 命令式:清除临时图层并刷新 */
|
|
87
|
+
clearTempLayer: () => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* PlotLayer 编辑模式管理 hook
|
|
91
|
+
*/
|
|
92
|
+
export declare function usePlotEditMode(options: UsePlotEditModeOptions): UsePlotEditModeResult;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 田间道路组件
|
|
3
|
+
*/
|
|
4
|
+
import '@geoman-io/leaflet-geoman-free';
|
|
5
|
+
import 'leaflet-ant-path';
|
|
6
|
+
import type { RoadProps, RoadRef } from '../../types';
|
|
7
|
+
declare const Road: import("react").ForwardRefExoticComponent<RoadProps<Record<string, unknown>> & import("react").RefAttributes<RoadRef>>;
|
|
8
|
+
export default Road;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 道路编辑工具栏组件
|
|
3
|
+
*/
|
|
4
|
+
import type { RoadEditToolbarProps } from '../../types';
|
|
5
|
+
declare const RoadEditToolbar: ({ visible, selectedRoadId, currentMode, enabledButtons, pointCount, hintMessage, showHint, color, size, iconOnly, children, onEdit, onRedraw, onCreate, onCancel, onSave, onDelete, }: RoadEditToolbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default RoadEditToolbar;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 天地图图层组件
|
|
3
|
+
* @description 封装天地图的矢量图层和标注图层,支持多种图层风格和自定义瓦片URL
|
|
4
|
+
*/
|
|
5
|
+
import type { TianDiTuLayerProps } from '../../types';
|
|
6
|
+
export declare const LAYER_TYPES: {
|
|
7
|
+
readonly VECTOR: "vector";
|
|
8
|
+
readonly SATELLITE: "satellite";
|
|
9
|
+
readonly TERRAIN: "terrain";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 天地图图层组件
|
|
13
|
+
*/
|
|
14
|
+
export declare function TianDiTuLayer({ apiKey, showAnnotation, layerType: layerTypeProp, tileUrl, annotationUrl, overlayUrl, subdomains, maxZoom, minZoom, attribution, theme: themeProp, showLayerSelector, onLayerTypeChange, }: TianDiTuLayerProps): JSX.Element;
|
|
15
|
+
export default TianDiTuLayer;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 聚合模式渲染子组件
|
|
3
|
+
* @module components/Track/ClusterView
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import L from 'leaflet';
|
|
7
|
+
import Supercluster from 'supercluster';
|
|
8
|
+
import type { ClusterIconConfig } from '../../types';
|
|
9
|
+
import type { MiniMapProps } from '../../types';
|
|
10
|
+
interface ClusterViewProps {
|
|
11
|
+
clusterResults: Supercluster.ClusterFeature<any>[];
|
|
12
|
+
markerIcon: L.DivIcon;
|
|
13
|
+
showTooltip: boolean;
|
|
14
|
+
clusterIconConfig?: ClusterIconConfig;
|
|
15
|
+
miniMapConfig: MiniMapProps | null;
|
|
16
|
+
onClusterClick: (feature: Supercluster.ClusterFeature<Supercluster.AnyProps>) => void;
|
|
17
|
+
onMarkerClick: (trackKey: string) => void;
|
|
18
|
+
}
|
|
19
|
+
declare const _default: React.NamedExoticComponent<ClusterViewProps>;
|
|
20
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 轨迹模式渲染子组件
|
|
3
|
+
* @module components/Track/TrackView
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import type { MiniMapProps } from '../../types';
|
|
7
|
+
interface TrackViewProps {
|
|
8
|
+
sortedVisibleTracks: any[];
|
|
9
|
+
simplifiedTrackMap: Map<string, Record<string, [number, number][]>> | null;
|
|
10
|
+
hoveredTrack: string | null;
|
|
11
|
+
miniMapConfig: MiniMapProps | null;
|
|
12
|
+
checkIsSelected: (key: string) => boolean;
|
|
13
|
+
isTrackVisible: (key: string) => boolean;
|
|
14
|
+
getStyles: (state: number, isSelected: boolean, isHovered: boolean) => any;
|
|
15
|
+
handleTrackClick: (trackKey: string) => void;
|
|
16
|
+
handleTrackHover: (trackKey: string, isHovered: boolean) => void;
|
|
17
|
+
renderStartEndMarkers: (trackKey: string, points: Array<{
|
|
18
|
+
position: [number, number];
|
|
19
|
+
state: number;
|
|
20
|
+
}>) => React.ReactNode | null;
|
|
21
|
+
polylineRefs: React.MutableRefObject<Map<string, any>>;
|
|
22
|
+
}
|
|
23
|
+
declare const _default: React.NamedExoticComponent<TrackViewProps>;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Track 组件命令式方法(useImperativeHandle)的纯工具逻辑
|
|
3
|
+
* @module components/Track/commands
|
|
4
|
+
*/
|
|
5
|
+
import L from 'leaflet';
|
|
6
|
+
import type { FilterResult } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* 根据 filter 字符串筛选轨迹
|
|
9
|
+
* 支持 imei、date、imei|date 格式
|
|
10
|
+
*/
|
|
11
|
+
export declare function filterTracksByString<T extends {
|
|
12
|
+
key: string;
|
|
13
|
+
imei: string;
|
|
14
|
+
date: string;
|
|
15
|
+
}>(tracks: T[], filter?: string): T[];
|
|
16
|
+
/**
|
|
17
|
+
* 从轨迹列表计算统计信息
|
|
18
|
+
*/
|
|
19
|
+
export declare function computeTrackStats<T extends {
|
|
20
|
+
key: string;
|
|
21
|
+
imei: string;
|
|
22
|
+
date: string;
|
|
23
|
+
allPoints?: any[];
|
|
24
|
+
bounds?: any;
|
|
25
|
+
}>(tracks: T[]): {
|
|
26
|
+
imeis: string[];
|
|
27
|
+
dates: string[];
|
|
28
|
+
totalPoints: number;
|
|
29
|
+
totalTracks: number;
|
|
30
|
+
bounds: [number, number, number, number] | null;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* 从轨迹列表中提取 bounds 并安全构建 latLngBounds
|
|
34
|
+
*/
|
|
35
|
+
export declare function safeLatLngBounds(tracks: Array<{
|
|
36
|
+
bounds?: any;
|
|
37
|
+
}>): L.LatLngBounds | null;
|
|
38
|
+
/**
|
|
39
|
+
* 飞行到指定 bounds(带动画时长计算)
|
|
40
|
+
*/
|
|
41
|
+
export declare function flyToBounds(map: L.Map, bounds: L.LatLngBounds, options?: {
|
|
42
|
+
padding?: [number, number];
|
|
43
|
+
}): void;
|
|
44
|
+
/**
|
|
45
|
+
* 构建 filter 方法的返回结果
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildFilterResult<T extends {
|
|
48
|
+
key: string;
|
|
49
|
+
imei: string;
|
|
50
|
+
date: string;
|
|
51
|
+
allPoints?: any[];
|
|
52
|
+
bounds?: any;
|
|
53
|
+
}>(filteredTracks: T[]): FilterResult;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Track 组件内部常量和工具函数
|
|
3
|
+
* @module components/Track/constants
|
|
4
|
+
*/
|
|
5
|
+
import type { BBox } from '../../utils/spatialIndex';
|
|
6
|
+
import type { TrackMeta } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* 默认的轨迹样式配置
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_STYLES: {
|
|
11
|
+
working: {
|
|
12
|
+
color: string;
|
|
13
|
+
weight: number;
|
|
14
|
+
opacity: number;
|
|
15
|
+
};
|
|
16
|
+
nonWorking: {
|
|
17
|
+
color: string;
|
|
18
|
+
weight: number;
|
|
19
|
+
opacity: number;
|
|
20
|
+
dashArray: string;
|
|
21
|
+
};
|
|
22
|
+
selected: {
|
|
23
|
+
weight: number;
|
|
24
|
+
opacity: number;
|
|
25
|
+
};
|
|
26
|
+
hover: {
|
|
27
|
+
weight: number;
|
|
28
|
+
opacity: number;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/** 从 [[number, number], [number, number]] 转换为 [minLat, minLng, maxLat, maxLng] */
|
|
32
|
+
export declare function toBBox(bounds: [[number, number], [number, number]]): BBox;
|
|
33
|
+
/** 比较两个 TrackMeta Map 是否相等 */
|
|
34
|
+
export declare function areMapsEqual(a: Map<string, TrackMeta>, b: Map<string, TrackMeta>): boolean;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Track 农机轨迹组件
|
|
3
|
+
* @description 用于在地图上显示农机作业轨迹,支持轨迹绘制、状态分段、轨迹动画、虚拟化渲染等功能
|
|
4
|
+
* @module components/Track
|
|
5
|
+
*
|
|
6
|
+
* ## 核心架构
|
|
7
|
+
*
|
|
8
|
+
* 本组件采用 **双模式渲染** 架构:
|
|
9
|
+
* - **Marker 模式** (`displayMode === 'marker'`): 小缩放级别下,将每条轨迹显示为一个 Marker 点
|
|
10
|
+
* 支持聚合(supercluster)以提升大量轨迹时的渲染性能和视觉可读性
|
|
11
|
+
* - **Track 模式** (`displayMode === 'track'`): 大缩放级别下,绘制完整的轨迹折线,支持状态分段着色
|
|
12
|
+
*
|
|
13
|
+
* 模式切换由 `currentZoom` 和 `markerZoomThreshold` 共同决定:
|
|
14
|
+
* currentZoom <= markerZoomThreshold → Marker 模式
|
|
15
|
+
* currentZoom > markerZoomThreshold → Track 模式
|
|
16
|
+
*
|
|
17
|
+
* ## 数据流
|
|
18
|
+
*
|
|
19
|
+
* 1. `dataSource` → `parsedTracks` (解析原始数据,提取 imei/date/bounds/allPoints)
|
|
20
|
+
* 2. `parsedTracks` → `trackMetaMap` (计算每条轨迹的元数据:中心点、边界)
|
|
21
|
+
* 3. `trackMetaMap` → `spatialIndexRef` (构建空间索引,用于视口裁剪)
|
|
22
|
+
* 4. `parsedTracks` + `trackMetaMap` → `visibleTracksInView` (视口裁剪 + 虚拟化过滤)
|
|
23
|
+
* 5. `visibleTracksInView` → `sortedVisibleTracks` (选中轨迹优先排序)
|
|
24
|
+
* 6. `sortedVisibleTracks` → `TrackView` (渲染轨迹折线)
|
|
25
|
+
*
|
|
26
|
+
* ## 受控 / 非受控模式
|
|
27
|
+
*
|
|
28
|
+
* - 受控模式: `value !== undefined` 时,选中值完全由外部控制,内部通过 `onChange` 通知变更
|
|
29
|
+
* - 非受控模式: `value === undefined` 时,使用 `internalValue` 管理内部状态,支持 `defaultValue`
|
|
30
|
+
* - `mode === 'single'`: value 为 string,点击切换选中/取消
|
|
31
|
+
* - `mode === 'multiple'`: value 为 string[],点击追加/移除
|
|
32
|
+
*
|
|
33
|
+
* ## 性能优化
|
|
34
|
+
*
|
|
35
|
+
* - **虚拟化渲染**: 仅渲染视口范围内的轨迹 (GridSpatialIndex 空间查询)
|
|
36
|
+
* - **轨迹简化**: Douglas-Peucker 算法减少折线点数
|
|
37
|
+
* - **冗余点过滤**: 移除距离过近的重复坐标点
|
|
38
|
+
* - **聚合模式**: 小缩放级别下将相近轨迹聚合为气泡显示
|
|
39
|
+
*/
|
|
40
|
+
import type { TrackProps, TrackRef } from '../../types';
|
|
41
|
+
/**
|
|
42
|
+
* 农机轨迹组件
|
|
43
|
+
* @description 用于在地图上显示农机作业轨迹,支持:
|
|
44
|
+
* - 轨迹分段显示(路上/作业中不同颜色)
|
|
45
|
+
* - 轨迹选中高亮
|
|
46
|
+
* - 轨迹动画播放
|
|
47
|
+
* - 虚拟化渲染(视口裁剪)
|
|
48
|
+
* - 双模式显示:Marker 模式(小缩放级别)和轨迹模式(大缩放级别)
|
|
49
|
+
* - 聚合气泡(supercluster)
|
|
50
|
+
* - 小地图(鹰眼图)
|
|
51
|
+
* - 命令式 API(通过 ref 调用 fitBounds / flyToTrack / query 等方法)
|
|
52
|
+
*/
|
|
53
|
+
declare const Track: import("react").ForwardRefExoticComponent<TrackProps & import("react").RefAttributes<TrackRef>>;
|
|
54
|
+
export default Track;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Track 组件配置解析
|
|
3
|
+
* @description 将 boolean | ObjectConfig 三态配置解析为统一的配置对象
|
|
4
|
+
* @module components/Track/parseConfig
|
|
5
|
+
*/
|
|
6
|
+
import type { PerformanceConfig, MarkerModeConfig, ClusterIconConfig, MarkerIconConfig } from '../../types';
|
|
7
|
+
export interface ParsedPerformanceConfig {
|
|
8
|
+
isVirtualized: boolean;
|
|
9
|
+
virtualMinZoom: number;
|
|
10
|
+
virtualMaxZoom: number;
|
|
11
|
+
simplifyTolerance: number;
|
|
12
|
+
duplicateTolerance: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ParsedMarkerModeConfig {
|
|
15
|
+
markerZoomThreshold: number;
|
|
16
|
+
markerZoomToLevel: number;
|
|
17
|
+
enableCluster: boolean;
|
|
18
|
+
clusterOptions: {
|
|
19
|
+
radius?: number;
|
|
20
|
+
maxZoom?: number;
|
|
21
|
+
minPoints?: number;
|
|
22
|
+
icon?: ClusterIconConfig;
|
|
23
|
+
} | undefined;
|
|
24
|
+
clusterIconConfig: ClusterIconConfig | undefined;
|
|
25
|
+
markerIconConfig: MarkerIconConfig | undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 解析 performance 配置
|
|
29
|
+
* - undefined / false → 关闭所有优化
|
|
30
|
+
* - true → 启用虚拟化(默认参数)
|
|
31
|
+
* - object → 自定义参数
|
|
32
|
+
*/
|
|
33
|
+
export declare function parsePerformanceConfig(performanceConfig: boolean | PerformanceConfig | undefined): ParsedPerformanceConfig;
|
|
34
|
+
/**
|
|
35
|
+
* 解析 markerMode 配置
|
|
36
|
+
* - undefined / false → 关闭 Marker 模式
|
|
37
|
+
* - true → 启用 Marker 模式 + 聚合
|
|
38
|
+
* - object → 自定义参数
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseMarkerModeConfig(markerModeConfig: boolean | MarkerModeConfig | undefined): ParsedMarkerModeConfig;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Track 组件内部类型定义
|
|
3
|
+
* @module components/Track/types
|
|
4
|
+
*/
|
|
5
|
+
import type { BoundedItem } from '../../utils/spatialIndex';
|
|
6
|
+
/** 轨迹元数据,用于 Marker 模式和空间索引 */
|
|
7
|
+
export interface TrackMeta {
|
|
8
|
+
key: string;
|
|
9
|
+
imei: string;
|
|
10
|
+
date: string;
|
|
11
|
+
center: [number, number];
|
|
12
|
+
bounds: [[number, number], [number, number]];
|
|
13
|
+
}
|
|
14
|
+
/** 带边界框的轨迹索引项 */
|
|
15
|
+
export interface BoundedTrackItem extends BoundedItem {
|
|
16
|
+
key: string;
|
|
17
|
+
}
|
|
18
|
+
/** 轨迹点的自定义属性 */
|
|
19
|
+
export interface TrackPointProperties {
|
|
20
|
+
key: string;
|
|
21
|
+
imei: string;
|
|
22
|
+
date: string;
|
|
23
|
+
}
|
|
24
|
+
/** 筛选结果类型 */
|
|
25
|
+
export interface FilterResult {
|
|
26
|
+
tracks: Array<{
|
|
27
|
+
key: string;
|
|
28
|
+
imei: string;
|
|
29
|
+
date: string;
|
|
30
|
+
bounds: any;
|
|
31
|
+
pointCount: number;
|
|
32
|
+
}>;
|
|
33
|
+
imeis: string[];
|
|
34
|
+
dates: string[];
|
|
35
|
+
totalTracks: number;
|
|
36
|
+
totalPoints: number;
|
|
37
|
+
bounds: [number, number, number, number] | null;
|
|
38
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Marker 图标创建 hook
|
|
3
|
+
* @module components/Track/useMarkerIcon
|
|
4
|
+
*/
|
|
5
|
+
import L from 'leaflet';
|
|
6
|
+
import type { MarkerIconConfig } from '../../types';
|
|
7
|
+
/**
|
|
8
|
+
* 根据 MarkerIconConfig 创建 Leaflet DivIcon
|
|
9
|
+
*/
|
|
10
|
+
export declare function createMarkerIcon(config?: MarkerIconConfig): L.DivIcon;
|
|
11
|
+
/**
|
|
12
|
+
* 自定义 hook:缓存 markerIcon 的创建结果
|
|
13
|
+
*/
|
|
14
|
+
export declare function useMarkerIcon(config?: MarkerIconConfig): L.DivIcon;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Track 组件命令式方法 hook
|
|
3
|
+
* @description 将 useImperativeHandle 中的方法逻辑提取为独立 hook,便于维护
|
|
4
|
+
* @module components/Track/useTrackCommands
|
|
5
|
+
*/
|
|
6
|
+
import { type MutableRefObject } from 'react';
|
|
7
|
+
import type L from 'leaflet';
|
|
8
|
+
import type { TrackRef } from '../../types';
|
|
9
|
+
import type { FilterResult } from './types';
|
|
10
|
+
interface UseTrackCommandsOptions {
|
|
11
|
+
map: L.Map | null;
|
|
12
|
+
parsedTracks: any[];
|
|
13
|
+
isControlled: boolean;
|
|
14
|
+
mode: 'single' | 'multiple';
|
|
15
|
+
currentValue: string | string[];
|
|
16
|
+
onChange?: (value: string | string[]) => void;
|
|
17
|
+
onClickRef: MutableRefObject<((key: string, track: any) => void) | undefined>;
|
|
18
|
+
setInternalValue: (value: string | string[]) => void;
|
|
19
|
+
visibleTracksRef: MutableRefObject<Set<string>>;
|
|
20
|
+
setVisibleTracksVersion: React.Dispatch<React.SetStateAction<number>>;
|
|
21
|
+
}
|
|
22
|
+
export interface TrackCommands {
|
|
23
|
+
/** 查询匹配的轨迹(纯查询,不修改任何状态) */
|
|
24
|
+
query: (filter?: string, callback?: (result: FilterResult) => void) => void;
|
|
25
|
+
/** 获取当前可见轨迹的 key 数组 */
|
|
26
|
+
getVisibleTracks: () => string[];
|
|
27
|
+
/** 获取当前选中轨迹的 key 数组 */
|
|
28
|
+
getSelectedTracks: () => string[];
|
|
29
|
+
/** 即时跳转视图到指定轨迹范围(无动画) */
|
|
30
|
+
fitBounds: (filter?: string, callback?: () => void) => void;
|
|
31
|
+
/** 带动画飞行到指定轨迹范围(callback 在飞行动画结束后触发) */
|
|
32
|
+
flyTo: (filter?: string, callback?: () => void) => void;
|
|
33
|
+
/** 设置可见轨迹(仅显示匹配的轨迹,隐藏其它) */
|
|
34
|
+
setVisibleTracks: (filter?: string) => void;
|
|
35
|
+
/** 恢复所有轨迹可见(清除可见性筛选,不影响选中状态) */
|
|
36
|
+
clearVisibleFilter: () => void;
|
|
37
|
+
/** 选中匹配的轨迹(修改 value + 触发 onClick,不移动地图) */
|
|
38
|
+
select: (filter?: string, callback?: () => void) => void;
|
|
39
|
+
/** 清除选中状态(不影响可见性筛选) */
|
|
40
|
+
deselect: () => void;
|
|
41
|
+
/** 全量重置(清除选中 + 恢复所有轨迹可见) */
|
|
42
|
+
reset: (callback?: () => void) => void;
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated 请使用 query + setVisibleTracks 替代
|
|
45
|
+
*/
|
|
46
|
+
filter: (filter?: string, callback?: (result: FilterResult) => void) => void;
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated 请使用 select + flyTo + setVisibleTracks 组合替代
|
|
49
|
+
*/
|
|
50
|
+
flyToTrack: (filter?: string, filterVisible?: boolean, onComplete?: () => void) => void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Track 组件命令式方法 hook
|
|
54
|
+
*/
|
|
55
|
+
export declare function useTrackCommands(ref: React.Ref<TrackRef>, options: UseTrackCommandsOptions): void;
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用编辑工具栏组件
|
|
3
|
+
* @description 用于统一各编辑组件的工具栏实现
|
|
4
|
+
*/
|
|
5
|
+
import type { ReactNode } from 'react';
|
|
6
|
+
/** 按钮样式变体 */
|
|
7
|
+
export type ButtonVariant = 'default' | 'primary' | 'danger';
|
|
8
|
+
/** 预设色板(参照 Ant Design 5.x PresetColors) */
|
|
9
|
+
export type ToolbarPresetColors = 'success' | 'warning' | 'error' | 'magenta' | 'volcano' | 'gold' | 'orange' | 'cyan' | 'geekblue' | 'purple';
|
|
10
|
+
/** 按钮 color 属性类型(支持预设色和自定义颜色如 #ff0000、rgba(255,0,0,0.5)) */
|
|
11
|
+
export type ToolbarColor = 'default' | 'primary' | 'danger' | ToolbarPresetColors | string;
|
|
12
|
+
/** 预设颜色集合(用于区分预设色和自定义颜色) */
|
|
13
|
+
export declare const PRESET_COLOR_SET: Set<string>;
|
|
14
|
+
/** 单个按钮配置 */
|
|
15
|
+
export interface ToolbarButton<T extends string> {
|
|
16
|
+
/** 按钮操作类型 */
|
|
17
|
+
action: T;
|
|
18
|
+
/** 显示文本 */
|
|
19
|
+
label: string;
|
|
20
|
+
/** 图标组件 */
|
|
21
|
+
icon?: ReactNode;
|
|
22
|
+
/** 提示文本 */
|
|
23
|
+
tooltip?: string;
|
|
24
|
+
/** 按钮样式变体(兼容,优先使用 color) */
|
|
25
|
+
variant?: ButtonVariant;
|
|
26
|
+
/** 按钮颜色 */
|
|
27
|
+
color?: ToolbarColor;
|
|
28
|
+
/** 是否需要选中项才能点击 */
|
|
29
|
+
needsSelection?: boolean;
|
|
30
|
+
/** 编辑模式下是否显示 */
|
|
31
|
+
showInEdit?: boolean;
|
|
32
|
+
/** 是否禁用 */
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** 工具栏尺寸(支持预设尺寸和自定义数字,单位 px) */
|
|
36
|
+
export type ToolbarSize = 'large' | 'middle' | 'small' | number;
|
|
37
|
+
/** 工具栏属性 */
|
|
38
|
+
export interface BaseEditToolbarProps<T extends string> {
|
|
39
|
+
/** 是否可见 */
|
|
40
|
+
visible: boolean;
|
|
41
|
+
/** 工具栏尺寸 */
|
|
42
|
+
size?: ToolbarSize;
|
|
43
|
+
/** 当前选中ID */
|
|
44
|
+
selectedId: string | number | null;
|
|
45
|
+
/** 当前模式 */
|
|
46
|
+
currentMode: string;
|
|
47
|
+
/** 启用的按钮 */
|
|
48
|
+
enabledButtons: T[];
|
|
49
|
+
/** 按钮配置 */
|
|
50
|
+
buttons: ToolbarButton<T>[];
|
|
51
|
+
/** 编辑模式判断函数(默认 mode !== 'idle') */
|
|
52
|
+
isEditingFn?: (mode: string) => boolean;
|
|
53
|
+
/** 模式提示信息 */
|
|
54
|
+
modeHints?: Record<string, string>;
|
|
55
|
+
/** 类名前缀 */
|
|
56
|
+
classPrefix: string;
|
|
57
|
+
/** 保存按钮是否禁用 */
|
|
58
|
+
saveDisabled?: boolean;
|
|
59
|
+
/** 是否显示编辑模式提示 */
|
|
60
|
+
showHint?: boolean;
|
|
61
|
+
/** 警告提示信息(不受 showHint 控制,始终显示) */
|
|
62
|
+
warningHint?: string;
|
|
63
|
+
/** 内置按钮的统一颜色(覆盖各按钮自身的 variant/color),支持预设色和自定义颜色 */
|
|
64
|
+
color?: ToolbarColor;
|
|
65
|
+
/** 是否仅显示图标(不显示文字) */
|
|
66
|
+
iconOnly?: boolean;
|
|
67
|
+
/** 额外内容(自定义工具栏按钮) */
|
|
68
|
+
children?: ReactNode;
|
|
69
|
+
/** 标准动作:取消 */
|
|
70
|
+
onCancel?: () => void;
|
|
71
|
+
/** 标准动作:保存(自动传入 selectedId) */
|
|
72
|
+
onSave?: (id?: string | number | null) => void;
|
|
73
|
+
/** 标准动作:新建 */
|
|
74
|
+
onCreate?: () => void;
|
|
75
|
+
/** 标准动作:删除(自动传入 selectedId) */
|
|
76
|
+
onDelete?: (id?: string | number | null) => void;
|
|
77
|
+
/** 自定义动作映射表,key 为 action 名称,value 为回调(自动传入 selectedId) */
|
|
78
|
+
actionHandlers?: Partial<Record<T, (id?: string | number | null) => void>>;
|
|
79
|
+
}
|
|
80
|
+
/** 工具栏上下文 */
|
|
81
|
+
export interface ToolbarContextValue {
|
|
82
|
+
/** 类名前缀 */
|
|
83
|
+
classPrefix: string;
|
|
84
|
+
}
|
|
85
|
+
/** 工具栏上下文 */
|
|
86
|
+
export declare const ToolbarContext: import("react").Context<ToolbarContextValue | null>;
|
|
87
|
+
/**
|
|
88
|
+
* 获取工具栏上下文
|
|
89
|
+
*/
|
|
90
|
+
export declare function useToolbarContext(): ToolbarContextValue;
|
|
91
|
+
/** 工具栏 ref 方法 */
|
|
92
|
+
export interface BaseEditToolbarRef {
|
|
93
|
+
showNotification: (message: string, title?: string) => void;
|
|
94
|
+
clearNotification: () => void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 通用编辑工具栏
|
|
98
|
+
*/
|
|
99
|
+
declare const BaseEditToolbar: import("react").ForwardRefExoticComponent<BaseEditToolbarProps<string> & import("react").RefAttributes<BaseEditToolbarRef>>;
|
|
100
|
+
export default BaseEditToolbar;
|