@mapcomponents/react-maplibre 0.1.66 → 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 +13 -0
  5. package/coverage/clover.xml +419 -344
  6. package/coverage/coverage-final.json +15 -14
  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 +80 -11
  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 -8
  145. package/dist/index.esm.js +5590 -3701
  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 -8
  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
@@ -0,0 +1,228 @@
1
+ import React, { useContext, useRef, useEffect, useState } from 'react';
2
+ import MapContext from '../../contexts/MapContext';
3
+
4
+ import Button from '@mui/material/Button';
5
+ import maplibregl, { CustomLayerInterface, LngLatLike, Map } from 'maplibre-gl';
6
+ import * as THREE from 'three';
7
+ import GLTFLoader from './lib/GLTFLoader';
8
+ import PropTypes from 'prop-types';
9
+ import MapLibreGlWrapper from '../MapLibreMap/lib/MapLibreGlWrapper';
10
+
11
+ /**
12
+ * Renders obj or gltf 3D Models on the MapLibreMap referenced by props.mapId
13
+ *
14
+ * @component
15
+ */
16
+
17
+ export interface MlThreeJsLayerProps {
18
+ mapId?: string;
19
+ init?: object;
20
+ onDone?: () => void;
21
+ }
22
+
23
+ const MlThreeJsLayer = (props: MlThreeJsLayerProps) => {
24
+ const mapContext = useContext(MapContext);
25
+
26
+ const layerName = '3d-model';
27
+ const [showLayer, setShowLayer] = useState(true);
28
+ const showLayerRef = useRef(true);
29
+ const initializedRef = useRef(false);
30
+ const mapRef = useRef<MapLibreGlWrapper>();
31
+ const initFuncRef = useRef(props.init);
32
+
33
+ const cleanup = () => {
34
+ if (mapRef.current && mapRef.current.style) {
35
+ if (mapRef.current.getLayer(layerName)) {
36
+ mapRef.current.removeLayer(layerName);
37
+ }
38
+ mapRef.current = undefined;
39
+ }
40
+ };
41
+
42
+ useEffect(() => {
43
+ if (typeof initFuncRef.current === 'function') {
44
+ initFuncRef.current();
45
+ }
46
+
47
+ return cleanup;
48
+ }, []);
49
+
50
+ useEffect(() => {
51
+ if (!mapContext.mapExists(props.mapId) || initializedRef.current) return;
52
+
53
+ initializedRef.current = true;
54
+ mapRef.current = mapContext.getMap(props.mapId);
55
+
56
+ mapRef.current?.setCenter([7.099771581806502, 50.73395746209983]);
57
+ mapRef.current?.setZoom(15);
58
+ mapRef.current?.setPitch(45);
59
+
60
+ // parameters to ensure the model is georeferenced correctly on the map
61
+ const modelOrigin = [7.099771581806502, 50.73395746209983];
62
+ // 50.73395746209983, 7.099771581806502
63
+ const modelAltitude = 0;
64
+ const modelRotate = [Math.PI / 2, 90, 0];
65
+
66
+ const modelAsMercatorCoordinate = maplibregl.MercatorCoordinate.fromLngLat(
67
+ modelOrigin as LngLatLike,
68
+ modelAltitude
69
+ );
70
+
71
+ // transformation parameters to position, rotate and scale the 3D model onto the map
72
+ const modelTransform = {
73
+ translateX: modelAsMercatorCoordinate.x + 0.0000008,
74
+ translateY: modelAsMercatorCoordinate.y + 0.0000018,
75
+ translateZ: modelAsMercatorCoordinate.z,
76
+ rotateX: modelRotate[0],
77
+ rotateY: modelRotate[1],
78
+ rotateZ: modelRotate[2],
79
+ /* Since our 3D model is in real world meters, a scale transform needs to be
80
+ * applied since the CustomLayerInterface expects units in MercatorCoordinates.
81
+ */
82
+ scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits() + 0.00000003,
83
+ };
84
+
85
+ //var THREE = window.THREE;
86
+
87
+ // configuration of the custom layer for a 3D model per the CustomLayerInterface
88
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
89
+ // @ts-ignore
90
+ const customLayer: CustomLayerInterface & {
91
+ camera: THREE.Camera | undefined;
92
+ scene: THREE.Scene | undefined;
93
+ map: Map;
94
+ renderer: THREE.WebGLRenderer;
95
+ } = {
96
+ id: '3d-model',
97
+ type: 'custom',
98
+ renderingMode: '3d',
99
+ camera: undefined,
100
+ scene: undefined,
101
+ onAdd: function (map: Map, gl: WebGL2RenderingContext) {
102
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
103
+ const self = this;
104
+ this.camera = new THREE.Camera();
105
+ this.scene = new THREE.Scene();
106
+
107
+ // create two three.js lights to illuminate the model
108
+ const directionalLight = new THREE.DirectionalLight(0xffffff);
109
+ directionalLight.position.set(0, -70, 100).normalize();
110
+ this.scene.add(directionalLight);
111
+
112
+ const directionalLight2 = new THREE.DirectionalLight(0xffffff);
113
+ directionalLight2.position.set(0, 70, 100).normalize();
114
+ this.scene.add(directionalLight2);
115
+
116
+ // use the three.js GLTF loader to add the 3D model to the three.js scene
117
+ const loader = new GLTFLoader();
118
+ loader.load(
119
+ 'assets/3D/godzilla_simple.glb',
120
+ //"https://docs.mapbox.com/mapbox-gl-js/assets/34M_17/34M_17.gltf",
121
+ function (gltf: { scene: THREE.Scene }) {
122
+ self.scene?.add(gltf.scene);
123
+ if (typeof props.onDone === 'function') {
124
+ props.onDone();
125
+ }
126
+ }.bind(this)
127
+ );
128
+ this.map = map;
129
+
130
+ // use the Mapbox GL JS map canvas for three.js
131
+ this.renderer = new THREE.WebGLRenderer({
132
+ canvas: map.getCanvas(),
133
+ context: gl,
134
+ antialias: true,
135
+ });
136
+
137
+ this.renderer.autoClear = false;
138
+ },
139
+ render: function (_gl, matrix) {
140
+ const rotationX = new THREE.Matrix4().makeRotationAxis(
141
+ new THREE.Vector3(1, 0, 0),
142
+ modelTransform.rotateX
143
+ );
144
+ const rotationY = new THREE.Matrix4().makeRotationAxis(
145
+ new THREE.Vector3(0, 1, 0),
146
+ modelTransform.rotateY
147
+ );
148
+ const rotationZ = new THREE.Matrix4().makeRotationAxis(
149
+ new THREE.Vector3(0, 0, 1),
150
+ modelTransform.rotateZ
151
+ );
152
+
153
+ const m = new THREE.Matrix4().fromArray(matrix);
154
+ const l = new THREE.Matrix4()
155
+ .makeTranslation(
156
+ modelTransform.translateX,
157
+ modelTransform.translateY,
158
+ modelTransform.translateZ
159
+ )
160
+ .scale(
161
+ new THREE.Vector3(modelTransform.scale, -modelTransform.scale, modelTransform.scale)
162
+ )
163
+ .multiply(rotationX)
164
+ .multiply(rotationY)
165
+ .multiply(rotationZ);
166
+
167
+ if (this.camera && this.scene) {
168
+ this.camera.projectionMatrix = m.multiply(l);
169
+ this.renderer.resetState();
170
+ this.renderer.render(this.scene, this.camera);
171
+ this.map.triggerRepaint();
172
+ }
173
+ },
174
+ };
175
+
176
+ mapRef.current?.addLayer(customLayer);
177
+
178
+ if (mapRef.current?.getLayer(layerName)) {
179
+ mapRef.current.setLayoutProperty(layerName, 'visibility', 'visible');
180
+ }
181
+ }, [mapContext.mapIds, mapContext, props]);
182
+
183
+ useEffect(() => {
184
+ if (!mapRef.current) return;
185
+
186
+ if (mapRef.current.getLayer(layerName)) {
187
+ // toggle layer visibility by changing the layout object's visibility property
188
+ if (showLayer) {
189
+ mapRef.current.setLayoutProperty(layerName, 'visibility', 'visible');
190
+ } else {
191
+ mapRef.current.setLayoutProperty(layerName, 'visibility', 'none');
192
+ }
193
+ }
194
+ //
195
+ }, [showLayer, mapContext]);
196
+
197
+ return (
198
+ <>
199
+ <Button
200
+ color="primary"
201
+ variant={showLayer ? 'contained' : 'outlined'}
202
+ onClick={() => {
203
+ setShowLayer(!showLayer);
204
+ showLayerRef.current = !showLayer;
205
+ }}
206
+ >
207
+ 3D
208
+ </Button>
209
+ </>
210
+ );
211
+ };
212
+
213
+ MlThreeJsLayer.propTypes = {
214
+ /**
215
+ * Id of the target MapLibre instance in mapContext
216
+ */
217
+ mapId: PropTypes.string,
218
+ /**
219
+ * function that gets called when initialized
220
+ */
221
+ init: PropTypes.func,
222
+ /**
223
+ * function that gets called when models are loaded
224
+ */
225
+ onDone: PropTypes.func,
226
+ };
227
+
228
+ export default MlThreeJsLayer;
@@ -1,6 +1,6 @@
1
1
  import React, { useRef, useEffect, useContext, useCallback, useState, useMemo } from 'react';
2
2
 
3
- import MapContext from '../../contexts/MapContext';
3
+ import MapContext, { MapContextType } from '../../contexts/MapContext';
4
4
  import { v4 as uuidv4 } from 'uuid';
5
5
 
6
6
  import MlWmsLayer from '../MlWmsLayer/MlWmsLayer';
@@ -13,7 +13,7 @@ import List from '@mui/material/List';
13
13
  import ListItem from '@mui/material/ListItem';
14
14
  import ListItemText from '@mui/material/ListItemText';
15
15
  import IconButton from '@mui/material/IconButton';
16
- import { LngLat } from 'maplibre-gl';
16
+ import { LngLat, MapMouseEvent } from 'maplibre-gl';
17
17
  import MapLibreGlWrapper from '../MapLibreMap/lib/MapLibreGlWrapper';
18
18
  import { Layer2, Layer3 } from 'wms-capabilities';
19
19
  import { useWmsReturnType } from '../../hooks/useWms';
@@ -117,7 +117,8 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => {
117
117
  }, [layers]);
118
118
 
119
119
  const getFeatureInfo = useCallback(
120
- (ev) => {
120
+ // eslint-disable-next-line @typescript-eslint/ban-types
121
+ (ev:(MapMouseEvent & Object)) => {
121
122
  if (!mapRef.current) return;
122
123
  setFeatureInfoLngLat(undefined);
123
124
  setFeatureInfoContent(undefined);
@@ -190,7 +191,9 @@ const MlWmsLoader = (props: MlWmsLoaderProps) => {
190
191
 
191
192
  const _getFeatureInfo = getFeatureInfo;
192
193
 
193
- mapRef.current.on('click', _getFeatureInfo, componentId.current);
194
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
195
+ // @ts-ignore: ts appears not to consider overloads
196
+ mapRef.current.map.on('click', _getFeatureInfo, componentId.current);
194
197
  return () => {
195
198
  mapRef.current?.map.off?.('click', _getFeatureInfo);
196
199
  };
@@ -1,9 +1,18 @@
1
- import React, { useState, useRef } from "react";
1
+ import React, { useState, useRef, ReactNode } from 'react';
2
2
  import MapLibreGlWrapper from '../components/MapLibreMap/lib/MapLibreGlWrapper';
3
3
 
4
+ export interface MapContextType {
5
+ mapIds: string[];
6
+ mapExists: (map_id: string | undefined) => boolean;
7
+ maps: MapLibreGlWrapper[];
8
+ map: MapLibreGlWrapper | undefined;
9
+ getMap: (map_id: string | undefined) => MapLibreGlWrapper;
10
+ setMap: (map: MapLibreGlWrapper) => void;
11
+ removeMap: (map_id: string | undefined) => void;
12
+ registerMap: (map_id: string | undefined, map: MapLibreGlWrapper) => void;
13
+ }
4
14
  const MapContext = React.createContext({} as MapContextType);
5
15
 
6
-
7
16
  /**
8
17
  * MapComponentsProvider must be imported and wrapped around component where at least one of its child nodes requires access to a MapLibre-gl or openlayers instance that is registered in this mapContext.
9
18
  MapComponentsProvider must be used one level higher than the first use of MapContext.
@@ -11,19 +20,18 @@ MapComponentsProvider must be used one level higher than the first use of MapCon
11
20
  * MapComponentsProvider requires at least one use of the MapLibreMap component somewhere down the component tree that will create the MapLibre-gl object and set the reference at MapContext.map. For MapLibre maps it is a good idea to provide a mapId attribute to the MapLibreMap Component even if you are only using a single map instance at start. It will make a later transition to using multiple instances within the same project much easier.
12
21
  */
13
22
 
14
- const MapComponentsProvider = ({ children }:{children:any}) => {
15
- const [map, setMap] = useState<(MapLibreGlWrapper | undefined)>(undefined);
23
+ const MapComponentsProvider = ({ children }: { children: ReactNode }) => {
24
+ const [map, setMap] = useState<MapLibreGlWrapper | undefined>(undefined);
16
25
  const [mapIds, setMapIds] = useState<[...string[]]>([]);
17
- let mapIds_raw = useRef<[...string[]]>([]);
18
- let maps = useRef<any>({});
19
-
26
+ const mapIds_raw = useRef<[...string[]]>([]);
27
+ const maps = useRef<{ [key: string]: MapLibreGlWrapper }>({});
20
28
 
21
- const removeMap = (mapId:string) => {
29
+ const removeMap = (mapId: string) => {
22
30
  if (mapId) {
23
- if (typeof maps.current[mapId] !== "undefined") {
31
+ if (typeof maps.current[mapId] !== 'undefined') {
24
32
  delete maps.current[mapId];
25
33
  }
26
- let mapIdIndex = mapIds_raw.current.indexOf(mapId);
34
+ const mapIdIndex = mapIds_raw.current.indexOf(mapId);
27
35
  if (mapIdIndex > -1) {
28
36
  mapIds_raw.current.splice(mapIdIndex, 1);
29
37
  }
@@ -34,15 +42,15 @@ const MapComponentsProvider = ({ children }:{children:any}) => {
34
42
  }
35
43
  } else {
36
44
  setMap(undefined);
37
- removeMap("anonymous_map");
45
+ removeMap('anonymous_map');
38
46
  }
39
47
  };
40
48
 
41
- const setMapHandler = (mapInstance:MapLibreGlWrapper) => {
49
+ const setMapHandler = (mapInstance: MapLibreGlWrapper) => {
42
50
  setMap(mapInstance);
43
51
 
44
52
  if (mapIds.length === 0) {
45
- let mapId = "anonymous_map";
53
+ const mapId = 'anonymous_map';
46
54
  setMapIds([...mapIds, mapId]);
47
55
  maps.current[mapId] = mapInstance;
48
56
  }
@@ -53,7 +61,7 @@ const MapComponentsProvider = ({ children }:{children:any}) => {
53
61
  setMap: setMapHandler,
54
62
  maps: maps.current,
55
63
  mapIds: mapIds,
56
- registerMap: (mapId:string, mapInstance:MapLibreGlWrapper) => {
64
+ registerMap: (mapId: string, mapInstance: MapLibreGlWrapper) => {
57
65
  if (mapId && mapInstance) {
58
66
  maps.current[mapId] = mapInstance;
59
67
  mapIds_raw.current.push(mapId);
@@ -65,7 +73,7 @@ const MapComponentsProvider = ({ children }:{children:any}) => {
65
73
  }
66
74
  },
67
75
  removeMap,
68
- mapExists: (mapId:string) => {
76
+ mapExists: (mapId: string) => {
69
77
  if (mapId && Object.keys(maps.current).indexOf(mapId) === -1) {
70
78
  return false;
71
79
  } else if (!mapId && !map) {
@@ -73,7 +81,7 @@ const MapComponentsProvider = ({ children }:{children:any}) => {
73
81
  }
74
82
  return true;
75
83
  },
76
- getMap: (mapId:string):(MapLibreGlWrapper | null) => {
84
+ getMap: (mapId: string): MapLibreGlWrapper | null => {
77
85
  if (mapId && mapIds.indexOf(mapId) !== -1) {
78
86
  return maps.current[mapId];
79
87
  } else if (!mapId && map) {
@@ -82,11 +90,10 @@ const MapComponentsProvider = ({ children }:{children:any}) => {
82
90
 
83
91
  return null;
84
92
  },
85
- };
93
+ } as unknown as MapContextType;
86
94
 
87
- //@ts-ignore
88
95
  return <MapContext.Provider value={value}>{children}</MapContext.Provider>;
89
96
  };
90
97
 
91
98
  export { MapComponentsProvider };
92
- export default MapContext;
99
+ export default MapContext;
@@ -0,0 +1,5 @@
1
+ export interface GeoJSON {
2
+ type: string,
3
+ features?: any
4
+ geometry?: any
5
+ }
@@ -1,34 +1,45 @@
1
- import React from "react";
1
+ import React, { useMemo } from 'react';
2
2
 
3
- import { MapComponentsProvider } from "../index";
4
- import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
- import "./style.css";
6
- import MlNavgiationTools from "../components/MlNavigationTools/MlNavigationTools";
7
- import ThemeWrapper from "./ThemeWrapper";
3
+ import { MapComponentsProvider } from '../index';
4
+ import MapLibreMap from '../components/MapLibreMap/MapLibreMap';
5
+ import './style.css';
6
+ import MlNavgiationTools from '../components/MlNavigationTools/MlNavigationTools';
7
+ import { ThemeProvider as MUIThemeProvider, createTheme } from '@mui/material/styles';
8
8
 
9
9
  const decorators = [
10
- (Story) => (
11
- <div className="fullscreen_map">
12
- <ThemeWrapper>
13
- <MapComponentsProvider>
14
- <Story />
15
- <MapLibreMap
16
- options={{
17
- zoom: 14.5,
18
- style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
19
- center: [7.0851268, 50.73884],
20
- }}
21
- mapId="map_1"
22
- />
23
- <MlNavgiationTools
24
- sx={{ bottom: "25px", right: 0 }}
25
- showZoomButtons={false}
26
- mapId="map_1"
27
- />
28
- </MapComponentsProvider>
29
- </ThemeWrapper>
30
- </div>
31
- ),
10
+ (Story, context) => {
11
+ const theme = useMemo(
12
+ () =>
13
+ createTheme({
14
+ palette: {
15
+ mode: context?.globals?.theme ? context?.globals?.theme : 'light',
16
+ },
17
+ }),
18
+ [context?.globals?.theme]
19
+ );
20
+ return (
21
+ <div className="fullscreen_map">
22
+ <MUIThemeProvider theme={theme}>
23
+ <MapComponentsProvider>
24
+ <Story />
25
+ <MapLibreMap
26
+ options={{
27
+ zoom: 14.5,
28
+ style: 'https://wms.wheregroup.com/tileserver/style/osm-bright.json',
29
+ center: [7.0851268, 50.73884],
30
+ }}
31
+ mapId="map_1"
32
+ />
33
+ <MlNavgiationTools
34
+ sx={{ bottom: '25px', right: 0 }}
35
+ showZoomButtons={false}
36
+ mapId="map_1"
37
+ />
38
+ </MapComponentsProvider>
39
+ </MUIThemeProvider>
40
+ </div>
41
+ );
42
+ },
32
43
  ];
33
44
 
34
45
  export default decorators;
@@ -1,15 +1,25 @@
1
- import React from "react";
1
+ import React, { useMemo } from 'react';
2
2
 
3
3
  import { MapComponentsProvider } from "../index";
4
4
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
5
  import "./style.css";
6
6
  import MlNavgiationTools from "../components/MlNavigationTools/MlNavigationTools";
7
- import ThemeWrapper from "./ThemeWrapper";
7
+ import { ThemeProvider as MUIThemeProvider, createTheme } from '@mui/material/styles';
8
8
 
9
9
  const decorators = [
10
- (Story) => (
11
- <div className="fullscreen_map">
12
- <ThemeWrapper>
10
+ (Story, context) => {
11
+ const theme = useMemo(
12
+ () =>
13
+ createTheme({
14
+ palette: {
15
+ mode: context?.globals?.theme ? context?.globals?.theme : 'light',
16
+ },
17
+ }),
18
+ [context?.globals?.theme]
19
+ );
20
+ return (
21
+ <div className="fullscreen_map">
22
+ <MUIThemeProvider theme={theme}>
13
23
  <MapComponentsProvider>
14
24
  <Story />
15
25
  <MapLibreMap
@@ -26,9 +36,9 @@ const decorators = [
26
36
  mapId="map_1"
27
37
  />
28
38
  </MapComponentsProvider>
29
- </ThemeWrapper>
30
- </div>
31
- ),
39
+ </MUIThemeProvider>
40
+ </div>)
41
+ },
32
42
  ];
33
43
 
34
44
  export default decorators;
@@ -1,80 +1,90 @@
1
- import React from "react";
1
+ import React, { useMemo } from 'react';
2
2
 
3
- import { MapComponentsProvider } from "../index";
3
+ import { MapComponentsProvider } from '../index';
4
4
 
5
- import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
+ import MapLibreMap from '../components/MapLibreMap/MapLibreMap';
6
6
 
7
- import "./style.css";
8
- import { createTheme, ThemeProvider } from "@mui/material/styles";
9
- import MlNavgiationTools from "../components/MlNavigationTools/MlNavigationTools";
7
+ import './style.css';
8
+ import MlNavgiationTools from '../components/MlNavigationTools/MlNavigationTools';
10
9
 
11
- const theme = createTheme({});
10
+ import { ThemeProvider as MUIThemeProvider, createTheme } from '@mui/material/styles';
12
11
 
13
12
  const decorators = [
14
- (Story) => (
15
- <div className="fullscreen_map">
16
- <ThemeProvider theme={theme}>
17
- <MapComponentsProvider>
18
- <div
19
- style={{
20
- overflow: "hidden",
21
- position: "absolute",
22
- top: "0",
23
- bottom: "0",
24
- left: "0",
25
- right: "0",
26
- }}
27
- >
28
- <Story />
29
- <div className="maps">
30
- <MapLibreMap
31
- mapId="map_1"
32
- options={{
33
- //style: "mapbox://styles/mapbox/light-v10",
34
- //center: [-87.62712, 41.89033],
35
- zoom: 14.5,
36
- //pitch: 45,
37
- //style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
38
- style: "https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
39
- //center: [8.607, 53.1409349],
40
- //zoom: 13,
41
- center: [7.0851268, 50.73884],
42
- //maxBounds: [
43
- // [1.40625, 43.452919],
44
- // [17.797852, 55.973798],
45
- //],
46
- }}
47
- />
48
- <MapLibreMap
49
- mapId="map_2"
50
- options={{
51
- //style: "mapbox://styles/mapbox/light-v10",
52
- //center: [-87.62712, 41.89033],
53
- zoom: 14.5,
54
- //pitch: 45,
55
- style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
56
- //style: "https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
57
- //center: [8.607, 53.1409349],
58
- //zoom: 13,
59
- center: [7.0851268, 50.73884],
60
- //maxBounds: [
61
- // [1.40625, 43.452919],
62
- // [17.797852, 55.973798],
63
- //],
64
- }}
65
- />
13
+ (Story, context) => {
14
+ const theme = useMemo(
15
+ () =>
16
+ createTheme({
17
+ palette: {
18
+ mode: context?.globals?.theme ? context?.globals?.theme : 'light',
19
+ },
20
+ }),
21
+ [context?.globals?.theme]
22
+ );
23
+ return (
24
+ <div className="fullscreen_map">
25
+ <MUIThemeProvider theme={theme}>
26
+ <MapComponentsProvider>
27
+ <div
28
+ style={{
29
+ overflow: 'hidden',
30
+ position: 'absolute',
31
+ top: '0',
32
+ bottom: '0',
33
+ left: '0',
34
+ right: '0',
35
+ }}
36
+ >
37
+ <Story />
38
+ <div className="maps">
39
+ <MapLibreMap
40
+ mapId="map_1"
41
+ options={{
42
+ //style: "mapbox://styles/mapbox/light-v10",
43
+ //center: [-87.62712, 41.89033],
44
+ zoom: 14.5,
45
+ //pitch: 45,
46
+ //style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
47
+ style: 'https://wms.wheregroup.com/tileserver/style/osm-liberty.json',
48
+ //center: [8.607, 53.1409349],
49
+ //zoom: 13,
50
+ center: [7.0851268, 50.73884],
51
+ //maxBounds: [
52
+ // [1.40625, 43.452919],
53
+ // [17.797852, 55.973798],
54
+ //],
55
+ }}
56
+ />
57
+ <MapLibreMap
58
+ mapId="map_2"
59
+ options={{
60
+ //style: "mapbox://styles/mapbox/light-v10",
61
+ //center: [-87.62712, 41.89033],
62
+ zoom: 14.5,
63
+ //pitch: 45,
64
+ style: 'https://wms.wheregroup.com/tileserver/style/osm-bright.json',
65
+ //style: "https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
66
+ //center: [8.607, 53.1409349],
67
+ //zoom: 13,
68
+ center: [7.0851268, 50.73884],
69
+ //maxBounds: [
70
+ // [1.40625, 43.452919],
71
+ // [17.797852, 55.973798],
72
+ //],
73
+ }}
74
+ />
66
75
 
67
- <MlNavgiationTools
68
- sx={{ top: "10px", right: "5px" }}
69
- showZoomButtons={false}
70
- mapId="map_1"
71
- />
76
+ <MlNavgiationTools
77
+ sx={{ top: '10px', right: '5px' }}
78
+ showZoomButtons={false}
79
+ mapId="map_1"
80
+ />
81
+ </div>
72
82
  </div>
73
- </div>
74
- </MapComponentsProvider>
75
- </ThemeProvider>
76
- </div>
77
- ),
83
+ </MapComponentsProvider>
84
+ </MUIThemeProvider>
85
+ </div>
86
+ );
87
+ },
78
88
  ];
79
89
 
80
90
  export default decorators;