@biodiv-platform/naksha-maplibre-draw 5.0.2 → 5.0.4

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 +1,532 @@
1
- var ne=Object.defineProperty,ae=Object.defineProperties;var ie=Object.getOwnPropertyDescriptors;var J=Object.getOwnPropertySymbols;var se=Object.prototype.hasOwnProperty,le=Object.prototype.propertyIsEnumerable;var O=(e,t,r)=>t in e?ne(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,b=(e,t)=>{for(var r in t||(t={}))se.call(t,r)&&O(e,r,t[r]);if(J)for(var r of J(t))le.call(t,r)&&O(e,r,t[r]);return e},D=(e,t)=>ae(e,ie(t));import Y from"maplibre-gl";import{TerraDraw as ue,TerraDrawSelectMode as de,TerraDrawPointMode as ce,TerraDrawLineStringMode as pe,TerraDrawPolygonMode as ge,TerraDrawCircleMode as me,TerraDrawFreehandMode as fe,ValidateNotSelfIntersecting as F,TerraDrawRectangleMode as he}from"terra-draw";import{TerraDrawMapLibreGLAdapter as we}from"terra-draw-maplibre-gl-adapter";function V(e){return new ue({tracked:!0,adapter:new we({map:e,coordinatePrecision:9}),modes:[new de({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 ce,new pe({validation:(t,{updateType:r})=>r==="finish"||r==="commit"?F(t):{valid:!0}}),new he,new ge({pointerDistance:30,validation:(t,{updateType:r})=>r==="finish"||r==="commit"?F(t):{valid:!0}}),new me,new fe({pointerDistance:5,validation:t=>F(t)})]})}import{useRef as ye,useState as m,useEffect as X,useCallback as P}from"react";import L from"maplibre-gl";function z({containerId:e,latitude:t=0,longitude:r=0,zoom:d,pitch:i,bearing:c,mapstyle:N}){return L.getRTLTextPluginStatus()==="unavailable"&&L.setRTLTextPlugin("https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",!0),new L.Map({container:e,style:N,center:{lat:t,lng:r},zoom:d,pitch:i,bearing:c})}import{jsx as l,jsxs as q}from"react/jsx-runtime";var E=()=>q("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:[l("path",{d:"M12.586 12.586 19 19"}),l("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"})]}),W=()=>q("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:[l("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"}),l("circle",{cx:"12",cy:"10",r:"3"})]}),A=()=>l("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:l("line",{x1:"4",y1:"20",x2:"20",y2:"4"})}),H=()=>l("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:l("polygon",{points:"12,2 22,8 18,22 6,22 2,8"})}),Z=()=>l("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:l("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 K}from"react/jsx-runtime";var be=({draw:e})=>e?K("button",{onClick:()=>e.clear(),title:"Delete",style:{display:"flex",justifyContent:"center",alignItems:"center",width:"30px",height:"30px",padding:"0",borderRadius:"4px",backgroundColor:"#f0f0f0",cursor:"pointer"},children:K(Z,{})}):null,Q=be;import{jsx as xe}from"react/jsx-runtime";var Me=({mode:e,currentMode:t,changeMode:r,icon:d,tooltip:i})=>xe("button",{onClick:()=>r(e),title:i,style:{display:"flex",justifyContent:"center",alignItems:"center",width:"30px",height:"30px",padding:"0",borderRadius:"4px",backgroundColor:t===e?"#02cf87":"#f0f0f0",cursor:"pointer"},children:d}),M=Me;import{jsx as u,jsxs as ve}from"react/jsx-runtime";var Se=({mode:e,changeMode:t,draw:r})=>ve("div",{style:{position:"absolute",top:"10px",left:"10px",display:"flex",flexDirection:"column",gap:"6px",zIndex:1e3,backgroundColor:"rgba(255, 255, 255, 0.9)",padding:"8px",borderRadius:"6px",boxShadow:"0 2px 6px rgba(0,0,0,0.2)"},children:[u(M,{mode:"select",icon:u(E,{}),currentMode:e,changeMode:t,tooltip:"Select"}),u(M,{mode:"point",icon:u(W,{}),currentMode:e,changeMode:t,tooltip:"Point"}),u(M,{mode:"linestring",icon:u(A,{}),currentMode:e,changeMode:t,tooltip:"Line"}),u(M,{mode:"polygon",icon:u(H,{}),currentMode:e,changeMode:t,tooltip:"Polygon"}),r&&u(Q,{draw:r})]}),U=Se;import{defaultMapStyles as ke}from"@biodiv-platform/naksha-commons";import{Fragment as Pe,jsx as T,jsxs as Te}from"react/jsx-runtime";var Ce=e=>e.map(t=>{var i,c;if((i=t.properties)!=null&&i.mode)return t;let r=(c=t.geometry)==null?void 0:c.type,d=r==="Point"?"point":r==="Polygon"?"polygon":r==="LineString"?"linestring":"unknown";return D(b({},t),{properties:D(b({},t.properties),{mode:d})})}),De=e=>{if(!e.length)return null;let t=new Y.LngLatBounds;return e.forEach(r=>{Fe(r).forEach(i=>{Array.isArray(i[0])?i.forEach(c=>t.extend(c)):t.extend(i)})}),t},Fe=e=>{let t=e.geometry;switch(t.type){case"Point":return[t.coordinates];case"LineString":return[t.coordinates];case"Polygon":return t.coordinates;default:return[]}},Le=e=>{let t=ye(null),[r,d]=m(),[i,c]=m("static"),[N,$]=m(),[Ie,I]=m([]),[p,j]=m(),ee=ke[(e==null?void 0:e.mapStyle)||0].style,{isMultiple:x=!0,isControlled:S=!1,setFeatures:v}=e,[te,re]=m([]),y=P(o=>{S&&v?v(o):re(o)},[S,v]),Be=S?e.features||[]:te,k=P(o=>{if(!r||o.length===0)return;let s=De(o);s&&!s.isEmpty()&&r.fitBounds(s,{padding:50,duration:1e3,maxZoom:5})},[r]);X(()=>{var f,a,n,h,C,w,g,B,R,G;let o=z({containerId:"maplibre-map",latitude:(a=(f=e.defaultViewState)==null?void 0:f.latitude)!=null?a:0,longitude:(h=(n=e.defaultViewState)==null?void 0:n.longitude)!=null?h:0,zoom:(w=(C=e.defaultViewState)==null?void 0:C.zoom)!=null?w:0,pitch:(B=(g=e.defaultViewState)==null?void 0:g.pitch)!=null?B:0,bearing:(G=(R=e.defaultViewState)==null?void 0:R.bearing)!=null?G:0,mapstyle:ee}),s=new Y.NavigationControl({showCompass:!0,showZoom:!0,visualizePitch:!0});return o.addControl(s,"bottom-right"),o.once("style.load",()=>d(o)),()=>{s&&o&&o.removeControl(s)}},[]),X(()=>{var f;if(!r)return;let o=V(r);o.start(),j(o);let s=()=>{let a=o.getSnapshot(),n=a;if(!x&&a.length>1){n=[a[a.length-1]];let w=a.slice(0,-1).map(g=>g.id).filter(g=>g!==void 0);w.length>0&&o.removeFeatures(w)}I(n),y(n),$(n.find(h=>h.properties.selected)),n.length>0&&k(n)};return o.on("change",s),(f=e.features)!=null&&f.length&&setTimeout(()=>{if(o.getSnapshot().length===0){let a=Ce(e.features),n=a;!x&&a.length>1&&(n=[a[a.length-1]]),o.addFeatures(n),I(n),y(n),k(n)}},300),()=>{o.off("change",s),o.stop()}},[r,x,y,k]);let oe=P(o=>{p==null||p.setMode(o),c(o)},[p]);return Te("div",{children:[T("div",{ref:t,id:"maplibre-map",style:{width:"100%",height:"100vh"}}),p&&T(Pe,{children:T(U,{mode:i,changeMode:oe,draw:p})})]})},_=Le;import{jsx as Ne}from"react/jsx-runtime";var ut=e=>Ne(_,b({},e));export{ut as NakshaMaplibreDraw};
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
+
24
+ // src/components/setup-draw.tsx
25
+ import {
26
+ TerraDraw,
27
+ TerraDrawSelectMode,
28
+ TerraDrawPointMode,
29
+ TerraDrawLineStringMode,
30
+ TerraDrawPolygonMode,
31
+ TerraDrawCircleMode,
32
+ TerraDrawFreehandMode,
33
+ ValidateNotSelfIntersecting,
34
+ TerraDrawRectangleMode
35
+ } from "terra-draw";
36
+ import { TerraDrawMapLibreGLAdapter } from "terra-draw-maplibre-gl-adapter";
37
+ function setupDraw(map) {
38
+ return new TerraDraw({
39
+ tracked: true,
40
+ adapter: new TerraDrawMapLibreGLAdapter({
41
+ map,
42
+ coordinatePrecision: 9
43
+ }),
44
+ modes: [
45
+ new TerraDrawSelectMode({
46
+ flags: {
47
+ polygon: {
48
+ feature: {
49
+ scaleable: true,
50
+ rotateable: true,
51
+ draggable: true,
52
+ coordinates: {
53
+ midpoints: true,
54
+ draggable: true,
55
+ deletable: true
56
+ }
57
+ }
58
+ },
59
+ linestring: {
60
+ feature: {
61
+ draggable: true,
62
+ coordinates: {
63
+ midpoints: true,
64
+ draggable: true,
65
+ deletable: true
66
+ }
67
+ }
68
+ },
69
+ circle: {
70
+ feature: {
71
+ draggable: true
72
+ }
73
+ },
74
+ point: {
75
+ feature: {
76
+ draggable: true
77
+ }
78
+ },
79
+ rectangle: {
80
+ feature: {
81
+ draggable: true,
82
+ coordinates: {
83
+ resizable: "opposite"
84
+ }
85
+ }
86
+ },
87
+ freehand: {
88
+ feature: {
89
+ draggable: true
90
+ }
91
+ }
92
+ }
93
+ }),
94
+ new TerraDrawPointMode(),
95
+ new TerraDrawLineStringMode({
96
+ validation: (feature, { updateType }) => {
97
+ if (updateType === "finish" || updateType === "commit") {
98
+ return ValidateNotSelfIntersecting(feature);
99
+ }
100
+ return {
101
+ valid: true
102
+ };
103
+ }
104
+ }),
105
+ new TerraDrawRectangleMode(),
106
+ new TerraDrawPolygonMode({
107
+ pointerDistance: 30,
108
+ validation: (feature, { updateType }) => {
109
+ if (updateType === "finish" || updateType === "commit") {
110
+ return ValidateNotSelfIntersecting(feature);
111
+ }
112
+ return {
113
+ valid: true
114
+ };
115
+ }
116
+ }),
117
+ new TerraDrawCircleMode(),
118
+ new TerraDrawFreehandMode({
119
+ pointerDistance: 5,
120
+ validation: (feature) => {
121
+ return ValidateNotSelfIntersecting(feature);
122
+ }
123
+ })
124
+ ]
125
+ });
126
+ }
127
+
128
+ // src/components/map.tsx
129
+ import { useRef, useState, useEffect, useCallback } from "react";
130
+
131
+ // src/components/setup-maplibre.tsx
132
+ import maplibregl from "maplibre-gl";
133
+ function setupMaplibreMap({
134
+ containerId,
135
+ latitude = 0,
136
+ longitude = 0,
137
+ zoom,
138
+ pitch,
139
+ bearing,
140
+ mapstyle
141
+ }) {
142
+ if (maplibregl.getRTLTextPluginStatus() === "unavailable") {
143
+ maplibregl.setRTLTextPlugin(
144
+ "https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",
145
+ true
146
+ );
147
+ }
148
+ return new maplibregl.Map({
149
+ container: containerId,
150
+ style: mapstyle,
151
+ center: { lat: latitude, lng: longitude },
152
+ zoom,
153
+ pitch,
154
+ bearing
155
+ });
156
+ }
157
+
158
+ // src/components/icon-buttons/icons.tsx
159
+ import { jsx, jsxs } from "react/jsx-runtime";
160
+ var SelectIcon = () => /* @__PURE__ */ jsxs("svg", {
161
+ xmlns: "http://www.w3.org/2000/svg",
162
+ width: "24",
163
+ height: "24",
164
+ viewBox: "0 0 24 24",
165
+ fill: "none",
166
+ stroke: "currentColor",
167
+ strokeWidth: "1.5",
168
+ strokeLinecap: "round",
169
+ strokeLinejoin: "round",
170
+ children: [
171
+ /* @__PURE__ */ jsx("path", {
172
+ d: "M12.586 12.586 19 19"
173
+ }),
174
+ /* @__PURE__ */ jsx("path", {
175
+ 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
+ })
177
+ ]
178
+ });
179
+ var PointIcon = () => /* @__PURE__ */ jsxs("svg", {
180
+ xmlns: "http://www.w3.org/2000/svg",
181
+ width: "24",
182
+ height: "24",
183
+ viewBox: "0 0 24 24",
184
+ fill: "none",
185
+ stroke: "currentColor",
186
+ strokeWidth: "1.5",
187
+ strokeLinecap: "round",
188
+ strokeLinejoin: "round",
189
+ children: [
190
+ /* @__PURE__ */ jsx("path", {
191
+ 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
+ }),
193
+ /* @__PURE__ */ jsx("circle", {
194
+ cx: "12",
195
+ cy: "10",
196
+ r: "3"
197
+ })
198
+ ]
199
+ });
200
+ var LineIcon = () => /* @__PURE__ */ jsx("svg", {
201
+ width: "16",
202
+ height: "16",
203
+ viewBox: "0 0 24 24",
204
+ fill: "none",
205
+ stroke: "currentColor",
206
+ strokeWidth: "2",
207
+ children: /* @__PURE__ */ jsx("line", {
208
+ x1: "4",
209
+ y1: "20",
210
+ x2: "20",
211
+ y2: "4"
212
+ })
213
+ });
214
+ var PolygonIcon = () => /* @__PURE__ */ jsx("svg", {
215
+ width: "16",
216
+ height: "16",
217
+ viewBox: "0 0 24 24",
218
+ fill: "none",
219
+ stroke: "currentColor",
220
+ strokeWidth: "2",
221
+ children: /* @__PURE__ */ jsx("polygon", {
222
+ points: "12,2 22,8 18,22 6,22 2,8"
223
+ })
224
+ });
225
+ var DeleteIcon = () => /* @__PURE__ */ jsx("svg", {
226
+ width: "16",
227
+ height: "16",
228
+ viewBox: "0 0 24 24",
229
+ fill: "none",
230
+ stroke: "currentColor",
231
+ strokeWidth: "2",
232
+ children: /* @__PURE__ */ jsx("path", {
233
+ 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
+ })
235
+ });
236
+
237
+ // src/components/map-button/MapButton.tsx
238
+ import { jsx as jsx2 } from "react/jsx-runtime";
239
+ var MapButton = ({
240
+ mode,
241
+ currentMode,
242
+ changeMode,
243
+ icon,
244
+ tooltip
245
+ }) => {
246
+ return /* @__PURE__ */ jsx2("button", {
247
+ onClick: () => changeMode(mode),
248
+ title: tooltip,
249
+ style: {
250
+ display: "flex",
251
+ justifyContent: "center",
252
+ alignItems: "center",
253
+ width: "30px",
254
+ height: "30px",
255
+ padding: "0",
256
+ borderRadius: "4px",
257
+ backgroundColor: currentMode === mode ? "#02cf87" : "#f0f0f0",
258
+ cursor: "pointer"
259
+ },
260
+ children: icon
261
+ });
262
+ };
263
+ var MapButton_default = MapButton;
264
+
265
+ // src/components/map-buttons/MapButtons.tsx
266
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
267
+ var MapButtons = ({
268
+ mode,
269
+ changeMode
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/map.tsx
320
+ import { defaultMapStyles } from "@biodiv-platform/naksha-commons";
321
+
322
+ // src/components/icon-buttons/ClearButton.tsx
323
+ import { jsx as jsx4 } from "react/jsx-runtime";
324
+ var ClearButton = ({
325
+ draw,
326
+ onFeaturesChange
327
+ }) => {
328
+ if (!draw)
329
+ return null;
330
+ const handleClear = () => {
331
+ draw.clear();
332
+ if (onFeaturesChange) {
333
+ onFeaturesChange([]);
334
+ }
335
+ };
336
+ return /* @__PURE__ */ jsx4("button", {
337
+ onClick: handleClear,
338
+ title: "Delete",
339
+ style: {
340
+ display: "flex",
341
+ justifyContent: "center",
342
+ alignItems: "center",
343
+ width: "30px",
344
+ height: "30px",
345
+ padding: "0",
346
+ borderRadius: "4px",
347
+ backgroundColor: "#f0f0f0",
348
+ cursor: "pointer"
349
+ },
350
+ children: /* @__PURE__ */ jsx4(DeleteIcon, {})
351
+ });
352
+ };
353
+ var ClearButton_default = ClearButton;
354
+
355
+ // src/components/map.tsx
356
+ import bbox from "@turf/bbox";
357
+ import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
358
+ var ensureModeProperty = (features) => features.map((feature) => {
359
+ var _a, _b;
360
+ if ((_a = feature.properties) == null ? void 0 : _a.mode)
361
+ return feature;
362
+ let mode;
363
+ switch ((_b = feature.geometry) == null ? void 0 : _b.type) {
364
+ case "Point":
365
+ mode = "point";
366
+ break;
367
+ case "Polygon":
368
+ mode = "polygon";
369
+ break;
370
+ case "LineString":
371
+ mode = "linestring";
372
+ break;
373
+ default:
374
+ mode = "unknown";
375
+ }
376
+ return __spreadProps(__spreadValues({}, feature), {
377
+ properties: __spreadProps(__spreadValues({}, feature.properties), { mode })
378
+ });
379
+ });
380
+ var Map = (props) => {
381
+ const {
382
+ mapStyle: mapStyleIdx = 0,
383
+ defaultViewState,
384
+ isMultiple = true,
385
+ isControlled = false,
386
+ onFeaturesChange,
387
+ features = []
388
+ } = props;
389
+ const mapRef = useRef(null);
390
+ const [map, setMap] = useState(null);
391
+ const [mode, setMode] = useState("static");
392
+ const [draw, setDraw] = useState(null);
393
+ const handleFeaturesChange = useCallback(
394
+ (newFeatures) => {
395
+ if (onFeaturesChange) {
396
+ onFeaturesChange(newFeatures);
397
+ }
398
+ },
399
+ [onFeaturesChange]
400
+ );
401
+ const autoFocus = useCallback(() => {
402
+ if (!(features == null ? void 0 : features.length) || !map)
403
+ return;
404
+ const _bbox = bbox({ type: "FeatureCollection", features });
405
+ map.fitBounds(_bbox, { padding: 40, duration: 1e3 });
406
+ }, [map, features]);
407
+ useEffect(() => {
408
+ var _a, _b, _c, _d, _e;
409
+ const maplibreMap = setupMaplibreMap({
410
+ containerId: "maplibre-map",
411
+ latitude: (_a = defaultViewState == null ? void 0 : defaultViewState.latitude) != null ? _a : 0,
412
+ longitude: (_b = defaultViewState == null ? void 0 : defaultViewState.longitude) != null ? _b : 0,
413
+ zoom: (_c = defaultViewState == null ? void 0 : defaultViewState.zoom) != null ? _c : 0,
414
+ pitch: (_d = defaultViewState == null ? void 0 : defaultViewState.pitch) != null ? _d : 0,
415
+ bearing: (_e = defaultViewState == null ? void 0 : defaultViewState.bearing) != null ? _e : 0,
416
+ mapstyle: defaultMapStyles[mapStyleIdx].style
417
+ });
418
+ const navControl = new maplibregl2.NavigationControl({
419
+ showCompass: true,
420
+ showZoom: true,
421
+ visualizePitch: true
422
+ });
423
+ maplibreMap.addControl(navControl, "bottom-right");
424
+ maplibreMap.once("style.load", () => setMap(maplibreMap));
425
+ return () => {
426
+ maplibreMap.removeControl(navControl);
427
+ setMap(null);
428
+ };
429
+ }, []);
430
+ useEffect(() => {
431
+ if (!map)
432
+ return;
433
+ const terraDraw = setupDraw(map);
434
+ terraDraw.start();
435
+ setDraw(terraDraw);
436
+ const onChange = () => {
437
+ let snapshot = terraDraw.getSnapshot();
438
+ if (!isMultiple && snapshot.length > 1) {
439
+ const latestFeature = snapshot[snapshot.length - 1];
440
+ const toRemove = snapshot.slice(0, -1);
441
+ const featureIds = toRemove.map((f) => f.id).filter(Boolean);
442
+ if (featureIds.length > 0) {
443
+ terraDraw.removeFeatures(featureIds);
444
+ }
445
+ snapshot = [latestFeature];
446
+ }
447
+ handleFeaturesChange(snapshot);
448
+ };
449
+ terraDraw.on("change", onChange);
450
+ if (features.length) {
451
+ const timeoutId = setTimeout(() => {
452
+ if (terraDraw.getSnapshot().length === 0) {
453
+ let featuresWithMode = ensureModeProperty(features);
454
+ if (!isMultiple && featuresWithMode.length > 1) {
455
+ featuresWithMode = [featuresWithMode[featuresWithMode.length - 1]];
456
+ }
457
+ terraDraw.addFeatures(featuresWithMode);
458
+ handleFeaturesChange(featuresWithMode);
459
+ autoFocus();
460
+ }
461
+ }, 300);
462
+ return () => {
463
+ clearTimeout(timeoutId);
464
+ terraDraw.off("change", onChange);
465
+ terraDraw.stop();
466
+ setDraw(null);
467
+ };
468
+ }
469
+ return () => {
470
+ terraDraw.off("change", onChange);
471
+ terraDraw.stop();
472
+ setDraw(null);
473
+ };
474
+ }, [map, isMultiple, features, handleFeaturesChange, autoFocus]);
475
+ useEffect(() => {
476
+ if (features && features.length > 0) {
477
+ onFeaturesChange == null ? void 0 : onFeaturesChange(features);
478
+ autoFocus();
479
+ }
480
+ }, [features, autoFocus, onFeaturesChange]);
481
+ const changeMode = useCallback(
482
+ (newMode) => {
483
+ draw == null ? void 0 : draw.setMode(newMode);
484
+ setMode(newMode);
485
+ },
486
+ [draw]
487
+ );
488
+ return /* @__PURE__ */ jsxs3("div", {
489
+ children: [
490
+ /* @__PURE__ */ jsx5("div", {
491
+ ref: mapRef,
492
+ id: "maplibre-map",
493
+ style: { width: "100%", height: "100vh" }
494
+ }),
495
+ draw && /* @__PURE__ */ jsxs3(Fragment, {
496
+ children: [
497
+ /* @__PURE__ */ jsx5(MapButtons_default, {
498
+ mode,
499
+ changeMode
500
+ }),
501
+ /* @__PURE__ */ jsx5("div", {
502
+ style: {
503
+ position: "absolute",
504
+ top: "180px",
505
+ left: "10px",
506
+ display: "flex",
507
+ flexDirection: "column",
508
+ gap: "6px",
509
+ zIndex: 1e3,
510
+ backgroundColor: "rgba(255, 255, 255, 0.9)",
511
+ padding: "8px",
512
+ borderRadius: "6px",
513
+ boxShadow: "0 2px 6px rgba(0,0,0,0.2)"
514
+ },
515
+ children: /* @__PURE__ */ jsx5(ClearButton_default, {
516
+ draw,
517
+ onFeaturesChange
518
+ })
519
+ })
520
+ ]
521
+ })
522
+ ]
523
+ });
524
+ };
525
+ var map_default = Map;
526
+
527
+ // src/index.tsx
528
+ import { jsx as jsx6 } from "react/jsx-runtime";
529
+ var NakshaMaplibreDraw = (props) => /* @__PURE__ */ jsx6(map_default, __spreadValues({}, props));
530
+ export {
531
+ NakshaMaplibreDraw
532
+ };
package/dist/index.js CHANGED
@@ -1 +1,552 @@
1
- "use strict";var ue=Object.create;var x=Object.defineProperty,de=Object.defineProperties,ce=Object.getOwnPropertyDescriptor,pe=Object.getOwnPropertyDescriptors,ge=Object.getOwnPropertyNames,V=Object.getOwnPropertySymbols,me=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty,fe=Object.prototype.propertyIsEnumerable;var z=(e,t,r)=>t in e?x(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,S=(e,t)=>{for(var r in t||(t={}))E.call(t,r)&&z(e,r,t[r]);if(V)for(var r of V(t))fe.call(t,r)&&z(e,r,t[r]);return e},T=(e,t)=>de(e,pe(t));var he=(e,t)=>{for(var r in t)x(e,r,{get:t[r],enumerable:!0})},W=(e,t,r,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ge(t))!E.call(e,a)&&a!==r&&x(e,a,{get:()=>t[a],enumerable:!(c=ce(t,a))||c.enumerable});return e};var A=(e,t,r)=>(r=e!=null?ue(me(e)):{},W(t||!e||!e.__esModule?x(r,"default",{value:e,enumerable:!0}):r,e)),we=e=>W(x({},"__esModule",{value:!0}),e);var De={};he(De,{NakshaMaplibreDraw:()=>Ce});module.exports=we(De);var I=A(require("maplibre-gl"));var n=require("terra-draw"),H=require("terra-draw-maplibre-gl-adapter");function Z(e){return new n.TerraDraw({tracked:!0,adapter:new H.TerraDrawMapLibreGLAdapter({map:e,coordinatePrecision:9}),modes:[new n.TerraDrawSelectMode({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 n.TerraDrawPointMode,new n.TerraDrawLineStringMode({validation:(t,{updateType:r})=>r==="finish"||r==="commit"?(0,n.ValidateNotSelfIntersecting)(t):{valid:!0}}),new n.TerraDrawRectangleMode,new n.TerraDrawPolygonMode({pointerDistance:30,validation:(t,{updateType:r})=>r==="finish"||r==="commit"?(0,n.ValidateNotSelfIntersecting)(t):{valid:!0}}),new n.TerraDrawCircleMode,new n.TerraDrawFreehandMode({pointerDistance:5,validation:t=>(0,n.ValidateNotSelfIntersecting)(t)})]})}var i=require("react");var y=A(require("maplibre-gl"));function q({containerId:e,latitude:t=0,longitude:r=0,zoom:c,pitch:a,bearing:g,mapstyle:B}){return y.default.getRTLTextPluginStatus()==="unavailable"&&y.default.setRTLTextPlugin("https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",!0),new y.default.Map({container:e,style:B,center:{lat:t,lng:r},zoom:c,pitch:a,bearing:g})}var l=require("react/jsx-runtime"),K=()=>(0,l.jsxs)("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:[(0,l.jsx)("path",{d:"M12.586 12.586 19 19"}),(0,l.jsx)("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"})]}),Q=()=>(0,l.jsxs)("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:[(0,l.jsx)("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"}),(0,l.jsx)("circle",{cx:"12",cy:"10",r:"3"})]}),U=()=>(0,l.jsx)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:(0,l.jsx)("line",{x1:"4",y1:"20",x2:"20",y2:"4"})}),X=()=>(0,l.jsx)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:(0,l.jsx)("polygon",{points:"12,2 22,8 18,22 6,22 2,8"})}),Y=()=>(0,l.jsx)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:(0,l.jsx)("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"})});var N=require("react/jsx-runtime"),be=({draw:e})=>e?(0,N.jsx)("button",{onClick:()=>e.clear(),title:"Delete",style:{display:"flex",justifyContent:"center",alignItems:"center",width:"30px",height:"30px",padding:"0",borderRadius:"4px",backgroundColor:"#f0f0f0",cursor:"pointer"},children:(0,N.jsx)(Y,{})}):null,_=be;var $=require("react/jsx-runtime"),Me=({mode:e,currentMode:t,changeMode:r,icon:c,tooltip:a})=>(0,$.jsx)("button",{onClick:()=>r(e),title:a,style:{display:"flex",justifyContent:"center",alignItems:"center",width:"30px",height:"30px",padding:"0",borderRadius:"4px",backgroundColor:t===e?"#02cf87":"#f0f0f0",cursor:"pointer"},children:c}),v=Me;var d=require("react/jsx-runtime"),xe=({mode:e,changeMode:t,draw:r})=>(0,d.jsxs)("div",{style:{position:"absolute",top:"10px",left:"10px",display:"flex",flexDirection:"column",gap:"6px",zIndex:1e3,backgroundColor:"rgba(255, 255, 255, 0.9)",padding:"8px",borderRadius:"6px",boxShadow:"0 2px 6px rgba(0,0,0,0.2)"},children:[(0,d.jsx)(v,{mode:"select",icon:(0,d.jsx)(K,{}),currentMode:e,changeMode:t,tooltip:"Select"}),(0,d.jsx)(v,{mode:"point",icon:(0,d.jsx)(Q,{}),currentMode:e,changeMode:t,tooltip:"Point"}),(0,d.jsx)(v,{mode:"linestring",icon:(0,d.jsx)(U,{}),currentMode:e,changeMode:t,tooltip:"Line"}),(0,d.jsx)(v,{mode:"polygon",icon:(0,d.jsx)(X,{}),currentMode:e,changeMode:t,tooltip:"Polygon"}),r&&(0,d.jsx)(_,{draw:r})]}),j=xe;var ee=require("@biodiv-platform/naksha-commons");var m=require("react/jsx-runtime"),Se=e=>e.map(t=>{var a,g;if((a=t.properties)!=null&&a.mode)return t;let r=(g=t.geometry)==null?void 0:g.type,c=r==="Point"?"point":r==="Polygon"?"polygon":r==="LineString"?"linestring":"unknown";return T(S({},t),{properties:T(S({},t.properties),{mode:c})})}),ve=e=>{if(!e.length)return null;let t=new I.default.LngLatBounds;return e.forEach(r=>{ye(r).forEach(a=>{Array.isArray(a[0])?a.forEach(g=>t.extend(g)):t.extend(a)})}),t},ye=e=>{let t=e.geometry;switch(t.type){case"Point":return[t.coordinates];case"LineString":return[t.coordinates];case"Polygon":return t.coordinates;default:return[]}},ke=e=>{let t=(0,i.useRef)(null),[r,c]=(0,i.useState)(),[a,g]=(0,i.useState)("static"),[B,oe]=(0,i.useState)(),[Fe,R]=(0,i.useState)([]),[f,ne]=(0,i.useState)(),ae=ee.defaultMapStyles[(e==null?void 0:e.mapStyle)||0].style,{isMultiple:k=!0,isControlled:C=!1,setFeatures:D}=e,[ie,se]=(0,i.useState)([]),F=(0,i.useCallback)(o=>{C&&D?D(o):se(o)},[C,D]),Le=C?e.features||[]:ie,L=(0,i.useCallback)(o=>{if(!r||o.length===0)return;let p=ve(o);p&&!p.isEmpty()&&r.fitBounds(p,{padding:50,duration:1e3,maxZoom:5})},[r]);(0,i.useEffect)(()=>{var w,u,s,b,P,M,h,G,J,O;let o=q({containerId:"maplibre-map",latitude:(u=(w=e.defaultViewState)==null?void 0:w.latitude)!=null?u:0,longitude:(b=(s=e.defaultViewState)==null?void 0:s.longitude)!=null?b:0,zoom:(M=(P=e.defaultViewState)==null?void 0:P.zoom)!=null?M:0,pitch:(G=(h=e.defaultViewState)==null?void 0:h.pitch)!=null?G:0,bearing:(O=(J=e.defaultViewState)==null?void 0:J.bearing)!=null?O:0,mapstyle:ae}),p=new I.default.NavigationControl({showCompass:!0,showZoom:!0,visualizePitch:!0});return o.addControl(p,"bottom-right"),o.once("style.load",()=>c(o)),()=>{p&&o&&o.removeControl(p)}},[]),(0,i.useEffect)(()=>{var w;if(!r)return;let o=Z(r);o.start(),ne(o);let p=()=>{let u=o.getSnapshot(),s=u;if(!k&&u.length>1){s=[u[u.length-1]];let M=u.slice(0,-1).map(h=>h.id).filter(h=>h!==void 0);M.length>0&&o.removeFeatures(M)}R(s),F(s),oe(s.find(b=>b.properties.selected)),s.length>0&&L(s)};return o.on("change",p),(w=e.features)!=null&&w.length&&setTimeout(()=>{if(o.getSnapshot().length===0){let u=Se(e.features),s=u;!k&&u.length>1&&(s=[u[u.length-1]]),o.addFeatures(s),R(s),F(s),L(s)}},300),()=>{o.off("change",p),o.stop()}},[r,k,F,L]);let le=(0,i.useCallback)(o=>{f==null||f.setMode(o),g(o)},[f]);return(0,m.jsxs)("div",{children:[(0,m.jsx)("div",{ref:t,id:"maplibre-map",style:{width:"100%",height:"100vh"}}),f&&(0,m.jsx)(m.Fragment,{children:(0,m.jsx)(j,{mode:a,changeMode:le,draw:f})})]})},te=ke;var re=require("react/jsx-runtime"),Ce=e=>(0,re.jsx)(te,S({},e));0&&(module.exports={NakshaMaplibreDraw});
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __copyProps = (to, from, except, desc) => {
30
+ if (from && typeof from === "object" || typeof from === "function") {
31
+ for (let key of __getOwnPropNames(from))
32
+ if (!__hasOwnProp.call(to, key) && key !== except)
33
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
+ }
35
+ return to;
36
+ };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
39
+ mod
40
+ ));
41
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
42
+
43
+ // src/index.tsx
44
+ var src_exports = {};
45
+ __export(src_exports, {
46
+ NakshaMaplibreDraw: () => NakshaMaplibreDraw
47
+ });
48
+ module.exports = __toCommonJS(src_exports);
49
+
50
+ // src/components/map.tsx
51
+ var import_maplibre_gl2 = __toESM(require("maplibre-gl"));
52
+
53
+ // src/components/setup-draw.tsx
54
+ var import_terra_draw = require("terra-draw");
55
+ var import_terra_draw_maplibre_gl_adapter = require("terra-draw-maplibre-gl-adapter");
56
+ function setupDraw(map) {
57
+ return new import_terra_draw.TerraDraw({
58
+ tracked: true,
59
+ adapter: new import_terra_draw_maplibre_gl_adapter.TerraDrawMapLibreGLAdapter({
60
+ map,
61
+ coordinatePrecision: 9
62
+ }),
63
+ modes: [
64
+ new import_terra_draw.TerraDrawSelectMode({
65
+ flags: {
66
+ polygon: {
67
+ feature: {
68
+ scaleable: true,
69
+ rotateable: true,
70
+ draggable: true,
71
+ coordinates: {
72
+ midpoints: true,
73
+ draggable: true,
74
+ deletable: true
75
+ }
76
+ }
77
+ },
78
+ linestring: {
79
+ feature: {
80
+ draggable: true,
81
+ coordinates: {
82
+ midpoints: true,
83
+ draggable: true,
84
+ deletable: true
85
+ }
86
+ }
87
+ },
88
+ circle: {
89
+ feature: {
90
+ draggable: true
91
+ }
92
+ },
93
+ point: {
94
+ feature: {
95
+ draggable: true
96
+ }
97
+ },
98
+ rectangle: {
99
+ feature: {
100
+ draggable: true,
101
+ coordinates: {
102
+ resizable: "opposite"
103
+ }
104
+ }
105
+ },
106
+ freehand: {
107
+ feature: {
108
+ draggable: true
109
+ }
110
+ }
111
+ }
112
+ }),
113
+ new import_terra_draw.TerraDrawPointMode(),
114
+ new import_terra_draw.TerraDrawLineStringMode({
115
+ validation: (feature, { updateType }) => {
116
+ if (updateType === "finish" || updateType === "commit") {
117
+ return (0, import_terra_draw.ValidateNotSelfIntersecting)(feature);
118
+ }
119
+ return {
120
+ valid: true
121
+ };
122
+ }
123
+ }),
124
+ new import_terra_draw.TerraDrawRectangleMode(),
125
+ new import_terra_draw.TerraDrawPolygonMode({
126
+ pointerDistance: 30,
127
+ validation: (feature, { updateType }) => {
128
+ if (updateType === "finish" || updateType === "commit") {
129
+ return (0, import_terra_draw.ValidateNotSelfIntersecting)(feature);
130
+ }
131
+ return {
132
+ valid: true
133
+ };
134
+ }
135
+ }),
136
+ new import_terra_draw.TerraDrawCircleMode(),
137
+ new import_terra_draw.TerraDrawFreehandMode({
138
+ pointerDistance: 5,
139
+ validation: (feature) => {
140
+ return (0, import_terra_draw.ValidateNotSelfIntersecting)(feature);
141
+ }
142
+ })
143
+ ]
144
+ });
145
+ }
146
+
147
+ // src/components/map.tsx
148
+ var import_react = require("react");
149
+
150
+ // src/components/setup-maplibre.tsx
151
+ var import_maplibre_gl = __toESM(require("maplibre-gl"));
152
+ function setupMaplibreMap({
153
+ containerId,
154
+ latitude = 0,
155
+ longitude = 0,
156
+ zoom,
157
+ pitch,
158
+ bearing,
159
+ mapstyle
160
+ }) {
161
+ if (import_maplibre_gl.default.getRTLTextPluginStatus() === "unavailable") {
162
+ import_maplibre_gl.default.setRTLTextPlugin(
163
+ "https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",
164
+ true
165
+ );
166
+ }
167
+ return new import_maplibre_gl.default.Map({
168
+ container: containerId,
169
+ style: mapstyle,
170
+ center: { lat: latitude, lng: longitude },
171
+ zoom,
172
+ pitch,
173
+ bearing
174
+ });
175
+ }
176
+
177
+ // src/components/icon-buttons/icons.tsx
178
+ var import_jsx_runtime = require("react/jsx-runtime");
179
+ var SelectIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
180
+ xmlns: "http://www.w3.org/2000/svg",
181
+ width: "24",
182
+ height: "24",
183
+ viewBox: "0 0 24 24",
184
+ fill: "none",
185
+ stroke: "currentColor",
186
+ strokeWidth: "1.5",
187
+ strokeLinecap: "round",
188
+ strokeLinejoin: "round",
189
+ children: [
190
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
191
+ d: "M12.586 12.586 19 19"
192
+ }),
193
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
194
+ 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
+ })
196
+ ]
197
+ });
198
+ var PointIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
199
+ xmlns: "http://www.w3.org/2000/svg",
200
+ width: "24",
201
+ height: "24",
202
+ viewBox: "0 0 24 24",
203
+ fill: "none",
204
+ stroke: "currentColor",
205
+ strokeWidth: "1.5",
206
+ strokeLinecap: "round",
207
+ strokeLinejoin: "round",
208
+ children: [
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
210
+ 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
+ }),
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
213
+ cx: "12",
214
+ cy: "10",
215
+ r: "3"
216
+ })
217
+ ]
218
+ });
219
+ var LineIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
220
+ width: "16",
221
+ height: "16",
222
+ viewBox: "0 0 24 24",
223
+ fill: "none",
224
+ stroke: "currentColor",
225
+ strokeWidth: "2",
226
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", {
227
+ x1: "4",
228
+ y1: "20",
229
+ x2: "20",
230
+ y2: "4"
231
+ })
232
+ });
233
+ var PolygonIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
234
+ width: "16",
235
+ height: "16",
236
+ viewBox: "0 0 24 24",
237
+ fill: "none",
238
+ stroke: "currentColor",
239
+ strokeWidth: "2",
240
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", {
241
+ points: "12,2 22,8 18,22 6,22 2,8"
242
+ })
243
+ });
244
+ var DeleteIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
245
+ width: "16",
246
+ height: "16",
247
+ viewBox: "0 0 24 24",
248
+ fill: "none",
249
+ stroke: "currentColor",
250
+ strokeWidth: "2",
251
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
252
+ 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
+ })
254
+ });
255
+
256
+ // src/components/map-button/MapButton.tsx
257
+ var import_jsx_runtime2 = require("react/jsx-runtime");
258
+ var MapButton = ({
259
+ mode,
260
+ currentMode,
261
+ changeMode,
262
+ icon,
263
+ tooltip
264
+ }) => {
265
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", {
266
+ onClick: () => changeMode(mode),
267
+ title: tooltip,
268
+ style: {
269
+ display: "flex",
270
+ justifyContent: "center",
271
+ alignItems: "center",
272
+ width: "30px",
273
+ height: "30px",
274
+ padding: "0",
275
+ borderRadius: "4px",
276
+ backgroundColor: currentMode === mode ? "#02cf87" : "#f0f0f0",
277
+ cursor: "pointer"
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;
337
+
338
+ // src/components/map.tsx
339
+ var import_naksha_commons = require("@biodiv-platform/naksha-commons");
340
+
341
+ // src/components/icon-buttons/ClearButton.tsx
342
+ var import_jsx_runtime4 = require("react/jsx-runtime");
343
+ var ClearButton = ({
344
+ draw,
345
+ onFeaturesChange
346
+ }) => {
347
+ if (!draw)
348
+ return null;
349
+ const handleClear = () => {
350
+ draw.clear();
351
+ if (onFeaturesChange) {
352
+ onFeaturesChange([]);
353
+ }
354
+ };
355
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", {
356
+ onClick: handleClear,
357
+ title: "Delete",
358
+ style: {
359
+ display: "flex",
360
+ justifyContent: "center",
361
+ alignItems: "center",
362
+ width: "30px",
363
+ height: "30px",
364
+ padding: "0",
365
+ borderRadius: "4px",
366
+ backgroundColor: "#f0f0f0",
367
+ cursor: "pointer"
368
+ },
369
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DeleteIcon, {})
370
+ });
371
+ };
372
+ var ClearButton_default = ClearButton;
373
+
374
+ // src/components/map.tsx
375
+ var import_bbox = __toESM(require("@turf/bbox"));
376
+ var import_jsx_runtime5 = require("react/jsx-runtime");
377
+ var ensureModeProperty = (features) => features.map((feature) => {
378
+ var _a, _b;
379
+ if ((_a = feature.properties) == null ? void 0 : _a.mode)
380
+ return feature;
381
+ let mode;
382
+ switch ((_b = feature.geometry) == null ? void 0 : _b.type) {
383
+ case "Point":
384
+ mode = "point";
385
+ break;
386
+ case "Polygon":
387
+ mode = "polygon";
388
+ break;
389
+ case "LineString":
390
+ mode = "linestring";
391
+ break;
392
+ default:
393
+ mode = "unknown";
394
+ }
395
+ return __spreadProps(__spreadValues({}, feature), {
396
+ properties: __spreadProps(__spreadValues({}, feature.properties), { mode })
397
+ });
398
+ });
399
+ var Map = (props) => {
400
+ const {
401
+ mapStyle: mapStyleIdx = 0,
402
+ defaultViewState,
403
+ isMultiple = true,
404
+ isControlled = false,
405
+ onFeaturesChange,
406
+ features = []
407
+ } = props;
408
+ const mapRef = (0, import_react.useRef)(null);
409
+ const [map, setMap] = (0, import_react.useState)(null);
410
+ const [mode, setMode] = (0, import_react.useState)("static");
411
+ const [draw, setDraw] = (0, import_react.useState)(null);
412
+ const handleFeaturesChange = (0, import_react.useCallback)(
413
+ (newFeatures) => {
414
+ if (onFeaturesChange) {
415
+ onFeaturesChange(newFeatures);
416
+ }
417
+ },
418
+ [onFeaturesChange]
419
+ );
420
+ const autoFocus = (0, import_react.useCallback)(() => {
421
+ if (!(features == null ? void 0 : features.length) || !map)
422
+ return;
423
+ const _bbox = (0, import_bbox.default)({ type: "FeatureCollection", features });
424
+ map.fitBounds(_bbox, { padding: 40, duration: 1e3 });
425
+ }, [map, features]);
426
+ (0, import_react.useEffect)(() => {
427
+ var _a, _b, _c, _d, _e;
428
+ const maplibreMap = setupMaplibreMap({
429
+ containerId: "maplibre-map",
430
+ latitude: (_a = defaultViewState == null ? void 0 : defaultViewState.latitude) != null ? _a : 0,
431
+ longitude: (_b = defaultViewState == null ? void 0 : defaultViewState.longitude) != null ? _b : 0,
432
+ zoom: (_c = defaultViewState == null ? void 0 : defaultViewState.zoom) != null ? _c : 0,
433
+ pitch: (_d = defaultViewState == null ? void 0 : defaultViewState.pitch) != null ? _d : 0,
434
+ bearing: (_e = defaultViewState == null ? void 0 : defaultViewState.bearing) != null ? _e : 0,
435
+ mapstyle: import_naksha_commons.defaultMapStyles[mapStyleIdx].style
436
+ });
437
+ const navControl = new import_maplibre_gl2.default.NavigationControl({
438
+ showCompass: true,
439
+ showZoom: true,
440
+ visualizePitch: true
441
+ });
442
+ maplibreMap.addControl(navControl, "bottom-right");
443
+ maplibreMap.once("style.load", () => setMap(maplibreMap));
444
+ return () => {
445
+ maplibreMap.removeControl(navControl);
446
+ setMap(null);
447
+ };
448
+ }, []);
449
+ (0, import_react.useEffect)(() => {
450
+ if (!map)
451
+ return;
452
+ const terraDraw = setupDraw(map);
453
+ terraDraw.start();
454
+ setDraw(terraDraw);
455
+ const onChange = () => {
456
+ let snapshot = terraDraw.getSnapshot();
457
+ if (!isMultiple && snapshot.length > 1) {
458
+ const latestFeature = snapshot[snapshot.length - 1];
459
+ const toRemove = snapshot.slice(0, -1);
460
+ const featureIds = toRemove.map((f) => f.id).filter(Boolean);
461
+ if (featureIds.length > 0) {
462
+ terraDraw.removeFeatures(featureIds);
463
+ }
464
+ snapshot = [latestFeature];
465
+ }
466
+ handleFeaturesChange(snapshot);
467
+ };
468
+ terraDraw.on("change", onChange);
469
+ if (features.length) {
470
+ const timeoutId = setTimeout(() => {
471
+ if (terraDraw.getSnapshot().length === 0) {
472
+ let featuresWithMode = ensureModeProperty(features);
473
+ if (!isMultiple && featuresWithMode.length > 1) {
474
+ featuresWithMode = [featuresWithMode[featuresWithMode.length - 1]];
475
+ }
476
+ terraDraw.addFeatures(featuresWithMode);
477
+ handleFeaturesChange(featuresWithMode);
478
+ autoFocus();
479
+ }
480
+ }, 300);
481
+ return () => {
482
+ clearTimeout(timeoutId);
483
+ terraDraw.off("change", onChange);
484
+ terraDraw.stop();
485
+ setDraw(null);
486
+ };
487
+ }
488
+ return () => {
489
+ terraDraw.off("change", onChange);
490
+ terraDraw.stop();
491
+ setDraw(null);
492
+ };
493
+ }, [map, isMultiple, features, handleFeaturesChange, autoFocus]);
494
+ (0, import_react.useEffect)(() => {
495
+ if (features && features.length > 0) {
496
+ onFeaturesChange == null ? void 0 : onFeaturesChange(features);
497
+ autoFocus();
498
+ }
499
+ }, [features, autoFocus, onFeaturesChange]);
500
+ const changeMode = (0, import_react.useCallback)(
501
+ (newMode) => {
502
+ draw == null ? void 0 : draw.setMode(newMode);
503
+ setMode(newMode);
504
+ },
505
+ [draw]
506
+ );
507
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", {
508
+ children: [
509
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", {
510
+ ref: mapRef,
511
+ id: "maplibre-map",
512
+ style: { width: "100%", height: "100vh" }
513
+ }),
514
+ draw && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, {
515
+ children: [
516
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MapButtons_default, {
517
+ mode,
518
+ changeMode
519
+ }),
520
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", {
521
+ style: {
522
+ position: "absolute",
523
+ top: "180px",
524
+ left: "10px",
525
+ display: "flex",
526
+ flexDirection: "column",
527
+ gap: "6px",
528
+ zIndex: 1e3,
529
+ backgroundColor: "rgba(255, 255, 255, 0.9)",
530
+ padding: "8px",
531
+ borderRadius: "6px",
532
+ boxShadow: "0 2px 6px rgba(0,0,0,0.2)"
533
+ },
534
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ClearButton_default, {
535
+ draw,
536
+ onFeaturesChange
537
+ })
538
+ })
539
+ ]
540
+ })
541
+ ]
542
+ });
543
+ };
544
+ var map_default = Map;
545
+
546
+ // src/index.tsx
547
+ var import_jsx_runtime6 = require("react/jsx-runtime");
548
+ var NakshaMaplibreDraw = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(map_default, __spreadValues({}, props));
549
+ // Annotate the CommonJS export names for ESM import in node:
550
+ 0 && (module.exports = {
551
+ NakshaMaplibreDraw
552
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biodiv-platform/naksha-maplibre-draw",
3
- "version": "5.0.2",
3
+ "version": "5.0.4",
4
4
  "author": "harshzalavadiya",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -36,7 +36,7 @@
36
36
  "react-icons": "^5.5.0"
37
37
  },
38
38
  "dependencies": {
39
- "@biodiv-platform/naksha-commons": "5.0.0-beta.1",
39
+ "@biodiv-platform/naksha-commons": "5.0.0-beta.2",
40
40
  "@turf/bbox": "^6.5.0",
41
41
  "boundingbox": "^1.4.0",
42
42
  "react-gbus": "^1.1.2",