@mapcomponents/react-maplibre 0.1.45 → 0.1.46

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 (169) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/coverage/clover.xml +206 -132
  3. package/coverage/coverage-final.json +7 -5
  4. package/coverage/lcov-report/index.html +86 -71
  5. package/coverage/lcov-report/src/components/MapLibreMap/MapLibreMap.tsx.html +40 -10
  6. package/coverage/lcov-report/src/components/MapLibreMap/index.html +17 -17
  7. package/coverage/lcov-report/src/components/MlCreatePdfButton/MlCreatePdfButton.tsx.html +1 -1
  8. package/coverage/lcov-report/src/components/MlCreatePdfButton/index.html +1 -1
  9. package/coverage/lcov-report/src/components/MlFeatureEditor/MlFeatureEditor.tsx.html +1 -1
  10. package/coverage/lcov-report/src/components/MlFeatureEditor/index.html +1 -1
  11. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/MlFillExtrusionLayer.tsx.html +1 -1
  12. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/index.html +1 -1
  13. package/coverage/lcov-report/src/components/MlFollowGps/MlFollowGps.tsx.html +1 -1
  14. package/coverage/lcov-report/src/components/MlFollowGps/index.html +1 -1
  15. package/coverage/lcov-report/src/components/MlGPXViewer/MlGPXViewer.tsx.html +1 -1
  16. package/coverage/lcov-report/src/components/MlGPXViewer/gpxConverter.js.html +1 -1
  17. package/coverage/lcov-report/src/components/MlGPXViewer/index.html +1 -1
  18. package/coverage/lcov-report/src/components/MlGeoJsonLayer/MlGeoJsonLayer.tsx.html +1 -1
  19. package/coverage/lcov-report/src/components/MlGeoJsonLayer/index.html +1 -1
  20. package/coverage/lcov-report/src/components/MlImageMarkerLayer/MlImageMarkerLayer.tsx.html +188 -53
  21. package/coverage/lcov-report/src/components/MlImageMarkerLayer/index.html +21 -21
  22. package/coverage/lcov-report/src/components/MlLayer/MlLayer.tsx.html +1 -1
  23. package/coverage/lcov-report/src/components/MlLayer/index.html +1 -1
  24. package/coverage/lcov-report/src/components/MlLayerMagnify/MlLayerMagnify.tsx.html +1 -1
  25. package/coverage/lcov-report/src/components/MlLayerMagnify/index.html +1 -1
  26. package/coverage/lcov-report/src/components/MlLayerSwipe/MlLayerSwipe.tsx.html +1 -1
  27. package/coverage/lcov-report/src/components/MlLayerSwipe/index.html +1 -1
  28. package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +2 -2
  29. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +1 -1
  30. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +1 -1
  31. package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +1 -1
  32. package/coverage/lcov-report/src/components/MlMarker/MlMarker.tsx.html +1 -1
  33. package/coverage/lcov-report/src/components/MlMarker/index.html +1 -1
  34. package/coverage/lcov-report/src/components/MlMeasureTool/MlMeasureTool.tsx.html +184 -0
  35. package/coverage/lcov-report/src/components/MlMeasureTool/index.html +116 -0
  36. package/coverage/lcov-report/src/components/MlNavigationCompass/MlNavigationCompass.tsx.html +1 -1
  37. package/coverage/lcov-report/src/components/MlNavigationCompass/index.html +1 -1
  38. package/coverage/lcov-report/src/components/MlNavigationTools/MlNavigationTools.tsx.html +1 -1
  39. package/coverage/lcov-report/src/components/MlNavigationTools/index.html +1 -1
  40. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.js.html +1 -1
  41. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.stories_.js.html +232 -0
  42. package/coverage/lcov-report/src/components/MlOsmLayer/index.html +25 -10
  43. package/coverage/lcov-report/src/components/MlScaleReference/MlScaleReference.js.html +1 -1
  44. package/coverage/lcov-report/src/components/MlScaleReference/index.html +1 -1
  45. package/coverage/lcov-report/src/components/MlShareMapState/MlShareMapState.js.html +1 -1
  46. package/coverage/lcov-report/src/components/MlShareMapState/index.html +1 -1
  47. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.js.html +1 -1
  48. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/index.html +1 -1
  49. package/coverage/lcov-report/src/components/MlThreeJsLayer/MlThreeJsLayer.js.html +1 -1
  50. package/coverage/lcov-report/src/components/MlThreeJsLayer/index.html +1 -1
  51. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/MlTransitionGeoJsonLayer.tsx.html +1 -1
  52. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/index.html +1 -1
  53. package/coverage/lcov-report/src/components/MlUseMapDebugger/MlUseMapDebugger.js.html +1 -1
  54. package/coverage/lcov-report/src/components/MlUseMapDebugger/index.html +1 -1
  55. package/coverage/lcov-report/src/components/MlVectorTileLayer/MlVectorTileLayer.tsx.html +74 -20
  56. package/coverage/lcov-report/src/components/MlVectorTileLayer/index.html +19 -19
  57. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +1 -1
  58. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/index.html +1 -1
  59. package/coverage/lcov-report/src/components/MlWmsLayer/MlWmsLayer.tsx.html +80 -20
  60. package/coverage/lcov-report/src/components/MlWmsLayer/index.html +21 -21
  61. package/coverage/lcov-report/src/components/MlWmsLoader/MlWmsLoader.tsx.html +1 -1
  62. package/coverage/lcov-report/src/components/MlWmsLoader/index.html +1 -1
  63. package/coverage/lcov-report/src/contexts/MapContext.tsx.html +1 -1
  64. package/coverage/lcov-report/src/contexts/SimpleDataContext.js.html +1 -1
  65. package/coverage/lcov-report/src/contexts/SimpleDataProvider.js.html +1 -1
  66. package/coverage/lcov-report/src/contexts/index.html +1 -1
  67. package/coverage/lcov-report/src/hooks/index.html +19 -19
  68. package/coverage/lcov-report/src/hooks/useLayer.ts.html +46 -22
  69. package/coverage/lcov-report/src/hooks/useMap.ts.html +1 -1
  70. package/coverage/lcov-report/src/hooks/useMapState.ts.html +1 -1
  71. package/coverage/lcov-report/src/hooks/useWms.js.html +1 -1
  72. package/coverage/lcov-report/src/index.html +1 -1
  73. package/coverage/lcov-report/src/index.ts.html +9 -6
  74. package/coverage/lcov.info +422 -252
  75. package/dist/index.esm.js +127 -36
  76. package/dist/index.esm.js.map +1 -1
  77. package/docs-build/{0.b1b9b035.iframe.bundle.js → 0.0ee4f98c.iframe.bundle.js} +2 -2
  78. package/docs-build/0.0ee4f98c.iframe.bundle.js.map +1 -0
  79. package/docs-build/{1.c50fb367.iframe.bundle.js → 1.bb3cf738.iframe.bundle.js} +3 -3
  80. package/docs-build/1.bb3cf738.iframe.bundle.js.map +1 -0
  81. package/docs-build/{17.2e544968.iframe.bundle.js → 17.97db5b3f.iframe.bundle.js} +2 -2
  82. package/docs-build/17.97db5b3f.iframe.bundle.js.map +1 -0
  83. package/docs-build/{18.42087006.iframe.bundle.js → 18.f8d843df.iframe.bundle.js} +3 -3
  84. package/docs-build/18.f8d843df.iframe.bundle.js.map +1 -0
  85. package/docs-build/{19.7e782442.iframe.bundle.js → 19.c45e6b08.iframe.bundle.js} +2 -2
  86. package/docs-build/19.c45e6b08.iframe.bundle.js.map +1 -0
  87. package/docs-build/{2.e58dc625.iframe.bundle.js → 2.42c790e4.iframe.bundle.js} +2 -2
  88. package/docs-build/2.42c790e4.iframe.bundle.js.map +1 -0
  89. package/docs-build/{20.f009289a.iframe.bundle.js → 20.120bbcfb.iframe.bundle.js} +2 -2
  90. package/docs-build/20.120bbcfb.iframe.bundle.js.map +1 -0
  91. package/docs-build/{21.1cdc9040.iframe.bundle.js → 21.37c885f1.iframe.bundle.js} +2 -2
  92. package/docs-build/21.37c885f1.iframe.bundle.js.map +1 -0
  93. package/docs-build/{22.c9e6b2d7.iframe.bundle.js → 22.7fbc99f4.iframe.bundle.js} +2 -2
  94. package/docs-build/22.7fbc99f4.iframe.bundle.js.map +1 -0
  95. package/docs-build/{3.a8172b89.iframe.bundle.js → 3.1a37a83e.iframe.bundle.js} +2 -2
  96. package/docs-build/3.1a37a83e.iframe.bundle.js.map +1 -0
  97. package/docs-build/iframe.html +1 -1
  98. package/docs-build/main~24120820.905c51c8.iframe.bundle.js +2 -0
  99. package/docs-build/main~24120820.905c51c8.iframe.bundle.js.map +1 -0
  100. package/docs-build/thumbnails/MlMeasureTool.png +0 -0
  101. package/docs-build/{vendors~main~0ad7406a.2054ae7c.iframe.bundle.js → vendors~main~0ad7406a.93aea1be.iframe.bundle.js} +3 -3
  102. package/docs-build/vendors~main~0ad7406a.93aea1be.iframe.bundle.js.map +1 -0
  103. package/docs-build/vendors~main~0f485567.6e7163ef.iframe.bundle.js +2 -0
  104. package/docs-build/vendors~main~0f485567.6e7163ef.iframe.bundle.js.map +1 -0
  105. package/docs-build/{vendors~main~41a6ab2c.a947ed53.iframe.bundle.js → vendors~main~41a6ab2c.da377733.iframe.bundle.js} +2 -2
  106. package/docs-build/vendors~main~41a6ab2c.da377733.iframe.bundle.js.map +1 -0
  107. package/docs-build/{vendors~main~52589227.1d1558cd.iframe.bundle.js → vendors~main~52589227.cebbe724.iframe.bundle.js} +2 -2
  108. package/docs-build/vendors~main~52589227.cebbe724.iframe.bundle.js.map +1 -0
  109. package/docs-build/{vendors~main~57c1f6cb.6a433835.iframe.bundle.js → vendors~main~57c1f6cb.86178471.iframe.bundle.js} +2 -2
  110. package/docs-build/vendors~main~57c1f6cb.86178471.iframe.bundle.js.map +1 -0
  111. package/docs-build/{vendors~main~73914085.a8e03e3b.iframe.bundle.js → vendors~main~73914085.e2f34f8e.iframe.bundle.js} +6 -6
  112. package/docs-build/{vendors~main~73914085.a8e03e3b.iframe.bundle.js.map → vendors~main~73914085.e2f34f8e.iframe.bundle.js.map} +1 -1
  113. package/docs-build/{vendors~main~9c5b28f6.7b8beed1.iframe.bundle.js → vendors~main~9c5b28f6.eefa7445.iframe.bundle.js} +3 -3
  114. package/docs-build/vendors~main~9c5b28f6.eefa7445.iframe.bundle.js.map +1 -0
  115. package/docs-build/{vendors~main~b5906859.7f66dcaf.iframe.bundle.js → vendors~main~b5906859.210afc21.iframe.bundle.js} +5 -5
  116. package/docs-build/vendors~main~b5906859.210afc21.iframe.bundle.js.map +1 -0
  117. package/docs-build/{vendors~main~b8f44717.7053e467.iframe.bundle.js → vendors~main~b8f44717.7b869975.iframe.bundle.js} +3 -3
  118. package/docs-build/vendors~main~b8f44717.7b869975.iframe.bundle.js.map +1 -0
  119. package/docs-build/{vendors~main~b9cf3951.a4fd68f5.iframe.bundle.js → vendors~main~b9cf3951.62d39717.iframe.bundle.js} +11 -11
  120. package/docs-build/vendors~main~b9cf3951.62d39717.iframe.bundle.js.map +1 -0
  121. package/docs-build/vendors~main~d939e436.394e3bc7.iframe.bundle.js +2 -0
  122. package/docs-build/vendors~main~d939e436.394e3bc7.iframe.bundle.js.map +1 -0
  123. package/docs-build/vendors~main~f420d588.88814a6a.iframe.bundle.js +107 -0
  124. package/docs-build/vendors~main~f420d588.88814a6a.iframe.bundle.js.map +1 -0
  125. package/package.json +1 -1
  126. package/public/thumbnails/MlMeasureTool.png +0 -0
  127. package/src/components/MapLibreMap/MapLibreMap.stories.js +75 -20
  128. package/src/components/MapLibreMap/MapLibreMap.tsx +11 -1
  129. package/src/components/MapLibreMap/lib/MapLibreGlWrapper.ts +2 -2
  130. package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.test.js +1 -1
  131. package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.tsx +82 -37
  132. package/src/components/MlLayerSwitcher/MlLayerSwitcher.js +1 -1
  133. package/src/components/MlMeasureTool/MlMeasureTool.doc.de.md +3 -0
  134. package/src/components/MlMeasureTool/MlMeasureTool.meta.json +15 -0
  135. package/src/components/MlMeasureTool/MlMeasureTool.stories.js +67 -0
  136. package/src/components/MlMeasureTool/MlMeasureTool.tsx +33 -0
  137. package/src/components/MlOsmLayer/{MlOsmLayer.stories.js → MlOsmLayer.stories_.js} +0 -0
  138. package/src/components/MlVectorTileLayer/MlVectorTileLayer.tsx +26 -8
  139. package/src/components/MlWmsLayer/MlWmsLayer.stories.js +2 -3
  140. package/src/components/MlWmsLayer/MlWmsLayer.tsx +27 -7
  141. package/src/hooks/useLayer.ts +15 -7
  142. package/src/index.ts +4 -4
  143. package/src/util/layerRemovalTest.js +5 -0
  144. package/docs-build/0.b1b9b035.iframe.bundle.js.map +0 -1
  145. package/docs-build/1.c50fb367.iframe.bundle.js.map +0 -1
  146. package/docs-build/17.2e544968.iframe.bundle.js.map +0 -1
  147. package/docs-build/18.42087006.iframe.bundle.js.map +0 -1
  148. package/docs-build/19.7e782442.iframe.bundle.js.map +0 -1
  149. package/docs-build/2.e58dc625.iframe.bundle.js.map +0 -1
  150. package/docs-build/20.f009289a.iframe.bundle.js.map +0 -1
  151. package/docs-build/21.1cdc9040.iframe.bundle.js.map +0 -1
  152. package/docs-build/22.c9e6b2d7.iframe.bundle.js.map +0 -1
  153. package/docs-build/3.a8172b89.iframe.bundle.js.map +0 -1
  154. package/docs-build/main~24120820.edd86ba9.iframe.bundle.js +0 -2
  155. package/docs-build/main~24120820.edd86ba9.iframe.bundle.js.map +0 -1
  156. package/docs-build/vendors~main~0ad7406a.2054ae7c.iframe.bundle.js.map +0 -1
  157. package/docs-build/vendors~main~0f485567.de36692f.iframe.bundle.js +0 -2
  158. package/docs-build/vendors~main~0f485567.de36692f.iframe.bundle.js.map +0 -1
  159. package/docs-build/vendors~main~41a6ab2c.a947ed53.iframe.bundle.js.map +0 -1
  160. package/docs-build/vendors~main~52589227.1d1558cd.iframe.bundle.js.map +0 -1
  161. package/docs-build/vendors~main~57c1f6cb.6a433835.iframe.bundle.js.map +0 -1
  162. package/docs-build/vendors~main~9c5b28f6.7b8beed1.iframe.bundle.js.map +0 -1
  163. package/docs-build/vendors~main~b5906859.7f66dcaf.iframe.bundle.js.map +0 -1
  164. package/docs-build/vendors~main~b8f44717.7053e467.iframe.bundle.js.map +0 -1
  165. package/docs-build/vendors~main~b9cf3951.a4fd68f5.iframe.bundle.js.map +0 -1
  166. package/docs-build/vendors~main~d939e436.ba1cad1b.iframe.bundle.js +0 -2
  167. package/docs-build/vendors~main~d939e436.ba1cad1b.iframe.bundle.js.map +0 -1
  168. package/docs-build/vendors~main~f420d588.59c93444.iframe.bundle.js +0 -107
  169. package/docs-build/vendors~main~f420d588.59c93444.iframe.bundle.js.map +0 -1
@@ -1,7 +1,11 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
2
 
3
3
  import MapLibreMap from "./MapLibreMap";
4
4
  import { MapComponentsProvider } from "../../contexts/MapContext";
5
+ import MlGeoJsonLayer from "../MlGeoJsonLayer/MlGeoJsonLayer";
6
+ import { Button } from "@mui/material";
7
+ import TopToolbar from "../../ui_components/TopToolbar";
8
+ import sample_geojson_1 from "../MlGeoJsonLayer/assets/sample_1.json";
5
9
 
6
10
  const storyoptions = {
7
11
  title: "Core/MapLibreMap",
@@ -16,30 +20,81 @@ const storyoptions = {
16
20
  };
17
21
  export default storyoptions;
18
22
 
19
- const Template = (args) => (
20
- <MapComponentsProvider>
21
- <MapLibreMap
22
- options={args.options}
23
- style={{
24
- position: "absolute",
25
- height: "100vh",
26
- width: "100vw",
27
- top: 0,
28
- right: 0,
29
- left: 0,
30
- bottom: 0,
31
- zIndex: 100,
32
- }}
33
- />
34
- </MapComponentsProvider>
35
- );
23
+ const Template = (args) => {
24
+ return (
25
+ <MapComponentsProvider>
26
+ <MapLibreMap
27
+ options={args.options}
28
+ style={{
29
+ position: "absolute",
30
+ height: "100vh",
31
+ width: "100vw",
32
+ top: 0,
33
+ right: 0,
34
+ left: 0,
35
+ bottom: 0,
36
+ zIndex: 100,
37
+ }}
38
+ />
39
+ </MapComponentsProvider>
40
+ );
41
+ };
36
42
 
37
43
  export const ExampleConfig = Template.bind({});
38
44
  ExampleConfig.args = {
39
45
  options: {
40
46
  style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
41
47
  center: [8.607, 53.1409349],
42
- zoom: 14
48
+ zoom: 14,
49
+ },
50
+ };
51
+
52
+ const StyleChangeTemplate = (args) => {
53
+ const [activeStyle, setActiveStyle] = useState(
54
+ "https://wms.wheregroup.com/tileserver/style/osm-fiord-color.json"
55
+ );
56
+
57
+ return (
58
+ <MapComponentsProvider>
59
+ <TopToolbar>
60
+ <Button
61
+ onClick={() =>
62
+ setActiveStyle("https://wms.wheregroup.com/tileserver/style/osm-bright.json")
63
+ }
64
+ >
65
+ OSM-Bright
66
+ </Button>
67
+ <Button
68
+ onClick={() =>
69
+ setActiveStyle("https://wms.wheregroup.com/tileserver/style/osm-fiord-color.json")
70
+ }
71
+ >
72
+ OSM-Fiord-Color
73
+ </Button>
74
+ </TopToolbar>
75
+ <MapLibreMap
76
+ options={{ ...args.options, style: activeStyle }}
77
+ style={{
78
+ position: "absolute",
79
+ height: "100vh",
80
+ width: "100vw",
81
+ top: 0,
82
+ right: 0,
83
+ left: 0,
84
+ bottom: 0,
85
+ zIndex: 100,
86
+ }}
87
+ />
88
+ <MlGeoJsonLayer type="line" geojson={sample_geojson_1} />
89
+ </MapComponentsProvider>
90
+ );
91
+ };
92
+
93
+ export const StyleChangeConfig = StyleChangeTemplate.bind({});
94
+ StyleChangeConfig.args = {
95
+ options: {
96
+ zoom: 14.5,
97
+ center: [7.0851268, 50.73884],
43
98
  },
44
99
  };
45
- ExampleConfig.parameters = {};
100
+ StyleChangeConfig.parameters = {};
@@ -40,7 +40,7 @@ const defaultProps: MapLibreMapProps = {
40
40
  id: "background",
41
41
  type: "background",
42
42
  paint: {
43
- "background-color": "rgba(80,0,0,0)",
43
+ "background-color": "rgba(0,0,0,0)",
44
44
  },
45
45
  },
46
46
  ],
@@ -66,6 +66,7 @@ const MapLibreMap: FC<MapLibreMapProps> = (props: MapLibreMapProps) => {
66
66
 
67
67
  const mapIdRef = useRef(props.mapId);
68
68
  const initializedRef = useRef(false);
69
+ const currentStyle = useRef(props.options?.style);
69
70
 
70
71
  useEffect(() => {
71
72
  let mapId = mapIdRef.current;
@@ -101,6 +102,15 @@ const MapLibreMap: FC<MapLibreMapProps> = (props: MapLibreMapProps) => {
101
102
  }
102
103
  }, [props.options, props.mapId]);
103
104
 
105
+ useEffect(() => {
106
+ if (map.current?.map && props?.options?.style && currentStyle.current !== props.options.style) {
107
+ console.log("set style");
108
+ currentStyle.current = props.options.style;
109
+ map.current.map.setStyle(props.options.style);
110
+ }
111
+ // @ts-ignore: props.options is either passed or populated with default values
112
+ }, [props.options.style])
113
+
104
114
  return <div ref={mapContainer as RefObject<HTMLDivElement>} className="mapContainer" style={props.style} />;
105
115
  };
106
116
 
@@ -213,7 +213,7 @@ class MapLibreGlWrapper {
213
213
  */
214
214
  buildLayerObjects: () => {
215
215
  // @ts-ignore
216
- return self.style._order
216
+ return self.map.style._order
217
217
  .map((layerId: string) => {
218
218
  return self.wrapper.buildLayerObject(
219
219
  self.map.style._layers[layerId]
@@ -487,7 +487,7 @@ class MapLibreGlWrapper {
487
487
  this[item] = (...props: any[]) => {
488
488
  if (
489
489
  self.map &&
490
- this.map.style &&
490
+ self.map.style &&
491
491
  typeof self.map.style[item] === "function"
492
492
  ) {
493
493
  self.map.style[item](...props);
@@ -3,7 +3,7 @@ import { uuid_regex } from "../../setupTests";
3
3
 
4
4
  import MlImageMarkerLayer from "./MlImageMarkerLayer";
5
5
 
6
- const testComponent = <MlImageMarkerLayer options={{ source: {} }} imgSrc="testImage" />;
6
+ const testComponent = <MlImageMarkerLayer options={{ source: {} }} />;
7
7
 
8
8
  layerRemovalTest(
9
9
  "<MlImageMarkerLayer />",
@@ -1,7 +1,7 @@
1
1
  import React, { useRef, useCallback, useEffect } from "react";
2
2
 
3
3
  import { GeoJSONSource } from "maplibre-gl";
4
- import useMap from "../../hooks/useMap";
4
+ import useMap, { useMapType } from "../../hooks/useMap";
5
5
 
6
6
  interface MlImageMarkerLayerProps {
7
7
  /**
@@ -37,12 +37,12 @@ const MlImageMarkerLayer = (props: MlImageMarkerLayerProps) => {
37
37
  waitForLayer: props.insertBeforeLayer,
38
38
  });
39
39
 
40
- const layerInitializedRef = useRef(false);
40
+ const initializedRef = useRef(false);
41
+ const recreationInProgress = useRef(false);
41
42
  const imageIdRef = useRef(props.imageId || "img_" + new Date().getTime());
42
- const layerId = useRef(
43
- props.layerId || "MlImageMarkerLayer-" + mapHook.componentId
44
- );
43
+ const layerId = useRef(props.layerId || "MlImageMarkerLayer-" + mapHook.componentId);
45
44
 
45
+ // effect to sync Layer paint & layout properties
46
46
  useEffect(() => {
47
47
  if (
48
48
  !mapHook.map ||
@@ -50,32 +50,53 @@ const MlImageMarkerLayer = (props: MlImageMarkerLayerProps) => {
50
50
  !props.options
51
51
  )
52
52
  return;
53
- // the MapLibre-gl instance (mapContext.map) is accessible here
54
- // initialize the layer and add it to the MapLibre-gl instance or do something else with it
53
+
55
54
  var key;
56
55
 
57
56
  if (props.options.layout) {
58
57
  for (key in props.options.layout) {
59
- mapHook.map.map.setLayoutProperty(
60
- layerId.current,
61
- key,
62
- props.options.layout[key]
63
- );
58
+ mapHook.map.map.setLayoutProperty(layerId.current, key, props.options.layout[key]);
64
59
  }
65
60
  }
66
61
  if (props.options.paint) {
67
62
  for (key in props.options.paint) {
68
- mapHook.map.map.setPaintProperty(
69
- layerId.current,
70
- key,
71
- props.options.paint[key]
72
- );
63
+ mapHook.map.map.setPaintProperty(layerId.current, key, props.options.paint[key]);
73
64
  }
74
65
  }
75
66
  }, [props.options, layerId.current, props.mapId]);
76
67
 
77
- const addLayer = useCallback(() => {
78
- if(!mapHook.map)return;
68
+ const createImage = (mapHook: useMapType, props: MlImageMarkerLayerProps, callback: Function) => {
69
+ if (!mapHook.map) {
70
+ initializedRef.current = false;
71
+
72
+ return;
73
+ }
74
+
75
+ if (props.imgSrc && !mapHook.map.map.hasImage(imageIdRef.current)) {
76
+ mapHook.map.map.loadImage(props.imgSrc, function (error, image) {
77
+ if (error) throw error;
78
+
79
+ if (!mapHook.map || mapHook.map.map.hasImage(imageIdRef.current)) return;
80
+
81
+ mapHook.map.addImage(imageIdRef.current, image, mapHook.componentId);
82
+
83
+ if (typeof callback === "function") {
84
+ callback();
85
+ }
86
+ });
87
+ } else {
88
+ if (typeof callback === "function") {
89
+ callback();
90
+ }
91
+ }
92
+ };
93
+
94
+ const createLayer = (
95
+ mapHook: useMapType,
96
+ props: MlImageMarkerLayerProps,
97
+ createMapLibreElements: Function
98
+ ) => {
99
+ if (!props.options || !mapHook.map || mapHook.map?.map.getLayer(layerId.current)) return;
79
100
 
80
101
  let tmpOptions = {
81
102
  id: layerId.current,
@@ -83,31 +104,55 @@ const MlImageMarkerLayer = (props: MlImageMarkerLayerProps) => {
83
104
  ...props.options,
84
105
  };
85
106
  tmpOptions.layout["icon-image"] = imageIdRef.current;
86
- mapHook.map.addLayer(
87
- tmpOptions,
88
- props.insertBeforeLayer,
107
+ mapHook.map.addLayer(tmpOptions, props.insertBeforeLayer, mapHook.componentId);
108
+
109
+ // recreate layer if map style.json has changed
110
+ mapHook.map.on(
111
+ "styledata",
112
+ () => {
113
+ if (
114
+ initializedRef.current &&
115
+ !mapHook.map?.map.getLayer(layerId.current) &&
116
+ !recreationInProgress.current
117
+ ) {
118
+ initializedRef.current = false;
119
+ recreationInProgress.current = true;
120
+ console.log("Recreate Layer " + layerId.current);
121
+ createMapLibreElements();
122
+ }
123
+ },
89
124
  mapHook.componentId
90
125
  );
91
- }, [props, mapHook.map]);
92
126
 
93
- useEffect(() => {
94
- if (!props.options || !mapHook.map || layerInitializedRef.current)
127
+ if (recreationInProgress.current) {
128
+ recreationInProgress.current = false;
129
+ }
130
+ };
131
+
132
+ const createMapLibreElements = useCallback(() => {
133
+ if (!mapHook.map || initializedRef.current || mapHook.map?.map.getLayer(layerId.current))
95
134
  return;
96
135
 
97
- layerInitializedRef.current = true;
136
+ initializedRef.current = true;
98
137
 
99
- if (props.imgSrc) {
100
- mapHook.map.map.loadImage(props.imgSrc, function (error, image) {
101
- if (error) throw error;
102
-
103
- if(!mapHook.map)return;
138
+ if (recreationInProgress.current) {
139
+ mapHook.cleanup();
140
+ }
104
141
 
105
- mapHook.map.addImage(imageIdRef.current, image, mapHook.componentId);
142
+ if (props.imgSrc) {
143
+ createImage(mapHook, props, () => {
144
+ createLayer(mapHook, props, createMapLibreElements);
106
145
  });
146
+ } else {
147
+ createLayer(mapHook, props, createMapLibreElements);
107
148
  }
149
+ }, [props, mapHook]);
108
150
 
109
- addLayer();
110
- }, [mapHook.map, addLayer, props]);
151
+ useEffect(() => {
152
+ if (initializedRef.current) return;
153
+
154
+ createMapLibreElements();
155
+ }, [createMapLibreElements]);
111
156
 
112
157
  useEffect(() => {
113
158
  if (
@@ -118,9 +163,9 @@ const MlImageMarkerLayer = (props: MlImageMarkerLayerProps) => {
118
163
  return;
119
164
  }
120
165
 
121
- (mapHook.map.map
122
- .getSource(layerId.current) as GeoJSONSource)
123
- .setData(props.options.source.data);
166
+ (mapHook.map.map.getSource(layerId.current) as GeoJSONSource).setData(
167
+ props.options.source.data
168
+ );
124
169
  }, [props.options.source.data, props]);
125
170
 
126
171
  return <></>;
@@ -1,6 +1,6 @@
1
1
  import "./MlLayerSwitcher.css";
2
2
  //External
3
- import { useEffect, useContext, useState } from "react";
3
+ import React, { useEffect, useContext, useState } from "react";
4
4
  import PropTypes from "prop-types";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import { Card, CardContent, Typography, Box } from "@mui/material";
@@ -0,0 +1,3 @@
1
+ # Component Beschreibung
2
+
3
+ Beschreibungstext
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "MlMeasureTool",
3
+ "title": "Measure tool",
4
+ "description": "",
5
+ "i18n": {
6
+ "de": {
7
+ "title": "Messwerkzeug",
8
+ "description": ""
9
+ }
10
+ },
11
+ "tags": [],
12
+ "category": "",
13
+ "type": "component",
14
+ "price": 0
15
+ }
@@ -0,0 +1,67 @@
1
+ import React from "react";
2
+
3
+ import MlMeasureTool from "./MlMeasureTool";
4
+
5
+ import mapContextDecorator from "../../decorators/MapContextDecorator";
6
+ import StraightenOutlinedIcon from "@mui/icons-material/StraightenOutlined";
7
+ import SquareFootOutlinedIcon from "@mui/icons-material/SquareFootOutlined";
8
+ import Grid from "@mui/material/Grid";
9
+ import Box from "@mui/material/Box";
10
+
11
+ const storyoptions = {
12
+ title: "MapComponents/MlMeasureTool",
13
+ component: MlMeasureTool,
14
+ argTypes: {
15
+ },
16
+ decorators: mapContextDecorator,
17
+ };
18
+ export default storyoptions;
19
+
20
+ const Template = (args) => (
21
+ <div style={{ width: "200px", position: "absolute", zIndex:105 }}>
22
+ <Grid
23
+ container
24
+ style={{
25
+ textAlign: "left",
26
+ alignItems: "center",
27
+ }}
28
+ >
29
+ <SquareFootOutlinedIcon />
30
+
31
+ <h4 style={{ margin: "0px" }}>Measure Polygon</h4>
32
+ </Grid>
33
+
34
+ <Box m={2} style={{ textAlign: "left" }}>
35
+ <MlMeasureTool measureType={"polygon"} />
36
+ </Box>
37
+ </div>
38
+ )
39
+
40
+ const LineTemplate = (args) => (
41
+ <div style={{ width: "200px", position: "absolute", zIndex:105, }}>
42
+ <Grid
43
+ container
44
+ style={{
45
+ textAlign: "left",
46
+ alignItems: "center",
47
+ }}
48
+ >
49
+ <StraightenOutlinedIcon />
50
+
51
+ <h4 style={{ margin: "0px" }}>Measure Line</h4>
52
+ </Grid>
53
+
54
+ <Box m={2} style={{ textAlign: "left" }}>
55
+ <MlMeasureTool measureType={"line"} />
56
+ </Box>
57
+ </div>
58
+ )
59
+
60
+ export const MeasureLine = LineTemplate.bind( {});
61
+ MeasureLine.parameters = {};
62
+ MeasureLine.args = {};
63
+
64
+ export const MeasurePolygon = Template.bind({});
65
+ MeasurePolygon.parameters = {};
66
+ MeasurePolygon.args = {};
67
+
@@ -0,0 +1,33 @@
1
+ import React, { useState } from "react";
2
+ import MlFeatureEditor from "../MlFeatureEditor/MlFeatureEditor";
3
+ import * as turf from "@turf/turf";
4
+
5
+ interface MlMeasureToolProps {
6
+ /**
7
+ * String that specify if the Tool measures an area ("polygon") or length ("line")
8
+ */
9
+ measureType: string;
10
+ }
11
+
12
+ const MlMeasureTool = (props: MlMeasureToolProps) => {
13
+ const [length, setLength] = useState(0)
14
+
15
+ return (
16
+ <>
17
+ <MlFeatureEditor
18
+ onChange={(features) => {
19
+ console.log(features);
20
+ if(features[0]) {
21
+ setLength(props.measureType === "polygon" ? turf.area(features[0]) / 1000000 : turf.length(features[0]));
22
+ }}}
23
+ mode = {props.measureType === "polygon" ? "custom_polygon" : "draw_line_string"}
24
+ />
25
+ {props.measureType === "polygon" ? "Area" : "Length"}: {length.toFixed(2)} {props.measureType === "polygon" ? "km²" : "km"}
26
+ </>);
27
+ };
28
+
29
+ MlMeasureTool.defaultProps = {
30
+ mapId: undefined,
31
+ measureType: "line",
32
+ };
33
+ export default MlMeasureTool;
@@ -1,4 +1,4 @@
1
- import React, { useRef, useEffect } from "react";
1
+ import React, { useRef, useEffect, useCallback } from "react";
2
2
  import useMap from "../../hooks/useMap";
3
3
  import PropTypes from "prop-types";
4
4
 
@@ -24,18 +24,20 @@ const MlVectorTileLayer = (props: MlVectorTileLayerProps) => {
24
24
  });
25
25
 
26
26
  const layerIdsRef = useRef({});
27
- const layerId = useRef(
28
- props.layerId || "MlVectorTileLayer-" + mapHook.componentId
29
- );
27
+ const layerId = useRef(props.layerId || "MlVectorTileLayer-" + mapHook.componentId);
30
28
  const layerPaintConfsRef = useRef({});
31
29
  const layerLayoutConfsRef = useRef({});
32
30
  const initializedRef = useRef(false);
33
31
 
34
- useEffect(() => {
35
- if (!mapHook.map || initializedRef.current) return;
32
+ const createLayer = useCallback(() => {
33
+ if (!mapHook.map) return;
36
34
 
37
35
  initializedRef.current = true;
38
36
 
37
+ if (mapHook.map.map.getLayer(layerId.current)) {
38
+ mapHook.cleanup();
39
+ }
40
+
39
41
  // Add the new layer to the openlayers instance once it is available
40
42
  mapHook.map.addSource(
41
43
  layerId.current,
@@ -72,12 +74,28 @@ const MlVectorTileLayer = (props: MlVectorTileLayerProps) => {
72
74
  mapHook.componentId
73
75
  );
74
76
  layerPaintConfsRef.current[key] = JSON.stringify(props.layers[key].paint);
75
- layerLayoutConfsRef.current[key] = JSON.stringify(
76
- props.layers[key].layout
77
+ layerLayoutConfsRef.current[key] = JSON.stringify(props.layers[key].layout);
78
+
79
+ // recreate layer if style has changed
80
+ mapHook.map.on(
81
+ "styledata",
82
+ () => {
83
+ if (initializedRef.current && !mapHook.map?.map.getSource(layerId.current)) {
84
+ console.log("Recreate Layer " + layerId.current);
85
+ createLayer();
86
+ }
87
+ },
88
+ mapHook.componentId
77
89
  );
78
90
  }
79
91
  }, [mapHook.map, props]);
80
92
 
93
+ useEffect(() => {
94
+ if (initializedRef.current) return;
95
+
96
+ createLayer();
97
+ }, [createLayer]);
98
+
81
99
  useEffect(() => {
82
100
  if (!mapHook.map || !initializedRef.current) return;
83
101
  // initialize the layer and add it to the MapLibre-gl instance or do something else with it
@@ -4,7 +4,7 @@ import MlWmsLayer from "./MlWmsLayer";
4
4
  import TopToolbar from "../../ui_components/TopToolbar";
5
5
  import Button from "@mui/material/Button";
6
6
 
7
- import multiMapContextDecorator from "../../decorators/MultiMapContextDecorator";
7
+ import mapContextDecorator from "../../decorators/MapContextDecorator";
8
8
 
9
9
  import "../../App.css";
10
10
 
@@ -15,7 +15,7 @@ const storyoptions = {
15
15
  url: {},
16
16
  layer: {},
17
17
  },
18
- decorators: multiMapContextDecorator,
18
+ decorators: mapContextDecorator,
19
19
  };
20
20
  export default storyoptions;
21
21
 
@@ -41,7 +41,6 @@ const Template = (props) => {
41
41
  export const ExampleConfig = Template.bind({});
42
42
  ExampleConfig.parameters = {};
43
43
  ExampleConfig.args = {
44
- mapId: "map_2",
45
44
  url: "https://www.wms.nrw.de/geobasis/wms_nw_uraufnahme",
46
45
  urlParameters: {
47
46
  layers: "nw_uraufnahme_rw",
@@ -1,4 +1,4 @@
1
- import React, { useRef, useEffect } from "react";
1
+ import React, { useRef, useEffect, useCallback } from "react";
2
2
  import useMap from "../../hooks/useMap";
3
3
 
4
4
  import PropTypes from "prop-types";
@@ -54,7 +54,7 @@ interface MlWmsLayerProps {
54
54
  *
55
55
  * @component
56
56
  */
57
- const MlWmsLayer = (props:MlWmsLayerProps) => {
57
+ const MlWmsLayer = (props: MlWmsLayerProps) => {
58
58
  const mapHook = useMap({
59
59
  mapId: props.mapId,
60
60
  waitForLayer: props.insertBeforeLayer,
@@ -63,11 +63,15 @@ const MlWmsLayer = (props:MlWmsLayerProps) => {
63
63
  const initializedRef = useRef(false);
64
64
  const layerId = useRef(props.layerId || "MlWmsLayer-" + mapHook.componentId);
65
65
 
66
- useEffect(() => {
67
- if (!mapHook.map || initializedRef.current) return;
66
+ const createLayer = useCallback(() => {
67
+ if (!mapHook.map) return;
68
68
 
69
69
  initializedRef.current = true;
70
70
 
71
+ if (mapHook.map.map.getLayer(layerId.current)) {
72
+ mapHook.cleanup();
73
+ }
74
+
71
75
  let _propsUrlParams;
72
76
  let _wmsUrl = props.url;
73
77
  if (props.url.indexOf("?") !== -1) {
@@ -83,8 +87,7 @@ const MlWmsLayer = (props:MlWmsLayerProps) => {
83
87
  };
84
88
  let urlParams = new URLSearchParams(urlParamsObj);
85
89
  let urlParamsStr =
86
- decodeURIComponent(urlParams.toString()) +
87
- "".replace(/%2F/g, "/").replace(/%3A/g, ":");
90
+ decodeURIComponent(urlParams.toString()) + "".replace(/%2F/g, "/").replace(/%3A/g, ":");
88
91
 
89
92
  mapHook.map.addSource(
90
93
  layerId.current,
@@ -109,10 +112,27 @@ const MlWmsLayer = (props:MlWmsLayerProps) => {
109
112
  mapHook.componentId
110
113
  );
111
114
 
115
+ // recreate layer if map style.json has changed
116
+ mapHook.map.on(
117
+ "styledata",
118
+ () => {
119
+ if (initializedRef.current && !mapHook.map?.map.getLayer(layerId.current)) {
120
+ console.log("Recreate Layer " + layerId.current);
121
+ createLayer();
122
+ }
123
+ },
124
+ mapHook.componentId
125
+ );
112
126
  if (!props.visible) {
113
127
  mapHook.map.map.setLayoutProperty(layerId.current, "visibility", "none");
114
128
  }
115
- }, [mapHook, props]);
129
+ }, [mapHook.map, props]);
130
+
131
+ useEffect(() => {
132
+ if (initializedRef.current) return;
133
+
134
+ createLayer();
135
+ }, [createLayer]);
116
136
 
117
137
  useEffect(() => {
118
138
  if (!mapHook.map || !initializedRef.current) return;