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