@sindicum/libre-draw 0.1.0
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/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/LibreDraw.d.ts +359 -0
- package/dist/core/EventBus.d.ts +37 -0
- package/dist/core/FeatureStore.d.ts +68 -0
- package/dist/core/HistoryManager.d.ts +47 -0
- package/dist/core/ModeManager.d.ts +44 -0
- package/dist/core/errors.d.ts +6 -0
- package/dist/index.d.ts +7 -0
- package/dist/input/InputHandler.d.ts +29 -0
- package/dist/input/KeyboardInput.d.ts +31 -0
- package/dist/input/MouseInput.d.ts +41 -0
- package/dist/input/TouchInput.d.ts +58 -0
- package/dist/libre-draw.cjs +2 -0
- package/dist/libre-draw.cjs.map +1 -0
- package/dist/libre-draw.js +2116 -0
- package/dist/libre-draw.js.map +1 -0
- package/dist/modes/DrawMode.d.ts +70 -0
- package/dist/modes/IdleMode.d.ts +16 -0
- package/dist/modes/Mode.d.ts +26 -0
- package/dist/modes/SelectMode.d.ts +158 -0
- package/dist/rendering/RenderManager.d.ts +80 -0
- package/dist/rendering/SourceManager.d.ts +52 -0
- package/dist/types/events.d.ts +43 -0
- package/dist/types/features.d.ts +80 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/input.d.ts +23 -0
- package/dist/types/options.d.ts +30 -0
- package/dist/ui/Toolbar.d.ts +59 -0
- package/dist/ui/ToolbarButton.d.ts +53 -0
- package/dist/ui/icons/delete.d.ts +4 -0
- package/dist/ui/icons/draw.d.ts +4 -0
- package/dist/ui/icons/redo.d.ts +4 -0
- package/dist/ui/icons/select.d.ts +4 -0
- package/dist/ui/icons/undo.d.ts +4 -0
- package/dist/validation/geojson.d.ts +20 -0
- package/dist/validation/intersection.d.ts +28 -0
- package/package.json +76 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { Mode } from './Mode';
|
|
2
|
+
import type { NormalizedInputEvent } from '../types/input';
|
|
3
|
+
import type { LibreDrawFeature, Position, Action } from '../types/features';
|
|
4
|
+
import type { LibreDrawEventMap } from '../types/events';
|
|
5
|
+
/**
|
|
6
|
+
* Callbacks that SelectMode needs from the host application.
|
|
7
|
+
*/
|
|
8
|
+
export interface SelectModeCallbacks {
|
|
9
|
+
/** Remove a feature from the store. */
|
|
10
|
+
removeFeatureFromStore(id: string): LibreDrawFeature | undefined;
|
|
11
|
+
/** Push an action to the history manager. */
|
|
12
|
+
pushToHistory(action: Action): void;
|
|
13
|
+
/** Emit an event through the event bus. */
|
|
14
|
+
emitEvent<K extends keyof LibreDrawEventMap>(type: K, payload: LibreDrawEventMap[K]): void;
|
|
15
|
+
/** Re-render all features. */
|
|
16
|
+
renderFeatures(): void;
|
|
17
|
+
/** Get a feature by ID. */
|
|
18
|
+
getFeatureById(id: string): LibreDrawFeature | undefined;
|
|
19
|
+
/** Get all features in the store. */
|
|
20
|
+
getAllFeatures(): LibreDrawFeature[];
|
|
21
|
+
/** Convert a geographic coordinate to a screen point. */
|
|
22
|
+
getScreenPoint(lngLat: {
|
|
23
|
+
lng: number;
|
|
24
|
+
lat: number;
|
|
25
|
+
}): {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
};
|
|
29
|
+
/** Update a feature in the store. */
|
|
30
|
+
updateFeatureInStore(id: string, feature: LibreDrawFeature): void;
|
|
31
|
+
/** Render vertex and midpoint markers for editing. */
|
|
32
|
+
renderVertices(featureId: string, vertices: Position[], midpoints: Position[], highlightIndex?: number): void;
|
|
33
|
+
/** Clear vertex/midpoint markers. */
|
|
34
|
+
clearVertices(): void;
|
|
35
|
+
/** Enable or disable map drag panning. */
|
|
36
|
+
setDragPan(enabled: boolean): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Selection and editing mode for existing polygons.
|
|
40
|
+
*
|
|
41
|
+
* Users click on a polygon to select it. Selected polygons display
|
|
42
|
+
* vertex handles that can be dragged to reshape the polygon. Midpoint
|
|
43
|
+
* handles appear between vertices and can be dragged to add new vertices.
|
|
44
|
+
* Double-clicking a vertex removes it (minimum 3 vertices maintained).
|
|
45
|
+
*/
|
|
46
|
+
export declare class SelectMode implements Mode {
|
|
47
|
+
private selectedIds;
|
|
48
|
+
private isActive;
|
|
49
|
+
private callbacks;
|
|
50
|
+
private onSelectionChange?;
|
|
51
|
+
private dragging;
|
|
52
|
+
private dragVertexIndex;
|
|
53
|
+
private dragStartFeature;
|
|
54
|
+
private draggingPolygon;
|
|
55
|
+
private dragPolygonStartLngLat;
|
|
56
|
+
private highlightedVertexIndex;
|
|
57
|
+
constructor(callbacks: SelectModeCallbacks, onSelectionChange?: (selectedIds: string[]) => void);
|
|
58
|
+
activate(): void;
|
|
59
|
+
deactivate(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Get the currently selected feature IDs.
|
|
62
|
+
*/
|
|
63
|
+
getSelectedIds(): string[];
|
|
64
|
+
/**
|
|
65
|
+
* Programmatically select a feature by ID.
|
|
66
|
+
*
|
|
67
|
+
* Replaces any existing selection. Renders vertex handles and
|
|
68
|
+
* emits a selectionchange event. Cancels any in-progress drag.
|
|
69
|
+
*
|
|
70
|
+
* @param id - The feature ID to select.
|
|
71
|
+
* @returns `true` if the feature was found and selected, `false` otherwise.
|
|
72
|
+
*/
|
|
73
|
+
selectFeature(id: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Programmatically clear the current selection.
|
|
76
|
+
*
|
|
77
|
+
* Removes vertex handles and emits a selectionchange event.
|
|
78
|
+
* No-op if nothing is selected or mode is not active.
|
|
79
|
+
*/
|
|
80
|
+
clearSelection(): void;
|
|
81
|
+
onPointerDown(event: NormalizedInputEvent): void;
|
|
82
|
+
onPointerMove(event: NormalizedInputEvent): void;
|
|
83
|
+
onPointerUp(_event: NormalizedInputEvent): void;
|
|
84
|
+
onDoubleClick(event: NormalizedInputEvent): void;
|
|
85
|
+
onLongPress(event: NormalizedInputEvent): void;
|
|
86
|
+
onKeyDown(key: string, _event: KeyboardEvent): void;
|
|
87
|
+
/**
|
|
88
|
+
* Get the hit-test threshold based on input type.
|
|
89
|
+
*/
|
|
90
|
+
private getThreshold;
|
|
91
|
+
/**
|
|
92
|
+
* Get the unique vertices (excluding closing point) of a polygon.
|
|
93
|
+
*/
|
|
94
|
+
private getVertices;
|
|
95
|
+
/**
|
|
96
|
+
* Find the nearest vertex within the hit threshold.
|
|
97
|
+
* @returns The vertex index, or -1 if none is close enough.
|
|
98
|
+
*/
|
|
99
|
+
private findNearestVertex;
|
|
100
|
+
/**
|
|
101
|
+
* Find the nearest point (vertex or midpoint) within the hit threshold.
|
|
102
|
+
* @returns The index, or -1 if none is close enough.
|
|
103
|
+
*/
|
|
104
|
+
private findNearestPoint;
|
|
105
|
+
/**
|
|
106
|
+
* Compute midpoints for each edge of the polygon.
|
|
107
|
+
*/
|
|
108
|
+
private computeMidpoints;
|
|
109
|
+
/**
|
|
110
|
+
* Start a vertex drag operation.
|
|
111
|
+
*/
|
|
112
|
+
private startDrag;
|
|
113
|
+
/**
|
|
114
|
+
* Start a polygon drag (whole-polygon move) operation.
|
|
115
|
+
*/
|
|
116
|
+
private startPolygonDrag;
|
|
117
|
+
/**
|
|
118
|
+
* End a drag operation and restore map interactions.
|
|
119
|
+
*/
|
|
120
|
+
private endDrag;
|
|
121
|
+
/**
|
|
122
|
+
* Create a new feature with a vertex moved to a new position.
|
|
123
|
+
*/
|
|
124
|
+
private moveVertex;
|
|
125
|
+
/**
|
|
126
|
+
* Create a new feature with all vertices translated by the given delta.
|
|
127
|
+
*/
|
|
128
|
+
private movePolygon;
|
|
129
|
+
/**
|
|
130
|
+
* Create a new feature with a vertex inserted at the given index.
|
|
131
|
+
*/
|
|
132
|
+
private insertVertex;
|
|
133
|
+
/**
|
|
134
|
+
* Create a new feature with a vertex removed at the given index.
|
|
135
|
+
*/
|
|
136
|
+
private removeVertex;
|
|
137
|
+
/**
|
|
138
|
+
* Refresh vertex/midpoint handles for the currently selected feature.
|
|
139
|
+
* Call this after external geometry changes (e.g. undo/redo).
|
|
140
|
+
*/
|
|
141
|
+
refreshVertexHandles(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Show vertex and midpoint handles for a selected feature.
|
|
144
|
+
*/
|
|
145
|
+
private showVertexHandles;
|
|
146
|
+
/**
|
|
147
|
+
* Get the first selected feature ID.
|
|
148
|
+
*/
|
|
149
|
+
private getFirstSelectedId;
|
|
150
|
+
/**
|
|
151
|
+
* Delete all currently selected features.
|
|
152
|
+
*/
|
|
153
|
+
private deleteSelected;
|
|
154
|
+
/**
|
|
155
|
+
* Notify the host about selection changes.
|
|
156
|
+
*/
|
|
157
|
+
private notifySelectionChange;
|
|
158
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Map as MaplibreMap } from 'maplibre-gl';
|
|
2
|
+
import type { LibreDrawFeature, Position } from '../types/features';
|
|
3
|
+
import { SourceManager } from './SourceManager';
|
|
4
|
+
/**
|
|
5
|
+
* Layer IDs used by LibreDraw for rendering.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LAYER_IDS: {
|
|
8
|
+
readonly FILL: "libre-draw-fill";
|
|
9
|
+
readonly OUTLINE: "libre-draw-outline";
|
|
10
|
+
readonly VERTICES: "libre-draw-vertices";
|
|
11
|
+
readonly PREVIEW: "libre-draw-preview";
|
|
12
|
+
readonly EDIT_VERTICES: "libre-draw-edit-vertices";
|
|
13
|
+
readonly EDIT_MIDPOINTS: "libre-draw-edit-midpoints";
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Manages the rendering layers for LibreDraw.
|
|
17
|
+
*
|
|
18
|
+
* Creates and manages MapLibre layers for:
|
|
19
|
+
* - Fill: polygon fill rendering
|
|
20
|
+
* - Outline: polygon border rendering
|
|
21
|
+
* - Vertices: vertex point rendering
|
|
22
|
+
* - Preview: in-progress drawing preview
|
|
23
|
+
*
|
|
24
|
+
* Uses requestAnimationFrame for batch updates to avoid
|
|
25
|
+
* redundant re-renders within a single frame.
|
|
26
|
+
*/
|
|
27
|
+
export declare class RenderManager {
|
|
28
|
+
private map;
|
|
29
|
+
private sourceManager;
|
|
30
|
+
private selectedIds;
|
|
31
|
+
private pendingRender;
|
|
32
|
+
private pendingFeatures;
|
|
33
|
+
private initialized;
|
|
34
|
+
constructor(map: MaplibreMap, sourceManager: SourceManager);
|
|
35
|
+
/**
|
|
36
|
+
* Initialize rendering layers on the map.
|
|
37
|
+
* Should be called after the map style and sources are ready.
|
|
38
|
+
*/
|
|
39
|
+
initialize(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Render features to the map. Uses requestAnimationFrame
|
|
42
|
+
* to batch multiple render calls within a single frame.
|
|
43
|
+
* @param features - The features to render.
|
|
44
|
+
*/
|
|
45
|
+
render(features: LibreDrawFeature[]): void;
|
|
46
|
+
/**
|
|
47
|
+
* Render a polygon preview for in-progress drawing.
|
|
48
|
+
* @param coordinates - The preview polygon coordinates (ring).
|
|
49
|
+
*/
|
|
50
|
+
renderPreview(coordinates: Position[]): void;
|
|
51
|
+
/**
|
|
52
|
+
* Clear the drawing preview.
|
|
53
|
+
*/
|
|
54
|
+
clearPreview(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Render vertex and midpoint markers for editing a selected polygon.
|
|
57
|
+
* @param vertices - The polygon vertex positions.
|
|
58
|
+
* @param midpoints - The edge midpoint positions.
|
|
59
|
+
* @param highlightIndex - Optional index of the vertex to highlight.
|
|
60
|
+
*/
|
|
61
|
+
renderVertices(vertices: Position[], midpoints: Position[], highlightIndex?: number): void;
|
|
62
|
+
/**
|
|
63
|
+
* Clear the vertex/midpoint markers.
|
|
64
|
+
*/
|
|
65
|
+
clearVertices(): void;
|
|
66
|
+
/**
|
|
67
|
+
* Set the IDs of selected features for visual highlighting.
|
|
68
|
+
* @param ids - The selected feature IDs.
|
|
69
|
+
*/
|
|
70
|
+
setSelectedIds(ids: string[]): void;
|
|
71
|
+
/**
|
|
72
|
+
* Remove all layers and sources from the map.
|
|
73
|
+
*/
|
|
74
|
+
destroy(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Perform the actual render, converting features to GeoJSON
|
|
77
|
+
* with selection state embedded in properties.
|
|
78
|
+
*/
|
|
79
|
+
private performRender;
|
|
80
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Map as MaplibreMap } from 'maplibre-gl';
|
|
2
|
+
/**
|
|
3
|
+
* The GeoJSON source IDs used by LibreDraw.
|
|
4
|
+
*/
|
|
5
|
+
export declare const SOURCE_IDS: {
|
|
6
|
+
readonly FEATURES: "libre-draw-features";
|
|
7
|
+
readonly PREVIEW: "libre-draw-preview";
|
|
8
|
+
readonly EDIT_VERTICES: "libre-draw-edit-vertices";
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Manages MapLibre GeoJSON sources for the drawing layers.
|
|
12
|
+
*
|
|
13
|
+
* Provides methods to add, update, and remove the sources that
|
|
14
|
+
* the RenderManager's layers read from.
|
|
15
|
+
*/
|
|
16
|
+
export declare class SourceManager {
|
|
17
|
+
private map;
|
|
18
|
+
private initialized;
|
|
19
|
+
constructor(map: MaplibreMap);
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the GeoJSON sources on the map.
|
|
22
|
+
* Should be called after the map style has loaded.
|
|
23
|
+
*/
|
|
24
|
+
initialize(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Update the features source with new GeoJSON data.
|
|
27
|
+
* @param data - A GeoJSON FeatureCollection.
|
|
28
|
+
*/
|
|
29
|
+
updateFeatures(data: GeoJSON.FeatureCollection): void;
|
|
30
|
+
/**
|
|
31
|
+
* Update the preview source with new GeoJSON data.
|
|
32
|
+
* @param data - A GeoJSON FeatureCollection.
|
|
33
|
+
*/
|
|
34
|
+
updatePreview(data: GeoJSON.FeatureCollection): void;
|
|
35
|
+
/**
|
|
36
|
+
* Clear the preview source.
|
|
37
|
+
*/
|
|
38
|
+
clearPreview(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Update the edit vertices source with new GeoJSON data.
|
|
41
|
+
* @param data - A GeoJSON FeatureCollection of Point features.
|
|
42
|
+
*/
|
|
43
|
+
updateEditVertices(data: GeoJSON.FeatureCollection): void;
|
|
44
|
+
/**
|
|
45
|
+
* Clear the edit vertices source.
|
|
46
|
+
*/
|
|
47
|
+
clearEditVertices(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Remove all sources from the map.
|
|
50
|
+
*/
|
|
51
|
+
destroy(): void;
|
|
52
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { LibreDrawFeature } from './features';
|
|
2
|
+
/**
|
|
3
|
+
* Event payload for feature creation.
|
|
4
|
+
*/
|
|
5
|
+
export interface CreateEvent {
|
|
6
|
+
feature: LibreDrawFeature;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Event payload for feature update.
|
|
10
|
+
*/
|
|
11
|
+
export interface UpdateEvent {
|
|
12
|
+
feature: LibreDrawFeature;
|
|
13
|
+
oldFeature: LibreDrawFeature;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Event payload for feature deletion.
|
|
17
|
+
*/
|
|
18
|
+
export interface DeleteEvent {
|
|
19
|
+
feature: LibreDrawFeature;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Event payload for selection changes.
|
|
23
|
+
*/
|
|
24
|
+
export interface SelectionChangeEvent {
|
|
25
|
+
selectedIds: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Event payload for mode changes.
|
|
29
|
+
*/
|
|
30
|
+
export interface ModeChangeEvent {
|
|
31
|
+
mode: string;
|
|
32
|
+
previousMode: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Map of all LibreDraw event types to their payloads.
|
|
36
|
+
*/
|
|
37
|
+
export interface LibreDrawEventMap {
|
|
38
|
+
create: CreateEvent;
|
|
39
|
+
update: UpdateEvent;
|
|
40
|
+
delete: DeleteEvent;
|
|
41
|
+
selectionchange: SelectionChangeEvent;
|
|
42
|
+
modechange: ModeChangeEvent;
|
|
43
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A geographic coordinate pair [longitude, latitude].
|
|
3
|
+
*/
|
|
4
|
+
export type Position = [number, number];
|
|
5
|
+
/**
|
|
6
|
+
* GeoJSON Polygon geometry.
|
|
7
|
+
*/
|
|
8
|
+
export interface PolygonGeometry {
|
|
9
|
+
type: 'Polygon';
|
|
10
|
+
coordinates: Position[][];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Arbitrary key-value properties attached to a feature.
|
|
14
|
+
*/
|
|
15
|
+
export interface FeatureProperties {
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A GeoJSON Feature with Polygon geometry used internally by LibreDraw.
|
|
20
|
+
*/
|
|
21
|
+
export interface LibreDrawFeature {
|
|
22
|
+
id: string;
|
|
23
|
+
type: 'Feature';
|
|
24
|
+
geometry: PolygonGeometry;
|
|
25
|
+
properties: FeatureProperties;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The type of history action.
|
|
29
|
+
*/
|
|
30
|
+
export type ActionType = 'create' | 'update' | 'delete';
|
|
31
|
+
/**
|
|
32
|
+
* A reversible action that can be applied and reverted on a FeatureStore.
|
|
33
|
+
*/
|
|
34
|
+
export interface Action {
|
|
35
|
+
type: ActionType;
|
|
36
|
+
apply(store: FeatureStoreInterface): void;
|
|
37
|
+
revert(store: FeatureStoreInterface): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Minimal interface for the FeatureStore used by actions.
|
|
41
|
+
* This avoids circular imports between types and core modules.
|
|
42
|
+
*/
|
|
43
|
+
export interface FeatureStoreInterface {
|
|
44
|
+
add(feature: LibreDrawFeature): void;
|
|
45
|
+
update(id: string, feature: LibreDrawFeature): void;
|
|
46
|
+
remove(id: string): void;
|
|
47
|
+
getById(id: string): LibreDrawFeature | undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Action that represents the creation of a new feature.
|
|
51
|
+
*/
|
|
52
|
+
export declare class CreateAction implements Action {
|
|
53
|
+
readonly feature: LibreDrawFeature;
|
|
54
|
+
readonly type: ActionType;
|
|
55
|
+
constructor(feature: LibreDrawFeature);
|
|
56
|
+
apply(store: FeatureStoreInterface): void;
|
|
57
|
+
revert(store: FeatureStoreInterface): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Action that represents the update of an existing feature.
|
|
61
|
+
*/
|
|
62
|
+
export declare class UpdateAction implements Action {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
readonly oldFeature: LibreDrawFeature;
|
|
65
|
+
readonly newFeature: LibreDrawFeature;
|
|
66
|
+
readonly type: ActionType;
|
|
67
|
+
constructor(id: string, oldFeature: LibreDrawFeature, newFeature: LibreDrawFeature);
|
|
68
|
+
apply(store: FeatureStoreInterface): void;
|
|
69
|
+
revert(store: FeatureStoreInterface): void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Action that represents the deletion of a feature.
|
|
73
|
+
*/
|
|
74
|
+
export declare class DeleteAction implements Action {
|
|
75
|
+
readonly feature: LibreDrawFeature;
|
|
76
|
+
readonly type: ActionType;
|
|
77
|
+
constructor(feature: LibreDrawFeature);
|
|
78
|
+
apply(store: FeatureStoreInterface): void;
|
|
79
|
+
revert(store: FeatureStoreInterface): void;
|
|
80
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { Position, PolygonGeometry, FeatureProperties, LibreDrawFeature, ActionType, Action, FeatureStoreInterface, } from './features';
|
|
2
|
+
export { CreateAction, UpdateAction, DeleteAction, } from './features';
|
|
3
|
+
export type { CreateEvent, UpdateEvent, DeleteEvent, SelectionChangeEvent, ModeChangeEvent, LibreDrawEventMap, } from './events';
|
|
4
|
+
export type { ToolbarPosition, ToolbarControls, ToolbarOptions, LibreDrawOptions, } from './options';
|
|
5
|
+
export type { InputType, NormalizedInputEvent, } from './input';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type of input device that generated an event.
|
|
3
|
+
*/
|
|
4
|
+
export type InputType = 'mouse' | 'touch';
|
|
5
|
+
/**
|
|
6
|
+
* A normalized input event shared across mouse and touch handlers.
|
|
7
|
+
*/
|
|
8
|
+
export interface NormalizedInputEvent {
|
|
9
|
+
/** The geographic coordinate at the event location. */
|
|
10
|
+
lngLat: {
|
|
11
|
+
lng: number;
|
|
12
|
+
lat: number;
|
|
13
|
+
};
|
|
14
|
+
/** The screen pixel coordinate at the event location. */
|
|
15
|
+
point: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
};
|
|
19
|
+
/** The original DOM event. */
|
|
20
|
+
originalEvent: MouseEvent | TouchEvent;
|
|
21
|
+
/** The input device type that generated this event. */
|
|
22
|
+
inputType: InputType;
|
|
23
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Position of the toolbar control on the map.
|
|
3
|
+
*/
|
|
4
|
+
export type ToolbarPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for which toolbar controls to display.
|
|
7
|
+
*/
|
|
8
|
+
export interface ToolbarControls {
|
|
9
|
+
draw?: boolean;
|
|
10
|
+
select?: boolean;
|
|
11
|
+
delete?: boolean;
|
|
12
|
+
undo?: boolean;
|
|
13
|
+
redo?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Configuration options for the toolbar.
|
|
17
|
+
*/
|
|
18
|
+
export interface ToolbarOptions {
|
|
19
|
+
position?: ToolbarPosition;
|
|
20
|
+
controls?: ToolbarControls;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Options for creating a LibreDraw instance.
|
|
24
|
+
*/
|
|
25
|
+
export interface LibreDrawOptions {
|
|
26
|
+
/** Whether to show the toolbar, or toolbar configuration options. */
|
|
27
|
+
toolbar?: boolean | ToolbarOptions;
|
|
28
|
+
/** Maximum number of undo/redo history entries. Defaults to 100. */
|
|
29
|
+
historyLimit?: number;
|
|
30
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Map as MaplibreMap } from 'maplibre-gl';
|
|
2
|
+
import type { ToolbarOptions } from '../types/options';
|
|
3
|
+
/**
|
|
4
|
+
* Callbacks that the Toolbar needs from the host application.
|
|
5
|
+
*/
|
|
6
|
+
export interface ToolbarCallbacks {
|
|
7
|
+
onDrawClick(): void;
|
|
8
|
+
onSelectClick(): void;
|
|
9
|
+
onDeleteClick(): void;
|
|
10
|
+
onUndoClick(): void;
|
|
11
|
+
onRedoClick(): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates and manages the drawing toolbar UI.
|
|
15
|
+
*
|
|
16
|
+
* The toolbar is positioned on the map using MapLibre's control
|
|
17
|
+
* container system. It creates buttons for draw, select, delete,
|
|
18
|
+
* undo, and redo actions. Button states are updated externally
|
|
19
|
+
* to reflect the current mode and history state.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Toolbar {
|
|
22
|
+
private map;
|
|
23
|
+
private container;
|
|
24
|
+
private buttons;
|
|
25
|
+
private callbacks;
|
|
26
|
+
private options;
|
|
27
|
+
constructor(map: MaplibreMap, callbacks: ToolbarCallbacks, options?: ToolbarOptions);
|
|
28
|
+
/**
|
|
29
|
+
* Update the active mode displayed in the toolbar.
|
|
30
|
+
* @param mode - The active mode name ('idle', 'draw', 'select').
|
|
31
|
+
*/
|
|
32
|
+
setActiveMode(mode: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Update the undo/redo button states.
|
|
35
|
+
* @param canUndo - Whether undo is available.
|
|
36
|
+
* @param canRedo - Whether redo is available.
|
|
37
|
+
*/
|
|
38
|
+
setHistoryState(canUndo: boolean, canRedo: boolean): void;
|
|
39
|
+
/**
|
|
40
|
+
* Remove the toolbar from the map and clean up.
|
|
41
|
+
*/
|
|
42
|
+
destroy(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Create all toolbar buttons based on the configured controls.
|
|
45
|
+
*/
|
|
46
|
+
private createButtons;
|
|
47
|
+
/**
|
|
48
|
+
* Create a button and add it to the toolbar.
|
|
49
|
+
*/
|
|
50
|
+
private addButton;
|
|
51
|
+
/**
|
|
52
|
+
* Mount the toolbar container to the map's control container.
|
|
53
|
+
*/
|
|
54
|
+
private mount;
|
|
55
|
+
/**
|
|
56
|
+
* Apply CSS styles to the toolbar container.
|
|
57
|
+
*/
|
|
58
|
+
private applyContainerStyles;
|
|
59
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for creating a toolbar button.
|
|
3
|
+
*/
|
|
4
|
+
export interface ToolbarButtonOptions {
|
|
5
|
+
/** The unique identifier for this button. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** The SVG icon string to display. */
|
|
8
|
+
icon: string;
|
|
9
|
+
/** Tooltip text for the button. */
|
|
10
|
+
title: string;
|
|
11
|
+
/** Click handler callback. */
|
|
12
|
+
onClick: () => void;
|
|
13
|
+
/** Whether this is a toggle button (draw/select) vs. action button (delete/undo/redo). */
|
|
14
|
+
isToggle?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates and manages a single toolbar button DOM element.
|
|
18
|
+
*
|
|
19
|
+
* Supports active and disabled states for visual feedback.
|
|
20
|
+
* All DOM creation uses createElement for security (no innerHTML).
|
|
21
|
+
*/
|
|
22
|
+
export declare class ToolbarButton {
|
|
23
|
+
private element;
|
|
24
|
+
private iconContainer;
|
|
25
|
+
private options;
|
|
26
|
+
constructor(options: ToolbarButtonOptions);
|
|
27
|
+
/**
|
|
28
|
+
* Get the DOM element for this button.
|
|
29
|
+
*/
|
|
30
|
+
getElement(): HTMLButtonElement;
|
|
31
|
+
/**
|
|
32
|
+
* Set the active state of the button.
|
|
33
|
+
* @param active - Whether the button should appear active.
|
|
34
|
+
*/
|
|
35
|
+
setActive(active: boolean): void;
|
|
36
|
+
/**
|
|
37
|
+
* Set the disabled state of the button.
|
|
38
|
+
* @param disabled - Whether the button should be disabled.
|
|
39
|
+
*/
|
|
40
|
+
setDisabled(disabled: boolean): void;
|
|
41
|
+
/**
|
|
42
|
+
* Clean up the button element.
|
|
43
|
+
*/
|
|
44
|
+
destroy(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Set the icon SVG content using DOM parsing (no innerHTML).
|
|
47
|
+
*/
|
|
48
|
+
private setIcon;
|
|
49
|
+
/**
|
|
50
|
+
* Apply the base CSS styles to the button.
|
|
51
|
+
*/
|
|
52
|
+
private applyStyles;
|
|
53
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trash can SVG icon for the delete tool.
|
|
3
|
+
*/
|
|
4
|
+
export declare const deleteIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/></svg>";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pentagon SVG icon for the draw tool.
|
|
3
|
+
*/
|
|
4
|
+
export declare const drawIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2l8.5 6.2-3.2 9.8H6.7L3.5 8.2z\"/></svg>";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Right arrow SVG icon for the redo action.
|
|
3
|
+
*/
|
|
4
|
+
export declare const redoIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 14 20 9 15 4\"/><path d=\"M4 20v-7a4 4 0 014-4h12\"/></svg>";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor SVG icon for the select tool.
|
|
3
|
+
*/
|
|
4
|
+
export declare const selectIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\"/><path d=\"M13 13l6 6\"/></svg>";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Left arrow SVG icon for the undo action.
|
|
3
|
+
*/
|
|
4
|
+
export declare const undoIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 14 4 9 9 4\"/><path d=\"M20 20v-7a4 4 0 00-4-4H4\"/></svg>";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { LibreDrawFeature } from '../types/features';
|
|
2
|
+
/**
|
|
3
|
+
* Validate a single GeoJSON-like object as a valid LibreDraw Feature
|
|
4
|
+
* with Polygon geometry.
|
|
5
|
+
* @param feature - The object to validate.
|
|
6
|
+
* @returns The validated feature.
|
|
7
|
+
* @throws LibreDrawError if the feature is invalid.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateFeature(feature: unknown): LibreDrawFeature;
|
|
10
|
+
/**
|
|
11
|
+
* Validate that an unknown value is a valid GeoJSON FeatureCollection
|
|
12
|
+
* containing only valid Polygon features.
|
|
13
|
+
* @param geojson - The value to validate.
|
|
14
|
+
* @returns The validated FeatureCollection.
|
|
15
|
+
* @throws LibreDrawError if the value is invalid.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateGeoJSON(geojson: unknown): {
|
|
18
|
+
type: 'FeatureCollection';
|
|
19
|
+
features: LibreDrawFeature[];
|
|
20
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Position } from '../types/features';
|
|
2
|
+
/**
|
|
3
|
+
* Check if two line segments (p1-p2) and (p3-p4) truly intersect.
|
|
4
|
+
* Segments that share an endpoint are NOT considered intersecting.
|
|
5
|
+
*/
|
|
6
|
+
export declare function segmentsIntersect(p1: Position, p2: Position, p3: Position, p4: Position): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Check if a closed polygon ring has any self-intersections.
|
|
9
|
+
* The ring should include the closing point (first === last).
|
|
10
|
+
* @param ring - The polygon ring coordinates.
|
|
11
|
+
* @returns True if the ring has self-intersections.
|
|
12
|
+
*/
|
|
13
|
+
export declare function hasRingSelfIntersection(ring: Position[]): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check if adding a new vertex to the current drawing vertices would cause
|
|
16
|
+
* the new edge to intersect any existing edge.
|
|
17
|
+
* @param vertices - Current vertices (NOT closed, no closing point).
|
|
18
|
+
* @param newVertex - The vertex to add.
|
|
19
|
+
* @returns True if adding the vertex would cause an intersection.
|
|
20
|
+
*/
|
|
21
|
+
export declare function wouldNewVertexCauseIntersection(vertices: Position[], newVertex: Position): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if closing the polygon (connecting last vertex to first) would cause
|
|
24
|
+
* the closing edge to intersect any existing edge.
|
|
25
|
+
* @param vertices - Current vertices (NOT closed, no closing point).
|
|
26
|
+
* @returns True if closing would cause an intersection.
|
|
27
|
+
*/
|
|
28
|
+
export declare function wouldClosingCauseIntersection(vertices: Position[]): boolean;
|