@mapcomponents/react-maplibre 0.1.12 → 0.1.16

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 (133) hide show
  1. package/.github/workflows/storybook.yml +4 -2
  2. package/CHANGELOG.md +33 -0
  3. package/README.md +22 -6
  4. package/coverage/clover.xml +893 -760
  5. package/coverage/coverage-final.json +22 -17
  6. package/coverage/lcov-report/index.html +183 -123
  7. package/coverage/lcov-report/{components → src/components}/MapLibreMap/MapLibreMap.js.html +10 -10
  8. package/coverage/lcov-report/{components → src/components}/MapLibreMap/index.html +10 -10
  9. package/coverage/lcov-report/{components → src/components}/MlCreatePdfButton/MlCreatePdfButton.js.html +10 -10
  10. package/coverage/lcov-report/{components → src/components}/MlCreatePdfButton/index.html +10 -10
  11. package/coverage/lcov-report/{components → src/components}/MlFeatureEditor/MlFeatureEditor.js.html +10 -10
  12. package/coverage/lcov-report/{components → src/components}/MlFeatureEditor/index.html +10 -10
  13. package/coverage/lcov-report/{components → src/components}/MlFillExtrusionLayer/MlFillExtrusionLayer.js.html +10 -10
  14. package/coverage/lcov-report/{components → src/components}/MlFillExtrusionLayer/index.html +10 -10
  15. package/coverage/lcov-report/{components → src/components}/MlFollowGps/MlFollowGps.js.html +148 -136
  16. package/coverage/lcov-report/{components → src/components}/MlFollowGps/index.html +24 -24
  17. package/coverage/lcov-report/{components → src/components}/MlGPXViewer/MlGPXViewer.js.html +66 -60
  18. package/coverage/lcov-report/{components → src/components}/MlGPXViewer/gpxConverter.js.html +49 -70
  19. package/coverage/lcov-report/{components → src/components}/MlGPXViewer/index.html +25 -25
  20. package/coverage/lcov-report/{components → src/components}/MlGeoJsonLayer/MlGeoJsonLayer.js.html +155 -47
  21. package/coverage/lcov-report/{components → src/components}/MlGeoJsonLayer/index.html +28 -28
  22. package/coverage/lcov-report/{components/MlLayer/MlLayer.js.html → src/components/MlImageMarkerLayer/MlImageMarkerLayer.js.html} +88 -121
  23. package/coverage/lcov-report/{components → src/components}/MlImageMarkerLayer/index.html +28 -28
  24. package/coverage/lcov-report/{components/MlImageMarkerLayer/MlImageMarkerLayer.js.html → src/components/MlLayer/MlLayer.js.html} +116 -125
  25. package/coverage/lcov-report/src/components/MlLayer/index.html +117 -0
  26. package/coverage/lcov-report/{components → src/components}/MlLayerMagnify/MlLayerMagnify.js.html +41 -41
  27. package/coverage/lcov-report/{components → src/components}/MlLayerMagnify/index.html +24 -24
  28. package/coverage/lcov-report/{components → src/components}/MlLayerSwipe/MlLayerSwipe.js.html +38 -41
  29. package/coverage/lcov-report/{components → src/components}/MlLayerSwipe/index.html +24 -24
  30. package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +755 -0
  31. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +380 -0
  32. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +117 -0
  33. package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +117 -0
  34. package/coverage/lcov-report/{components → src/components}/MlMarker/MlMarker.js.html +11 -11
  35. package/coverage/lcov-report/{components → src/components}/MlMarker/index.html +10 -10
  36. package/coverage/lcov-report/{components → src/components}/MlNavigationCompass/MlNavigationCompass.js.html +10 -10
  37. package/coverage/lcov-report/{components → src/components}/MlNavigationCompass/index.html +10 -10
  38. package/coverage/lcov-report/{components → src/components}/MlNavigationTools/MlNavigationTools.js.html +50 -41
  39. package/coverage/lcov-report/{components → src/components}/MlNavigationTools/index.html +18 -18
  40. package/coverage/lcov-report/{components → src/components}/MlOsmLayer/MlOsmLayer.js.html +10 -10
  41. package/coverage/lcov-report/{components → src/components}/MlOsmLayer/index.html +10 -10
  42. package/coverage/lcov-report/{components → src/components}/MlScaleReference/MlScaleReference.js.html +10 -10
  43. package/coverage/lcov-report/{components → src/components}/MlScaleReference/index.html +10 -10
  44. package/coverage/lcov-report/{components → src/components}/MlShareMapState/MlShareMapState.js.html +217 -25
  45. package/coverage/lcov-report/{components → src/components}/MlShareMapState/index.html +18 -18
  46. package/coverage/lcov-report/{components → src/components}/MlSpatialElevationProfile/MlSpatialElevationProfile.js.html +10 -10
  47. package/coverage/lcov-report/{components → src/components}/MlSpatialElevationProfile/index.html +10 -10
  48. package/coverage/lcov-report/{components → src/components}/MlThreeJsLayer/MlThreeJsLayer.js.html +30 -54
  49. package/coverage/lcov-report/{components → src/components}/MlThreeJsLayer/index.html +24 -24
  50. package/coverage/lcov-report/{components → src/components}/MlUseMapDebugger/MlUseMapDebugger.js.html +10 -10
  51. package/coverage/lcov-report/{components → src/components}/MlUseMapDebugger/index.html +10 -10
  52. package/coverage/lcov-report/{components → src/components}/MlVectorTileLayer/MlVectorTileLayer.js.html +10 -10
  53. package/coverage/lcov-report/{components → src/components}/MlVectorTileLayer/index.html +10 -10
  54. package/coverage/lcov-report/{components → src/components}/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +10 -10
  55. package/coverage/lcov-report/{components → src/components}/MlWmsFeatureInfoPopup/index.html +10 -10
  56. package/coverage/lcov-report/{components → src/components}/MlWmsLayer/MlWmsLayer.js.html +13 -13
  57. package/coverage/lcov-report/{components → src/components}/MlWmsLayer/index.html +14 -14
  58. package/coverage/lcov-report/{components → src/components}/MlWmsLoader/MlWmsLoader.js.html +31 -19
  59. package/coverage/lcov-report/{components → src/components}/MlWmsLoader/index.html +16 -16
  60. package/coverage/lcov-report/src/hooks/index.html +147 -0
  61. package/coverage/lcov-report/src/hooks/useMap.js.html +296 -0
  62. package/coverage/lcov-report/{hooks → src/hooks}/useMapState.js.html +91 -91
  63. package/coverage/lcov-report/{hooks → src/hooks}/useWms.js.html +18 -18
  64. package/coverage/lcov-report/src/i18n.js.html +167 -0
  65. package/coverage/lcov-report/src/index.html +117 -0
  66. package/coverage/lcov-report/src/translations/english.js.html +95 -0
  67. package/coverage/lcov-report/src/translations/german.js.html +95 -0
  68. package/coverage/lcov-report/src/translations/index.html +132 -0
  69. package/coverage/lcov.info +1610 -1314
  70. package/dist/b556faa3bc6829d2.png +0 -0
  71. package/dist/index.esm.js +934 -668
  72. package/dist/index.esm.js.map +1 -1
  73. package/package.json +3 -1
  74. package/public/assets/dop.png +0 -0
  75. package/public/assets/historic.png +0 -0
  76. package/public/assets/osm.png +0 -0
  77. package/public/thumbnails/MlFollowGps.png +0 -0
  78. package/public/thumbnails/MlThreeJsLayer.png +0 -0
  79. package/src/components/MapLibreMap/lib/MapLibreGlWrapper.js +53 -67
  80. package/src/components/MlComponentTemplate/MlComponentTemplate.js +6 -31
  81. package/src/components/MlFeatureEditor/MlFeatureEditor.meta.json +2 -2
  82. package/src/components/MlFollowGps/MlFollowGps.js +92 -88
  83. package/src/components/MlFollowGps/MlFollowGps.meta.json +2 -2
  84. package/src/components/MlFollowGps/MlFollowGps.test.js +3 -5
  85. package/src/components/MlFollowGps/assets/marker.png +0 -0
  86. package/src/components/MlGPXViewer/MlGPXViewer.js +45 -43
  87. package/src/components/MlGPXViewer/gpxConverter.js +22 -29
  88. package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.js +45 -9
  89. package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.js +21 -57
  90. package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.test.js +6 -7
  91. package/src/components/MlLayer/MlLayer.js +28 -6
  92. package/src/components/MlLayer/MlLayer.test.js +12 -10
  93. package/src/components/MlLayerMagnify/MlLayerMagnify.js +3 -3
  94. package/src/components/MlLayerSwipe/MlLayerSwipe.js +4 -5
  95. package/src/components/MlLayerSwitcher/MlLayerSwitcher.css +17 -0
  96. package/src/components/MlLayerSwitcher/MlLayerSwitcher.doc.de.md +3 -0
  97. package/src/components/MlLayerSwitcher/MlLayerSwitcher.js +223 -0
  98. package/src/components/MlLayerSwitcher/MlLayerSwitcher.meta_.json +15 -0
  99. package/src/components/MlLayerSwitcher/MlLayerSwitcher.stories.js +106 -0
  100. package/src/components/MlLayerSwitcher/assets/sample_1.json +26 -0
  101. package/src/components/MlLayerSwitcher/assets/sample_2.json +22 -0
  102. package/src/components/MlLayerSwitcher/components/LayerBox.js +98 -0
  103. package/src/components/MlMarker/MlMarker.js +1 -1
  104. package/src/components/MlNavigationTools/MlNavigationTools.js +29 -26
  105. package/src/components/MlScaleReference/MlScaleReference.meta.json +1 -1
  106. package/src/components/MlScaleReference/MlScaleReference.stories.js +25 -21
  107. package/src/components/MlShareMapState/MlShareMapState.js +73 -9
  108. package/src/components/MlShareMapState/MlShareMapState.stories.js +24 -1
  109. package/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.stories.js +12 -6
  110. package/src/components/MlThreeJsLayer/MlThreeJsLayer.js +8 -15
  111. package/src/components/MlWmsLayer/MlWmsLayer.js +1 -1
  112. package/src/components/MlWmsLoader/MlWmsLoader.js +8 -4
  113. package/src/components/MlWmsLoader/MlWmsLoader.meta.json +1 -1
  114. package/src/components/MlWmsLoader/MlWmsLoader.stories.js +5 -4
  115. package/src/decorators/EmptyMapContextDecorator.js +11 -6
  116. package/src/decorators/MapContext3DDecorator.js +25 -20
  117. package/src/decorators/MapContextDashboardDecorator.js +7 -2
  118. package/src/decorators/MapContextDecorator.js +7 -3
  119. package/src/decorators/MapContextKlokantechBasicDecorator.js +8 -4
  120. package/src/decorators/MultiMapContextDecorator.js +2 -1
  121. package/src/hooks/useMap.js +33 -62
  122. package/src/hooks/useMapState.js +3 -3
  123. package/src/hooks/useWms.js +7 -6
  124. package/src/i18n.js +28 -0
  125. package/src/index.js +3 -0
  126. package/src/translations/english.js +4 -0
  127. package/src/translations/german.js +4 -0
  128. package/src/ui_components/ImageLoader.js +73 -0
  129. package/src/ui_components/Sidebar.js +75 -20
  130. package/src/ui_components/TopToolbar.js +18 -18
  131. package/coverage/lcov-report/components/MlLayer/index.html +0 -117
  132. package/coverage/lcov-report/hooks/index.html +0 -147
  133. package/coverage/lcov-report/hooks/useMap.js.html +0 -383
@@ -3,30 +3,35 @@ import React from "react";
3
3
  import { MapComponentsProvider } from "@mapcomponents/react-core";
4
4
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
5
  import "./style.css";
6
+ import { createTheme, ThemeProvider } from "@mui/material/styles";
7
+
8
+ const theme = createTheme({});
6
9
 
7
10
  const decorators = [
8
11
  (Story) => (
9
12
  <div className="fullscreen_map">
10
- <MapComponentsProvider>
11
- <Story />
12
- <MapLibreMap
13
- options={{
14
- //style: "mapbox://styles/mapbox/light-v10",
15
- //center: [-87.62712, 41.89033],
16
- zoom: 14.5,
17
- //pitch: 45,
18
- //style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
19
- style: "https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
20
- //center: [8.607, 53.1409349],
21
- // zoom: 13,
22
- center: [7.0851268, 50.73884],
23
- // maxBounds: [
24
- // [1.40625, 43.452919],
25
- // [17.797852, 55.973798],
26
- // ],
27
- }}
28
- />
29
- </MapComponentsProvider>
13
+ <ThemeProvider theme={theme}>
14
+ <MapComponentsProvider>
15
+ <Story />
16
+ <MapLibreMap
17
+ options={{
18
+ //style: "mapbox://styles/mapbox/light-v10",
19
+ //center: [-87.62712, 41.89033],
20
+ zoom: 14.5,
21
+ //pitch: 45,
22
+ //style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
23
+ style: "https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
24
+ //center: [8.607, 53.1409349],
25
+ // zoom: 13,
26
+ center: [7.0851268, 50.73884],
27
+ // maxBounds: [
28
+ // [1.40625, 43.452919],
29
+ // [17.797852, 55.973798],
30
+ // ],
31
+ }}
32
+ />
33
+ </MapComponentsProvider>
34
+ </ThemeProvider>
30
35
  </div>
31
36
  ),
32
37
  ];
@@ -2,12 +2,17 @@ import React from "react";
2
2
 
3
3
  import { MapComponentsProvider } from "@mapcomponents/react-core";
4
4
  import "./style.css";
5
+ import { createTheme, ThemeProvider } from "@mui/material/styles";
6
+
7
+ const theme = createTheme({});
5
8
 
6
9
  const decorators = [
7
10
  (Story) => (
8
- <MapComponentsProvider>
11
+ <ThemeProvider theme={theme}>
12
+ <MapComponentsProvider>
9
13
  <Story />
10
- </MapComponentsProvider>
14
+ </MapComponentsProvider>
15
+ </ThemeProvider>
11
16
  ),
12
17
  ];
13
18
 
@@ -3,12 +3,15 @@ import React from "react";
3
3
  import { MapComponentsProvider } from "@mapcomponents/react-core";
4
4
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
5
  import "./style.css";
6
+ import { createTheme, ThemeProvider } from "@mui/material/styles";
7
+
8
+ const theme = createTheme({});
6
9
 
7
10
  const decorators = [
8
11
  (Story) => (
9
12
  <div className="fullscreen_map">
10
- <MapComponentsProvider>
11
-
13
+ <ThemeProvider theme={theme}>
14
+ <MapComponentsProvider>
12
15
  <Story />
13
16
  <MapLibreMap
14
17
  options={{
@@ -18,7 +21,8 @@ const decorators = [
18
21
  }}
19
22
  mapId="map_1"
20
23
  />
21
- </MapComponentsProvider>
24
+ </MapComponentsProvider>
25
+ </ThemeProvider>
22
26
  </div>
23
27
  ),
24
28
  ];
@@ -3,11 +3,15 @@ import React from "react";
3
3
  import { MapComponentsProvider } from "@mapcomponents/react-core";
4
4
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
5
  import "./style.css";
6
+ import { createTheme, ThemeProvider } from "@mui/material/styles";
7
+
8
+ const theme = createTheme({});
6
9
 
7
10
  const decorators = [
8
11
  (Story) => (
9
12
  <div className="fullscreen_map">
10
- <MapComponentsProvider>
13
+ <ThemeProvider theme={theme}>
14
+ <MapComponentsProvider>
11
15
  <Story />
12
16
  <MapLibreMap
13
17
  options={{
@@ -15,8 +19,7 @@ const decorators = [
15
19
  //center: [-87.62712, 41.89033],
16
20
  zoom: 14.5,
17
21
  //pitch: 45,
18
- style:
19
- "https://wms.wheregroup.com/tileserver/style/klokantech-basic.json",
22
+ style: "https://wms.wheregroup.com/tileserver/style/klokantech-basic.json",
20
23
  //style:"https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
21
24
  //center: [8.607, 53.1409349],
22
25
  // zoom: 13,
@@ -27,7 +30,8 @@ const decorators = [
27
30
  // ],
28
31
  }}
29
32
  />
30
- </MapComponentsProvider>
33
+ </MapComponentsProvider>
34
+ </ThemeProvider>
31
35
  </div>
32
36
  ),
33
37
  ];
@@ -4,12 +4,13 @@ import { MapComponentsProvider } from "@mapcomponents/react-core";
4
4
 
5
5
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
6
6
 
7
- import { createTheme, ThemeProvider } from "@mui/material/styles";
8
7
 
9
8
  import "./style.css";
9
+ import { createTheme, ThemeProvider } from "@mui/material/styles";
10
10
 
11
11
  const theme = createTheme({});
12
12
 
13
+
13
14
  const decorators = [
14
15
  (Story) => (
15
16
  <div className="fullscreen_map">
@@ -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
 
@@ -34,11 +34,11 @@ function useMapState(props) {
34
34
  */
35
35
  const layerIdFilter = useCallback(
36
36
  (layer) => {
37
- if (!props.filter.includeBaseLayers && layer.baseLayer) {
37
+ if (!props?.filter?.includeBaseLayers && layer.baseLayer) {
38
38
  return false;
39
39
  }
40
40
 
41
- if (typeof props.filter.matchLayerIds !== "undefined") {
41
+ if (typeof props.filter?.matchLayerIds !== "undefined") {
42
42
  if (props.filter.matchLayerIds instanceof RegExp) {
43
43
  return props.filter.matchLayerIds.test(layer.id);
44
44
  } else {
@@ -58,7 +58,7 @@ function useMapState(props) {
58
58
  layersRef.current = _layerStateString;
59
59
  setLayers(_layerState);
60
60
  }
61
- },[layerIdFilter]);
61
+ }, [layerIdFilter]);
62
62
 
63
63
  useEffect(() => {
64
64
  let _componentId = componentId.current;
@@ -25,12 +25,13 @@ function useWms(props) {
25
25
  // extract URL parameters from the given URL
26
26
  clearState();
27
27
  setError(undefined);
28
- if (!props.url) return;
28
+
29
+ if (!url) return;
29
30
 
30
31
  let _propsUrlParams;
31
- let _wmsUrl = props.url;
32
- if (props.url.indexOf("?") !== -1) {
33
- _propsUrlParams = props.url.split("?");
32
+ let _wmsUrl = url;
33
+ if (url.indexOf("?") !== -1) {
34
+ _propsUrlParams = url.split("?");
34
35
  _wmsUrl = _propsUrlParams[0];
35
36
  }
36
37
  let _urlParamsFromUrl = new URLSearchParams(_propsUrlParams?.[1]);
@@ -62,7 +63,7 @@ function useWms(props) {
62
63
  console.log(error);
63
64
  setError(error.message);
64
65
  });
65
- }, [props.url, props.urlParameters]);
66
+ }, [url, props.urlParameters]);
66
67
 
67
68
  useEffect(() => {
68
69
  if (!capabilities?.Service) return;
@@ -92,4 +93,4 @@ useWms.defaultProps = {
92
93
  },
93
94
  };
94
95
 
95
- export default useWms;
96
+ export default useWms;
package/src/i18n.js ADDED
@@ -0,0 +1,28 @@
1
+ import i18n from "i18next";
2
+ import { initReactI18next } from "react-i18next";
3
+ import english from "./translations/english.js"
4
+ import german from "./translations/german.js"
5
+
6
+
7
+ // the translations
8
+ // (tip move them in a JSON file and import them,
9
+ // or even better, manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files)
10
+ const resources = { ...english, ...german };
11
+
12
+
13
+ i18n
14
+ .use(initReactI18next) // passes i18n down to react-i18next
15
+ .init({
16
+ resources,
17
+ lng: "de", // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources
18
+ // you can use the i18n.changeLanguage function to change the language manually: https://www.i18next.com/overview/api#changelanguage
19
+ // if you're using a language detector, do not define the lng option
20
+
21
+ interpolation: {
22
+ escapeValue: false // react already safes from xss
23
+ }
24
+ });
25
+
26
+
27
+
28
+ export default i18n;
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";
@@ -17,5 +18,7 @@ export { default as MlLayerSwipe } from "./components/MlLayerSwipe/MlLayerSwipe"
17
18
  export { default as MlGPXViewer } from "./components/MlGPXViewer/MlGPXViewer";
18
19
  export { default as GeoJsonProvider } from "./components/MlGPXViewer/util/GeoJsonProvider";
19
20
  export { default as GeoJsonContext } from "./components/MlGPXViewer/util/GeoJsonContext";
21
+ export { default as MlSpatialElevationProfile } from "./components/MlSpatialElevationProfile/MlSpatialElevationProfile";
20
22
 
21
23
  export { default as useMapState } from "./hooks/useMapState";
24
+ export { default as useMap } from "./hooks/useMap";
@@ -0,0 +1,4 @@
1
+ const english = {
2
+ "en": { "Layer": "Layer" }
3
+ }
4
+ export default english;
@@ -0,0 +1,4 @@
1
+ const german = {
2
+ "de": { "Layer": "Ebene" }
3
+ }
4
+ export default german;
@@ -0,0 +1,73 @@
1
+
2
+ import { useEffect, useState } from "react"
3
+ import CircularProgress from '@mui/material/CircularProgress';
4
+
5
+ import ErrorIcon from '@mui/icons-material/Error';
6
+ import { Box } from "@mui/system";
7
+ const ImageLoader = (props) => {
8
+ const [state, setState] = useState("loading");
9
+
10
+ useEffect(() => {
11
+ if (!props.src) {
12
+ setState("error");
13
+ return;
14
+ }
15
+ fetch(props.src)
16
+ .then(({ ok }) => {
17
+ if (ok) {
18
+ setState("ready");
19
+ } else {
20
+ setState("error");
21
+ }
22
+ })
23
+ .catch((e) => {
24
+ console.error(e);
25
+ setState("error");
26
+ });
27
+ }, [props.src]);
28
+
29
+ const boxStyle = {
30
+ width: "100%",
31
+ height: "100%",
32
+ border: 2,
33
+ borderRadius: "8px",
34
+ textAlign: "center",
35
+ display: "flex",
36
+ };
37
+
38
+ const LoadingImage = () => {
39
+ return (
40
+ <Box className={props.className} sx={{ ...boxStyle, ...props.style }}>
41
+ <CircularProgress />
42
+ </Box>
43
+ );
44
+ };
45
+
46
+ const ReadyImage = () => {
47
+ return (
48
+ <img className={props.className} style={{ ...boxStyle, ...props.style }} src={props.src} />
49
+ );
50
+ };
51
+ const ErrorImage = () => {
52
+ return (
53
+ <Box className={props.className} sx={{ boxStyle, ...props.style }}>
54
+ <ErrorIcon sx={{ display: "block", margin: "auto" }} />
55
+ </Box>
56
+ );
57
+ };
58
+
59
+ const renderImage = (state) => {
60
+ switch (state) {
61
+ case "ready":
62
+ return <ReadyImage />;
63
+ case "error":
64
+ return <ErrorImage />;
65
+ }
66
+
67
+ return <LoadingImage />;
68
+ };
69
+
70
+ return <>{renderImage(state)}</>;
71
+ };
72
+
73
+ export default ImageLoader
@@ -1,12 +1,16 @@
1
- import React from "react";
1
+ import React, {useState} from "react";
2
+ import { useTheme, styled } from "@mui/material/styles";
2
3
  import makeStyles from "@mui/styles/makeStyles";
3
4
  import Drawer from "@mui/material/Drawer";
4
- import { InsertInvitationOutlined } from "@mui/icons-material";
5
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
6
+ import MenuIcon from '@mui/icons-material/Menu';
7
+ import { IconButton } from "@mui/material";
8
+ import useMediaQuery from "@mui/material/useMediaQuery";
5
9
 
6
10
  const useStyles = makeStyles((theme) => ({
7
11
  drawer: {
8
12
  flexGrow: 1,
9
- zIndex: 101,
13
+ zIndex: 105,
10
14
  position: "absolute",
11
15
  top: 0,
12
16
  left: 0,
@@ -14,32 +18,83 @@ const useStyles = makeStyles((theme) => ({
14
18
  backgroundColor: "#fafafa",
15
19
  display: "flex",
16
20
  flexDirection: "column",
17
- alignContent: "stretch",
18
21
  alignItems: "stretch",
22
+ alignContent: "stretch",
19
23
  },
20
24
  drawerPaper: {
21
- position: "initial",
22
- padding: "20px",
25
+ position: "initial !important",
26
+ boxSizing: "border-box",
27
+ padding: "40px",
28
+ visibility: "visible !important",
29
+ zIndex: "initial !important",
30
+ },
31
+ drawerHeader: {
32
+ alignContent: "flex-start",
33
+ display: "flex",
23
34
  },
35
+ drawerContent: {},
36
+ }));
37
+
38
+ const DrawerHeader = styled("div")(({ theme }) => ({
39
+ display: "flex",
40
+ alignItems: "center",
24
41
  }));
25
42
 
26
43
  export default function Sidebar(props) {
27
44
  const classes = useStyles();
45
+ const mediaIsMobile = useMediaQuery("(max-width:900px)");
46
+
47
+ const [drawerOpen, setDrawerOpen] = useState(true);
48
+
49
+ const handleDrawerOpen = () => {
50
+ setDrawerOpen(true);
51
+ };
52
+ const handleDrawerClose = () => {
53
+ setDrawerOpen(false);
54
+ };
28
55
 
29
56
  return (
30
- <Drawer
31
- className={classes.drawer}
32
- variant="persistent"
33
- anchor="left"
34
- open={true}
35
- classes={{
36
- paper: classes.drawerPaper,
37
- }}
38
- sx={{
39
- ...props.sx,
40
- }}
41
- >
42
- {props.children}
43
- </Drawer>
57
+ <>
58
+ <IconButton
59
+ onClick={handleDrawerOpen}
60
+ style={{
61
+ zIndex: 101,
62
+ position: "relative",
63
+ padding: "20px",
64
+ }}
65
+ >
66
+ <MenuIcon />
67
+ </IconButton>
68
+ <Drawer
69
+ transitionDuration={0}
70
+ className={classes.drawer}
71
+ variant="persistent"
72
+ anchor="left"
73
+ open={drawerOpen}
74
+ classes={{
75
+ paper: classes.drawerPaper,
76
+ }}
77
+ sx={{
78
+ ...props.sx,
79
+ ...{
80
+ maxWidth: mediaIsMobile ? "90vw" : "20vw",
81
+ },
82
+ ...(drawerOpen ? {} : { left: mediaIsMobile ? "-90vw" : "-20vw" }),
83
+ }}
84
+ >
85
+ <DrawerHeader className={classes.drawerHeader}>
86
+ <IconButton onClick={handleDrawerClose}>
87
+ <ChevronLeftIcon
88
+ style={
89
+ {
90
+ //paddingBottom: "40px",
91
+ }
92
+ }
93
+ />
94
+ </IconButton>
95
+ </DrawerHeader>
96
+ <div style={{ maxWidth: "100%" }}>{props.children}</div>
97
+ </Drawer>
98
+ </>
44
99
  );
45
100
  }
@@ -3,27 +3,27 @@ import makeStyles from "@mui/styles/makeStyles";
3
3
  import AppBar from "@mui/material/AppBar";
4
4
  import Toolbar from "@mui/material/Toolbar";
5
5
 
6
- const useStyles = makeStyles((theme) => ({
7
- root: {
8
- flexGrow: 1,
9
- zIndex: 120,
10
- position: "absolute",
11
- top: 0,
12
- left: 0,
13
- right: 0,
14
- },
15
- AppBar: {
16
- backgroundColor: "#fafafa",
17
- minHeight: "62px",
18
- },
19
- }));
20
6
 
21
7
  export default function TopToolbar(props) {
22
- const classes = useStyles();
23
-
24
8
  return (
25
- <div className={classes.root}>
26
- <AppBar className={classes.AppBar} position="static">
9
+ <div
10
+ style={{
11
+ flexGrow: 1,
12
+ zIndex: 120,
13
+ position: "absolute",
14
+ top: 0,
15
+ left: 0,
16
+ right: 0,
17
+ }}
18
+ >
19
+ <AppBar
20
+ sx={{
21
+ minHeight: "62px",
22
+ backgroundColor: "#f1f1f1",
23
+ }}
24
+ color="primary"
25
+ position="static"
26
+ >
27
27
  <Toolbar>{props.children}</Toolbar>
28
28
  </AppBar>
29
29
  </div>