@biodiv-platform/naksha-maplibre-draw 5.0.7 → 5.0.8
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/esm/index.js +439 -206
- package/dist/index.d.ts +6 -0
- package/dist/index.js +448 -215
- package/package.json +7 -8
package/dist/esm/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
|
20
20
|
|
|
21
21
|
// src/components/map.tsx
|
|
22
22
|
import maplibregl2 from "maplibre-gl";
|
|
23
|
+
import { useRef, useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
|
|
23
24
|
|
|
24
25
|
// src/components/setup-draw.tsx
|
|
25
26
|
import {
|
|
@@ -34,6 +35,9 @@ import {
|
|
|
34
35
|
TerraDrawRectangleMode
|
|
35
36
|
} from "terra-draw";
|
|
36
37
|
import { TerraDrawMapLibreGLAdapter } from "terra-draw-maplibre-gl-adapter";
|
|
38
|
+
import { tw } from "twind";
|
|
39
|
+
import React from "react";
|
|
40
|
+
import { jsx } from "react/jsx-runtime";
|
|
37
41
|
function setupDraw(map) {
|
|
38
42
|
return new TerraDraw({
|
|
39
43
|
tracked: true,
|
|
@@ -124,9 +128,50 @@ function setupDraw(map) {
|
|
|
124
128
|
]
|
|
125
129
|
});
|
|
126
130
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
var ensureModeProperty = (features) => {
|
|
132
|
+
return features.map((feature) => {
|
|
133
|
+
var _a, _b;
|
|
134
|
+
if ((_a = feature.properties) == null ? void 0 : _a.mode)
|
|
135
|
+
return feature;
|
|
136
|
+
const type = (_b = feature.geometry) == null ? void 0 : _b.type;
|
|
137
|
+
const mode = type === "Point" ? "point" : type === "Polygon" ? "polygon" : type === "LineString" ? "linestring" : "unknown";
|
|
138
|
+
return __spreadProps(__spreadValues({}, feature), {
|
|
139
|
+
properties: __spreadProps(__spreadValues({}, feature.properties), { mode })
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
var IconButton = React.forwardRef(
|
|
144
|
+
(props, ref) => /* @__PURE__ */ jsx("button", __spreadValues({
|
|
145
|
+
ref,
|
|
146
|
+
type: "button",
|
|
147
|
+
className: tw`h-8 px-3 py-2 rounded-md focus:outline-none cursor-pointer text-md flex align-middle items-center gap-2 bg-gray-100 hover:bg-gray-200 text-gray-700 disabled:cursor-not-allowed disabled:bg-gray-100! disabled:opacity-50`
|
|
148
|
+
}, props))
|
|
149
|
+
);
|
|
150
|
+
var MapStyleSwitcher = ({
|
|
151
|
+
currentStyleIdx,
|
|
152
|
+
onStyleChange,
|
|
153
|
+
mapStyles
|
|
154
|
+
}) => /* @__PURE__ */ jsx("div", {
|
|
155
|
+
style: {
|
|
156
|
+
position: "absolute",
|
|
157
|
+
left: 12,
|
|
158
|
+
bottom: 12,
|
|
159
|
+
background: "rgba(255,255,255,0.95)",
|
|
160
|
+
padding: "8px",
|
|
161
|
+
borderRadius: "6px",
|
|
162
|
+
zIndex: 1e3,
|
|
163
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
164
|
+
},
|
|
165
|
+
children: /* @__PURE__ */ jsx("select", {
|
|
166
|
+
value: currentStyleIdx,
|
|
167
|
+
onChange: (e) => onStyleChange(Number(e.target.value)),
|
|
168
|
+
style: { fontSize: 14, padding: "4px" },
|
|
169
|
+
children: mapStyles.map((style, idx) => /* @__PURE__ */ jsx("option", {
|
|
170
|
+
value: idx,
|
|
171
|
+
children: style.text || `Style ${idx + 1}`
|
|
172
|
+
}, style.key || idx))
|
|
173
|
+
})
|
|
174
|
+
});
|
|
130
175
|
|
|
131
176
|
// src/components/setup-maplibre.tsx
|
|
132
177
|
import maplibregl from "maplibre-gl";
|
|
@@ -155,8 +200,97 @@ function setupMaplibreMap({
|
|
|
155
200
|
});
|
|
156
201
|
}
|
|
157
202
|
|
|
203
|
+
// src/components/map-buttons/map-buttons.tsx
|
|
204
|
+
import { useEffect, useState, useCallback, useMemo } from "react";
|
|
205
|
+
|
|
158
206
|
// src/components/icon-buttons/icons.tsx
|
|
159
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
207
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
208
|
+
var PencilOpenIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
209
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
210
|
+
width: "24",
|
|
211
|
+
height: "24",
|
|
212
|
+
viewBox: "0 0 24 24",
|
|
213
|
+
fill: "none",
|
|
214
|
+
stroke: "currentColor",
|
|
215
|
+
strokeWidth: "1.5",
|
|
216
|
+
strokeLinecap: "round",
|
|
217
|
+
strokeLinejoin: "round",
|
|
218
|
+
children: [
|
|
219
|
+
/* @__PURE__ */ jsx2("path", {
|
|
220
|
+
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"
|
|
221
|
+
}),
|
|
222
|
+
/* @__PURE__ */ jsx2("path", {
|
|
223
|
+
d: "m15 5 4 4"
|
|
224
|
+
})
|
|
225
|
+
]
|
|
226
|
+
});
|
|
227
|
+
var PencilCloseIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
228
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
229
|
+
width: "24",
|
|
230
|
+
height: "24",
|
|
231
|
+
viewBox: "0 0 24 24",
|
|
232
|
+
fill: "none",
|
|
233
|
+
stroke: "currentColor",
|
|
234
|
+
strokeWidth: "1.5",
|
|
235
|
+
strokeLinecap: "round",
|
|
236
|
+
strokeLinejoin: "round",
|
|
237
|
+
children: [
|
|
238
|
+
/* @__PURE__ */ jsx2("path", {
|
|
239
|
+
d: "m10 10-6.157 6.162a2 2 0 0 0-.5.833l-1.322 4.36a.5.5 0 0 0 .622.624l4.358-1.323a2 2 0 0 0 .83-.5L14 13.982"
|
|
240
|
+
}),
|
|
241
|
+
/* @__PURE__ */ jsx2("path", {
|
|
242
|
+
d: "m12.829 7.172 4.359-4.346a1 1 0 1 1 3.986 3.986l-4.353 4.353"
|
|
243
|
+
}),
|
|
244
|
+
/* @__PURE__ */ jsx2("path", {
|
|
245
|
+
d: "m15 5 4 4"
|
|
246
|
+
}),
|
|
247
|
+
/* @__PURE__ */ jsx2("path", {
|
|
248
|
+
d: "m2 2 20 20"
|
|
249
|
+
})
|
|
250
|
+
]
|
|
251
|
+
});
|
|
252
|
+
var LocateIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
253
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
254
|
+
width: "24",
|
|
255
|
+
height: "24",
|
|
256
|
+
viewBox: "0 0 24 24",
|
|
257
|
+
fill: "none",
|
|
258
|
+
stroke: "currentColor",
|
|
259
|
+
strokeWidth: "1.5",
|
|
260
|
+
strokeLinecap: "round",
|
|
261
|
+
strokeLinejoin: "round",
|
|
262
|
+
children: [
|
|
263
|
+
/* @__PURE__ */ jsx2("line", {
|
|
264
|
+
x1: "2",
|
|
265
|
+
x2: "5",
|
|
266
|
+
y1: "12",
|
|
267
|
+
y2: "12"
|
|
268
|
+
}),
|
|
269
|
+
/* @__PURE__ */ jsx2("line", {
|
|
270
|
+
x1: "19",
|
|
271
|
+
x2: "22",
|
|
272
|
+
y1: "12",
|
|
273
|
+
y2: "12"
|
|
274
|
+
}),
|
|
275
|
+
/* @__PURE__ */ jsx2("line", {
|
|
276
|
+
x1: "12",
|
|
277
|
+
x2: "12",
|
|
278
|
+
y1: "2",
|
|
279
|
+
y2: "5"
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ jsx2("line", {
|
|
282
|
+
x1: "12",
|
|
283
|
+
x2: "12",
|
|
284
|
+
y1: "19",
|
|
285
|
+
y2: "22"
|
|
286
|
+
}),
|
|
287
|
+
/* @__PURE__ */ jsx2("circle", {
|
|
288
|
+
cx: "12",
|
|
289
|
+
cy: "12",
|
|
290
|
+
r: "7"
|
|
291
|
+
})
|
|
292
|
+
]
|
|
293
|
+
});
|
|
160
294
|
var SelectIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
161
295
|
xmlns: "http://www.w3.org/2000/svg",
|
|
162
296
|
width: "24",
|
|
@@ -168,10 +302,10 @@ var SelectIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
|
168
302
|
strokeLinecap: "round",
|
|
169
303
|
strokeLinejoin: "round",
|
|
170
304
|
children: [
|
|
171
|
-
/* @__PURE__ */
|
|
305
|
+
/* @__PURE__ */ jsx2("path", {
|
|
172
306
|
d: "M12.586 12.586 19 19"
|
|
173
307
|
}),
|
|
174
|
-
/* @__PURE__ */
|
|
308
|
+
/* @__PURE__ */ jsx2("path", {
|
|
175
309
|
d: "M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z"
|
|
176
310
|
})
|
|
177
311
|
]
|
|
@@ -187,150 +321,143 @@ var PointIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
|
187
321
|
strokeLinecap: "round",
|
|
188
322
|
strokeLinejoin: "round",
|
|
189
323
|
children: [
|
|
190
|
-
/* @__PURE__ */
|
|
324
|
+
/* @__PURE__ */ jsx2("path", {
|
|
191
325
|
d: "M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"
|
|
192
326
|
}),
|
|
193
|
-
/* @__PURE__ */
|
|
327
|
+
/* @__PURE__ */ jsx2("circle", {
|
|
194
328
|
cx: "12",
|
|
195
329
|
cy: "10",
|
|
196
330
|
r: "3"
|
|
197
331
|
})
|
|
198
332
|
]
|
|
199
333
|
});
|
|
200
|
-
var LineIcon = () => /* @__PURE__ */
|
|
334
|
+
var LineIcon = () => /* @__PURE__ */ jsx2("svg", {
|
|
201
335
|
width: "16",
|
|
202
336
|
height: "16",
|
|
203
337
|
viewBox: "0 0 24 24",
|
|
204
338
|
fill: "none",
|
|
205
339
|
stroke: "currentColor",
|
|
206
340
|
strokeWidth: "2",
|
|
207
|
-
children: /* @__PURE__ */
|
|
341
|
+
children: /* @__PURE__ */ jsx2("line", {
|
|
208
342
|
x1: "4",
|
|
209
343
|
y1: "20",
|
|
210
344
|
x2: "20",
|
|
211
345
|
y2: "4"
|
|
212
346
|
})
|
|
213
347
|
});
|
|
214
|
-
var PolygonIcon = () => /* @__PURE__ */
|
|
348
|
+
var PolygonIcon = () => /* @__PURE__ */ jsx2("svg", {
|
|
215
349
|
width: "16",
|
|
216
350
|
height: "16",
|
|
217
351
|
viewBox: "0 0 24 24",
|
|
218
352
|
fill: "none",
|
|
219
353
|
stroke: "currentColor",
|
|
220
354
|
strokeWidth: "2",
|
|
221
|
-
children: /* @__PURE__ */
|
|
355
|
+
children: /* @__PURE__ */ jsx2("polygon", {
|
|
222
356
|
points: "12,2 22,8 18,22 6,22 2,8"
|
|
223
357
|
})
|
|
224
358
|
});
|
|
225
|
-
var
|
|
359
|
+
var RectangleIcon = () => /* @__PURE__ */ jsx2("svg", {
|
|
226
360
|
width: "16",
|
|
227
361
|
height: "16",
|
|
228
362
|
viewBox: "0 0 24 24",
|
|
229
363
|
fill: "none",
|
|
230
364
|
stroke: "currentColor",
|
|
231
365
|
strokeWidth: "2",
|
|
232
|
-
children: /* @__PURE__ */
|
|
366
|
+
children: /* @__PURE__ */ jsx2("rect", {
|
|
367
|
+
x: "4",
|
|
368
|
+
y: "4",
|
|
369
|
+
width: "16",
|
|
370
|
+
height: "16"
|
|
371
|
+
})
|
|
372
|
+
});
|
|
373
|
+
var CircleIcon = () => /* @__PURE__ */ jsx2("svg", {
|
|
374
|
+
width: "16",
|
|
375
|
+
height: "16",
|
|
376
|
+
viewBox: "0 0 24 24",
|
|
377
|
+
fill: "none",
|
|
378
|
+
stroke: "currentColor",
|
|
379
|
+
strokeWidth: "2",
|
|
380
|
+
children: /* @__PURE__ */ jsx2("circle", {
|
|
381
|
+
cx: "12",
|
|
382
|
+
cy: "12",
|
|
383
|
+
r: "10"
|
|
384
|
+
})
|
|
385
|
+
});
|
|
386
|
+
var FreeHandIcon = () => /* @__PURE__ */ jsx2("svg", {
|
|
387
|
+
width: "16",
|
|
388
|
+
height: "16",
|
|
389
|
+
viewBox: "0 0 24 24",
|
|
390
|
+
fill: "none",
|
|
391
|
+
stroke: "currentColor",
|
|
392
|
+
strokeWidth: "2",
|
|
393
|
+
children: /* @__PURE__ */ jsx2("path", {
|
|
394
|
+
d: "M3 16c1-3 4-5 7-4 3 1 5 3 7 2 2-1 3-4 1-6-1-2-4-2-6-1"
|
|
395
|
+
})
|
|
396
|
+
});
|
|
397
|
+
var DeleteIcon = () => /* @__PURE__ */ jsx2("svg", {
|
|
398
|
+
width: "16",
|
|
399
|
+
height: "16",
|
|
400
|
+
viewBox: "0 0 24 24",
|
|
401
|
+
fill: "none",
|
|
402
|
+
stroke: "currentColor",
|
|
403
|
+
strokeWidth: "2",
|
|
404
|
+
children: /* @__PURE__ */ jsx2("path", {
|
|
233
405
|
d: "M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
|
|
234
406
|
})
|
|
235
407
|
});
|
|
236
408
|
|
|
237
|
-
// src/components/map-button/
|
|
238
|
-
import { jsx as
|
|
409
|
+
// src/components/map-button/map-button.tsx
|
|
410
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
411
|
+
var BUTTON_STYLE = {
|
|
412
|
+
display: "flex",
|
|
413
|
+
justifyContent: "center",
|
|
414
|
+
alignItems: "center",
|
|
415
|
+
width: 30,
|
|
416
|
+
height: 30,
|
|
417
|
+
padding: 0,
|
|
418
|
+
borderRadius: 4
|
|
419
|
+
};
|
|
239
420
|
var MapButton = ({
|
|
240
421
|
mode,
|
|
241
422
|
currentMode,
|
|
242
|
-
|
|
423
|
+
onClick,
|
|
243
424
|
icon,
|
|
244
|
-
tooltip
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
},
|
|
260
|
-
children: icon
|
|
261
|
-
});
|
|
262
|
-
};
|
|
263
|
-
var MapButton_default = MapButton;
|
|
425
|
+
tooltip,
|
|
426
|
+
disabled
|
|
427
|
+
}) => /* @__PURE__ */ jsx3(IconButton, {
|
|
428
|
+
type: "button",
|
|
429
|
+
title: tooltip,
|
|
430
|
+
disabled,
|
|
431
|
+
onClick: () => !disabled && onClick(mode != null ? mode : ""),
|
|
432
|
+
style: __spreadProps(__spreadValues({}, BUTTON_STYLE), {
|
|
433
|
+
backgroundColor: disabled ? "#d3d3d3" : currentMode === mode ? "#02cf87" : "#f0f0f0",
|
|
434
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
435
|
+
opacity: disabled ? 0.6 : 1
|
|
436
|
+
}),
|
|
437
|
+
children: icon
|
|
438
|
+
});
|
|
439
|
+
var map_button_default = MapButton;
|
|
264
440
|
|
|
265
|
-
// src/components/map-buttons/
|
|
266
|
-
import { jsx as
|
|
267
|
-
|
|
441
|
+
// src/components/map-buttons/map-buttons.tsx
|
|
442
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
443
|
+
function MapButtons({
|
|
268
444
|
mode,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
return /* @__PURE__ */ jsxs2("div", {
|
|
272
|
-
style: {
|
|
273
|
-
position: "absolute",
|
|
274
|
-
top: "10px",
|
|
275
|
-
left: "10px",
|
|
276
|
-
display: "flex",
|
|
277
|
-
flexDirection: "column",
|
|
278
|
-
gap: "6px",
|
|
279
|
-
zIndex: 1e3,
|
|
280
|
-
backgroundColor: "rgba(255, 255, 255, 0.9)",
|
|
281
|
-
padding: "8px",
|
|
282
|
-
borderRadius: "6px",
|
|
283
|
-
boxShadow: "0 2px 6px rgba(0,0,0,0.2)"
|
|
284
|
-
},
|
|
285
|
-
children: [
|
|
286
|
-
/* @__PURE__ */ jsx3(MapButton_default, {
|
|
287
|
-
mode: "select",
|
|
288
|
-
icon: /* @__PURE__ */ jsx3(SelectIcon, {}),
|
|
289
|
-
currentMode: mode,
|
|
290
|
-
changeMode,
|
|
291
|
-
tooltip: "Select"
|
|
292
|
-
}),
|
|
293
|
-
/* @__PURE__ */ jsx3(MapButton_default, {
|
|
294
|
-
mode: "point",
|
|
295
|
-
icon: /* @__PURE__ */ jsx3(PointIcon, {}),
|
|
296
|
-
currentMode: mode,
|
|
297
|
-
changeMode,
|
|
298
|
-
tooltip: "Point"
|
|
299
|
-
}),
|
|
300
|
-
/* @__PURE__ */ jsx3(MapButton_default, {
|
|
301
|
-
mode: "linestring",
|
|
302
|
-
icon: /* @__PURE__ */ jsx3(LineIcon, {}),
|
|
303
|
-
currentMode: mode,
|
|
304
|
-
changeMode,
|
|
305
|
-
tooltip: "Line"
|
|
306
|
-
}),
|
|
307
|
-
/* @__PURE__ */ jsx3(MapButton_default, {
|
|
308
|
-
mode: "polygon",
|
|
309
|
-
icon: /* @__PURE__ */ jsx3(PolygonIcon, {}),
|
|
310
|
-
currentMode: mode,
|
|
311
|
-
changeMode,
|
|
312
|
-
tooltip: "Polygon"
|
|
313
|
-
})
|
|
314
|
-
]
|
|
315
|
-
});
|
|
316
|
-
};
|
|
317
|
-
var MapButtons_default = MapButtons;
|
|
318
|
-
|
|
319
|
-
// src/components/icon-buttons/ClearButton.tsx
|
|
320
|
-
import { useState, useEffect } from "react";
|
|
321
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
322
|
-
var ClearButton = ({
|
|
445
|
+
setMode,
|
|
446
|
+
onClick,
|
|
323
447
|
draw,
|
|
324
|
-
onFeaturesChange
|
|
325
|
-
|
|
448
|
+
onFeaturesChange,
|
|
449
|
+
isMultiple = true,
|
|
450
|
+
autoFocus
|
|
451
|
+
}) {
|
|
452
|
+
const [expanded, setExpanded] = useState(false);
|
|
326
453
|
const [hasFeatures, setHasFeatures] = useState(false);
|
|
454
|
+
const updateHasFeatures = useCallback(
|
|
455
|
+
() => setHasFeatures(draw.getSnapshot().length > 0),
|
|
456
|
+
[draw]
|
|
457
|
+
);
|
|
327
458
|
useEffect(() => {
|
|
328
459
|
if (!draw)
|
|
329
460
|
return;
|
|
330
|
-
const updateHasFeatures = () => {
|
|
331
|
-
const snapshot = draw.getSnapshot();
|
|
332
|
-
setHasFeatures(snapshot.length > 0);
|
|
333
|
-
};
|
|
334
461
|
draw.on("finish", updateHasFeatures);
|
|
335
462
|
draw.on("change", updateHasFeatures);
|
|
336
463
|
updateHasFeatures();
|
|
@@ -338,128 +465,242 @@ var ClearButton = ({
|
|
|
338
465
|
draw.off("finish", updateHasFeatures);
|
|
339
466
|
draw.off("change", updateHasFeatures);
|
|
340
467
|
};
|
|
341
|
-
}, [draw]);
|
|
342
|
-
const
|
|
343
|
-
if (!
|
|
468
|
+
}, [draw, updateHasFeatures]);
|
|
469
|
+
const handleGeolocation = useCallback(() => {
|
|
470
|
+
if (!("geolocation" in navigator)) {
|
|
471
|
+
alert("Geolocation is not supported in this browser.");
|
|
344
472
|
return;
|
|
473
|
+
}
|
|
474
|
+
navigator.geolocation.getCurrentPosition(
|
|
475
|
+
(pos) => {
|
|
476
|
+
const coords = [
|
|
477
|
+
pos.coords.longitude,
|
|
478
|
+
pos.coords.latitude
|
|
479
|
+
];
|
|
480
|
+
const pt = {
|
|
481
|
+
type: "Feature",
|
|
482
|
+
geometry: { type: "Point", coordinates: coords },
|
|
483
|
+
properties: { mode: "point", source: "geolocation" }
|
|
484
|
+
};
|
|
485
|
+
if (!isMultiple)
|
|
486
|
+
draw.clear();
|
|
487
|
+
draw.addFeatures([pt]);
|
|
488
|
+
onFeaturesChange == null ? void 0 : onFeaturesChange(draw.getSnapshot());
|
|
489
|
+
autoFocus == null ? void 0 : autoFocus([pt]);
|
|
490
|
+
},
|
|
491
|
+
(error) => {
|
|
492
|
+
alert("Error getting geolocation");
|
|
493
|
+
console.error(error);
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
setMode("current-location");
|
|
497
|
+
}, [draw, isMultiple, onFeaturesChange, autoFocus]);
|
|
498
|
+
const handleClear = useCallback(() => {
|
|
345
499
|
draw.clear();
|
|
346
500
|
setHasFeatures(false);
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
501
|
+
setMode("static");
|
|
502
|
+
onFeaturesChange == null ? void 0 : onFeaturesChange([]);
|
|
503
|
+
}, [draw, onFeaturesChange]);
|
|
504
|
+
const buttons = useMemo(
|
|
505
|
+
() => [
|
|
506
|
+
{
|
|
507
|
+
icon: /* @__PURE__ */ jsx4(LocateIcon, {}),
|
|
508
|
+
mode: "current-location",
|
|
509
|
+
onClick: handleGeolocation,
|
|
510
|
+
tooltip: "Use current location"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
icon: /* @__PURE__ */ jsx4(SelectIcon, {}),
|
|
514
|
+
mode: "select",
|
|
515
|
+
onClick,
|
|
516
|
+
tooltip: "Select"
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
icon: /* @__PURE__ */ jsx4(PointIcon, {}),
|
|
520
|
+
mode: "point",
|
|
521
|
+
onClick,
|
|
522
|
+
tooltip: "Point"
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
icon: /* @__PURE__ */ jsx4(LineIcon, {}),
|
|
526
|
+
mode: "linestring",
|
|
527
|
+
onClick,
|
|
528
|
+
tooltip: "Linestring"
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
icon: /* @__PURE__ */ jsx4(PolygonIcon, {}),
|
|
532
|
+
mode: "polygon",
|
|
533
|
+
onClick,
|
|
534
|
+
tooltip: "Polygon"
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
icon: /* @__PURE__ */ jsx4(RectangleIcon, {}),
|
|
538
|
+
mode: "rectangle",
|
|
539
|
+
onClick,
|
|
540
|
+
tooltip: "Reactangle"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
icon: /* @__PURE__ */ jsx4(CircleIcon, {}),
|
|
544
|
+
mode: "circle",
|
|
545
|
+
onClick,
|
|
546
|
+
tooltip: "Circle"
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
icon: /* @__PURE__ */ jsx4(FreeHandIcon, {}),
|
|
550
|
+
mode: "freehand",
|
|
551
|
+
onClick,
|
|
552
|
+
tooltip: "Freehand"
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
icon: /* @__PURE__ */ jsx4(DeleteIcon, {}),
|
|
556
|
+
mode: "clear",
|
|
557
|
+
onClick: handleClear,
|
|
558
|
+
tooltip: "Clear all features",
|
|
559
|
+
disabled: !hasFeatures
|
|
560
|
+
}
|
|
561
|
+
],
|
|
562
|
+
[onClick, handleGeolocation, handleClear, hasFeatures]
|
|
563
|
+
);
|
|
564
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
354
565
|
style: {
|
|
566
|
+
position: "absolute",
|
|
567
|
+
top: 10,
|
|
568
|
+
left: 10,
|
|
355
569
|
display: "flex",
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
padding:
|
|
361
|
-
borderRadius:
|
|
362
|
-
|
|
363
|
-
cursor: hasFeatures ? "pointer" : "not-allowed"
|
|
570
|
+
flexDirection: "column",
|
|
571
|
+
gap: 6,
|
|
572
|
+
zIndex: 1e3,
|
|
573
|
+
backgroundColor: "rgba(255,255,255,0.9)",
|
|
574
|
+
padding: 8,
|
|
575
|
+
borderRadius: 6,
|
|
576
|
+
boxShadow: "0 2px 6px rgba(0,0,0,0.2)"
|
|
364
577
|
},
|
|
365
|
-
children:
|
|
578
|
+
children: [
|
|
579
|
+
/* @__PURE__ */ jsx4(IconButton, {
|
|
580
|
+
onClick: () => setExpanded((v) => !v),
|
|
581
|
+
style: {
|
|
582
|
+
display: "flex",
|
|
583
|
+
justifyContent: "center",
|
|
584
|
+
alignItems: "center",
|
|
585
|
+
width: 30,
|
|
586
|
+
height: 30,
|
|
587
|
+
padding: 0,
|
|
588
|
+
borderRadius: 4,
|
|
589
|
+
backgroundColor: "#d3d3d3"
|
|
590
|
+
},
|
|
591
|
+
title: "Expand or collapse tools",
|
|
592
|
+
children: expanded ? /* @__PURE__ */ jsx4(PencilCloseIcon, {}) : /* @__PURE__ */ jsx4(PencilOpenIcon, {})
|
|
593
|
+
}),
|
|
594
|
+
expanded && /* @__PURE__ */ jsx4("div", {
|
|
595
|
+
style: { display: "flex", flexDirection: "column", gap: 6 },
|
|
596
|
+
children: buttons.map((btn, i) => /* @__PURE__ */ jsx4(map_button_default, {
|
|
597
|
+
icon: btn.icon,
|
|
598
|
+
mode: btn.mode,
|
|
599
|
+
currentMode: mode,
|
|
600
|
+
onClick: btn.onClick,
|
|
601
|
+
tooltip: btn.tooltip,
|
|
602
|
+
disabled: btn.disabled
|
|
603
|
+
}, i))
|
|
604
|
+
})
|
|
605
|
+
]
|
|
366
606
|
});
|
|
367
|
-
}
|
|
368
|
-
var
|
|
607
|
+
}
|
|
608
|
+
var map_buttons_default = MapButtons;
|
|
369
609
|
|
|
370
610
|
// src/components/map.tsx
|
|
371
|
-
import { defaultMapStyles } from "@biodiv-platform/naksha-commons";
|
|
372
611
|
import bbox from "@turf/bbox";
|
|
373
|
-
import {
|
|
374
|
-
|
|
375
|
-
return features.map((feature) => {
|
|
376
|
-
var _a, _b;
|
|
377
|
-
if ((_a = feature.properties) == null ? void 0 : _a.mode)
|
|
378
|
-
return feature;
|
|
379
|
-
const geometryType = (_b = feature.geometry) == null ? void 0 : _b.type;
|
|
380
|
-
const mode = geometryType === "Point" ? "point" : geometryType === "Polygon" ? "polygon" : geometryType === "LineString" ? "linestring" : "unknown";
|
|
381
|
-
return __spreadProps(__spreadValues({}, feature), {
|
|
382
|
-
properties: __spreadProps(__spreadValues({}, feature.properties), { mode })
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
};
|
|
612
|
+
import { defaultMapStyles } from "@biodiv-platform/naksha-commons";
|
|
613
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
386
614
|
var Map = (props) => {
|
|
615
|
+
var _a;
|
|
616
|
+
console.info("Rendering Naksha Maplibre Draw Map Component");
|
|
387
617
|
const mapRef = useRef(null);
|
|
388
618
|
const [map, setMap] = useState2();
|
|
389
619
|
const [mode, setMode] = useState2("static");
|
|
390
620
|
const [draw, setDraw] = useState2();
|
|
391
|
-
const
|
|
392
|
-
const
|
|
621
|
+
const { isMultiple = true, features = [], onFeaturesChange } = props;
|
|
622
|
+
const [selectedMapStyleIdx, setSelectedMapStyleIdx] = useState2(
|
|
623
|
+
(props == null ? void 0 : props.mapStyle) || 0
|
|
624
|
+
);
|
|
625
|
+
const mapTile = props.mapStyles ? props.mapStyles : defaultMapStyles;
|
|
626
|
+
const mapStyle = (_a = mapTile[selectedMapStyleIdx]) == null ? void 0 : _a.style;
|
|
627
|
+
const autoFocus = useCallback2(
|
|
628
|
+
(features2) => {
|
|
629
|
+
if (!(features2 == null ? void 0 : features2.length) || !map)
|
|
630
|
+
return;
|
|
631
|
+
const _bbox = bbox({ type: "FeatureCollection", features: features2 });
|
|
632
|
+
map.fitBounds(_bbox, {
|
|
633
|
+
padding: 40,
|
|
634
|
+
duration: 1e3,
|
|
635
|
+
maxZoom: 15
|
|
636
|
+
});
|
|
637
|
+
},
|
|
638
|
+
[map]
|
|
639
|
+
);
|
|
640
|
+
const mapStyleConfig = mapTile[selectedMapStyleIdx];
|
|
393
641
|
useEffect2(() => {
|
|
394
|
-
var
|
|
642
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
395
643
|
const maplibreMap = setupMaplibreMap({
|
|
396
644
|
containerId: "maplibre-map",
|
|
397
|
-
latitude: (_b = (
|
|
645
|
+
latitude: (_b = (_a2 = props.defaultViewState) == null ? void 0 : _a2.latitude) != null ? _b : 0,
|
|
398
646
|
longitude: (_d = (_c = props.defaultViewState) == null ? void 0 : _c.longitude) != null ? _d : 0,
|
|
399
647
|
zoom: (_f = (_e = props.defaultViewState) == null ? void 0 : _e.zoom) != null ? _f : 0,
|
|
400
648
|
pitch: (_h = (_g = props.defaultViewState) == null ? void 0 : _g.pitch) != null ? _h : 0,
|
|
401
649
|
bearing: (_j = (_i = props.defaultViewState) == null ? void 0 : _i.bearing) != null ? _j : 0,
|
|
402
650
|
mapstyle: mapStyle
|
|
403
651
|
});
|
|
652
|
+
if ("maxZoom" in mapStyleConfig && mapStyleConfig.maxZoom) {
|
|
653
|
+
maplibreMap.setMaxZoom(mapStyleConfig.maxZoom);
|
|
654
|
+
}
|
|
404
655
|
const navControl = new maplibregl2.NavigationControl({
|
|
405
656
|
showCompass: true,
|
|
406
657
|
showZoom: true,
|
|
407
658
|
visualizePitch: true
|
|
408
659
|
});
|
|
660
|
+
const fullscreen = new maplibregl2.FullscreenControl({});
|
|
409
661
|
maplibreMap.addControl(navControl, "bottom-right");
|
|
662
|
+
maplibreMap.addControl(fullscreen, "bottom-right");
|
|
410
663
|
maplibreMap.once("style.load", () => setMap(maplibreMap));
|
|
411
664
|
return () => {
|
|
412
|
-
|
|
413
|
-
maplibreMap.removeControl(navControl);
|
|
414
|
-
}
|
|
665
|
+
maplibreMap.removeControl(navControl);
|
|
415
666
|
};
|
|
416
|
-
}, []);
|
|
417
|
-
const
|
|
418
|
-
(
|
|
419
|
-
if (!(features == null ? void 0 : features.length) || !map)
|
|
420
|
-
return;
|
|
421
|
-
const _bbox = bbox({
|
|
422
|
-
type: "FeatureCollection",
|
|
423
|
-
features
|
|
424
|
-
});
|
|
425
|
-
map.fitBounds(_bbox, { padding: 40, duration: 1e3 });
|
|
426
|
-
},
|
|
427
|
-
[map]
|
|
667
|
+
}, [mapStyle, props.defaultViewState]);
|
|
668
|
+
const filterUserFeatures = (features2) => features2.filter(
|
|
669
|
+
(f) => f.geometry.type !== "Point" || f.properties.mode !== "static" && f.properties.mode !== "select"
|
|
428
670
|
);
|
|
429
671
|
useEffect2(() => {
|
|
430
|
-
var _a;
|
|
431
672
|
if (!map)
|
|
432
673
|
return;
|
|
433
674
|
const terraDraw = setupDraw(map);
|
|
434
675
|
terraDraw.start();
|
|
435
676
|
setDraw(terraDraw);
|
|
436
677
|
const handleChange = () => {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
678
|
+
let snapshot = terraDraw.getSnapshot();
|
|
679
|
+
let userFeatures = filterUserFeatures(snapshot);
|
|
680
|
+
if (!isMultiple && userFeatures.length > 1) {
|
|
681
|
+
const lastFeature = userFeatures.at(-1);
|
|
682
|
+
const toRemove = userFeatures.slice(0, -1).map((f) => f.id).filter((id) => Boolean(id));
|
|
683
|
+
if (toRemove.length > 0) {
|
|
684
|
+
try {
|
|
685
|
+
terraDraw.removeFeatures(toRemove);
|
|
686
|
+
} catch (e) {
|
|
687
|
+
console.warn("removeFeatures failed", e);
|
|
688
|
+
}
|
|
447
689
|
}
|
|
690
|
+
userFeatures = [lastFeature];
|
|
448
691
|
}
|
|
449
|
-
|
|
450
|
-
autoFocus(
|
|
692
|
+
onFeaturesChange == null ? void 0 : onFeaturesChange(userFeatures);
|
|
693
|
+
autoFocus(userFeatures);
|
|
694
|
+
setMode("static");
|
|
451
695
|
};
|
|
452
696
|
terraDraw.on("finish", handleChange);
|
|
453
|
-
if (
|
|
697
|
+
if (features.length) {
|
|
454
698
|
setTimeout(() => {
|
|
455
699
|
if (terraDraw.getSnapshot().length === 0) {
|
|
456
|
-
|
|
457
|
-
let
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
terraDraw.addFeatures(initialFeatures);
|
|
462
|
-
autoFocus(initialFeatures);
|
|
700
|
+
let withMode = ensureModeProperty(features);
|
|
701
|
+
let initial = !isMultiple && withMode.length > 1 ? [withMode.at(-1)] : withMode;
|
|
702
|
+
terraDraw.addFeatures(initial);
|
|
703
|
+
autoFocus(initial);
|
|
463
704
|
}
|
|
464
705
|
});
|
|
465
706
|
}
|
|
@@ -467,45 +708,37 @@ var Map = (props) => {
|
|
|
467
708
|
terraDraw.off("finish", handleChange);
|
|
468
709
|
terraDraw.stop();
|
|
469
710
|
};
|
|
470
|
-
}, [map, isMultiple, autoFocus]);
|
|
471
|
-
const changeMode =
|
|
711
|
+
}, [map, isMultiple, autoFocus, features, onFeaturesChange]);
|
|
712
|
+
const changeMode = useCallback2(
|
|
472
713
|
(newMode) => {
|
|
473
714
|
draw == null ? void 0 : draw.setMode(newMode);
|
|
474
715
|
setMode(newMode);
|
|
475
716
|
},
|
|
476
717
|
[draw]
|
|
477
718
|
);
|
|
478
|
-
|
|
719
|
+
const handleStyleChange = (idx) => {
|
|
720
|
+
setSelectedMapStyleIdx(idx);
|
|
721
|
+
};
|
|
722
|
+
return /* @__PURE__ */ jsxs3("div", {
|
|
479
723
|
ref: mapRef,
|
|
480
724
|
id: "maplibre-map",
|
|
481
|
-
style: { width: "100%", height: "100%" },
|
|
482
|
-
children:
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
padding: "8px",
|
|
499
|
-
borderRadius: "6px",
|
|
500
|
-
boxShadow: "0 2px 6px rgba(0,0,0,0.2)"
|
|
501
|
-
},
|
|
502
|
-
children: /* @__PURE__ */ jsx5(ClearButton_default, {
|
|
503
|
-
draw,
|
|
504
|
-
onFeaturesChange: props.onFeaturesChange
|
|
505
|
-
})
|
|
506
|
-
})
|
|
507
|
-
]
|
|
508
|
-
})
|
|
725
|
+
style: { width: "100%", height: "100%", position: "relative" },
|
|
726
|
+
children: [
|
|
727
|
+
/* @__PURE__ */ jsx5(MapStyleSwitcher, {
|
|
728
|
+
currentStyleIdx: selectedMapStyleIdx,
|
|
729
|
+
onStyleChange: handleStyleChange,
|
|
730
|
+
mapStyles: mapTile
|
|
731
|
+
}),
|
|
732
|
+
draw && /* @__PURE__ */ jsx5(map_buttons_default, {
|
|
733
|
+
mode,
|
|
734
|
+
setMode,
|
|
735
|
+
onClick: changeMode,
|
|
736
|
+
draw,
|
|
737
|
+
onFeaturesChange,
|
|
738
|
+
isMultiple,
|
|
739
|
+
autoFocus
|
|
740
|
+
})
|
|
741
|
+
]
|
|
509
742
|
});
|
|
510
743
|
};
|
|
511
744
|
var map_default = Map;
|