@metastringfoundation/map-list 0.1.0 → 0.1.2

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.
Files changed (106) hide show
  1. package/dist/components/Handler/LayerCompareControl.d.ts +7 -0
  2. package/dist/components/Handler/LayerCompareControl.d.ts.map +1 -0
  3. package/dist/components/Handler/LayerCompareControl.js +18 -0
  4. package/dist/components/Handler/MapComparisonControl.d.ts +7 -0
  5. package/dist/components/Handler/MapComparisonControl.d.ts.map +1 -0
  6. package/dist/components/Handler/MapComparisonControl.js +8 -0
  7. package/dist/components/core/button.js +1 -1
  8. package/dist/components/core/input.d.ts.map +1 -1
  9. package/dist/components/core/input.js +1 -1
  10. package/dist/components/dualMap/MapLayerCard.d.ts +8 -0
  11. package/dist/components/dualMap/MapLayerCard.d.ts.map +1 -0
  12. package/dist/components/dualMap/MapLayerCard.js +68 -0
  13. package/dist/components/dualMap/index.d.ts +3 -0
  14. package/dist/components/dualMap/index.d.ts.map +1 -0
  15. package/dist/components/dualMap/index.js +277 -0
  16. package/dist/components/map/compare-sidebar.d.ts +2 -0
  17. package/dist/components/map/compare-sidebar.d.ts.map +1 -0
  18. package/dist/components/map/compare-sidebar.js +34 -0
  19. package/dist/components/map/compare.d.ts +2 -0
  20. package/dist/components/map/compare.d.ts.map +1 -0
  21. package/dist/components/map/compare.js +42 -0
  22. package/dist/components/map/index.d.ts.map +1 -1
  23. package/dist/components/map/index.js +14 -1
  24. package/dist/components/map/layers/grid/index.d.ts.map +1 -1
  25. package/dist/components/map/layers/grid/index.js +11 -1
  26. package/dist/components/map/layers/index.d.ts.map +1 -1
  27. package/dist/components/map/layers/index.js +17 -14
  28. package/dist/components/map/layers/raster/index.d.ts.map +1 -1
  29. package/dist/components/map/layers/raster/index.js +8 -8
  30. package/dist/components/map/layers/vector/index.d.ts.map +1 -1
  31. package/dist/components/map/layers/vector/index.js +25 -1
  32. package/dist/components/map/search.d.ts +2 -0
  33. package/dist/components/map/search.d.ts.map +1 -0
  34. package/dist/components/map/search.js +122 -0
  35. package/dist/components/map/split-map/SplitMapComparision.d.ts +2 -0
  36. package/dist/components/map/split-map/SplitMapComparision.d.ts.map +1 -0
  37. package/dist/components/map/split-map/SplitMapComparision.js +78 -0
  38. package/dist/components/map-comparison/attribute-selector.d.ts +11 -0
  39. package/dist/components/map-comparison/attribute-selector.d.ts.map +1 -0
  40. package/dist/components/map-comparison/attribute-selector.js +10 -0
  41. package/dist/components/map-comparison/comparison-panel.d.ts +2 -0
  42. package/dist/components/map-comparison/comparison-panel.d.ts.map +1 -0
  43. package/dist/components/map-comparison/comparison-panel.js +45 -0
  44. package/dist/components/map-comparison/comparison-stats.d.ts +2 -0
  45. package/dist/components/map-comparison/comparison-stats.d.ts.map +1 -0
  46. package/dist/components/map-comparison/comparison-stats.js +35 -0
  47. package/dist/components/map-comparison/comparison-view.d.ts +2 -0
  48. package/dist/components/map-comparison/comparison-view.d.ts.map +1 -0
  49. package/dist/components/map-comparison/comparison-view.js +152 -0
  50. package/dist/components/map-comparison/comparison-wrapper.d.ts +8 -0
  51. package/dist/components/map-comparison/comparison-wrapper.d.ts.map +1 -0
  52. package/dist/components/map-comparison/comparison-wrapper.js +26 -0
  53. package/dist/components/map-comparison/index.d.ts +3 -0
  54. package/dist/components/map-comparison/index.d.ts.map +1 -0
  55. package/dist/components/map-comparison/index.js +165 -0
  56. package/dist/components/map-comparison/types.d.ts +30 -0
  57. package/dist/components/map-comparison/types.d.ts.map +1 -0
  58. package/dist/components/map-comparison/types.js +2 -0
  59. package/dist/components/map-comparison/use-map-comparison.d.ts +18 -0
  60. package/dist/components/map-comparison/use-map-comparison.d.ts.map +1 -0
  61. package/dist/components/map-comparison/use-map-comparison.js +139 -0
  62. package/dist/components/sidebar/common/attribute-compare-addon.d.ts +7 -0
  63. package/dist/components/sidebar/common/attribute-compare-addon.d.ts.map +1 -0
  64. package/dist/components/sidebar/common/attribute-compare-addon.js +36 -0
  65. package/dist/components/sidebar/common/layer-compare-addon.d.ts +4 -0
  66. package/dist/components/sidebar/common/layer-compare-addon.d.ts.map +1 -0
  67. package/dist/components/sidebar/common/layer-compare-addon.js +17 -0
  68. package/dist/components/sidebar/common/layer-item-style.d.ts.map +1 -1
  69. package/dist/components/sidebar/common/layer-item-style.js +46 -1
  70. package/dist/components/sidebar/common/layer-item.d.ts.map +1 -1
  71. package/dist/components/sidebar/common/layer-item.js +1 -1
  72. package/dist/components/sidebar/common/opacity-handler-addon.d.ts +5 -2
  73. package/dist/components/sidebar/common/opacity-handler-addon.d.ts.map +1 -1
  74. package/dist/components/sidebar/common/opacity-handler-addon.js +101 -4
  75. package/dist/components/sidebar/common/style-legend.d.ts.map +1 -1
  76. package/dist/components/sidebar/common/style-legend.js +1 -2
  77. package/dist/components/sidebar/comparison/index.d.ts +4 -0
  78. package/dist/components/sidebar/comparison/index.d.ts.map +1 -0
  79. package/dist/components/sidebar/comparison/index.js +34 -0
  80. package/dist/components/sidebar/index.d.ts.map +1 -1
  81. package/dist/components/sidebar/search/attribute-comparison.d.ts +10 -0
  82. package/dist/components/sidebar/search/attribute-comparison.d.ts.map +1 -0
  83. package/dist/components/sidebar/search/attribute-comparison.js +137 -0
  84. package/dist/components/sidebar/search/index.d.ts +2 -0
  85. package/dist/components/sidebar/search/index.d.ts.map +1 -0
  86. package/dist/components/sidebar/search/index.js +29 -0
  87. package/dist/components/sidebar/selected/index.d.ts.map +1 -1
  88. package/dist/components/sidebar/selected/index.js +7 -4
  89. package/dist/components/sidebar/tabs.js +2 -2
  90. package/dist/hooks/use-layers.d.ts +10 -0
  91. package/dist/hooks/use-layers.d.ts.map +1 -1
  92. package/dist/hooks/use-layers.js +115 -5
  93. package/dist/hooks/use-polygon-data.d.ts +34 -0
  94. package/dist/hooks/use-polygon-data.d.ts.map +1 -0
  95. package/dist/hooks/use-polygon-data.js +74 -0
  96. package/dist/index.css +708 -28
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +10 -1
  99. package/dist/services/naksha.d.ts.map +1 -1
  100. package/dist/services/naksha.js +22 -158
  101. package/dist/services/polygon.d.ts +36 -0
  102. package/dist/services/polygon.d.ts.map +1 -0
  103. package/dist/services/polygon.js +67 -0
  104. package/dist/utils/naksha.d.ts.map +1 -1
  105. package/dist/utils/naksha.js +15 -6
  106. package/package.json +16 -15
@@ -63,6 +63,51 @@ const LayersProvider = ({ mp: _mp, children }) => {
63
63
  const [selectedLayerIds, setSelectedLayerIds] = (0, react_1.useState)(mp.selectedLayers || []);
64
64
  const [hoverFeatures, setHoverFeatures] = (0, react_1.useState)();
65
65
  const [selectedFeatures, setSelectedFeatures] = (0, react_1.useState)();
66
+ const [compareList, setCompareList] = (0, react_1.useState)((_mp && _mp.compareList) || []);
67
+ const [layerOpacities, setLayerOpacities] = (0, react_1.useState)({});
68
+ const [layerVisibilities, setLayerVisibilities] = (0, react_1.useState)({});
69
+ // State for tracking checked attributes for comparison (format: "layerId-styleIndex")
70
+ const [checkedAttributes, setCheckedAttributes] = (0, react_1.useState)(new Set());
71
+ // State for compare mode (showing dual map)
72
+ const [isCompareMode, setIsCompareMode] = (0, react_1.useState)(false);
73
+ const setCompareLayer = (layerId, checked) => {
74
+ setCompareList((prev) => {
75
+ if (checked)
76
+ return Array.from(new Set([layerId, ...prev]));
77
+ return prev.filter((id) => id !== layerId);
78
+ });
79
+ // optional: call mp.onCompareChange(layerId, checked) if you want callbacks
80
+ };
81
+ const toggleAttributeCompare = (attributeKey) => {
82
+ setCheckedAttributes((prev) => {
83
+ const newSet = new Set(prev);
84
+ if (newSet.has(attributeKey)) {
85
+ // Removing - always allowed
86
+ newSet.delete(attributeKey);
87
+ }
88
+ else {
89
+ // Adding - check limit
90
+ if (newSet.size >= 8) {
91
+ alert("Maximum 8 attributes can be compared at a time");
92
+ return prev; // Don't add, return previous state
93
+ }
94
+ newSet.add(attributeKey);
95
+ }
96
+ return newSet;
97
+ });
98
+ };
99
+ const getCheckedAttributesCount = () => {
100
+ return checkedAttributes.size;
101
+ };
102
+ const getLayerOpacity = (layerId) => {
103
+ return layerOpacities[layerId] ?? 1;
104
+ };
105
+ const setLayerOpacity = (layerId, opacity) => {
106
+ setLayerOpacities((prev) => ({
107
+ ...prev,
108
+ [layerId]: Math.max(0, Math.min(1, opacity)), // Clamp between 0 and 1
109
+ }));
110
+ };
66
111
  const selectedFeaturesId = (0, react_1.useMemo)(() => {
67
112
  const meta = {};
68
113
  for (const qr of selectedFeatures || []) {
@@ -103,18 +148,41 @@ const LayersProvider = ({ mp: _mp, children }) => {
103
148
  // @ts-ignore
104
149
  layer, styleIndex, mp.nakshaApiEndpoint, mp.geoserver);
105
150
  updateLayerById(layer.id, { data: layerData });
106
- focus &&
107
- mapl?.fitBounds(layer.bbox, { padding: 40, duration: 1000 });
151
+ // focus && mapl?.fitBounds(layer.bbox as any, { padding: 40, duration: 1000 });
108
152
  };
109
153
  const updateLayerStyle = async (layerId, styleIndex) => {
110
154
  const layerIndex = getLayerIndexById(layerId);
111
155
  toggleVectorLayer(layerIndex, styleIndex, false);
112
156
  };
157
+ // Fetch style data for comparison without changing the active styleIndex on main map
158
+ const fetchStyleForComparison = async (layerId, styleIndex) => {
159
+ const layerIndex = getLayerIndexById(layerId);
160
+ const layer = layers[layerIndex];
161
+ if (!layer)
162
+ return;
163
+ // Get the current active styleIndex to preserve it
164
+ const currentStyleIndex = layer.data?.styleIndex ?? 0;
165
+ // Fetch the style data
166
+ const layerData = await (0, naksha_2.getLayerStyle)(
167
+ // @ts-ignore
168
+ layer, styleIndex, mp.nakshaApiEndpoint, mp.geoserver);
169
+ // Update layer data but preserve the original styleIndex so main map doesn't change
170
+ updateLayerById(layer.id, {
171
+ data: {
172
+ ...layerData,
173
+ styleIndex: currentStyleIndex, // Keep the original active style
174
+ }
175
+ });
176
+ };
113
177
  const onMapHover = async (e) => {
114
178
  if (!selectedLayerIds.length || !mapl)
115
179
  return;
116
180
  try {
117
181
  const lastLayerId = selectedLayerIds[0];
182
+ // console.log(lastLayerId , "lastLayerId")
183
+ // added check
184
+ if (!mapl?.getLayer(lastLayerId))
185
+ return;
118
186
  const feats = mapl.queryRenderedFeatures(e.point, {
119
187
  layers: [lastLayerId],
120
188
  });
@@ -146,17 +214,31 @@ const LayersProvider = ({ mp: _mp, children }) => {
146
214
  const toggleLayer = async ({ layerId, add, styleIndex = 0, focus = true, }) => {
147
215
  if (!add) {
148
216
  setSelectedLayerIds(selectedLayerIds.filter((_lyrId) => layerId !== _lyrId));
217
+ // Remove all checked attributes for this layer when it's deselected
218
+ setCheckedAttributes((prev) => {
219
+ const newSet = new Set(prev);
220
+ for (const attrKey of prev) {
221
+ if (attrKey.startsWith(`${layerId}-`)) {
222
+ newSet.delete(attrKey);
223
+ }
224
+ }
225
+ return newSet;
226
+ });
149
227
  return;
150
228
  }
151
- // const layerIndex = getLayerIndexById(layerId);
229
+ const layerIndex = getLayerIndexById(layerId);
152
230
  // const sourceType = layers[layerIndex]?.source.type;
153
- // await toggleVectorLayer(layerIndex, styleIndex, focus);
231
+ await toggleVectorLayer(layerIndex, styleIndex, focus);
154
232
  setSelectedLayerIds((prev) => {
155
233
  const updated = [layerId, ...prev.filter((id) => id !== layerId)];
156
234
  return updated;
157
235
  });
158
236
  };
159
- const clearAllLayers = async () => setSelectedLayerIds([]);
237
+ const clearAllLayers = async () => {
238
+ setSelectedLayerIds([]);
239
+ // Clear all checked attributes when all layers are cleared
240
+ setCheckedAttributes(new Set());
241
+ };
160
242
  const updateMP = (key, value) => {
161
243
  setMP({ ...mp, [key]: value });
162
244
  };
@@ -251,6 +333,24 @@ const LayersProvider = ({ mp: _mp, children }) => {
251
333
  // if it takes more then 300 selection will be discarded
252
334
  setTimeout(featuresAtLatLng, 300);
253
335
  }, [clickedLngLat, selectionStyle, selectedLayerIds]);
336
+ // Sync checkedAttributes with selectedLayers - remove attributes for unselected layers
337
+ (0, react_1.useEffect)(() => {
338
+ setCheckedAttributes((prev) => {
339
+ const selectedIdsSet = new Set(selectedLayerIds);
340
+ const newSet = new Set();
341
+ for (const attrKey of prev) {
342
+ const [layerId] = attrKey.split("-");
343
+ if (!layerId) {
344
+ continue;
345
+ }
346
+ // Only keep attributes for layers that are currently selected
347
+ if (selectedIdsSet.has(layerId)) {
348
+ newSet.add(attrKey);
349
+ }
350
+ }
351
+ return newSet;
352
+ });
353
+ }, [selectedLayerIds]);
254
354
  return ((0, jsx_runtime_1.jsx)(LayersContext.Provider, { value: {
255
355
  mp,
256
356
  updateMP,
@@ -277,6 +377,16 @@ const LayersProvider = ({ mp: _mp, children }) => {
277
377
  zoomToExtent,
278
378
  gridLegends,
279
379
  setGridLegends,
380
+ compareList: compareList,
381
+ setCompareLayer: setCompareLayer,
382
+ getLayerOpacity,
383
+ setLayerOpacity,
384
+ checkedAttributes: checkedAttributes,
385
+ toggleAttributeCompare: toggleAttributeCompare,
386
+ getCheckedAttributesCount: getCheckedAttributesCount,
387
+ isCompareMode: isCompareMode,
388
+ setCompareMode: setIsCompareMode,
389
+ fetchStyleForComparison: fetchStyleForComparison,
280
390
  },
281
391
  query: {
282
392
  term: queryTermDebounced,
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ /** GeoJSON Feature from map-draw (polygon) */
3
+ export type PolygonShape = {
4
+ id: string;
5
+ type: "Feature";
6
+ geometry: {
7
+ type: string;
8
+ coordinates: unknown;
9
+ };
10
+ properties?: Record<string, unknown>;
11
+ };
12
+ interface PolygonDataContextValue {
13
+ /** Current drawn polygon features from map-draw */
14
+ shapes: PolygonShape[];
15
+ /** Fetch data from backend for current polygon(s). Call after user draws and hits Search. */
16
+ fetchPolygonData: (searchTerm?: string) => Promise<void>;
17
+ /** Response data from last successful fetch */
18
+ polygonData: unknown;
19
+ /** Loading state while fetch is in progress */
20
+ loading: boolean;
21
+ /** Error message from last failed fetch */
22
+ error: string | null;
23
+ /** Clear error (e.g. when user retries or draws again) */
24
+ clearError: () => void;
25
+ }
26
+ export interface PolygonProviderProps {
27
+ /** Drawn polygon features from useMapDraw().shapes */
28
+ shapes: PolygonShape[];
29
+ children: React.ReactNode;
30
+ }
31
+ export declare function PolygonProvider({ shapes, children }: PolygonProviderProps): import("react/jsx-runtime").JSX.Element;
32
+ export declare function usePolygonData(): PolygonDataContextValue;
33
+ export {};
34
+ //# sourceMappingURL=use-polygon-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-polygon-data.d.ts","sourceRoot":"","sources":["../../src/hooks/use-polygon-data.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAKhF,8CAA8C;AAC9C,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF,UAAU,uBAAuB;IAC/B,mDAAmD;IACnD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,6FAA6F;IAC7F,gBAAgB,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,+CAA+C;IAC/C,WAAW,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAID,MAAM,WAAW,oBAAoB;IACnC,sDAAsD;IACtD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,oBAAoB,2CAkEzE;AAED,wBAAgB,cAAc,IAAI,uBAAuB,CAMxD"}
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PolygonProvider = PolygonProvider;
8
+ exports.usePolygonData = usePolygonData;
9
+ const jsx_runtime_1 = require("react/jsx-runtime");
10
+ const react_1 = require("react");
11
+ const polygon_1 = require("../services/polygon");
12
+ const use_layers_1 = __importDefault(require("./use-layers"));
13
+ const PolygonDataContext = (0, react_1.createContext)(null);
14
+ function PolygonProvider({ shapes, children }) {
15
+ const { mp } = (0, use_layers_1.default)();
16
+ const [polygonData, setPolygonData] = (0, react_1.useState)(null);
17
+ const [loading, setLoading] = (0, react_1.useState)(false);
18
+ const [error, setError] = (0, react_1.useState)(null);
19
+ const fetchPolygonData = (0, react_1.useCallback)(async (searchTerm) => {
20
+ const endpoint = mp?.nakshaApiEndpoint;
21
+ const hasFullUrl = mp?.polygonDataPath != null && mp.polygonDataPath.startsWith("http");
22
+ if (!endpoint && !hasFullUrl) {
23
+ setError("API endpoint not configured (set nakshaApiEndpoint or polygonDataPath)");
24
+ return;
25
+ }
26
+ if (!shapes?.length) {
27
+ setError("Draw at least one polygon on the map first");
28
+ return;
29
+ }
30
+ const url = mp?.polygonDataPath != null && mp.polygonDataPath !== ""
31
+ ? mp.polygonDataPath.startsWith("http")
32
+ ? mp.polygonDataPath
33
+ : `${(endpoint ?? "").replace(/\/$/, "")}${mp.polygonDataPath.startsWith("/") ? "" : "/"}${mp.polygonDataPath}`
34
+ : undefined;
35
+ setError(null);
36
+ setLoading(true);
37
+ try {
38
+ const result = await (0, polygon_1.axFetchDataByPolygon)({
39
+ endpoint: endpoint ?? "",
40
+ url,
41
+ token: mp?.nakshaEndpointToken ?? undefined,
42
+ features: shapes,
43
+ searchTerm,
44
+ });
45
+ if (result.success) {
46
+ setPolygonData(result.data);
47
+ }
48
+ else {
49
+ setError(result.error);
50
+ setPolygonData(null);
51
+ }
52
+ }
53
+ finally {
54
+ setLoading(false);
55
+ }
56
+ }, [mp?.nakshaApiEndpoint, mp?.nakshaEndpointToken, shapes]);
57
+ const clearError = (0, react_1.useCallback)(() => setError(null), []);
58
+ const value = {
59
+ shapes: shapes ?? [],
60
+ fetchPolygonData,
61
+ polygonData,
62
+ loading,
63
+ error,
64
+ clearError,
65
+ };
66
+ return ((0, jsx_runtime_1.jsx)(PolygonDataContext.Provider, { value: value, children: children }));
67
+ }
68
+ function usePolygonData() {
69
+ const ctx = (0, react_1.useContext)(PolygonDataContext);
70
+ if (!ctx) {
71
+ throw new Error("usePolygonData must be used within PolygonProvider");
72
+ }
73
+ return ctx;
74
+ }