@mapcomponents/react-maplibre 0.1.14 → 0.1.18

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 (100) hide show
  1. package/.github/workflows/storybook.yml +4 -2
  2. package/CHANGELOG.md +42 -0
  3. package/README.md +22 -6
  4. package/coverage/clover.xml +448 -460
  5. package/coverage/coverage-final.json +14 -14
  6. package/coverage/lcov-report/index.html +77 -78
  7. package/coverage/lcov-report/src/components/MapLibreMap/MapLibreMap.js.html +2 -3
  8. package/coverage/lcov-report/src/components/MapLibreMap/index.html +2 -3
  9. package/coverage/lcov-report/src/components/MlCreatePdfButton/MlCreatePdfButton.js.html +2 -3
  10. package/coverage/lcov-report/src/components/MlCreatePdfButton/index.html +2 -3
  11. package/coverage/lcov-report/src/components/MlFeatureEditor/MlFeatureEditor.js.html +2 -3
  12. package/coverage/lcov-report/src/components/MlFeatureEditor/index.html +2 -3
  13. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/MlFillExtrusionLayer.js.html +2 -3
  14. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/index.html +2 -3
  15. package/coverage/lcov-report/src/components/MlFollowGps/MlFollowGps.js.html +112 -107
  16. package/coverage/lcov-report/src/components/MlFollowGps/index.html +16 -17
  17. package/coverage/lcov-report/src/components/MlGPXViewer/MlGPXViewer.js.html +2 -3
  18. package/coverage/lcov-report/src/components/MlGPXViewer/gpxConverter.js.html +2 -3
  19. package/coverage/lcov-report/src/components/MlGPXViewer/index.html +2 -3
  20. package/coverage/lcov-report/src/components/MlGeoJsonLayer/MlGeoJsonLayer.js.html +168 -133
  21. package/coverage/lcov-report/src/components/MlGeoJsonLayer/index.html +20 -21
  22. package/coverage/lcov-report/src/components/MlImageMarkerLayer/MlImageMarkerLayer.js.html +46 -152
  23. package/coverage/lcov-report/src/components/MlImageMarkerLayer/index.html +20 -21
  24. package/coverage/lcov-report/src/components/MlLayer/MlLayer.js.html +92 -30
  25. package/coverage/lcov-report/src/components/MlLayer/index.html +20 -21
  26. package/coverage/lcov-report/src/components/MlLayerMagnify/MlLayerMagnify.js.html +2 -3
  27. package/coverage/lcov-report/src/components/MlLayerMagnify/index.html +2 -3
  28. package/coverage/lcov-report/src/components/MlLayerSwipe/MlLayerSwipe.js.html +2 -3
  29. package/coverage/lcov-report/src/components/MlLayerSwipe/index.html +2 -3
  30. package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +3 -10
  31. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +9 -82
  32. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +10 -11
  33. package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +2 -3
  34. package/coverage/lcov-report/src/components/MlMarker/MlMarker.js.html +6 -7
  35. package/coverage/lcov-report/src/components/MlMarker/index.html +6 -7
  36. package/coverage/lcov-report/src/components/MlNavigationCompass/MlNavigationCompass.js.html +2 -3
  37. package/coverage/lcov-report/src/components/MlNavigationCompass/index.html +2 -3
  38. package/coverage/lcov-report/src/components/MlNavigationTools/MlNavigationTools.js.html +11 -15
  39. package/coverage/lcov-report/src/components/MlNavigationTools/index.html +8 -9
  40. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.js.html +2 -3
  41. package/coverage/lcov-report/src/components/MlOsmLayer/index.html +2 -3
  42. package/coverage/lcov-report/src/components/MlScaleReference/MlScaleReference.js.html +2 -3
  43. package/coverage/lcov-report/src/components/MlScaleReference/index.html +2 -3
  44. package/coverage/lcov-report/src/components/MlShareMapState/MlShareMapState.js.html +209 -18
  45. package/coverage/lcov-report/src/components/MlShareMapState/index.html +10 -11
  46. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.js.html +2 -3
  47. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/index.html +2 -3
  48. package/coverage/lcov-report/src/components/MlThreeJsLayer/MlThreeJsLayer.js.html +2 -3
  49. package/coverage/lcov-report/src/components/MlThreeJsLayer/index.html +2 -3
  50. package/coverage/lcov-report/src/components/MlUseMapDebugger/MlUseMapDebugger.js.html +6 -25
  51. package/coverage/lcov-report/src/components/MlUseMapDebugger/index.html +6 -7
  52. package/coverage/lcov-report/src/components/MlVectorTileLayer/MlVectorTileLayer.js.html +2 -3
  53. package/coverage/lcov-report/src/components/MlVectorTileLayer/index.html +2 -3
  54. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +2 -3
  55. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/index.html +2 -3
  56. package/coverage/lcov-report/src/components/MlWmsLayer/MlWmsLayer.js.html +2 -3
  57. package/coverage/lcov-report/src/components/MlWmsLayer/index.html +2 -3
  58. package/coverage/lcov-report/src/components/MlWmsLoader/MlWmsLoader.js.html +6 -19
  59. package/coverage/lcov-report/src/components/MlWmsLoader/index.html +8 -9
  60. package/coverage/lcov-report/src/hooks/index.html +35 -36
  61. package/coverage/lcov-report/src/hooks/useMap.js.html +81 -169
  62. package/coverage/lcov-report/src/hooks/useMapState.js.html +82 -125
  63. package/coverage/lcov-report/src/hooks/useWms.js.html +9 -22
  64. package/coverage/lcov-report/src/i18n.js.html +2 -3
  65. package/coverage/lcov-report/src/index.html +2 -3
  66. package/coverage/lcov-report/src/translations/english.js.html +2 -3
  67. package/coverage/lcov-report/src/translations/german.js.html +2 -3
  68. package/coverage/lcov-report/src/translations/index.html +2 -3
  69. package/coverage/lcov.info +898 -900
  70. package/dist/index.esm.js +866 -758
  71. package/dist/index.esm.js.map +1 -1
  72. package/package.json +2 -2
  73. package/src/components/MapLibreMap/lib/MapLibreGlWrapper.js +16 -14
  74. package/src/components/MlComponentTemplate/MlComponentTemplate.js +7 -32
  75. package/src/components/MlFollowGps/MlFollowGps.js +67 -65
  76. package/src/components/MlFollowGps/MlFollowGps.test.js +3 -5
  77. package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.js +101 -89
  78. package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.stories.js +35 -6
  79. package/src/components/MlGeoJsonLayer/assets/sample_polygon_1.json +33 -0
  80. package/src/components/MlGeoJsonLayer/util/getDefaultLayerTypeByGeometry.js +25 -0
  81. package/src/components/MlGeoJsonLayer/util/getDefaultPaintPropsByType.js +31 -0
  82. package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.js +21 -56
  83. package/src/components/MlLayer/MlLayer.js +26 -5
  84. package/src/components/MlLayerSwitcher/MlLayerSwitcher.js +0 -2
  85. package/src/components/MlLayerSwitcher/MlLayerSwitcher.stories.js +3 -6
  86. package/src/components/MlLayerSwitcher/components/LayerBox.js +2 -26
  87. package/src/components/MlMarker/MlMarker.js +1 -1
  88. package/src/components/MlNavigationTools/MlNavigationTools.js +4 -5
  89. package/src/components/MlShareMapState/MlShareMapState.js +73 -9
  90. package/src/components/MlShareMapState/MlShareMapState.stories.js +22 -2
  91. package/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.stories.js +1 -3
  92. package/src/components/MlUseMapDebugger/MlUseMapDebugger.js +1 -7
  93. package/src/components/MlWmsLoader/MlWmsLoader.js +0 -4
  94. package/src/hooks/useMap.js +33 -62
  95. package/src/hooks/useMapState.js +3 -17
  96. package/src/hooks/useWms.js +2 -7
  97. package/src/index.js +2 -0
  98. package/src/ui_components/ImageLoader.js +8 -3
  99. package/src/ui_components/Sidebar.js +1 -1
  100. package/src/ui_components/TopToolbar.js +0 -2
@@ -2,6 +2,7 @@ import React, { useState} from "react";
2
2
 
3
3
  import MlShareMapState from "./MlShareMapState";
4
4
  import mapContextDecorator from "../../decorators/MapContextDecorator";
5
+ import MlLayer from "../MlLayer/MlLayer";
5
6
 
6
7
  const storyoptions = {
7
8
  title: "MapComponents/MlShareMapState",
@@ -12,7 +13,8 @@ const storyoptions = {
12
13
  export default storyoptions;
13
14
 
14
15
  const Template = (args) => {
15
- const [watchState, setWatchState] = useState(true);
16
+ const [watchState, setWatchState] = useState(false);
17
+ const [testLayerVisible, setTestLayerVisible] = useState(true);
16
18
 
17
19
  return (
18
20
  <>
@@ -20,9 +22,27 @@ const Template = (args) => {
20
22
  style={{ zIndex: "1000", position: "absolute" }}
21
23
  onClick={() => setWatchState(!watchState)}
22
24
  >
23
- watch map state {watchState?1:0}
25
+ watch map state {watchState ? 1 : 0}
26
+ </button>
27
+ <button
28
+ style={{ zIndex: "1000", position: "absolute" }}
29
+ onClick={() => setTestLayerVisible(!testLayerVisible)}
30
+ >
31
+ visibility {testLayerVisible ? 1 : 0}
24
32
  </button>
25
33
  <MlShareMapState active={watchState} />
34
+ <MlLayer
35
+ layerId={"MlLayer-testLayer"}
36
+ options={{ layout: { visibility: testLayerVisible ? "visible" : "none" } }}
37
+ />
38
+ <MlLayer
39
+ layerId={"MlLayer-testLayer2"}
40
+ options={{ layout: { visibility: testLayerVisible ? "visible" : "none" } }}
41
+ />
42
+ <MlLayer
43
+ layerId={"MlLayer-testLayer3"}
44
+ options={{ layout: { visibility: testLayerVisible ? "visible" : "none" } }}
45
+ />
26
46
  </>
27
47
  );
28
48
  };
@@ -5,9 +5,7 @@ import MlGPXViewer from "../MlGPXViewer/MlGPXViewer";
5
5
 
6
6
  import mapContextDecorator from "../../decorators/MapContextDecorator";
7
7
  import GeoJsonProvider from "../MlGPXViewer/util/GeoJsonProvider";
8
- import Button from "@mui/material/Button";
9
- import FileDownloadIcon from '@mui/icons-material/FileDownload';
10
- import InfoIcon from "@mui/icons-material/Info";
8
+ import FileDownloadIcon from "@mui/icons-material/FileDownload";
11
9
  import IconButton from "@mui/material/IconButton";
12
10
  import useMediaQuery from "@mui/material/useMediaQuery";
13
11
 
@@ -1,11 +1,7 @@
1
- import React, { useRef, useState } from "react";
1
+ import React, { useRef } from "react";
2
2
  import PropTypes from "prop-types";
3
3
 
4
- import { Drawer, IconButton } from "@mui/material";
5
- import CodeIcon from "@mui/icons-material/Code";
6
-
7
4
  import useMapState from "../../hooks/useMapState";
8
- import { render } from "@testing-library/react";
9
5
 
10
6
  /**
11
7
  * Renders a collapsable top-drawer containing live map debug information
@@ -30,8 +26,6 @@ const MlUseMapDebugger = (props) => {
30
26
  });
31
27
  const renderCounter = useRef(0);
32
28
  renderCounter.current = renderCounter.current + 1;
33
- const [debuggerOpen, setDebuggerOpen] = useState(true);
34
- //const [maxHeight /*setMaxHeight*/] = useState("50%");
35
29
 
36
30
  return (
37
31
  <>
@@ -155,10 +155,6 @@ const MlWmsLoader = (props) => {
155
155
  };
156
156
  }, [getFeatureInfoUrl]);
157
157
 
158
- const clearState = () => {
159
- setLayers([]);
160
- };
161
-
162
158
  useEffect(() => {
163
159
  if (!capabilities?.Service) return;
164
160
 
@@ -1,23 +1,28 @@
1
1
  import { useContext, useState, useEffect, useRef } from "react";
2
2
  import { v4 as uuidv4 } from "uuid";
3
3
  import { MapContext } from "@mapcomponents/react-core";
4
+ import useMapState from "./useMapState";
4
5
 
5
6
  function useMap(props) {
6
7
  // Use a useRef hook to reference the layer object to be able to access it later inside useEffect hooks
7
8
  const mapContext = useContext(MapContext);
8
9
 
10
+ const mapState = useMapState({
11
+ mapId: props.mapId,
12
+ watch: {
13
+ viewport: false,
14
+ layers: true,
15
+ sources: false,
16
+ },
17
+ });
18
+
9
19
  const initializedRef = useRef(false);
10
20
  const mapRef = useRef(undefined);
11
21
 
12
- const [center, setCenter] = useState(undefined);
13
- const [layerIds, setLayerIds] = useState(undefined);
14
- const layerIdsRef = useRef(undefined);
15
-
16
- const [layers, setLayers] = useState(undefined);
17
- const layersRef = useRef(undefined);
18
- //const mapRef = useRef(props.map);
19
22
  const componentId = useRef(uuidv4());
20
23
 
24
+ const [mapIsReady, setMapIsReady] = useState(undefined);
25
+
21
26
  useEffect(() => {
22
27
  let _componentId = componentId.current;
23
28
 
@@ -27,72 +32,38 @@ function useMap(props) {
27
32
  mapRef.current = undefined;
28
33
  }
29
34
  initializedRef.current = false;
35
+ setMapIsReady(false);
30
36
  };
31
37
  }, []);
32
38
 
33
- const buildLayerObjects = (layers) => {
34
- let res = {};
35
- Object.keys(layers).forEach((layerId) => {
36
- if (mapRef.current.baseLayers.indexOf(layerId) === -1) {
37
- res[layerId] = {
38
- //filter: layers[layerId].filter,
39
- id: layers[layerId].id,
40
- //layout: layers[layerId].layout,
41
- //maxzoom: layers[layerId].maxzoom,
42
- //metadata: layers[layerId].metadata,
43
- //minzoom: layers[layerId].minzoom,
44
- paint: layers[layerId].paint,
45
- //source: layers[layerId].source,
46
- //sourceLayer: layers[layerId].sourceLayer,
47
- type: layers[layerId].type,
48
- visibility: layers[layerId].visibility,
49
- };
50
- }
51
- });
52
- return res;
53
- };
54
-
55
39
  useEffect(() => {
56
40
  if (!mapContext.mapExists(props.mapId) || initializedRef.current) return;
41
+
42
+ //check if insertBeforeLayer exists
43
+ if (props.waitForLayer) {
44
+ let layerFound = false;
45
+
46
+ mapState?.layers?.forEach((layer) => {
47
+ if (layer.id === props.waitForLayer) {
48
+ layerFound = true;
49
+ }
50
+ });
51
+ if (!layerFound) {
52
+ return;
53
+ }
54
+ }
57
55
  // the MapLibre-gl instance (mapContext.getMap(props.mapId)) is accessible here
58
56
  // initialize the layer and add it to the MapLibre-gl instance or do something else with it
59
57
  initializedRef.current = true;
60
58
  mapRef.current = mapContext.getMap(props.mapId);
61
-
62
- setLayerIds([...mapRef.current.style._order]);
63
- mapRef.current.on(
64
- "idle",
65
- () => {
66
- if (JSON.stringify(mapRef.current.style._order) !== layerIdsRef.current) {
67
- let layerIds = [...mapRef.current.style._order];
68
- layerIdsRef.current = JSON.stringify(layerIds);
69
- setLayerIds(layerIds);
70
- }
71
-
72
- let layerStates = buildLayerObjects(mapRef.current.style._layers);
73
- let layerStatesString = JSON.stringify(layerStates);
74
- if (layerStatesString !== layersRef.current) {
75
- layersRef.current = layerStatesString;
76
- setLayers(layerStates);
77
- }
78
- },
79
- componentId.current
80
- );
81
-
82
- setCenter(mapRef.current.getCenter());
83
- mapRef.current.on(
84
- "move",
85
- () => {
86
- setCenter(mapRef.current.getCenter());
87
- },
88
- componentId.current
89
- );
90
- }, [mapContext.mapIds, mapContext, props.mapId]);
59
+ setMapIsReady(true);
60
+ }, [mapContext.mapIds, mapState.layers, mapContext, props.mapId]);
91
61
 
92
62
  return {
93
- layers,
94
- layerIds,
95
- center,
63
+ map: mapRef.current,
64
+ mapIsReady,
65
+ componentId: componentId.current,
66
+ layers: mapState.layers,
96
67
  };
97
68
  }
98
69
 
@@ -15,8 +15,6 @@ function useMapState(props) {
15
15
  const initializedRef = useRef(false);
16
16
  const mapRef = useRef(undefined);
17
17
 
18
- const [center, setCenter] = useState(undefined);
19
-
20
18
  const [viewport, setViewport] = useState(undefined);
21
19
  const viewportRef = useRef(undefined);
22
20
 
@@ -25,7 +23,6 @@ function useMapState(props) {
25
23
  //const mapRef = useRef(props.map);
26
24
  const componentId = useRef(uuidv4());
27
25
 
28
-
29
26
  /**
30
27
  * returns the element if it matches the defined filter criteria
31
28
  * to be used as filter function on the layers array
@@ -34,11 +31,11 @@ function useMapState(props) {
34
31
  */
35
32
  const layerIdFilter = useCallback(
36
33
  (layer) => {
37
- if (!props.filter.includeBaseLayers && layer.baseLayer) {
34
+ if (!props?.filter?.includeBaseLayers && layer.baseLayer) {
38
35
  return false;
39
36
  }
40
37
 
41
- if (typeof props.filter.matchLayerIds !== "undefined") {
38
+ if (typeof props.filter?.matchLayerIds !== "undefined") {
42
39
  if (props.filter.matchLayerIds instanceof RegExp) {
43
40
  return props.filter.matchLayerIds.test(layer.id);
44
41
  } else {
@@ -58,7 +55,7 @@ function useMapState(props) {
58
55
  layersRef.current = _layerStateString;
59
56
  setLayers(_layerState);
60
57
  }
61
- },[layerIdFilter]);
58
+ }, [layerIdFilter]);
62
59
 
63
60
  useEffect(() => {
64
61
  let _componentId = componentId.current;
@@ -79,16 +76,6 @@ function useMapState(props) {
79
76
  initializedRef.current = true;
80
77
  mapRef.current = mapContext.getMap(props.mapId);
81
78
 
82
- /*
83
- mapRef.current.on(
84
- "move",
85
- () => {
86
- setCenter(mapRef.current.getCenter());
87
- },
88
- componentId.current
89
- );
90
- */
91
-
92
79
  if (props?.watch?.viewport) {
93
80
  setViewport(mapRef.current.wrapper.viewportState);
94
81
 
@@ -97,7 +84,6 @@ function useMapState(props) {
97
84
  () => {
98
85
  if (viewportRef.current !== mapRef.current?.wrapper.viewportStateString) {
99
86
  setViewport(mapRef.current?.wrapper.viewportState);
100
- setCenter(mapRef.current?.wrapper.viewportState?.center);
101
87
  }
102
88
  },
103
89
  componentId.current
@@ -1,13 +1,8 @@
1
- import { useContext, useState, useEffect, useRef } from "react";
2
- import { v4 as uuidv4 } from "uuid";
1
+ import { useState, useEffect } from "react";
3
2
  import WMSCapabilities from "wms-capabilities";
4
- import { MapContext } from "@mapcomponents/react-core";
5
3
 
6
4
  function useWms(props) {
7
5
  // Use a useRef hook to reference the layer object to be able to access it later inside useEffect hooks
8
- const mapContext = useContext(MapContext);
9
- const initializedRef = useRef(false);
10
-
11
6
  const [getFeatureInfoUrl, setGetFeatureInfoUrl] = useState(undefined);
12
7
  const [url, setUrl] = useState(props.url);
13
8
  const [wmsUrl, setWmsUrl] = useState("");
@@ -93,4 +88,4 @@ useWms.defaultProps = {
93
88
  },
94
89
  };
95
90
 
96
- export default useWms;
91
+ export default useWms;
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { default as MapLibreMap } from "./components/MapLibreMap/MapLibreMap";
2
2
  export { default as MlComponentTemplate } from "./components/MlComponentTemplate/MlComponentTemplate";
3
3
  export { default as MlFillExtrusionLayer } from "./components/MlFillExtrusionLayer/MlFillExtrusionLayer";
4
+ export { default as MlFollowGps } from "./components/MlFollowGps/MlFollowGps";
4
5
  export { default as MlCreatePdfButton } from "./components/MlCreatePdfButton/MlCreatePdfButton";
5
6
  export { default as MlGeoJsonLayer } from "./components/MlGeoJsonLayer/MlGeoJsonLayer";
6
7
  export { default as MlImageMarkerLayer } from "./components/MlImageMarkerLayer/MlImageMarkerLayer";
@@ -20,3 +21,4 @@ export { default as GeoJsonContext } from "./components/MlGPXViewer/util/GeoJson
20
21
  export { default as MlSpatialElevationProfile } from "./components/MlSpatialElevationProfile/MlSpatialElevationProfile";
21
22
 
22
23
  export { default as useMapState } from "./hooks/useMapState";
24
+ export { default as useMap } from "./hooks/useMap";
@@ -45,7 +45,12 @@ const ImageLoader = (props) => {
45
45
 
46
46
  const ReadyImage = () => {
47
47
  return (
48
- <img className={props.className} style={{ ...boxStyle, ...props.style }} src={props.src} />
48
+ <img
49
+ className={props.className}
50
+ style={{ ...boxStyle, ...props.style }}
51
+ src={props.src}
52
+ alt={props.alt || ""}
53
+ />
49
54
  );
50
55
  };
51
56
  const ErrorImage = () => {
@@ -62,9 +67,9 @@ const ImageLoader = (props) => {
62
67
  return <ReadyImage />;
63
68
  case "error":
64
69
  return <ErrorImage />;
70
+ default:
71
+ return <LoadingImage />;
65
72
  }
66
-
67
- return <LoadingImage />;
68
73
  };
69
74
 
70
75
  return <>{renderImage(state)}</>;
@@ -1,5 +1,5 @@
1
1
  import React, {useState} from "react";
2
- import { useTheme, styled } from "@mui/material/styles";
2
+ import { styled } from "@mui/material/styles";
3
3
  import makeStyles from "@mui/styles/makeStyles";
4
4
  import Drawer from "@mui/material/Drawer";
5
5
  import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
@@ -1,9 +1,7 @@
1
1
  import React from "react";
2
- import makeStyles from "@mui/styles/makeStyles";
3
2
  import AppBar from "@mui/material/AppBar";
4
3
  import Toolbar from "@mui/material/Toolbar";
5
4
 
6
-
7
5
  export default function TopToolbar(props) {
8
6
  return (
9
7
  <div