@edgepdf/viewer-js 0.0.1
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/README.md +197 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11802 -0
- package/dist/lib/coordinate-mapper.d.ts +229 -0
- package/dist/lib/coordinate-mapper.d.ts.map +1 -0
- package/dist/lib/marker-delete-popup.d.ts +20 -0
- package/dist/lib/marker-delete-popup.d.ts.map +1 -0
- package/dist/lib/marker-edit-popup.d.ts +23 -0
- package/dist/lib/marker-edit-popup.d.ts.map +1 -0
- package/dist/lib/marker-manager.d.ts +408 -0
- package/dist/lib/marker-manager.d.ts.map +1 -0
- package/dist/lib/tile-layer-manager.d.ts +108 -0
- package/dist/lib/tile-layer-manager.d.ts.map +1 -0
- package/dist/lib/viewer.d.ts +135 -0
- package/dist/lib/viewer.d.ts.map +1 -0
- package/dist/lib/zoom-controller.d.ts +182 -0
- package/dist/lib/zoom-controller.d.ts.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import L from 'leaflet';
|
|
2
|
+
import type { ImageInfo, LeafletCoords, ImageCoords, CoordinateBounds } from '@edgepdf/types';
|
|
3
|
+
/**
|
|
4
|
+
* Image position information within the tile grid canvas
|
|
5
|
+
*/
|
|
6
|
+
export interface ImagePosition {
|
|
7
|
+
/** Width of rendered image in canvas coordinates */
|
|
8
|
+
imageRenderWidth: number;
|
|
9
|
+
/** Height of rendered image in canvas coordinates */
|
|
10
|
+
imageRenderHeight: number;
|
|
11
|
+
/** X offset of image within canvas */
|
|
12
|
+
imageOffsetX: number;
|
|
13
|
+
/** Y offset of image within canvas */
|
|
14
|
+
imageOffsetY: number;
|
|
15
|
+
/** Total canvas width */
|
|
16
|
+
canvasWidth: number;
|
|
17
|
+
/** Total canvas height */
|
|
18
|
+
canvasHeight: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* CoordinateMapper - Handles coordinate conversion between Leaflet and image pixel coordinates
|
|
22
|
+
*
|
|
23
|
+
* This class provides bidirectional coordinate conversion between:
|
|
24
|
+
* - Leaflet coordinates [y, x] (using custom CRS)
|
|
25
|
+
* - Image pixel coordinates {x, y}
|
|
26
|
+
*
|
|
27
|
+
* The conversion accounts for aspect ratio differences between the image and the tile grid canvas,
|
|
28
|
+
* properly handling cases where the image doesn't fill the entire canvas.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const mapper = new CoordinateMapper({
|
|
33
|
+
* width: 2000,
|
|
34
|
+
* height: 3000,
|
|
35
|
+
* tileSize: 256,
|
|
36
|
+
* maxZoom: 5,
|
|
37
|
+
* minZoom: 0
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Convert Leaflet coordinates to image coordinates
|
|
41
|
+
* const imageCoords = mapper.leafletToImage([1500, 1000]);
|
|
42
|
+
* // { x: 1000, y: 1500, withinBounds: true }
|
|
43
|
+
*
|
|
44
|
+
* // Convert image coordinates to Leaflet coordinates
|
|
45
|
+
* const leafletCoords = mapper.imageToLeaflet({ x: 1000, y: 1500 });
|
|
46
|
+
* // [1500, 1000]
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class CoordinateMapper {
|
|
50
|
+
private imageInfo;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new CoordinateMapper instance
|
|
53
|
+
*
|
|
54
|
+
* @param imageInfo - Image information including width, height, and zoom levels
|
|
55
|
+
*
|
|
56
|
+
* @throws {Error} If imageInfo is invalid
|
|
57
|
+
*/
|
|
58
|
+
constructor(imageInfo: ImageInfo);
|
|
59
|
+
/**
|
|
60
|
+
* Calculates the image position and dimensions within the tile grid canvas.
|
|
61
|
+
* This handles aspect ratio differences between the image and the canvas.
|
|
62
|
+
*
|
|
63
|
+
* @returns Object containing image render dimensions and offsets
|
|
64
|
+
*/
|
|
65
|
+
calculateImagePosition(): ImagePosition;
|
|
66
|
+
/**
|
|
67
|
+
* Converts Leaflet coordinates to image pixel coordinates.
|
|
68
|
+
*
|
|
69
|
+
* Accounts for image position within the tile grid canvas and aspect ratio differences.
|
|
70
|
+
*
|
|
71
|
+
* @param leafletCoords - Leaflet coordinates [y, x] (lat, lng in CRS.Simple)
|
|
72
|
+
* @returns Object containing image pixel coordinates and bounds check
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const result = mapper.leafletToImage([1500, 1000]);
|
|
77
|
+
* // { x: 1000, y: 1500, withinBounds: true }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
leafletToImage(leafletCoords: LeafletCoords): ImageCoords & {
|
|
81
|
+
withinBounds: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Converts image pixel coordinates to Leaflet coordinates.
|
|
85
|
+
*
|
|
86
|
+
* Accounts for image position within the tile grid canvas and aspect ratio differences.
|
|
87
|
+
*
|
|
88
|
+
* @param imageCoords - Image pixel coordinates {x, y}
|
|
89
|
+
* @returns Leaflet coordinates [y, x] (lat, lng in CRS.Simple)
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const leafletCoords = mapper.imageToLeaflet({ x: 1000, y: 1500 });
|
|
94
|
+
* // [1500, 1000]
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
imageToLeaflet(imageCoords: ImageCoords): LeafletCoords;
|
|
98
|
+
/**
|
|
99
|
+
* Calculates the center point of the image in Leaflet coordinates.
|
|
100
|
+
*
|
|
101
|
+
* @returns Object containing center coordinates {x, y} in Leaflet coordinate system
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const center = mapper.getImageCenter();
|
|
106
|
+
* // { x: 1000, y: 1500 } - center of a 2000x3000 image
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
getImageCenter(): {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Calculates the bounds for the map based on the tile grid.
|
|
115
|
+
*
|
|
116
|
+
* Uses the minimum zoom level to ensure consistent coordinate system
|
|
117
|
+
* across all zoom levels.
|
|
118
|
+
*
|
|
119
|
+
* @returns Leaflet bounds expression [[minY, minX], [maxY, maxX]]
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const bounds = mapper.calculateMapBounds();
|
|
124
|
+
* // [[0, 0], [512, 512]] for minZoom 0 with tileSize 256
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
calculateMapBounds(): L.LatLngBoundsExpression;
|
|
128
|
+
/**
|
|
129
|
+
* Validates Leaflet coordinates and checks bounds
|
|
130
|
+
*
|
|
131
|
+
* @param coords - Leaflet coordinates [y, x]
|
|
132
|
+
* @throws {Error} If coordinates are invalid or out of bounds
|
|
133
|
+
*/
|
|
134
|
+
validateLeafletCoords(coords: LeafletCoords): void;
|
|
135
|
+
/**
|
|
136
|
+
* Validates image pixel coordinates and checks bounds
|
|
137
|
+
*
|
|
138
|
+
* @param coords - Image pixel coordinates {x, y}
|
|
139
|
+
* @throws {Error} If coordinates are invalid or out of bounds
|
|
140
|
+
*/
|
|
141
|
+
validateImageCoords(coords: ImageCoords): void;
|
|
142
|
+
/**
|
|
143
|
+
* Creates a custom CRS (Coordinate Reference System) for direct tile coordinate mapping.
|
|
144
|
+
* This extends Leaflet's Simple CRS with a custom transformation.
|
|
145
|
+
*
|
|
146
|
+
* @returns Custom CRS instance
|
|
147
|
+
*/
|
|
148
|
+
createCustomCRS(): L.CRS;
|
|
149
|
+
/**
|
|
150
|
+
* Calculates the aspect ratio of the image
|
|
151
|
+
*
|
|
152
|
+
* @returns Aspect ratio (width / height)
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const aspectRatio = mapper.getAspectRatio();
|
|
157
|
+
* // 0.666... for a 2000x3000 image
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
getAspectRatio(): number;
|
|
161
|
+
/**
|
|
162
|
+
* Gets the coordinate bounds for the image
|
|
163
|
+
*
|
|
164
|
+
* @returns Coordinate bounds object
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const bounds = mapper.getBounds();
|
|
169
|
+
* // { minX: 0, maxX: 2000, minY: 0, maxY: 3000 }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
getBounds(): CoordinateBounds;
|
|
173
|
+
/**
|
|
174
|
+
* Gets the image information
|
|
175
|
+
*
|
|
176
|
+
* @returns Image info object
|
|
177
|
+
*/
|
|
178
|
+
getImageInfo(): ImageInfo;
|
|
179
|
+
/**
|
|
180
|
+
* Checks if coordinates are within bounds
|
|
181
|
+
*
|
|
182
|
+
* @param coords - Image pixel coordinates {x, y}
|
|
183
|
+
* @returns True if coordinates are within bounds, false otherwise
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* const isValid = mapper.isWithinBounds({ x: 1000, y: 1500 });
|
|
188
|
+
* // true
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
isWithinBounds(coords: ImageCoords): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Clamps coordinates to valid bounds
|
|
194
|
+
*
|
|
195
|
+
* If coordinates are outside bounds, they are clamped to the nearest valid value.
|
|
196
|
+
*
|
|
197
|
+
* @param coords - Image pixel coordinates {x, y}
|
|
198
|
+
* @returns Clamped coordinates within bounds
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* const clamped = mapper.clampToBounds({ x: 2500, y: 3500 });
|
|
203
|
+
* // { x: 2000, y: 3000 } (clamped to max bounds)
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
clampToBounds(coords: ImageCoords): ImageCoords;
|
|
207
|
+
/**
|
|
208
|
+
* Calculates offset for centering coordinates
|
|
209
|
+
*
|
|
210
|
+
* This is useful for centering a point in a viewport or container.
|
|
211
|
+
*
|
|
212
|
+
* @param coords - Image pixel coordinates {x, y} to center
|
|
213
|
+
* @param containerWidth - Width of the container/viewport
|
|
214
|
+
* @param containerHeight - Height of the container/viewport
|
|
215
|
+
* @returns Offset coordinates {x, y} to apply for centering
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* const offset = mapper.calculateCenterOffset(
|
|
220
|
+
* { x: 1000, y: 1500 },
|
|
221
|
+
* 800, // container width
|
|
222
|
+
* 600 // container height
|
|
223
|
+
* );
|
|
224
|
+
* // { x: 600, y: 1200 } - offset to center the point
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
calculateCenterOffset(coords: ImageCoords, containerWidth: number, containerHeight: number): ImageCoords;
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=coordinate-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate-mapper.d.ts","sourceRoot":"","sources":["../../src/lib/coordinate-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,SAAS,CAAC;AACxB,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,WAAW,EACX,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAY;IAE7B;;;;;;OAMG;gBACS,SAAS,EAAE,SAAS;IAchC;;;;;OAKG;IACH,sBAAsB,IAAI,aAAa;IAuCvC;;;;;;;;;;;;;OAaG;IACH,cAAc,CACZ,aAAa,EAAE,aAAa,GAC3B,WAAW,GAAG;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE;IAyB1C;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa;IAkBvD;;;;;;;;;;OAUG;IACH,cAAc,IAAI;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAU1C;;;;;;;;;;;;;OAaG;IACH,kBAAkB,IAAI,CAAC,CAAC,sBAAsB;IAU9C;;;;;OAKG;IACH,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAqBlD;;;;;OAKG;IACH,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IA+B9C;;;;;OAKG;IACH,eAAe,IAAI,CAAC,CAAC,GAAG;IAMxB;;;;;;;;;;OAUG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;;;;;;;OAUG;IACH,SAAS,IAAI,gBAAgB;IAS7B;;;;OAIG;IACH,YAAY,IAAI,SAAS;IAIzB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAS5C;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;IAO/C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,qBAAqB,CACnB,MAAM,EAAE,WAAW,EACnB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,GACtB,WAAW;CAaf"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Marker } from '@edgepdf/types';
|
|
2
|
+
/**
|
|
3
|
+
* Options for creating a delete confirmation popup
|
|
4
|
+
*/
|
|
5
|
+
export interface DeletePopupOptions {
|
|
6
|
+
/** Current marker data */
|
|
7
|
+
marker: Marker;
|
|
8
|
+
/** Callback when delete is confirmed */
|
|
9
|
+
onConfirm: () => void;
|
|
10
|
+
/** Callback when cancel is clicked */
|
|
11
|
+
onCancel: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates and shows a delete confirmation popup for a marker
|
|
15
|
+
*
|
|
16
|
+
* @param options - Delete popup options
|
|
17
|
+
* @returns HTML element containing the popup
|
|
18
|
+
*/
|
|
19
|
+
export declare function createDeletePopup(options: DeletePopupOptions): HTMLElement;
|
|
20
|
+
//# sourceMappingURL=marker-delete-popup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-delete-popup.d.ts","sourceRoot":"","sources":["../../src/lib/marker-delete-popup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAOD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAsG1E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Marker } from '@edgepdf/types';
|
|
2
|
+
/**
|
|
3
|
+
* Options for creating an edit popup
|
|
4
|
+
*/
|
|
5
|
+
export interface EditPopupOptions {
|
|
6
|
+
/** Current marker data */
|
|
7
|
+
marker: Marker;
|
|
8
|
+
/** Callback when save is clicked */
|
|
9
|
+
onSave: (updates: {
|
|
10
|
+
title?: string;
|
|
11
|
+
href?: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
/** Callback when cancel is clicked */
|
|
14
|
+
onCancel: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates and shows an edit popup for a marker
|
|
18
|
+
*
|
|
19
|
+
* @param options - Edit popup options
|
|
20
|
+
* @returns HTML element containing the popup
|
|
21
|
+
*/
|
|
22
|
+
export declare function createEditPopup(options: EditPopupOptions): HTMLElement;
|
|
23
|
+
//# sourceMappingURL=marker-edit-popup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-edit-popup.d.ts","sourceRoot":"","sources":["../../src/lib/marker-edit-popup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,MAAM,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,sCAAsC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAOD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW,CA2ItE"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import L from 'leaflet';
|
|
2
|
+
import type { Marker, MarkerData, LeafletCoords, ImageCoords, ImageInfo, MarkerEvent, MarkerEventType, MarkerInteractionConfig, MarkerSelectionState } from '@edgepdf/types';
|
|
3
|
+
import { CoordinateMapper } from './coordinate-mapper.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating a marker
|
|
6
|
+
*/
|
|
7
|
+
export interface CreateMarkerOptions {
|
|
8
|
+
/** Leaflet coordinates [lat, lng] */
|
|
9
|
+
position?: LeafletCoords;
|
|
10
|
+
/** Image pixel coordinates {x, y} */
|
|
11
|
+
imageCoords?: ImageCoords;
|
|
12
|
+
/** Marker title/tooltip text */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Marker annotation/description */
|
|
15
|
+
annotation?: string;
|
|
16
|
+
/** Link URL (optional) */
|
|
17
|
+
href?: string;
|
|
18
|
+
/** Link target (optional) */
|
|
19
|
+
target?: string;
|
|
20
|
+
/** Show label/tooltip */
|
|
21
|
+
showLabel?: boolean;
|
|
22
|
+
/** Custom marker ID (auto-generated if not provided) */
|
|
23
|
+
id?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* MarkerManager - Manages markers on the Leaflet map
|
|
27
|
+
*
|
|
28
|
+
* This class handles:
|
|
29
|
+
* - Marker creation from coordinates (Leaflet or image pixel coordinates)
|
|
30
|
+
* - Marker positioning and coordinate storage
|
|
31
|
+
* - Marker lifecycle management (add, remove, update, get)
|
|
32
|
+
* - Marker validation
|
|
33
|
+
* - Marker interactions (dragging, selection, tooltips, popups)
|
|
34
|
+
* - Event handling for marker actions
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const markerManager = new MarkerManager({
|
|
39
|
+
* map: leafletMap,
|
|
40
|
+
* coordinateMapper: coordinateMapper,
|
|
41
|
+
* imageInfo: imageInfo
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* // Enable interactions
|
|
45
|
+
* markerManager.setInteractionConfig({
|
|
46
|
+
* draggable: true,
|
|
47
|
+
* selectable: true,
|
|
48
|
+
* showTooltips: true,
|
|
49
|
+
* showPopups: true
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* // Listen to marker events
|
|
53
|
+
* markerManager.on('dragend', (event) => {
|
|
54
|
+
* console.log('Marker dragged:', event.marker.id);
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // Create marker from Leaflet coordinates
|
|
58
|
+
* const marker = markerManager.createMarker({
|
|
59
|
+
* position: [1500, 1000],
|
|
60
|
+
* title: 'My Marker'
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* // Get all markers
|
|
64
|
+
* const allMarkers = markerManager.getAllMarkers();
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare class MarkerManager {
|
|
68
|
+
private map;
|
|
69
|
+
private coordinateMapper;
|
|
70
|
+
private imageInfo;
|
|
71
|
+
private markers;
|
|
72
|
+
private leafletMarkers;
|
|
73
|
+
private markerLayerGroup;
|
|
74
|
+
private eventListeners;
|
|
75
|
+
private selectedIds;
|
|
76
|
+
private interactionConfig;
|
|
77
|
+
/**
|
|
78
|
+
* Creates a new MarkerManager instance
|
|
79
|
+
*
|
|
80
|
+
* @param options - Configuration options
|
|
81
|
+
* @param options.map - Leaflet map instance
|
|
82
|
+
* @param options.coordinateMapper - Coordinate mapper for coordinate conversion
|
|
83
|
+
* @param options.imageInfo - Image information for validation
|
|
84
|
+
*
|
|
85
|
+
* @throws {Error} If map is not provided or invalid
|
|
86
|
+
* @throws {Error} If coordinateMapper is not provided
|
|
87
|
+
* @throws {Error} If imageInfo is not provided
|
|
88
|
+
*/
|
|
89
|
+
constructor(options: {
|
|
90
|
+
map: L.Map;
|
|
91
|
+
coordinateMapper: CoordinateMapper;
|
|
92
|
+
imageInfo: ImageInfo;
|
|
93
|
+
});
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new marker from coordinates
|
|
96
|
+
*
|
|
97
|
+
* Either position (Leaflet coordinates) or imageCoords must be provided.
|
|
98
|
+
* If both are provided, position takes precedence.
|
|
99
|
+
*
|
|
100
|
+
* @param options - Marker creation options
|
|
101
|
+
* @param options.position - Leaflet coordinates [lat, lng]
|
|
102
|
+
* @param options.imageCoords - Image pixel coordinates {x, y}
|
|
103
|
+
* @param options.title - Marker title/tooltip text
|
|
104
|
+
* @param options.annotation - Marker annotation/description
|
|
105
|
+
* @param options.href - Link URL (optional)
|
|
106
|
+
* @param options.target - Link target (optional)
|
|
107
|
+
* @param options.showLabel - Show label/tooltip
|
|
108
|
+
* @param options.id - Custom marker ID (auto-generated if not provided)
|
|
109
|
+
*
|
|
110
|
+
* @returns The created marker
|
|
111
|
+
*
|
|
112
|
+
* @throws {Error} If neither position nor imageCoords is provided
|
|
113
|
+
* @throws {Error} If coordinates are invalid or out of bounds
|
|
114
|
+
*/
|
|
115
|
+
createMarker(options: CreateMarkerOptions): Marker;
|
|
116
|
+
/**
|
|
117
|
+
* Gets a marker by ID
|
|
118
|
+
*
|
|
119
|
+
* @param id - Marker ID
|
|
120
|
+
* @returns The marker, or undefined if not found
|
|
121
|
+
*/
|
|
122
|
+
getMarker(id: string): Marker | null;
|
|
123
|
+
/**
|
|
124
|
+
* Gets all markers
|
|
125
|
+
*
|
|
126
|
+
* @returns Array of all markers
|
|
127
|
+
*/
|
|
128
|
+
getAllMarkers(): Marker[];
|
|
129
|
+
/**
|
|
130
|
+
* Exports all markers as JSON data
|
|
131
|
+
*
|
|
132
|
+
* Serializes all markers into a MarkerData object that can be saved to a file
|
|
133
|
+
* or transmitted. The exported data includes metadata like export timestamp
|
|
134
|
+
* and version.
|
|
135
|
+
*
|
|
136
|
+
* @returns MarkerData object containing all markers and metadata
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const markerData = markerManager.exportMarkers();
|
|
141
|
+
* const jsonString = JSON.stringify(markerData, null, 2);
|
|
142
|
+
* // Save to file or send to server
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
exportMarkers(): MarkerData;
|
|
146
|
+
/**
|
|
147
|
+
* Imports markers from MarkerData
|
|
148
|
+
*
|
|
149
|
+
* Validates and imports markers from a MarkerData object. This method:
|
|
150
|
+
* - Validates the data structure
|
|
151
|
+
* - Validates each marker's coordinates are within bounds
|
|
152
|
+
* - Creates markers using the imported data
|
|
153
|
+
* - Handles coordinate compatibility (ensures both Leaflet and image coordinates are valid)
|
|
154
|
+
*
|
|
155
|
+
* @param data - MarkerData object to import
|
|
156
|
+
* @param options - Import options
|
|
157
|
+
* @param options.clearExisting - If true, removes all existing markers before import (default: false)
|
|
158
|
+
* @param options.validateCoordinates - If true, validates coordinates are within bounds (default: true)
|
|
159
|
+
*
|
|
160
|
+
* @returns Import result with success status and details
|
|
161
|
+
*
|
|
162
|
+
* @throws {Error} If data structure is invalid
|
|
163
|
+
* @throws {Error} If marker validation fails
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* try {
|
|
168
|
+
* const result = markerManager.importMarkers(markerData, {
|
|
169
|
+
* clearExisting: true,
|
|
170
|
+
* validateCoordinates: true
|
|
171
|
+
* });
|
|
172
|
+
* console.log(`Imported ${result.importedCount} markers`);
|
|
173
|
+
* } catch (error) {
|
|
174
|
+
* console.error('Import failed:', error);
|
|
175
|
+
* }
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
importMarkers(data: MarkerData, options?: {
|
|
179
|
+
clearExisting?: boolean;
|
|
180
|
+
validateCoordinates?: boolean;
|
|
181
|
+
}): {
|
|
182
|
+
success: boolean;
|
|
183
|
+
importedCount: number;
|
|
184
|
+
errors: string[];
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Removes a marker by ID
|
|
188
|
+
*
|
|
189
|
+
* @param id - Marker ID
|
|
190
|
+
* @returns True if marker was removed, false if not found
|
|
191
|
+
*/
|
|
192
|
+
removeMarker(id: string): boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Removes all markers
|
|
195
|
+
*/
|
|
196
|
+
removeAllMarkers(): void;
|
|
197
|
+
/**
|
|
198
|
+
* Updates a marker's position
|
|
199
|
+
*
|
|
200
|
+
* @param id - Marker ID
|
|
201
|
+
* @param position - New Leaflet coordinates [lat, lng]
|
|
202
|
+
* @returns True if marker was updated, false if not found
|
|
203
|
+
*
|
|
204
|
+
* @throws {Error} If coordinates are invalid or out of bounds
|
|
205
|
+
*/
|
|
206
|
+
updateMarkerPosition(id: string, position: LeafletCoords): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Updates a marker's properties (excluding position)
|
|
209
|
+
*
|
|
210
|
+
* @param id - Marker ID
|
|
211
|
+
* @param updates - Partial marker properties to update
|
|
212
|
+
* @returns True if marker was updated, false if not found
|
|
213
|
+
*/
|
|
214
|
+
updateMarker(id: string, updates: Partial<Omit<Marker, 'id' | 'position' | 'x' | 'y' | 'zoom'>>): boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Gets the number of markers
|
|
217
|
+
*
|
|
218
|
+
* @returns Number of markers
|
|
219
|
+
*/
|
|
220
|
+
getMarkerCount(): number;
|
|
221
|
+
/**
|
|
222
|
+
* Checks if a marker exists
|
|
223
|
+
*
|
|
224
|
+
* @param id - Marker ID
|
|
225
|
+
* @returns True if marker exists, false otherwise
|
|
226
|
+
*/
|
|
227
|
+
hasMarker(id: string): boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Sets the interaction configuration for markers
|
|
230
|
+
*
|
|
231
|
+
* @param config - Interaction configuration
|
|
232
|
+
*/
|
|
233
|
+
setInteractionConfig(config: Partial<MarkerInteractionConfig>): void;
|
|
234
|
+
/**
|
|
235
|
+
* Gets the current interaction configuration
|
|
236
|
+
*
|
|
237
|
+
* @returns Current interaction configuration
|
|
238
|
+
*/
|
|
239
|
+
getInteractionConfig(): MarkerInteractionConfig;
|
|
240
|
+
/**
|
|
241
|
+
* Selects a marker by ID
|
|
242
|
+
*
|
|
243
|
+
* @param id - Marker ID to select
|
|
244
|
+
* @returns True if marker was selected, false if not found
|
|
245
|
+
*/
|
|
246
|
+
selectMarker(id: string): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Deselects a marker by ID
|
|
249
|
+
*
|
|
250
|
+
* @param id - Marker ID to deselect
|
|
251
|
+
* @returns True if marker was deselected, false if not found
|
|
252
|
+
*/
|
|
253
|
+
deselectMarker(id: string): boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Deselects all markers
|
|
256
|
+
*/
|
|
257
|
+
deselectAllMarkers(): void;
|
|
258
|
+
/**
|
|
259
|
+
* Gets the current selection state
|
|
260
|
+
*
|
|
261
|
+
* @returns Selection state
|
|
262
|
+
*/
|
|
263
|
+
getSelectionState(): MarkerSelectionState;
|
|
264
|
+
/**
|
|
265
|
+
* Checks if a marker is selected
|
|
266
|
+
*
|
|
267
|
+
* @param id - Marker ID
|
|
268
|
+
* @returns True if marker is selected
|
|
269
|
+
*/
|
|
270
|
+
isMarkerSelected(id: string): boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Deletes a marker by ID (triggers delete event)
|
|
273
|
+
*
|
|
274
|
+
* @param id - Marker ID to delete
|
|
275
|
+
* @returns True if marker was deleted, false if not found
|
|
276
|
+
*/
|
|
277
|
+
deleteMarker(id: string): boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Registers an event listener
|
|
280
|
+
*
|
|
281
|
+
* @param eventType - Event type to listen for
|
|
282
|
+
* @param callback - Callback function
|
|
283
|
+
* @returns Unsubscribe function
|
|
284
|
+
*/
|
|
285
|
+
on(eventType: MarkerEventType, callback: (event: MarkerEvent) => void): () => void;
|
|
286
|
+
/**
|
|
287
|
+
* Unregisters an event listener
|
|
288
|
+
*
|
|
289
|
+
* @param eventType - Event type
|
|
290
|
+
* @param callback - Callback function to remove
|
|
291
|
+
*/
|
|
292
|
+
off(eventType: MarkerEventType, callback: (event: MarkerEvent) => void): void;
|
|
293
|
+
/**
|
|
294
|
+
* Removes all event listeners for a specific event type, or all events if no type is provided
|
|
295
|
+
*
|
|
296
|
+
* @param eventType - Optional event type to clear
|
|
297
|
+
*/
|
|
298
|
+
removeAllListeners(eventType?: MarkerEventType): void;
|
|
299
|
+
/**
|
|
300
|
+
* Disposes of the marker manager and cleans up resources
|
|
301
|
+
*
|
|
302
|
+
* This should be called when the marker manager is no longer needed.
|
|
303
|
+
*/
|
|
304
|
+
dispose(): void;
|
|
305
|
+
/**
|
|
306
|
+
* Creates a Leaflet marker from marker data
|
|
307
|
+
*
|
|
308
|
+
* @param marker - Marker data
|
|
309
|
+
* @returns Leaflet marker instance
|
|
310
|
+
*/
|
|
311
|
+
private createLeafletMarker;
|
|
312
|
+
/**
|
|
313
|
+
* Sets up interaction handlers for a marker
|
|
314
|
+
*
|
|
315
|
+
* @param leafletMarker - Leaflet marker instance
|
|
316
|
+
* @param marker - Marker data
|
|
317
|
+
*/
|
|
318
|
+
private setupMarkerInteractions;
|
|
319
|
+
/**
|
|
320
|
+
* Handles marker click events
|
|
321
|
+
*
|
|
322
|
+
* @param marker - Marker that was clicked
|
|
323
|
+
*/
|
|
324
|
+
private handleMarkerClick;
|
|
325
|
+
/**
|
|
326
|
+
* Updates the visual appearance of a marker based on selection state
|
|
327
|
+
*
|
|
328
|
+
* @param id - Marker ID
|
|
329
|
+
* @param selected - Whether marker is selected
|
|
330
|
+
*/
|
|
331
|
+
private updateMarkerSelectionVisual;
|
|
332
|
+
/**
|
|
333
|
+
* Emits an event to all registered listeners
|
|
334
|
+
*
|
|
335
|
+
* @param eventType - Event type
|
|
336
|
+
* @param marker - Marker that triggered the event
|
|
337
|
+
* @param coordinates - Optional coordinates
|
|
338
|
+
*/
|
|
339
|
+
private emitEvent;
|
|
340
|
+
/**
|
|
341
|
+
* Escapes HTML to prevent XSS
|
|
342
|
+
*
|
|
343
|
+
* @param text - Text to escape
|
|
344
|
+
* @returns Escaped HTML string
|
|
345
|
+
*/
|
|
346
|
+
private escapeHtml;
|
|
347
|
+
/**
|
|
348
|
+
* Creates popup content HTML for a marker
|
|
349
|
+
*
|
|
350
|
+
* @param marker - Marker data
|
|
351
|
+
* @returns HTML string for popup content
|
|
352
|
+
*/
|
|
353
|
+
private createPopupContent;
|
|
354
|
+
/**
|
|
355
|
+
* Updates Leaflet marker display (tooltip/popup)
|
|
356
|
+
*
|
|
357
|
+
* @param leafletMarker - Leaflet marker instance
|
|
358
|
+
* @param marker - Marker data
|
|
359
|
+
*/
|
|
360
|
+
private updateLeafletMarkerDisplay;
|
|
361
|
+
/**
|
|
362
|
+
* Attaches event listeners to popup edit/delete buttons
|
|
363
|
+
*
|
|
364
|
+
* @param leafletMarker - Leaflet marker instance
|
|
365
|
+
* @param marker - Marker data
|
|
366
|
+
*/
|
|
367
|
+
private attachPopupButtonListeners;
|
|
368
|
+
/**
|
|
369
|
+
* Handles marker edit action
|
|
370
|
+
*
|
|
371
|
+
* @param marker - Marker to edit
|
|
372
|
+
*/
|
|
373
|
+
private handleEdit;
|
|
374
|
+
/**
|
|
375
|
+
* Handles marker delete action
|
|
376
|
+
*
|
|
377
|
+
* @param marker - Marker to delete
|
|
378
|
+
*/
|
|
379
|
+
private handleDelete;
|
|
380
|
+
/**
|
|
381
|
+
* Validates a marker
|
|
382
|
+
*
|
|
383
|
+
* @param marker - Marker to validate
|
|
384
|
+
* @throws {Error} If marker is invalid
|
|
385
|
+
*/
|
|
386
|
+
private validateMarker;
|
|
387
|
+
/**
|
|
388
|
+
* Validates marker data structure for import
|
|
389
|
+
*
|
|
390
|
+
* @param markerData - Marker data to validate
|
|
391
|
+
* @throws {Error} If marker data is invalid
|
|
392
|
+
*/
|
|
393
|
+
private validateMarkerData;
|
|
394
|
+
/**
|
|
395
|
+
* Validates marker coordinates are within bounds
|
|
396
|
+
*
|
|
397
|
+
* @param markerData - Marker data to validate
|
|
398
|
+
* @throws {Error} If coordinates are out of bounds
|
|
399
|
+
*/
|
|
400
|
+
private validateMarkerCoordinates;
|
|
401
|
+
/**
|
|
402
|
+
* Generates a unique marker ID
|
|
403
|
+
*
|
|
404
|
+
* @returns Unique marker ID
|
|
405
|
+
*/
|
|
406
|
+
private generateMarkerId;
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=marker-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-manager.d.ts","sourceRoot":"","sources":["../../src/lib/marker-manager.ts"],"names":[],"mappings":"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"}
|