@biodiv-platform/naksha-maplibre-draw 5.0.9 → 5.0.11

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 CHANGED
@@ -1,783 +1 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
-
21
- // src/components/map.tsx
22
- import maplibregl2 from "maplibre-gl";
23
- import { useRef, useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
24
-
25
- // src/components/setup-draw.tsx
26
- import {
27
- TerraDraw,
28
- TerraDrawSelectMode,
29
- TerraDrawPointMode,
30
- TerraDrawLineStringMode,
31
- TerraDrawPolygonMode,
32
- TerraDrawCircleMode,
33
- TerraDrawFreehandMode,
34
- ValidateNotSelfIntersecting,
35
- TerraDrawRectangleMode
36
- } from "terra-draw";
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";
41
- function setupDraw(map) {
42
- return new TerraDraw({
43
- tracked: true,
44
- adapter: new TerraDrawMapLibreGLAdapter({
45
- map,
46
- coordinatePrecision: 9
47
- }),
48
- modes: [
49
- new TerraDrawSelectMode({
50
- flags: {
51
- polygon: {
52
- feature: {
53
- scaleable: true,
54
- rotateable: true,
55
- draggable: true,
56
- coordinates: {
57
- midpoints: true,
58
- draggable: true,
59
- deletable: true
60
- }
61
- }
62
- },
63
- linestring: {
64
- feature: {
65
- draggable: true,
66
- coordinates: {
67
- midpoints: true,
68
- draggable: true,
69
- deletable: true
70
- }
71
- }
72
- },
73
- circle: {
74
- feature: {
75
- draggable: true
76
- }
77
- },
78
- point: {
79
- feature: {
80
- draggable: true
81
- }
82
- },
83
- rectangle: {
84
- feature: {
85
- draggable: true,
86
- coordinates: {
87
- resizable: "opposite"
88
- }
89
- }
90
- },
91
- freehand: {
92
- feature: {
93
- draggable: true
94
- }
95
- }
96
- }
97
- }),
98
- new TerraDrawPointMode(),
99
- new TerraDrawLineStringMode({
100
- validation: (feature, { updateType }) => {
101
- if (updateType === "finish" || updateType === "commit") {
102
- return ValidateNotSelfIntersecting(feature);
103
- }
104
- return {
105
- valid: true
106
- };
107
- }
108
- }),
109
- new TerraDrawRectangleMode(),
110
- new TerraDrawPolygonMode({
111
- pointerDistance: 30,
112
- validation: (feature, { updateType }) => {
113
- if (updateType === "finish" || updateType === "commit") {
114
- return ValidateNotSelfIntersecting(feature);
115
- }
116
- return {
117
- valid: true
118
- };
119
- }
120
- }),
121
- new TerraDrawCircleMode(),
122
- new TerraDrawFreehandMode({
123
- pointerDistance: 5,
124
- validation: (feature) => {
125
- return ValidateNotSelfIntersecting(feature);
126
- }
127
- })
128
- ]
129
- });
130
- }
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
- });
175
-
176
- // src/components/setup-maplibre.tsx
177
- import maplibregl from "maplibre-gl";
178
- function setupMaplibreMap({
179
- containerId,
180
- latitude = 0,
181
- longitude = 0,
182
- zoom,
183
- pitch,
184
- bearing,
185
- mapstyle
186
- }) {
187
- if (maplibregl.getRTLTextPluginStatus() === "unavailable") {
188
- maplibregl.setRTLTextPlugin(
189
- "https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",
190
- true
191
- );
192
- }
193
- return new maplibregl.Map({
194
- container: containerId,
195
- style: mapstyle,
196
- center: { lat: latitude, lng: longitude },
197
- zoom,
198
- pitch,
199
- bearing
200
- });
201
- }
202
-
203
- // src/components/map-buttons/map-buttons.tsx
204
- import { useEffect, useState, useCallback, useMemo } from "react";
205
-
206
- // src/components/icon-buttons/icons.tsx
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
- });
294
- var SelectIcon = () => /* @__PURE__ */ jsxs("svg", {
295
- xmlns: "http://www.w3.org/2000/svg",
296
- width: "24",
297
- height: "24",
298
- viewBox: "0 0 24 24",
299
- fill: "none",
300
- stroke: "currentColor",
301
- strokeWidth: "1.5",
302
- strokeLinecap: "round",
303
- strokeLinejoin: "round",
304
- children: [
305
- /* @__PURE__ */ jsx2("path", {
306
- d: "M12.586 12.586 19 19"
307
- }),
308
- /* @__PURE__ */ jsx2("path", {
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"
310
- })
311
- ]
312
- });
313
- var PointIcon = () => /* @__PURE__ */ jsxs("svg", {
314
- xmlns: "http://www.w3.org/2000/svg",
315
- width: "24",
316
- height: "24",
317
- viewBox: "0 0 24 24",
318
- fill: "none",
319
- stroke: "currentColor",
320
- strokeWidth: "1.5",
321
- strokeLinecap: "round",
322
- strokeLinejoin: "round",
323
- children: [
324
- /* @__PURE__ */ jsx2("path", {
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"
326
- }),
327
- /* @__PURE__ */ jsx2("circle", {
328
- cx: "12",
329
- cy: "10",
330
- r: "3"
331
- })
332
- ]
333
- });
334
- var LineIcon = () => /* @__PURE__ */ jsx2("svg", {
335
- width: "16",
336
- height: "16",
337
- viewBox: "0 0 24 24",
338
- fill: "none",
339
- stroke: "currentColor",
340
- strokeWidth: "2",
341
- children: /* @__PURE__ */ jsx2("line", {
342
- x1: "4",
343
- y1: "20",
344
- x2: "20",
345
- y2: "4"
346
- })
347
- });
348
- var PolygonIcon = () => /* @__PURE__ */ jsx2("svg", {
349
- width: "16",
350
- height: "16",
351
- viewBox: "0 0 24 24",
352
- fill: "none",
353
- stroke: "currentColor",
354
- strokeWidth: "2",
355
- children: /* @__PURE__ */ jsx2("polygon", {
356
- points: "12,2 22,8 18,22 6,22 2,8"
357
- })
358
- });
359
- var RectangleIcon = () => /* @__PURE__ */ jsx2("svg", {
360
- width: "16",
361
- height: "16",
362
- viewBox: "0 0 24 24",
363
- fill: "none",
364
- stroke: "currentColor",
365
- strokeWidth: "2",
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", {
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"
406
- })
407
- });
408
-
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
- };
420
- var MapButton = ({
421
- mode,
422
- currentMode,
423
- onClick,
424
- icon,
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;
440
-
441
- // src/components/map-buttons/map-buttons.tsx
442
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
443
- function MapButtons({
444
- mode,
445
- setMode,
446
- onClick,
447
- draw,
448
- onFeaturesChange,
449
- isMultiple = true,
450
- autoFocus
451
- }) {
452
- const [expanded, setExpanded] = useState(false);
453
- const [hasFeatures, setHasFeatures] = useState(false);
454
- const updateHasFeatures = useCallback(
455
- () => setHasFeatures(draw.getSnapshot().length > 0),
456
- [draw]
457
- );
458
- useEffect(() => {
459
- if (!draw)
460
- return;
461
- draw.on("finish", updateHasFeatures);
462
- draw.on("change", updateHasFeatures);
463
- updateHasFeatures();
464
- return () => {
465
- draw.off("finish", updateHasFeatures);
466
- draw.off("change", updateHasFeatures);
467
- };
468
- }, [draw, updateHasFeatures]);
469
- const handleGeolocation = useCallback(() => {
470
- if (!("geolocation" in navigator)) {
471
- alert("Geolocation is not supported in this browser.");
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(() => {
499
- draw.clear();
500
- setHasFeatures(false);
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", {
565
- style: {
566
- position: "absolute",
567
- top: 10,
568
- left: 10,
569
- display: "flex",
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)"
577
- },
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
- ]
606
- });
607
- }
608
- var map_buttons_default = MapButtons;
609
-
610
- // src/components/map.tsx
611
- import bbox from "@turf/bbox";
612
- import { defaultMapStyles } from "@biodiv-platform/naksha-commons";
613
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
614
- var Map = (props) => {
615
- var _a;
616
- const mapRef = useRef(null);
617
- const [map, setMap] = useState2();
618
- const [mode, setMode] = useState2("static");
619
- const [draw, setDraw] = useState2();
620
- const drawRef = useRef();
621
- const { isMultiple, 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 mapStyleConfig = mapTile[selectedMapStyleIdx];
628
- const storedFeaturesRef = useRef([]);
629
- const autoFocus = useCallback2(
630
- (features2) => {
631
- if (!(features2 == null ? void 0 : features2.length) || !map)
632
- return;
633
- const _bbox = bbox({ type: "FeatureCollection", features: features2 });
634
- map.fitBounds(_bbox, {
635
- padding: 40,
636
- duration: 1e3,
637
- maxZoom: 15
638
- });
639
- },
640
- [map]
641
- );
642
- useEffect2(() => {
643
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
644
- if (features && features.length > 0) {
645
- storedFeaturesRef.current = ensureModeProperty(features);
646
- }
647
- const maplibreMap = setupMaplibreMap({
648
- containerId: "maplibre-map",
649
- latitude: (_b = (_a2 = props.defaultViewState) == null ? void 0 : _a2.latitude) != null ? _b : 0,
650
- longitude: (_d = (_c = props.defaultViewState) == null ? void 0 : _c.longitude) != null ? _d : 0,
651
- zoom: (_f = (_e = props.defaultViewState) == null ? void 0 : _e.zoom) != null ? _f : 0,
652
- pitch: (_h = (_g = props.defaultViewState) == null ? void 0 : _g.pitch) != null ? _h : 0,
653
- bearing: (_j = (_i = props.defaultViewState) == null ? void 0 : _i.bearing) != null ? _j : 0,
654
- mapstyle: mapStyle
655
- });
656
- if ("maxZoom" in mapStyleConfig && mapStyleConfig.maxZoom) {
657
- maplibreMap.setMaxZoom(mapStyleConfig.maxZoom);
658
- }
659
- const navControl = new maplibregl2.NavigationControl({
660
- showCompass: true,
661
- showZoom: true,
662
- visualizePitch: true
663
- });
664
- const fullscreen = new maplibregl2.FullscreenControl({});
665
- maplibreMap.addControl(navControl, "bottom-right");
666
- maplibreMap.addControl(fullscreen, "bottom-right");
667
- maplibreMap.once("style.load", () => {
668
- setMap(maplibreMap);
669
- });
670
- return () => {
671
- if (drawRef.current) {
672
- storedFeaturesRef.current = drawRef.current.getSnapshot();
673
- }
674
- if (drawRef.current) {
675
- try {
676
- drawRef.current.stop();
677
- } catch (e) {
678
- console.warn("terraDraw stop failed", e);
679
- }
680
- drawRef.current = void 0;
681
- setDraw(void 0);
682
- }
683
- if (maplibreMap) {
684
- maplibreMap.removeControl(navControl);
685
- maplibreMap.removeControl(fullscreen);
686
- maplibreMap.remove();
687
- }
688
- };
689
- }, [mapStyle]);
690
- const filterUserFeatures = (features2) => features2.filter(
691
- (f) => f.geometry.type !== "Point" || f.properties.mode !== "static" && f.properties.mode !== "select"
692
- );
693
- useEffect2(() => {
694
- if (!map)
695
- return;
696
- const terraDraw = setupDraw(map);
697
- terraDraw.start();
698
- drawRef.current = terraDraw;
699
- setDraw(terraDraw);
700
- const handleChange = () => {
701
- let snapshot = terraDraw.getSnapshot();
702
- let userFeatures = filterUserFeatures(snapshot);
703
- if (!isMultiple && userFeatures.length > 1) {
704
- const lastFeature = userFeatures.at(-1);
705
- const toRemove = userFeatures.slice(0, -1).map((f) => f.id).filter((id) => Boolean(id));
706
- if (toRemove.length > 0) {
707
- try {
708
- terraDraw.removeFeatures(toRemove);
709
- } catch (e) {
710
- console.warn("removeFeatures failed", e);
711
- }
712
- }
713
- userFeatures = [lastFeature];
714
- }
715
- onFeaturesChange == null ? void 0 : onFeaturesChange(userFeatures);
716
- autoFocus(userFeatures);
717
- };
718
- terraDraw.on("finish", handleChange);
719
- setTimeout(() => {
720
- if (terraDraw.getSnapshot().length === 0) {
721
- let featuresToAdd = [];
722
- if (storedFeaturesRef.current.length > 0) {
723
- featuresToAdd = storedFeaturesRef.current;
724
- } else if (features && features.length > 0) {
725
- featuresToAdd = ensureModeProperty(features);
726
- }
727
- if (!isMultiple && featuresToAdd.length > 1) {
728
- featuresToAdd = [featuresToAdd.at(-1)];
729
- }
730
- if (featuresToAdd.length > 0) {
731
- terraDraw.addFeatures(featuresToAdd);
732
- autoFocus(featuresToAdd);
733
- }
734
- }
735
- }, 100);
736
- return () => {
737
- terraDraw.off("finish", handleChange);
738
- };
739
- }, [map]);
740
- const changeMode = useCallback2(
741
- (newMode) => {
742
- draw == null ? void 0 : draw.setMode(newMode);
743
- setMode(newMode);
744
- },
745
- [draw]
746
- );
747
- const handleStyleChange = (idx) => {
748
- if (drawRef.current) {
749
- storedFeaturesRef.current = drawRef.current.getSnapshot();
750
- }
751
- setSelectedMapStyleIdx(idx);
752
- setMode("static");
753
- };
754
- return /* @__PURE__ */ jsxs3("div", {
755
- ref: mapRef,
756
- id: "maplibre-map",
757
- style: { width: "100%", height: "100%", position: "relative" },
758
- children: [
759
- /* @__PURE__ */ jsx5(MapStyleSwitcher, {
760
- currentStyleIdx: selectedMapStyleIdx,
761
- onStyleChange: handleStyleChange,
762
- mapStyles: mapTile
763
- }),
764
- draw && /* @__PURE__ */ jsx5(map_buttons_default, {
765
- mode,
766
- setMode,
767
- onClick: changeMode,
768
- draw,
769
- onFeaturesChange,
770
- isMultiple,
771
- autoFocus
772
- })
773
- ]
774
- });
775
- };
776
- var map_default = Map;
777
-
778
- // src/index.tsx
779
- import { jsx as jsx6 } from "react/jsx-runtime";
780
- var NakshaMaplibreDraw = (props) => /* @__PURE__ */ jsx6(map_default, __spreadValues({}, props));
781
- export {
782
- NakshaMaplibreDraw
783
- };
1
+ var we=Object.defineProperty,xe=Object.defineProperties;var ye=Object.getOwnPropertyDescriptors;var A=Object.getOwnPropertySymbols;var be=Object.prototype.hasOwnProperty,ve=Object.prototype.propertyIsEnumerable;var Y=(t,o,e)=>o in t?we(t,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[o]=e,w=(t,o)=>{for(var e in o||(o={}))be.call(o,e)&&Y(t,e,o[e]);if(A)for(var e of A(o))ve.call(o,e)&&Y(t,e,o[e]);return t},I=(t,o)=>xe(t,ye(o));import{FullscreenControl as Ze,NavigationControl as Ue}from"maplibre-gl";import{useRef as J,useState as T,useEffect as pe,useCallback as ue}from"react";import{TerraDraw as Se,TerraDrawSelectMode as Me,TerraDrawPointMode as ke,TerraDrawLineStringMode as Ce,TerraDrawPolygonMode as Ie,TerraDrawCircleMode as Pe,TerraDrawFreehandMode as Be,ValidateNotSelfIntersecting as F,TerraDrawRectangleMode as De}from"terra-draw";import{TerraDrawMapLibreGLAdapter as Le}from"terra-draw-maplibre-gl-adapter";import{tw as Ne}from"twind";import Te from"react";import{jsx as L}from"react/jsx-runtime";function _(t){return new Se({tracked:!0,adapter:new Le({map:t,coordinatePrecision:9}),modes:[new Me({flags:{polygon:{feature:{scaleable:!0,rotateable:!0,draggable:!0,coordinates:{midpoints:!0,draggable:!0,deletable:!0}}},linestring:{feature:{draggable:!0,coordinates:{midpoints:!0,draggable:!0,deletable:!0}}},circle:{feature:{draggable:!0}},point:{feature:{draggable:!0}},rectangle:{feature:{draggable:!0,coordinates:{resizable:"opposite"}}},freehand:{feature:{draggable:!0}}}}),new ke,new Ce({validation:(o,{updateType:e})=>e==="finish"||e==="commit"?F(o):{valid:!0}}),new De,new Ie({pointerDistance:30,validation:(o,{updateType:e})=>e==="finish"||e==="commit"?F(o):{valid:!0}}),new Pe,new Be({pointerDistance:5,validation:o=>F(o)})]})}var G=t=>t.map(o=>{var a,l;if((a=o.properties)!=null&&a.mode)return o;let e=(l=o.geometry)==null?void 0:l.type,n=e==="Point"?"point":e==="Polygon"?"polygon":e==="LineString"?"linestring":"unknown";return I(w({},o),{properties:I(w({},o.properties),{mode:n})})});var N=Te.forwardRef((t,o)=>L("button",w({ref:o,type:"button",className:Ne`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`},t))),$=({currentStyleIdx:t,onStyleChange:o,mapStyles:e})=>L("div",{style:{position:"absolute",left:12,bottom:12,background:"rgba(255,255,255,0.95)",padding:"8px",borderRadius:"6px",zIndex:1e3,boxShadow:"0 2px 4px rgba(0,0,0,0.2)"},children:L("select",{value:t,onChange:n=>o(Number(n.target.value)),style:{fontSize:14,padding:"4px"},children:e.map((n,a)=>L("option",{value:a,children:n.text||`Style ${a+1}`},n.key||a))})});import{getRTLTextPluginStatus as Re,Map as Fe,setRTLTextPlugin as Ge}from"maplibre-gl";function q({containerId:t,latitude:o=0,longitude:e=0,zoom:n,pitch:a,bearing:l,mapstyle:d}){return Re()==="unavailable"&&Ge("https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",!0),new Fe({container:t,style:d,center:{lat:o,lng:e},zoom:n,pitch:a,bearing:l})}import{useEffect as We,useState as ce,useCallback as O,useMemo as ze}from"react";import{jsx as i,jsxs as P}from"react/jsx-runtime";var K=()=>P("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[i("path",{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"}),i("path",{d:"m15 5 4 4"})]}),Q=()=>P("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[i("path",{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"}),i("path",{d:"m12.829 7.172 4.359-4.346a1 1 0 1 1 3.986 3.986l-4.353 4.353"}),i("path",{d:"m15 5 4 4"}),i("path",{d:"m2 2 20 20"})]}),X=()=>P("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[i("line",{x1:"2",x2:"5",y1:"12",y2:"12"}),i("line",{x1:"19",x2:"22",y1:"12",y2:"12"}),i("line",{x1:"12",x2:"12",y1:"2",y2:"5"}),i("line",{x1:"12",x2:"12",y1:"19",y2:"22"}),i("circle",{cx:"12",cy:"12",r:"7"})]}),ee=()=>P("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[i("path",{d:"M12.586 12.586 19 19"}),i("path",{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"})]}),te=()=>P("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[i("path",{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"}),i("circle",{cx:"12",cy:"10",r:"3"})]}),oe=()=>i("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:i("line",{x1:"4",y1:"20",x2:"20",y2:"4"})}),re=()=>i("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:i("polygon",{points:"12,2 22,8 18,22 6,22 2,8"})}),ne=()=>i("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:i("rect",{x:"4",y:"4",width:"16",height:"16"})}),ie=()=>i("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:i("circle",{cx:"12",cy:"12",r:"10"})}),ae=()=>i("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:i("path",{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"})}),le=()=>i("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:i("path",{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"})});import{jsx as Ve}from"react/jsx-runtime";var Oe={display:"flex",justifyContent:"center",alignItems:"center",width:30,height:30,padding:0,borderRadius:4},Je=({mode:t,currentMode:o,onClick:e,icon:n,tooltip:a,disabled:l})=>Ve(N,{type:"button",title:a,disabled:l,onClick:()=>!l&&e(t!=null?t:""),style:I(w({},Oe),{backgroundColor:l?"#d3d3d3":o===t?"#02cf87":"#f0f0f0",cursor:l?"not-allowed":"pointer",opacity:l?.6:1,width:40,height:40}),children:n}),se=Je;import{jsx as c,jsxs as He}from"react/jsx-runtime";function Ee({mode:t,setMode:o,onClick:e,draw:n,onFeaturesChange:a,isMultiple:l=!0,autoFocus:d}){let[M,m]=ce(!1),[b,x]=ce(!1),u=O(()=>x(n.getSnapshot().length>0),[n]);We(()=>{if(!!n)return n.on("finish",u),n.on("change",u),u(),()=>{n.off("finish",u),n.off("change",u)}},[n,u]);let v=O(()=>{if(!("geolocation"in navigator)){alert("Geolocation is not supported in this browser.");return}navigator.geolocation.getCurrentPosition(s=>{let f={type:"Feature",geometry:{type:"Point",coordinates:[s.coords.longitude,s.coords.latitude]},properties:{mode:"point",source:"geolocation"}};l||n.clear(),n.addFeatures([f]),a==null||a(n.getSnapshot()),d==null||d([f])},s=>{alert("Error getting geolocation"),console.error(s)}),o("current-location")},[n,l,a,d]),B=O(()=>{n.clear(),x(!1),o("static"),a==null||a([])},[n,a]),k=ze(()=>[{icon:c(X,{}),mode:"current-location",onClick:v,tooltip:"Use current location"},{icon:c(ee,{}),mode:"select",onClick:e,tooltip:"Select"},{icon:c(te,{}),mode:"point",onClick:e,tooltip:"Point"},{icon:c(oe,{}),mode:"linestring",onClick:e,tooltip:"Linestring"},{icon:c(re,{}),mode:"polygon",onClick:e,tooltip:"Polygon"},{icon:c(ne,{}),mode:"rectangle",onClick:e,tooltip:"Reactangle"},{icon:c(ie,{}),mode:"circle",onClick:e,tooltip:"Circle"},{icon:c(ae,{}),mode:"freehand",onClick:e,tooltip:"Freehand"},{icon:c(le,{}),mode:"clear",onClick:B,tooltip:"Clear all features",disabled:!b}],[e,v,B,b]);return He("div",{style:{position:"absolute",top:10,left:10,display:"flex",flexDirection:"column",gap:6,zIndex:1e3,backgroundColor:"rgba(255,255,255,0.9)",padding:8,borderRadius:6,boxShadow:"0 2px 6px rgba(0,0,0,0.2)",maxWidth:"90vw"},children:[c(N,{onClick:()=>m(s=>!s),style:{display:"flex",justifyContent:"center",alignItems:"center",width:40,height:40,padding:0,borderRadius:4,backgroundColor:"#d3d3d3"},title:"Expand or collapse tools",children:M?c(Q,{}):c(K,{})}),M&&c("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(40px, 1fr))",gap:6,maxHeight:"200px",overflowY:"auto",paddingRight:1},className:"custom-scrollbar",children:k.map((s,S)=>c(se,{icon:s.icon,mode:s.mode,currentMode:t,onClick:s.onClick,tooltip:s.tooltip,disabled:s.disabled},S))})]})}var de=Ee;import je from"@turf/bbox";import{defaultMapStyles as Ae}from"@biodiv-platform/naksha-commons";import{jsx as ge,jsxs as _e}from"react/jsx-runtime";var Ye=t=>{var V,W;let o=J(null),[e,n]=T(),[a,l]=T("static"),[d,M]=T(),m=J(),{isMultiple:b,features:x=[],onFeaturesChange:u}=t,[v,B]=T((t==null?void 0:t.mapStyle)||0),k=(V=t.mapStyles)!=null?V:Ae,s=(W=k[v])==null?void 0:W.style,S=k[v],f=J([]),R=ue(r=>{if(!(r!=null&&r.length)||!e)return;let g=je({type:"FeatureCollection",features:r});e.fitBounds(g,{padding:40,duration:1e3,maxZoom:15})},[e]);pe(()=>{var h,D,C,y,z,E,H,Z,U,j;x.length>0&&(f.current=G(x));let r=q({containerId:"maplibre-map",latitude:(D=(h=t.defaultViewState)==null?void 0:h.latitude)!=null?D:0,longitude:(y=(C=t.defaultViewState)==null?void 0:C.longitude)!=null?y:0,zoom:(E=(z=t.defaultViewState)==null?void 0:z.zoom)!=null?E:0,pitch:(Z=(H=t.defaultViewState)==null?void 0:H.pitch)!=null?Z:0,bearing:(j=(U=t.defaultViewState)==null?void 0:U.bearing)!=null?j:0,mapstyle:s});"maxZoom"in S&&S.maxZoom&&r.setMaxZoom(S.maxZoom);let g=new Ue({showCompass:!0,showZoom:!0,visualizePitch:!0}),p=new Ze({});return r.addControl(g,"bottom-right"),r.addControl(p,"bottom-right"),r.once("style.load",()=>{n(r)}),()=>{if(m.current&&(f.current=m.current.getSnapshot()),m.current){try{m.current.stop()}catch(Ke){}m.current=void 0,M(void 0)}r&&(r.removeControl(g),r.removeControl(p),r.remove())}},[s]);let he=r=>r.filter(g=>g.geometry.type!=="Point"||g.properties.mode!=="static"&&g.properties.mode!=="select");pe(()=>{if(!e)return;let r=_(e);r.start(),m.current=r,M(r);let g=()=>{let p=r.getSnapshot(),h=he(p);if(!b&&h.length>1){let D=h.at(-1),C=h.slice(0,-1).map(y=>y.id).filter(y=>Boolean(y));if(C.length>0)try{r.removeFeatures(C)}catch(y){}h=[D]}u==null||u(h),R(h)};return r.on("finish",g),setTimeout(()=>{if(r.getSnapshot().length===0){let p=[];f.current.length>0?p=f.current:x.length>0&&(p=G(x)),!b&&p.length>1&&(p=[p.at(-1)]),p.length>0&&(r.addFeatures(p),R(p))}},100),()=>{r.off("finish",g)}},[e]);let fe=ue(r=>{d==null||d.setMode(r),l(r)},[d]);return _e("div",{ref:o,id:"maplibre-map",style:{width:"100%",height:"100%",position:"relative"},children:[ge($,{currentStyleIdx:v,onStyleChange:r=>{m.current&&(f.current=m.current.getSnapshot()),B(r),l("static")},mapStyles:k}),d&&ge(de,{mode:a,setMode:l,onClick:fe,draw:d,onFeaturesChange:u,isMultiple:b,autoFocus:R})]})},me=Ye;import{jsx as $e}from"react/jsx-runtime";var Nt=t=>$e(me,w({},t));export{Nt as NakshaMaplibreDraw};