@mapcomponents/react-maplibre 0.1.65 → 0.1.67

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 (179) hide show
  1. package/.github/workflows/node_version_test.yml +1 -1
  2. package/.storybook/main.js +37 -31
  3. package/.storybook/preview.js +21 -0
  4. package/CHANGELOG.md +18 -0
  5. package/coverage/clover.xml +419 -344
  6. package/coverage/coverage-final.json +16 -15
  7. package/coverage/lcov-report/index.html +61 -61
  8. package/coverage/lcov-report/src/components/MapLibreMap/MapLibreMap.tsx.html +24 -18
  9. package/coverage/lcov-report/src/components/MapLibreMap/index.html +14 -14
  10. package/coverage/lcov-report/src/components/MlCenterPosition/MlCenterPosition.tsx.html +2 -2
  11. package/coverage/lcov-report/src/components/MlCenterPosition/index.html +1 -1
  12. package/coverage/lcov-report/src/components/MlCreatePdfButton/MlCreatePdfButton.tsx.html +1 -1
  13. package/coverage/lcov-report/src/components/MlCreatePdfButton/index.html +1 -1
  14. package/coverage/lcov-report/src/components/MlCreatePdfForm/MlCreatePdfForm.cy.tsx.html +1 -1
  15. package/coverage/lcov-report/src/components/MlCreatePdfForm/MlCreatePdfForm.tsx.html +1 -1
  16. package/coverage/lcov-report/src/components/MlCreatePdfForm/index.html +1 -1
  17. package/coverage/lcov-report/src/components/MlFeatureEditor/MlFeatureEditor.tsx.html +1 -1
  18. package/coverage/lcov-report/src/components/MlFeatureEditor/index.html +1 -1
  19. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/MlFillExtrusionLayer.tsx.html +1 -1
  20. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/index.html +1 -1
  21. package/coverage/lcov-report/src/components/MlFollowGps/MlFollowGps.tsx.html +9 -9
  22. package/coverage/lcov-report/src/components/MlFollowGps/index.html +1 -1
  23. package/coverage/lcov-report/src/components/MlGeoJsonLayer/MlGeoJsonLayer.tsx.html +1 -1
  24. package/coverage/lcov-report/src/components/MlGeoJsonLayer/index.html +1 -1
  25. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.lineStyler.js.html +1 -1
  26. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/MlGeoJsonLayer.polygonStyler.js.html +1 -1
  27. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/MlGeojsonLayerCircleStyler.tsx.html +1 -1
  28. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/MlGeojsonLayerHeatMapStyler.tsx.html +1 -1
  29. package/coverage/lcov-report/src/components/MlGeoJsonLayer/story_utils/index.html +1 -1
  30. package/coverage/lcov-report/src/components/MlGeojsonLayerWithSource/MlGeojsonLayerWithSource.tsx.html +1 -1
  31. package/coverage/lcov-report/src/components/MlGeojsonLayerWithSource/index.html +1 -1
  32. package/coverage/lcov-report/src/components/MlGpxViewer/MlGpxViewer.tsx.html +1 -1
  33. package/coverage/lcov-report/src/components/MlGpxViewer/index.html +1 -1
  34. package/coverage/lcov-report/src/components/MlImageMarkerLayer/MlImageMarkerLayer.tsx.html +1 -1
  35. package/coverage/lcov-report/src/components/MlImageMarkerLayer/index.html +1 -1
  36. package/coverage/lcov-report/src/components/MlLayer/MlLayer.tsx.html +1 -1
  37. package/coverage/lcov-report/src/components/MlLayer/index.html +1 -1
  38. package/coverage/lcov-report/src/components/MlLayerMagnify/MlLayerMagnify.tsx.html +52 -40
  39. package/coverage/lcov-report/src/components/MlLayerMagnify/index.html +10 -10
  40. package/coverage/lcov-report/src/components/MlLayerSwipe/MlLayerSwipe.tsx.html +4 -4
  41. package/coverage/lcov-report/src/components/MlLayerSwipe/index.html +1 -1
  42. package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +1 -1
  43. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +1 -1
  44. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +1 -1
  45. package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +1 -1
  46. package/coverage/lcov-report/src/components/MlMarker/MlMarker.tsx.html +1 -1
  47. package/coverage/lcov-report/src/components/MlMarker/index.html +1 -1
  48. package/coverage/lcov-report/src/components/MlMeasureTool/MlMeasureTool.tsx.html +1 -1
  49. package/coverage/lcov-report/src/components/MlMeasureTool/index.html +1 -1
  50. package/coverage/lcov-report/src/components/MlNavigationCompass/MlNavigationCompass.tsx.html +1 -1
  51. package/coverage/lcov-report/src/components/MlNavigationCompass/index.html +1 -1
  52. package/coverage/lcov-report/src/components/MlNavigationTools/MlNavigationTools.tsx.html +1 -1
  53. package/coverage/lcov-report/src/components/MlNavigationTools/index.html +1 -1
  54. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.js.html +1 -1
  55. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.stories_.js.html +1 -1
  56. package/coverage/lcov-report/src/components/MlOsmLayer/index.html +1 -1
  57. package/coverage/lcov-report/src/components/MlScaleReference/{MlScaleReference.js.html → MlScaleReference.tsx.html} +57 -36
  58. package/coverage/lcov-report/src/components/MlScaleReference/index.html +2 -2
  59. package/coverage/lcov-report/src/components/MlShareMapState/{MlShareMapState.js.html → MlShareMapState.tsx.html} +192 -84
  60. package/coverage/lcov-report/src/components/MlShareMapState/index.html +20 -20
  61. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/ColorPicker.tsx.html +1 -1
  62. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/LayerList.tsx.html +1 -1
  63. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/LayerListItem.tsx.html +1 -1
  64. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/LayerPropertyForm.tsx.html +1 -1
  65. package/coverage/lcov-report/src/components/MlSketchTool/LayerList/index.html +1 -1
  66. package/coverage/lcov-report/src/components/MlSketchTool/MlSketchTool.tsx.html +1 -1
  67. package/coverage/lcov-report/src/components/MlSketchTool/index.html +1 -1
  68. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.tsx.html +1 -1
  69. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/index.html +1 -1
  70. package/coverage/lcov-report/src/components/MlThreeJsLayer/MlThreeJsLayer.js.html +1 -1
  71. package/coverage/lcov-report/src/components/MlThreeJsLayer/MlThreejsLayer.tsx.html +769 -0
  72. package/coverage/lcov-report/src/components/MlThreeJsLayer/index.html +25 -10
  73. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/MlTransitionGeoJsonLayer.tsx.html +1 -1
  74. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/index.html +1 -1
  75. package/coverage/lcov-report/src/components/MlUseMapDebugger/MlUseMapDebugger.js.html +1 -1
  76. package/coverage/lcov-report/src/components/MlUseMapDebugger/index.html +1 -1
  77. package/coverage/lcov-report/src/components/MlVectorTileLayer/MlVectorTileLayer.tsx.html +1 -1
  78. package/coverage/lcov-report/src/components/MlVectorTileLayer/index.html +1 -1
  79. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +11 -11
  80. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/index.html +11 -11
  81. package/coverage/lcov-report/src/components/MlWmsLayer/MlWmsLayer.tsx.html +1 -1
  82. package/coverage/lcov-report/src/components/MlWmsLayer/index.html +1 -1
  83. package/coverage/lcov-report/src/components/MlWmsLoader/MlWmsLoader.tsx.html +27 -18
  84. package/coverage/lcov-report/src/components/MlWmsLoader/index.html +11 -11
  85. package/coverage/lcov-report/src/contexts/MapContext.tsx.html +50 -26
  86. package/coverage/lcov-report/src/contexts/SimpleDataContext.js.html +1 -1
  87. package/coverage/lcov-report/src/contexts/SimpleDataProvider.js.html +1 -1
  88. package/coverage/lcov-report/src/contexts/index.html +1 -1
  89. package/coverage/lcov-report/src/hooks/index.html +21 -21
  90. package/coverage/lcov-report/src/hooks/useCameraFollowPath/index.html +1 -1
  91. package/coverage/lcov-report/src/hooks/useCameraFollowPath/useCameraFollowPath.tsx.html +1 -1
  92. package/coverage/lcov-report/src/hooks/useExportMap/index.html +1 -1
  93. package/coverage/lcov-report/src/hooks/useExportMap/index.ts.html +1 -1
  94. package/coverage/lcov-report/src/hooks/useExportMap/lib.ts.html +1 -1
  95. package/coverage/lcov-report/src/hooks/useGpx/index.html +1 -1
  96. package/coverage/lcov-report/src/hooks/useGpx/useGpx.tsx.html +1 -1
  97. package/coverage/lcov-report/src/hooks/useLayer.ts.html +1 -1
  98. package/coverage/lcov-report/src/hooks/useLayerEvent.js.html +9 -9
  99. package/coverage/lcov-report/src/hooks/useLayerFilter/index.html +1 -1
  100. package/coverage/lcov-report/src/hooks/useLayerFilter/useLayerFilter.ts.html +1 -1
  101. package/coverage/lcov-report/src/hooks/useLayerHoverPopup/index.html +1 -1
  102. package/coverage/lcov-report/src/hooks/useLayerHoverPopup/useLayerHoverPopup.tsx.html +9 -6
  103. package/coverage/lcov-report/src/hooks/useMap.ts.html +2 -2
  104. package/coverage/lcov-report/src/hooks/useMapState.ts.html +8 -29
  105. package/coverage/lcov-report/src/hooks/useSource.ts.html +10 -10
  106. package/coverage/lcov-report/src/hooks/useWms.ts.html +1 -1
  107. package/coverage/lcov-report/src/index.html +1 -1
  108. package/coverage/lcov-report/src/index.ts.html +82 -10
  109. package/coverage/lcov.info +741 -604
  110. package/dist/components/MapLibreMap/MapLibreMap.stories.d.ts +3 -0
  111. package/dist/components/MapLibreMap/lib/MapLibreGlWrapper.d.ts +17 -15
  112. package/dist/components/MlCenterPosition/MlCenterPosition.stories.d.ts +1 -1
  113. package/dist/components/MlComponentTemplate/MlComponentTemplate.stories.d.ts +1 -1
  114. package/dist/components/MlCreatePdfButton/MlCreatePdfButton.stories.d.ts +1 -1
  115. package/dist/components/MlCreatePdfForm/MlCreatePdfForm.stories.d.ts +1 -1
  116. package/dist/components/MlFeatureEditor/lib/create_supplementary_points.d.ts +1 -1
  117. package/dist/components/MlFeatureEditor/lib/create_vertex.d.ts +1 -1
  118. package/dist/components/MlGeoJsonLayer/MlGeoJsonLayer.stories.d.ts +1 -1
  119. package/dist/components/MlGeojsonLayerWithSource/MlGeojsonLayerWithSource.stories.d.ts +1 -1
  120. package/dist/components/MlGpxViewer/MlGpxViewer.stories.d.ts +1 -1
  121. package/dist/components/MlImageMarkerLayer/MlImageMarkerLayer.stories.d.ts +1 -1
  122. package/dist/components/MlLayerMagnify/MlLayerMagnify.stories.d.ts +1 -1
  123. package/dist/components/MlLayerSwipe/MlLayerSwipe.stories.d.ts +1 -1
  124. package/dist/components/MlScaleReference/MlScaleReference.d.ts +7 -1
  125. package/dist/components/MlShareMapState/MlShareMapState.d.ts +32 -13
  126. package/dist/components/MlShareMapState/MlShareMapState.stories.d.ts +15 -9
  127. package/dist/components/MlSketchTool/MlSketchTool.stories.d.ts +1 -1
  128. package/dist/components/MlSpatialElevationProfile/MlSpatialElevationProfile.stories.d.ts +1 -1
  129. package/dist/components/MlSpatialElevationProfile/util/getElevationData.d.ts +1 -1
  130. package/dist/components/MlThreeJsLayer/MlThreeJsLayer.stories.d.ts +1 -1
  131. package/dist/components/MlThreeJsLayer/MlThreejsLayer.d.ts +29 -0
  132. package/dist/components/MlThreeJsLayer/lib/GLTFLoader.d.ts +2 -1
  133. package/dist/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.stories.d.ts +1 -1
  134. package/dist/components/MlWmsLoader/MlWmsLoader.stories.d.ts +1 -1
  135. package/dist/contexts/MapContext.d.ts +13 -2
  136. package/dist/custom.d.d.ts +1 -1
  137. package/dist/decorators/MapContextDecorator.d.ts +1 -1
  138. package/dist/decorators/MapContextDecoratorHooks.d.ts +1 -1
  139. package/dist/decorators/MultiMapContextDecorator.d.ts +1 -1
  140. package/dist/decorators/NoNavToolsDecorator.d.ts +1 -1
  141. package/dist/decorators/ThemeWrapper.d.ts +1 -3
  142. package/dist/hooks/useCameraFollowPath/useCameraFollowPath.stories.d.ts +1 -1
  143. package/dist/hooks/useLayerFilter/useLayerFilter.stories.d.ts +1 -1
  144. package/dist/index.d.ts +18 -7
  145. package/dist/index.esm.js +5488 -3580
  146. package/dist/index.esm.js.map +1 -1
  147. package/dist/setupTests.d.ts +6 -6
  148. package/package.json +56 -49
  149. package/public/thumbnails/{MlGPXViewer.png → MlGpxViewer.png} +0 -0
  150. package/rollup.config.js +49 -48
  151. package/src/@types/assets/index.d.ts +20 -0
  152. package/src/components/MapLibreMap/MapLibreMap.stories.js +8 -1
  153. package/src/components/MapLibreMap/MapLibreMap.tsx +11 -9
  154. package/src/components/MapLibreMap/lib/MapLibreGlWrapper.ts +49 -39
  155. package/src/components/MlCenterPosition/MlCenterPosition.tsx +1 -1
  156. package/src/components/MlFollowGps/MlFollowGps.tsx +8 -8
  157. package/src/components/MlLayerMagnify/MlLayerMagnify.tsx +21 -17
  158. package/src/components/MlLayerSwipe/MlLayerSwipe.tsx +3 -3
  159. package/src/components/MlScaleReference/{MlScaleReference.js → MlScaleReference.tsx} +38 -31
  160. package/src/components/MlShareMapState/MlShareMapState.stories.tsx +100 -0
  161. package/src/components/MlShareMapState/{MlShareMapState.js → MlShareMapState.tsx} +94 -58
  162. package/src/components/MlThreeJsLayer/MlThreejsLayer.tsx +228 -0
  163. package/src/components/MlWmsLoader/MlWmsLoader.tsx +7 -4
  164. package/src/contexts/MapContext.tsx +26 -19
  165. package/src/custom.d.ts +5 -0
  166. package/src/decorators/MapContextDecorator.js +39 -28
  167. package/src/decorators/MapContextDecoratorHooks.js +18 -8
  168. package/src/decorators/MultiMapContextDecorator.js +79 -69
  169. package/src/decorators/NoNavToolsDecorator.js +34 -25
  170. package/src/hooks/useLayerHoverPopup/useLayerHoverPopup.tsx +5 -4
  171. package/src/hooks/useMap.ts +1 -1
  172. package/src/hooks/useMapState.ts +6 -13
  173. package/src/hooks/useSource.ts +1 -1
  174. package/src/index.ts +31 -7
  175. package/src/ui_components/TopToolbar.tsx +1 -1
  176. package/tsconfig.json +1 -0
  177. package/src/components/MlShareMapState/MlShareMapState.stories.js +0 -100
  178. package/src/custom.d.tsx +0 -26
  179. package/src/decorators/ThemeWrapper.tsx +0 -9
@@ -3,7 +3,7 @@ import React, { useContext, useCallback, useRef, useEffect, useState, useMemo }
3
3
  // @ts-ignore
4
4
  import syncMove from '@mapbox/mapbox-gl-sync-move';
5
5
  import './style.css';
6
- import MapContext from '../../contexts/MapContext';
6
+ import MapContext, { MapContextType } from '../../contexts/MapContext';
7
7
 
8
8
  export interface MlLayerMagnifyProps {
9
9
  /**
@@ -34,10 +34,10 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
34
34
  const syncMoveInitializedRef = useRef(false);
35
35
  const syncCleanupFunctionRef = useRef(() => {});
36
36
 
37
- const [swipeX, setSwipeX] = useState('50');
38
- const swipeXRef = useRef('50');
39
- const [swipeY, setSwipeY] = useState('50');
40
- const swipeYRef = useRef('50');
37
+ const [swipeX, setSwipeX] = useState(50);
38
+ const swipeXRef = useRef(50);
39
+ const [swipeY, setSwipeY] = useState(50);
40
+ const swipeYRef = useRef(50);
41
41
 
42
42
  const magnifierRadius = useMemo(() => {
43
43
  return props.magnifierRadius || 200;
@@ -60,7 +60,7 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
60
60
  onMove({
61
61
  clientX: swipeXRef.current,
62
62
  clientY: swipeYRef.current,
63
- });
63
+ } as (TouchEvent & MouseEvent));
64
64
  });
65
65
 
66
66
  useEffect(() => {
@@ -74,25 +74,25 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
74
74
  }, []);
75
75
 
76
76
  const onMove = useCallback(
77
- (e) => {
77
+ (e:(TouchEvent & MouseEvent)) => {
78
78
  if (!mapExists()) return;
79
79
 
80
80
  const bounds = mapContext.maps[props.map1Id].getCanvas().getBoundingClientRect();
81
81
  let clientX =
82
- e.clientX ||
83
- (typeof e.touches !== 'undefined' && typeof e.touches[0] !== 'undefined'
84
- ? e.touches[0].clientX
82
+ e?.clientX ||
83
+ (typeof e?.touches !== 'undefined' && typeof e?.touches[0] !== 'undefined'
84
+ ? e?.touches[0].clientX
85
85
  : 0);
86
86
  let clientY =
87
- e.clientY ||
87
+ e?.clientY ||
88
88
  (typeof e.touches !== 'undefined' && typeof e.touches[0] !== 'undefined'
89
89
  ? e.touches[0].clientY
90
90
  : 0);
91
91
 
92
92
  clientX -= bounds.x;
93
93
  clientY -= bounds.y;
94
- const swipeX_tmp = ((clientX / bounds.width) * 100).toFixed(2);
95
- const swipeY_tmp = ((clientY / bounds.height) * 100).toFixed(2);
94
+ const swipeX_tmp = parseFloat(((clientX / bounds.width) * 100).toFixed(2));
95
+ const swipeY_tmp = parseFloat(((clientY / bounds.height) * 100).toFixed(2));
96
96
 
97
97
  if (swipeXRef.current !== swipeX_tmp || swipeYRef.current !== swipeY_tmp) {
98
98
  setSwipeX(swipeX_tmp);
@@ -102,9 +102,9 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
102
102
 
103
103
  mapContext.maps[props.map2Id].getContainer().style.clipPath =
104
104
  `circle(${magnifierRadius}px at ` +
105
- (parseFloat(swipeXRef.current) * bounds.width) / 100 +
105
+ (swipeXRef.current * bounds.width) / 100 +
106
106
  'px ' +
107
- (parseFloat(swipeYRef.current) * bounds.height) / 100 +
107
+ (swipeYRef.current * bounds.height) / 100 +
108
108
  'px)';
109
109
  }
110
110
  },
@@ -120,6 +120,10 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
120
120
  mapContext.getMap(props.map2Id).map
121
121
  );
122
122
 
123
+ onMove({
124
+ clientX: swipeXRef.current,
125
+ clientY: swipeYRef.current,
126
+ } as (TouchEvent & MouseEvent));
123
127
  /*
124
128
  automatically adjust radius for small screens
125
129
  if (
@@ -150,7 +154,7 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
150
154
  onMove({
151
155
  clientX: mapContext.maps[props.map1Id].getCanvas().clientWidth / 2,
152
156
  clientY: mapContext.maps[props.map1Id].getCanvas().clientHeight / 2,
153
- });
157
+ } as (TouchEvent & MouseEvent));
154
158
  }, [mapContext.mapIds, mapContext, mapExists, props, onMove]);
155
159
 
156
160
  const onDown = (e: React.MouseEvent | React.TouchEvent) => {
@@ -175,7 +179,7 @@ const MlLayerMagnify = (props: MlLayerMagnifyProps) => {
175
179
 
176
180
  const onWheel = (e: React.WheelEvent) => {
177
181
  const evCopy = new WheelEvent(e.type, e as unknown as WheelEventInit);
178
- mapContext.map.getCanvas().dispatchEvent(evCopy);
182
+ mapContext.map?.map.getCanvas().dispatchEvent(evCopy);
179
183
  };
180
184
 
181
185
  return (
@@ -3,7 +3,7 @@ import React, { useContext, useCallback, useRef, useEffect, useState } from 'rea
3
3
  // @ts-ignore
4
4
  import syncMove from '@mapbox/mapbox-gl-sync-move';
5
5
  import './style.css';
6
- import MapContext from '../../contexts/MapContext';
6
+ import MapContext, { MapContextType } from '../../contexts/MapContext';
7
7
 
8
8
  export interface MlLayerSwipeProps {
9
9
  /**
@@ -48,7 +48,7 @@ const MlLayerSwipe = (props: MlLayerSwipeProps) => {
48
48
  };
49
49
 
50
50
  const onMove = useCallback(
51
- (e) => {
51
+ (e:(TouchEvent & MouseEvent)) => {
52
52
  if (!mapExists()) return;
53
53
 
54
54
  const bounds = mapContext.maps[props.map1Id].getCanvas().getBoundingClientRect();
@@ -87,7 +87,7 @@ const MlLayerSwipe = (props: MlLayerSwipeProps) => {
87
87
  );
88
88
  onMove({
89
89
  clientX: mapContext.maps[props.map1Id].getCanvas().clientWidth / 2,
90
- });
90
+ } as (TouchEvent & MouseEvent));
91
91
  }, [mapContext.mapIds, mapContext, props, onMove, mapExists]);
92
92
 
93
93
  const onDown = (e: React.MouseEvent | React.TouchEvent) => {
@@ -1,18 +1,25 @@
1
- import React, { useRef, useEffect, useState, useCallback } from "react";
2
- import useMap from "../../hooks/useMap";
1
+ import React, { useRef, useEffect, useState, useCallback } from 'react';
2
+ import useMap from '../../hooks/useMap';
3
3
 
4
- const MlScaleReference = (props) => {
4
+ export interface MlScaleReferenceProps {
5
+ mapId?: string;
6
+ insertBeforeLayer?: string | undefined;
7
+ maxWidth?: number;
8
+ unit?: string;
9
+ }
10
+
11
+ const MlScaleReference = (props: MlScaleReferenceProps) => {
5
12
  const zoomRef = useRef(0);
6
13
  const mapHook = useMap({ mapId: props.mapId, waitForLayer: props.insertBeforeLayer });
7
14
 
8
15
  const [pxWidth, setPxWidth] = useState(0);
9
- const [text, setText] = useState("");
16
+ const [text, setText] = useState('');
10
17
 
11
18
  const updateScale = useCallback(() => {
19
+ if (!mapHook.map) return;
12
20
  if (mapHook.map?.map.getZoom() === zoomRef.current) {
13
21
  return;
14
22
  }
15
- if (!mapHook.map) return;
16
23
 
17
24
  zoomRef.current = mapHook.map?.map.getZoom();
18
25
  // Calculation from MapLibre
@@ -21,56 +28,56 @@ const MlScaleReference = (props) => {
21
28
  // found between the two coordinates.
22
29
  const maxWidth = props.maxWidth || 100;
23
30
 
24
- const y = mapHook.map._container.clientHeight / 2;
25
- const left = mapHook.map.unproject([0, y]);
26
- const right = mapHook.map.unproject([maxWidth, y]);
31
+ const y = mapHook.map.map._container.clientHeight / 2;
32
+ const left = mapHook.map.map.unproject([0, y]);
33
+ const right = mapHook.map.map.unproject([maxWidth, y]);
27
34
  const maxMeters = left.distanceTo(right);
28
35
  // The real distance corresponding to 100px scale length is rounded off to
29
36
  // near pretty number and the scale length for the same is found out.
30
37
  // Default unit of the scale is based on User's locale.
31
- if (props.unit === "imperial") {
38
+ if (props.unit === 'imperial') {
32
39
  const maxFeet = 3.2808 * maxMeters;
33
40
  if (maxFeet > 5280) {
34
41
  const maxMiles = maxFeet / 5280;
35
- setScale(maxWidth, maxMiles, mapHook.map._getUIString("ScaleControl.Miles"));
42
+ setScale(maxWidth, maxMiles, mapHook.map.map._getUIString('ScaleControl.Miles'));
36
43
  } else {
37
- setScale(maxWidth, maxFeet, mapHook.map._getUIString("ScaleControl.Feet"));
44
+ setScale(maxWidth, maxFeet, mapHook.map.map._getUIString('ScaleControl.Feet'));
38
45
  }
39
- } else if (props.unit === "nautical") {
46
+ } else if (props.unit === 'nautical') {
40
47
  const maxNauticals = maxMeters / 1852;
41
- setScale(maxWidth, maxNauticals, mapHook.map._getUIString("ScaleControl.NauticalMiles"));
48
+ setScale(maxWidth, maxNauticals, mapHook.map.map._getUIString('ScaleControl.NauticalMiles'));
42
49
  } else if (maxMeters >= 1000) {
43
- setScale(maxWidth, maxMeters / 1000, mapHook.map._getUIString("ScaleControl.Kilometers"));
50
+ setScale(maxWidth, maxMeters / 1000, mapHook.map.map._getUIString('ScaleControl.Kilometers'));
44
51
  } else {
45
- setScale(maxWidth, maxMeters, mapHook.map._getUIString("ScaleControl.Meters"));
52
+ setScale(maxWidth, maxMeters, mapHook.map.map._getUIString('ScaleControl.Meters'));
46
53
  }
47
54
  }, [mapHook.map, props.unit, props.maxWidth]);
48
55
 
49
56
  useEffect(() => {
50
57
  if (!mapHook.map) return;
51
58
 
52
- let _updateScale = updateScale;
53
- mapHook.map.on("move", _updateScale, mapHook.componentId);
59
+ const _updateScale = updateScale;
60
+ mapHook.map.on('move', _updateScale, mapHook.componentId);
54
61
  updateScale();
55
62
 
56
63
  return () => {
57
- mapHook.map.off("move", _updateScale);
64
+ mapHook.map?.map.off('move', _updateScale);
58
65
  };
59
66
  }, [mapHook.map, updateScale]);
60
67
 
61
- const setScale = (maxWidth, maxDistance, unit) => {
68
+ const setScale = (maxWidth: number, maxDistance: number, unit: string) => {
62
69
  const distance = getRoundNum(maxDistance);
63
70
  const ratio = distance / maxDistance;
64
71
  setPxWidth(maxWidth * ratio);
65
- setText(distance + " " + unit);
72
+ setText(distance + ' ' + unit);
66
73
  };
67
74
 
68
- const getDecimalRoundNum = (d) => {
75
+ const getDecimalRoundNum = (d: number) => {
69
76
  const multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10));
70
77
  return Math.round(d * multiplier) / multiplier;
71
78
  };
72
79
 
73
- const getRoundNum = (num) => {
80
+ const getRoundNum = (num: number) => {
74
81
  const pow10 = Math.pow(10, `${Math.floor(num)}`.length - 1);
75
82
  let d = num / pow10;
76
83
 
@@ -83,15 +90,15 @@ const MlScaleReference = (props) => {
83
90
  <>
84
91
  <div
85
92
  style={{
86
- backgroundColor: "hsla(0,0%,100%,.75)",
87
- fontSize: "10px",
88
- border: "2px solid #333",
89
- borderTop: "#333",
90
- padding: "0 5px",
91
- color: "#333",
92
- boxSizing: "border-box",
93
- width: pxWidth + "px",
94
- fontFamily: "sans-serif",
93
+ backgroundColor: 'hsla(0,0%,100%,.75)',
94
+ fontSize: '10px',
95
+ border: '2px solid #333',
96
+ borderTop: '#333',
97
+ padding: '0 5px',
98
+ color: '#333',
99
+ boxSizing: 'border-box',
100
+ width: pxWidth + 'px',
101
+ fontFamily: 'sans-serif',
95
102
  }}
96
103
  dangerouslySetInnerHTML={{ __html: text }}
97
104
  ></div>
@@ -0,0 +1,100 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import MlShareMapState from './MlShareMapState';
4
+ import mapContextDecorator from '../../decorators/MapContextDecorator';
5
+ import useMapState from '../../hooks/useMapState';
6
+ import useMap from '../../hooks/useMap';
7
+ import Sidebar from '../../ui_components/Sidebar';
8
+ import ListItem from '@mui/material/ListItem';
9
+ import IconButton from '@mui/material/IconButton';
10
+ import VisibilityIcon from '@mui/icons-material/Visibility';
11
+ import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
12
+ import ListItemText from '@mui/material/ListItemText';
13
+ import sample_geojson_1 from '../MlGeoJsonLayer/assets/sample_1.json';
14
+ import sample_geojson_2 from '../MlGeoJsonLayer/assets/sample_2.json';
15
+ import List from '@mui/material/List';
16
+ import MlGeoJsonLayer from '../MlGeoJsonLayer/MlGeoJsonLayer';
17
+ import { ToggleButton } from '@mui/material';
18
+ import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
19
+ import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
20
+
21
+ const storyoptions = {
22
+ title: 'MapComponents/MlShareMapState',
23
+ component: MlShareMapState,
24
+ argTypes: {},
25
+ decorators: mapContextDecorator,
26
+ };
27
+ export default storyoptions;
28
+
29
+ const Template = () => {
30
+ const geoJsonArray = [sample_geojson_1, sample_geojson_2];
31
+ const [watchState, setWatchState] = useState(true);
32
+ const mapHook = useMap({ mapId: 'map_1' });
33
+ const mapState = useMapState({
34
+ mapId: 'map_1',
35
+ watch: {
36
+ viewport: false,
37
+ layers: true,
38
+ sources: false,
39
+ },
40
+ filter: {
41
+ includeBaseLayers: false,
42
+ },
43
+ });
44
+
45
+ return (
46
+ <>
47
+ <MlShareMapState active={watchState} />
48
+ {geoJsonArray.map((el, i) => (
49
+ <MlGeoJsonLayer layerId={'GeoJson_' + i} type="line" geojson={el} key={'GeoJson_' + i} />
50
+ ))}
51
+ <Sidebar sx={{ wordBreak: 'break-word' }}>
52
+ <ToggleButton
53
+ size="small"
54
+ selected={watchState}
55
+ value={watchState}
56
+ onChange={() => {
57
+ setWatchState(!watchState);
58
+ }}
59
+ >
60
+ {watchState ? <CheckCircleOutlineIcon /> : <ErrorOutlineIcon />}
61
+
62
+ {watchState ? 'active' : 'inactive'}
63
+ </ToggleButton>
64
+ <List dense key="layers">
65
+ {mapState.layers?.map((el) => (
66
+ <ListItem
67
+ key={el?.id}
68
+ secondaryAction={
69
+ <IconButton
70
+ edge="end"
71
+ aria-label="toggle visibility"
72
+ onClick={() => {
73
+ const currentVisibility = mapHook.map
74
+ ?.getLayer?.(el?.id)
75
+ ?.getLayoutProperty('visibility');
76
+ mapHook.map
77
+ ?.getLayer?.(el?.id)
78
+ ?.setLayoutProperty(
79
+ 'visibility',
80
+ currentVisibility === 'none' ? 'visible' : 'none'
81
+ );
82
+ mapHook.map?.map.fire('zoom');
83
+ }}
84
+ >
85
+ {el?.visible ? <VisibilityIcon /> : <VisibilityOffIcon />}
86
+ </IconButton>
87
+ }
88
+ >
89
+ <ListItemText primary={el?.id} secondary={''} />
90
+ </ListItem>
91
+ ))}
92
+ </List>
93
+ </Sidebar>
94
+ </>
95
+ );
96
+ };
97
+
98
+ export const ExampleConfig = Template.bind({});
99
+ ExampleConfig.parameters = {};
100
+ ExampleConfig.args = {};
@@ -1,13 +1,26 @@
1
- import React, { useRef, useEffect, useContext, useState, useCallback } from "react";
2
- import PropTypes from "prop-types";
3
-
4
- import MapContext from "../../contexts/MapContext";
5
- import { v4 as uuidv4 } from "uuid";
6
- import useMapState from "../../hooks/useMapState";
7
-
8
- const getCurrentUrlParameters = () => {
9
- let currentParams = Object.fromEntries(new URLSearchParams(window.location.search));
10
- currentParams.layers = JSON.parse(currentParams?.layers ? currentParams.layers : "[]");
1
+ import React, { useRef, useEffect, useContext, useState, useCallback } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import MapContext from '../../contexts/MapContext';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ import useMapState from '../../hooks/useMapState';
7
+ import MapLibreGlWrapper from '../MapLibreMap/lib/MapLibreGlWrapper';
8
+
9
+ export interface MapState {
10
+ lat?: number;
11
+ lng?: number;
12
+ zoom?: number;
13
+ bearing?: number;
14
+ pitch?: number;
15
+ layers?: {
16
+ visible: boolean;
17
+ id: string;
18
+ }[];
19
+ }
20
+
21
+ const getCurrentUrlParameters = (): MapState => {
22
+ const currentParams = Object.fromEntries(new URLSearchParams(window.location.search));
23
+ currentParams.layers = JSON.parse(currentParams?.layers ? currentParams.layers : '[]');
11
24
 
12
25
  return currentParams;
13
26
  };
@@ -22,14 +35,27 @@ const initialUrlParams = getCurrentUrlParameters();
22
35
  *
23
36
  * @component
24
37
  */
25
- const MlShareMapState = (props) => {
38
+
39
+ export interface MlShareMapStateProps {
40
+ //
41
+ mapId?: string;
42
+ idPrefix?: string;
43
+ active?: boolean;
44
+ }
45
+
46
+ export interface LayerStatesInterface {
47
+ //
48
+ [key: string]: boolean;
49
+ }
50
+
51
+ const MlShareMapState = (props: MlShareMapStateProps) => {
26
52
  // Use a useRef hook to reference the layer object to be able to access it later inside useEffect hooks
27
53
  const mapContext = useContext(MapContext);
28
54
  const initializedRef = useRef(false);
29
- const mapRef = useRef(undefined);
30
- const [map, setMap] = useState(undefined);
55
+ const mapRef = useRef<MapLibreGlWrapper | undefined>();
56
+ const [map, setMap] = useState<MapLibreGlWrapper | undefined>(undefined);
31
57
  const layersFromUrlParamsRef = useRef({});
32
- const componentId = useRef((props.idPrefix ? props.idPrefix : "MlShareMapState-") + uuidv4());
58
+ const componentId = useRef((props.idPrefix ? props.idPrefix : 'MlShareMapState-') + uuidv4());
33
59
  const mapState = useMapState({
34
60
  watch: {
35
61
  viewport: false,
@@ -42,7 +68,7 @@ const MlShareMapState = (props) => {
42
68
  });
43
69
 
44
70
  const allStatesRestoredRef = useRef(false);
45
- const layerStatesRestored = useRef(undefined);
71
+ const layerStatesRestored = useRef<LayerStatesInterface>();
46
72
  const restoredStatesRef = useRef({
47
73
  viewport: {
48
74
  center: false,
@@ -56,42 +82,42 @@ const MlShareMapState = (props) => {
56
82
  });
57
83
 
58
84
  // initial URL-Params
59
- const mapStateRef = useRef({});
85
+ const mapStateRef = useRef<MapState>({});
60
86
 
61
87
  const refreshUrlParameters = useCallback(() => {
62
88
  if (!props.active) return;
63
89
 
64
- let mapLayers = [];
65
- for (let x in mapState.layers) {
90
+ const mapLayers = [];
91
+ for (const x in mapState.layers) {
66
92
  mapLayers.push({
67
- id: mapState.layers[x].id,
68
- type: mapState.layers[x].type,
69
- visible: mapState.layers[x].visible,
93
+ id: mapState.layers[x]?.id,
94
+ type: mapState.layers[x]?.type,
95
+ visible: mapState.layers[x]?.visible,
70
96
  });
71
97
  }
72
98
  refreshMapState();
73
- let urlParams = new URLSearchParams({
74
- ...getCurrentUrlParameters(),
75
- ...mapStateRef.current,
99
+ const urlParams = new URLSearchParams({
100
+ ...(getCurrentUrlParameters() as Record<string, string>),
101
+ ...(mapStateRef.current as Record<string, string>),
76
102
  layers: JSON.stringify(mapLayers),
77
103
  });
78
- JSON.parse(Object.fromEntries(urlParams).layers).forEach((el) => {
104
+ JSON.parse(Object.fromEntries(urlParams).layers).forEach((el: { id: number }) => {
105
+ // is iD a number?
79
106
  layersFromUrlParamsRef.current[el.id] = false;
80
107
  });
81
108
 
82
- let currentParams = new URLSearchParams(window.location.search);
83
- checkRestorationStates(mapState.layers);
109
+ const currentParams = new URLSearchParams(window.location.search);
84
110
  if (urlParams.toString() !== currentParams.toString()) {
85
111
  window.history.pushState(
86
112
  { ...mapStateRef.current },
87
113
  document.title,
88
- "?" + urlParams.toString()
114
+ '?' + urlParams.toString()
89
115
  );
90
116
  }
91
117
  }, [mapState.layers, props.active]);
92
118
 
93
119
  useEffect(() => {
94
- let _componentId = componentId.current;
120
+ const _componentId = componentId.current;
95
121
 
96
122
  mapStateRef.current = getCurrentUrlParameters();
97
123
 
@@ -119,12 +145,12 @@ const MlShareMapState = (props) => {
119
145
  useEffect(() => {
120
146
  if (!mapRef.current) return;
121
147
 
122
- let _refreshUrlParameters = refreshUrlParameters;
148
+ const _refreshUrlParameters = refreshUrlParameters;
123
149
 
124
- mapRef.current.on("moveend", _refreshUrlParameters, componentId.current);
150
+ mapRef.current.on('moveend', _refreshUrlParameters, componentId.current);
125
151
 
126
152
  return () => {
127
- mapRef.current?.off("moveend", _refreshUrlParameters);
153
+ mapRef.current?.map.off('moveend', _refreshUrlParameters);
128
154
  };
129
155
  }, [refreshUrlParameters, map]);
130
156
 
@@ -143,14 +169,16 @@ const MlShareMapState = (props) => {
143
169
  useEffect(() => {
144
170
  if (!mapState?.layers?.length) return;
145
171
 
146
- if (typeof layerStatesRestored.current === "undefined") {
147
- layerStatesRestored.current = {};
148
- initialUrlParams?.layers.forEach((layer) => {
149
- layerStatesRestored.current[layer.id] = false;
172
+ if (typeof layerStatesRestored.current === 'undefined') {
173
+ layerStatesRestored.current = undefined;
174
+ initialUrlParams?.layers?.forEach((layer: { id: string }) => {
175
+ if (layerStatesRestored.current?.[layer.id]) {
176
+ layerStatesRestored.current[layer.id] = false;
177
+ }
150
178
  });
151
179
  }
152
180
 
153
- for (let key in layerStatesRestored.current) {
181
+ for (const key in layerStatesRestored.current) {
154
182
  let _allDone = true;
155
183
  if (layerStatesRestored.current[key] === false) {
156
184
  _allDone = false;
@@ -162,11 +190,14 @@ const MlShareMapState = (props) => {
162
190
 
163
191
  if (initialUrlParams.layers) {
164
192
  initialUrlParams.layers.forEach((layer) => {
165
- if (mapRef.current?.getLayer(layer.id) && layerStatesRestored.current[layer.id] === false) {
193
+ if (
194
+ mapRef.current?.map.getLayer(layer.id) && //number oder str?
195
+ layerStatesRestored.current?.[layer.id] === false
196
+ ) {
166
197
  layerStatesRestored.current[layer.id] = true;
167
- mapRef.current
198
+ mapRef.current.map
168
199
  ?.getLayer(layer.id)
169
- ?.setLayoutProperty("visibility", layer.visible ? "visible" : "none");
200
+ ?.setLayoutProperty('visibility', layer.visible ? 'visible' : 'none');
170
201
  }
171
202
  });
172
203
  }
@@ -181,28 +212,32 @@ const MlShareMapState = (props) => {
181
212
  }
182
213
  }, [props.active, map, mapState.layers]);
183
214
 
184
- const refreshMapState = () => {
185
- mapStateRef.current.lat = mapRef.current.getCenter().lat;
186
- mapStateRef.current.lng = mapRef.current.getCenter().lng;
187
- mapStateRef.current.zoom = mapRef.current.getZoom();
188
- mapStateRef.current.bearing = mapRef.current.getBearing();
189
- mapStateRef.current.pitch = mapRef.current.getPitch();
190
- };
215
+ //ist .current?.map. richtig?
191
216
 
192
- const checkRestorationStates = (stateArray) => {
193
- let tempArray = {};
194
- stateArray.forEach((el, i, arr) => {
195
- if (!arr[el.key]) tempArray[el.key] = true;
196
- });
217
+ const refreshMapState = () => {
218
+ mapStateRef.current.lat = mapRef.current?.map.getCenter().lat;
219
+ mapStateRef.current.lng = mapRef.current?.map.getCenter().lng;
220
+ mapStateRef.current.zoom = mapRef.current?.map.getZoom();
221
+ mapStateRef.current.bearing = mapRef.current?.map.getBearing();
222
+ mapStateRef.current.pitch = mapRef.current?.map.getPitch();
197
223
  };
198
224
 
199
225
  const restoreViewportState = () => {
200
226
  if (!restoredStatesRef.current.viewport.center) {
201
227
  restoredStatesRef.current.viewport.center = true;
202
- mapRef.current.setCenter([mapStateRef.current.lng, mapStateRef.current.lat]);
203
- mapRef.current.setZoom(mapStateRef.current.zoom);
204
- mapRef.current.setBearing(mapStateRef.current.bearing);
205
- mapRef.current.setPitch(mapStateRef.current.pitch);
228
+
229
+ if (mapStateRef.current.lng && mapStateRef.current.lat) {
230
+ mapRef.current?.map.setCenter([mapStateRef.current.lng, mapStateRef.current.lat]);
231
+ }
232
+ if (mapStateRef.current.zoom) {
233
+ mapRef.current?.map.setZoom(mapStateRef.current.zoom);
234
+ }
235
+ if (mapStateRef.current.bearing) {
236
+ mapRef.current?.map.setBearing(mapStateRef.current.bearing);
237
+ }
238
+ if (mapStateRef.current.pitch) {
239
+ mapRef.current?.map.setPitch(mapStateRef.current.pitch);
240
+ }
206
241
  }
207
242
 
208
243
  allStatesRestoredRef.current = true;
@@ -210,7 +245,8 @@ const MlShareMapState = (props) => {
210
245
 
211
246
  window.onpopstate = (event) => {
212
247
  if (event.state && event.state.lng && event.state.lat && event.state.zoom) {
213
- mapRef.current.easeTo({
248
+ mapRef.current?.map.easeTo({
249
+ // so möglich?
214
250
  zoom: event.state.zoom,
215
251
  center: [event.state.lng, event.state.lat],
216
252
  });
@@ -218,7 +254,7 @@ const MlShareMapState = (props) => {
218
254
  };
219
255
 
220
256
  return <></>;
221
- };
257
+ };;
222
258
 
223
259
  MlShareMapState.defaultProps = {
224
260
  mapId: undefined,