@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.
- package/.github/workflows/storybook.yml +4 -2
- package/CHANGELOG.md +33 -0
- package/README.md +22 -6
- package/coverage/clover.xml +893 -760
- package/coverage/coverage-final.json +22 -17
- package/coverage/lcov-report/index.html +183 -123
- package/coverage/lcov-report/{components → src/components}/MapLibreMap/MapLibreMap.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MapLibreMap/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlCreatePdfButton/MlCreatePdfButton.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlCreatePdfButton/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlFeatureEditor/MlFeatureEditor.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlFeatureEditor/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlFillExtrusionLayer/MlFillExtrusionLayer.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlFillExtrusionLayer/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlFollowGps/MlFollowGps.js.html +148 -136
- package/coverage/lcov-report/{components → src/components}/MlFollowGps/index.html +24 -24
- package/coverage/lcov-report/{components → src/components}/MlGPXViewer/MlGPXViewer.js.html +66 -60
- package/coverage/lcov-report/{components → src/components}/MlGPXViewer/gpxConverter.js.html +49 -70
- package/coverage/lcov-report/{components → src/components}/MlGPXViewer/index.html +25 -25
- package/coverage/lcov-report/{components → src/components}/MlGeoJsonLayer/MlGeoJsonLayer.js.html +155 -47
- package/coverage/lcov-report/{components → src/components}/MlGeoJsonLayer/index.html +28 -28
- package/coverage/lcov-report/{components/MlLayer/MlLayer.js.html → src/components/MlImageMarkerLayer/MlImageMarkerLayer.js.html} +88 -121
- package/coverage/lcov-report/{components → src/components}/MlImageMarkerLayer/index.html +28 -28
- package/coverage/lcov-report/{components/MlImageMarkerLayer/MlImageMarkerLayer.js.html → src/components/MlLayer/MlLayer.js.html} +116 -125
- package/coverage/lcov-report/src/components/MlLayer/index.html +117 -0
- package/coverage/lcov-report/{components → src/components}/MlLayerMagnify/MlLayerMagnify.js.html +41 -41
- package/coverage/lcov-report/{components → src/components}/MlLayerMagnify/index.html +24 -24
- package/coverage/lcov-report/{components → src/components}/MlLayerSwipe/MlLayerSwipe.js.html +38 -41
- package/coverage/lcov-report/{components → src/components}/MlLayerSwipe/index.html +24 -24
- package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +755 -0
- package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +380 -0
- package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +117 -0
- package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +117 -0
- package/coverage/lcov-report/{components → src/components}/MlMarker/MlMarker.js.html +11 -11
- package/coverage/lcov-report/{components → src/components}/MlMarker/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlNavigationCompass/MlNavigationCompass.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlNavigationCompass/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlNavigationTools/MlNavigationTools.js.html +50 -41
- package/coverage/lcov-report/{components → src/components}/MlNavigationTools/index.html +18 -18
- package/coverage/lcov-report/{components → src/components}/MlOsmLayer/MlOsmLayer.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlOsmLayer/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlScaleReference/MlScaleReference.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlScaleReference/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlShareMapState/MlShareMapState.js.html +217 -25
- package/coverage/lcov-report/{components → src/components}/MlShareMapState/index.html +18 -18
- package/coverage/lcov-report/{components → src/components}/MlSpatialElevationProfile/MlSpatialElevationProfile.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlSpatialElevationProfile/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlThreeJsLayer/MlThreeJsLayer.js.html +30 -54
- package/coverage/lcov-report/{components → src/components}/MlThreeJsLayer/index.html +24 -24
- package/coverage/lcov-report/{components → src/components}/MlUseMapDebugger/MlUseMapDebugger.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlUseMapDebugger/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlVectorTileLayer/MlVectorTileLayer.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlVectorTileLayer/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlWmsFeatureInfoPopup/index.html +10 -10
- package/coverage/lcov-report/{components → src/components}/MlWmsLayer/MlWmsLayer.js.html +13 -13
- package/coverage/lcov-report/{components → src/components}/MlWmsLayer/index.html +14 -14
- package/coverage/lcov-report/{components → src/components}/MlWmsLoader/MlWmsLoader.js.html +31 -19
- package/coverage/lcov-report/{components → src/components}/MlWmsLoader/index.html +16 -16
- package/coverage/lcov-report/src/hooks/index.html +147 -0
- package/coverage/lcov-report/src/hooks/useMap.js.html +296 -0
- package/coverage/lcov-report/{hooks → src/hooks}/useMapState.js.html +91 -91
- package/coverage/lcov-report/{hooks → src/hooks}/useWms.js.html +18 -18
- package/coverage/lcov-report/src/i18n.js.html +167 -0
- package/coverage/lcov-report/src/index.html +117 -0
- package/coverage/lcov-report/src/translations/english.js.html +95 -0
- package/coverage/lcov-report/src/translations/german.js.html +95 -0
- package/coverage/lcov-report/src/translations/index.html +132 -0
- package/coverage/lcov.info +1610 -1314
- package/dist/b556faa3bc6829d2.png +0 -0
- package/dist/index.esm.js +934 -668
- package/dist/index.esm.js.map +1 -1
- package/package.json +3 -1
- package/public/assets/dop.png +0 -0
- package/public/assets/historic.png +0 -0
- package/public/assets/osm.png +0 -0
- package/public/thumbnails/MlFollowGps.png +0 -0
- package/public/thumbnails/MlThreeJsLayer.png +0 -0
- package/src/components/MapLibreMap/lib/MapLibreGlWrapper.js +53 -67
- package/src/components/MlComponentTemplate/MlComponentTemplate.js +6 -31
- package/src/components/MlFeatureEditor/MlFeatureEditor.meta.json +2 -2
- package/src/components/MlFollowGps/MlFollowGps.js +92 -88
- package/src/components/MlFollowGps/MlFollowGps.meta.json +2 -2
- package/src/components/MlFollowGps/MlFollowGps.test.js +3 -5
- package/src/components/MlFollowGps/assets/marker.png +0 -0
- package/src/components/MlGPXViewer/MlGPXViewer.js +45 -43
- package/src/components/MlGPXViewer/gpxConverter.js +22 -29
- package/src/components/MlGeoJsonLayer/MlGeoJsonLayer.js +45 -9
- package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.js +21 -57
- package/src/components/MlImageMarkerLayer/MlImageMarkerLayer.test.js +6 -7
- package/src/components/MlLayer/MlLayer.js +28 -6
- package/src/components/MlLayer/MlLayer.test.js +12 -10
- package/src/components/MlLayerMagnify/MlLayerMagnify.js +3 -3
- package/src/components/MlLayerSwipe/MlLayerSwipe.js +4 -5
- package/src/components/MlLayerSwitcher/MlLayerSwitcher.css +17 -0
- package/src/components/MlLayerSwitcher/MlLayerSwitcher.doc.de.md +3 -0
- package/src/components/MlLayerSwitcher/MlLayerSwitcher.js +223 -0
- package/src/components/MlLayerSwitcher/MlLayerSwitcher.meta_.json +15 -0
- package/src/components/MlLayerSwitcher/MlLayerSwitcher.stories.js +106 -0
- package/src/components/MlLayerSwitcher/assets/sample_1.json +26 -0
- package/src/components/MlLayerSwitcher/assets/sample_2.json +22 -0
- package/src/components/MlLayerSwitcher/components/LayerBox.js +98 -0
- package/src/components/MlMarker/MlMarker.js +1 -1
- package/src/components/MlNavigationTools/MlNavigationTools.js +29 -26
- package/src/components/MlScaleReference/MlScaleReference.meta.json +1 -1
- package/src/components/MlScaleReference/MlScaleReference.stories.js +25 -21
- package/src/components/MlShareMapState/MlShareMapState.js +73 -9
- package/src/components/MlShareMapState/MlShareMapState.stories.js +24 -1
- package/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.stories.js +12 -6
- package/src/components/MlThreeJsLayer/MlThreeJsLayer.js +8 -15
- package/src/components/MlWmsLayer/MlWmsLayer.js +1 -1
- package/src/components/MlWmsLoader/MlWmsLoader.js +8 -4
- package/src/components/MlWmsLoader/MlWmsLoader.meta.json +1 -1
- package/src/components/MlWmsLoader/MlWmsLoader.stories.js +5 -4
- package/src/decorators/EmptyMapContextDecorator.js +11 -6
- package/src/decorators/MapContext3DDecorator.js +25 -20
- package/src/decorators/MapContextDashboardDecorator.js +7 -2
- package/src/decorators/MapContextDecorator.js +7 -3
- package/src/decorators/MapContextKlokantechBasicDecorator.js +8 -4
- package/src/decorators/MultiMapContextDecorator.js +2 -1
- package/src/hooks/useMap.js +33 -62
- package/src/hooks/useMapState.js +3 -3
- package/src/hooks/useWms.js +7 -6
- package/src/i18n.js +28 -0
- package/src/index.js +3 -0
- package/src/translations/english.js +4 -0
- package/src/translations/german.js +4 -0
- package/src/ui_components/ImageLoader.js +73 -0
- package/src/ui_components/Sidebar.js +75 -20
- package/src/ui_components/TopToolbar.js +18 -18
- package/coverage/lcov-report/components/MlLayer/index.html +0 -117
- package/coverage/lcov-report/hooks/index.html +0 -147
- package/coverage/lcov-report/hooks/useMap.js.html +0 -383
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {useContext, useRef, useEffect, useState} from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {MapContext} from "@mapcomponents/react-core";
|
|
4
|
+
import {bbox} from "@turf/turf";
|
|
5
5
|
import Divider from "@mui/material/Divider";
|
|
6
6
|
import Typography from "@mui/material/Typography";
|
|
7
7
|
import Drawer from "@mui/material/Drawer";
|
|
8
8
|
import IconButton from "@mui/material/IconButton";
|
|
9
9
|
import InfoIcon from "@mui/icons-material/Info";
|
|
10
10
|
import FileCopy from "@mui/icons-material/FileCopy";
|
|
11
|
-
import {
|
|
11
|
+
import {Popup} from "maplibre-gl";
|
|
12
12
|
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 GeoJsonContext from "./util/GeoJsonContext";
|
|
16
16
|
import toGeoJSON from "./gpxConverter";
|
|
17
|
+
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
17
18
|
|
|
18
|
-
import {
|
|
19
|
+
import {v4 as uuidv4} from "uuid";
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* MlGPXViewer returns a dropzone and a button to load a GPX Track into the map.
|
|
@@ -38,6 +39,7 @@ const MlGPXViewer = (props) => {
|
|
|
38
39
|
const [zIndex, setZIndex] = useState(0);
|
|
39
40
|
const [metaData, setMetaData] = useState([]);
|
|
40
41
|
const fileupload = useRef(null);
|
|
42
|
+
const mediaIsMobile = useMediaQuery("(max-width:900px)");
|
|
41
43
|
|
|
42
44
|
const popup = useRef(
|
|
43
45
|
new Popup({
|
|
@@ -255,42 +257,42 @@ const MlGPXViewer = (props) => {
|
|
|
255
257
|
};
|
|
256
258
|
return (
|
|
257
259
|
<>
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
</
|
|
260
|
+
<div style={{
|
|
261
|
+
position: "fixed",
|
|
262
|
+
right: "5px",
|
|
263
|
+
bottom: mediaIsMobile ? "40px" : "25px",
|
|
264
|
+
display: "flex",
|
|
265
|
+
flexDirection: "column",
|
|
266
|
+
gap: "5px",
|
|
267
|
+
zIndex: 1000,
|
|
268
|
+
}}>
|
|
269
|
+
<IconButton
|
|
270
|
+
onClick={manualUpload}
|
|
271
|
+
style={{
|
|
272
|
+
backgroundColor: "rgba(255,255,255,1)",
|
|
273
|
+
}}
|
|
274
|
+
size="large"
|
|
275
|
+
>
|
|
276
|
+
<input
|
|
277
|
+
ref={fileupload}
|
|
278
|
+
onChange={fileUploadOnChange}
|
|
279
|
+
type="file"
|
|
280
|
+
id="input"
|
|
281
|
+
multiple
|
|
282
|
+
style={{display: "none"}}
|
|
283
|
+
></input>
|
|
284
|
+
<FileCopy/>
|
|
285
|
+
</IconButton>
|
|
286
|
+
<IconButton
|
|
287
|
+
onClick={toogleDrawer}
|
|
288
|
+
style={{
|
|
289
|
+
backgroundColor: "rgba(255,255,255,1)",
|
|
290
|
+
}}
|
|
291
|
+
size="large"
|
|
292
|
+
>
|
|
293
|
+
<InfoIcon/>
|
|
294
|
+
</IconButton>
|
|
295
|
+
</div>
|
|
294
296
|
<Drawer variant="persistent" anchor="left" open={open}>
|
|
295
297
|
<Typography
|
|
296
298
|
variant="h6"
|
|
@@ -302,11 +304,11 @@ const MlGPXViewer = (props) => {
|
|
|
302
304
|
>
|
|
303
305
|
Informationen zur Route
|
|
304
306
|
</Typography>
|
|
305
|
-
<Divider
|
|
307
|
+
<Divider/>
|
|
306
308
|
<List>
|
|
307
309
|
{metaData.map((item) => (
|
|
308
310
|
<ListItem key={`item--${item.id}`}>
|
|
309
|
-
<ListItemText primary={item.value}
|
|
311
|
+
<ListItemText primary={item.value}/>
|
|
310
312
|
</ListItem>
|
|
311
313
|
))}
|
|
312
314
|
</List>
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* https://github.com/mapbox/togeojson
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2016 Mapbox All rights reserved.
|
|
5
|
+
*
|
|
6
|
+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
7
|
+
*
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
9
|
+
*
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
11
|
+
*
|
|
12
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
13
|
+
*/
|
|
1
14
|
var toGeoJSON = (function () {
|
|
2
15
|
var removeSpace = /\s*/g,
|
|
3
16
|
trimSpace = /^\s*|\s*$/g,
|
|
@@ -145,15 +158,11 @@ var toGeoJSON = (function () {
|
|
|
145
158
|
styleByHash[hash] = styles[k];
|
|
146
159
|
}
|
|
147
160
|
for (var l = 0; l < styleMaps.length; l++) {
|
|
148
|
-
styleIndex["#" + attr(styleMaps[l], "id")] = okhash(
|
|
149
|
-
xml2str(styleMaps[l])
|
|
150
|
-
).toString(16);
|
|
161
|
+
styleIndex["#" + attr(styleMaps[l], "id")] = okhash(xml2str(styleMaps[l])).toString(16);
|
|
151
162
|
var pairs = get(styleMaps[l], "Pair");
|
|
152
163
|
var pairsMap = {};
|
|
153
164
|
for (var m = 0; m < pairs.length; m++) {
|
|
154
|
-
pairsMap[nodeVal(get1(pairs[m], "key"))] = nodeVal(
|
|
155
|
-
get1(pairs[m], "styleUrl")
|
|
156
|
-
);
|
|
165
|
+
pairsMap[nodeVal(get1(pairs[m], "key"))] = nodeVal(get1(pairs[m], "styleUrl"));
|
|
157
166
|
}
|
|
158
167
|
styleMapIndex["#" + attr(styleMaps[l], "id")] = pairsMap;
|
|
159
168
|
}
|
|
@@ -183,8 +192,7 @@ var toGeoJSON = (function () {
|
|
|
183
192
|
coords = [],
|
|
184
193
|
times = [];
|
|
185
194
|
if (elems.length === 0) elems = get(root, "gx:coord");
|
|
186
|
-
for (var i = 0; i < elems.length; i++)
|
|
187
|
-
coords.push(gxCoord(nodeVal(elems[i])));
|
|
195
|
+
for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
|
|
188
196
|
var timeElems = get(root, "when");
|
|
189
197
|
for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
|
|
190
198
|
return {
|
|
@@ -322,26 +330,19 @@ var toGeoJSON = (function () {
|
|
|
322
330
|
outline = nodeVal(get1(polyStyle, "outline"));
|
|
323
331
|
if (pcolor) properties.fill = pcolor;
|
|
324
332
|
if (!isNaN(popacity)) properties["fill-opacity"] = popacity;
|
|
325
|
-
if (fill)
|
|
326
|
-
properties["fill-opacity"] =
|
|
327
|
-
fill === "1" ? properties["fill-opacity"] || 1 : 0;
|
|
333
|
+
if (fill) properties["fill-opacity"] = fill === "1" ? properties["fill-opacity"] || 1 : 0;
|
|
328
334
|
if (outline)
|
|
329
|
-
properties["stroke-opacity"] =
|
|
330
|
-
outline === "1" ? properties["stroke-opacity"] || 1 : 0;
|
|
335
|
+
properties["stroke-opacity"] = outline === "1" ? properties["stroke-opacity"] || 1 : 0;
|
|
331
336
|
}
|
|
332
337
|
if (extendedData) {
|
|
333
338
|
var datas = get(extendedData, "Data"),
|
|
334
339
|
simpleDatas = get(extendedData, "SimpleData");
|
|
335
340
|
|
|
336
341
|
for (i = 0; i < datas.length; i++) {
|
|
337
|
-
properties[datas[i].getAttribute("name")] = nodeVal(
|
|
338
|
-
get1(datas[i], "value")
|
|
339
|
-
);
|
|
342
|
+
properties[datas[i].getAttribute("name")] = nodeVal(get1(datas[i], "value"));
|
|
340
343
|
}
|
|
341
344
|
for (i = 0; i < simpleDatas.length; i++) {
|
|
342
|
-
properties[simpleDatas[i].getAttribute("name")] = nodeVal(
|
|
343
|
-
simpleDatas[i]
|
|
344
|
-
);
|
|
345
|
+
properties[simpleDatas[i].getAttribute("name")] = nodeVal(simpleDatas[i]);
|
|
345
346
|
}
|
|
346
347
|
}
|
|
347
348
|
if (visibility) {
|
|
@@ -444,8 +445,7 @@ var toGeoJSON = (function () {
|
|
|
444
445
|
if (track.length === 0) return;
|
|
445
446
|
var properties = getProperties(node);
|
|
446
447
|
extend(properties, getLineStyle(get1(node, "extensions")));
|
|
447
|
-
if (times.length)
|
|
448
|
-
properties.coordTimes = track.length === 1 ? times[0] : times;
|
|
448
|
+
if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
|
|
449
449
|
if (heartRates.length)
|
|
450
450
|
properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
|
|
451
451
|
return {
|
|
@@ -501,14 +501,7 @@ var toGeoJSON = (function () {
|
|
|
501
501
|
return style;
|
|
502
502
|
}
|
|
503
503
|
function getProperties(node) {
|
|
504
|
-
var prop = getMulti(node, [
|
|
505
|
-
"name",
|
|
506
|
-
"cmt",
|
|
507
|
-
"desc",
|
|
508
|
-
"type",
|
|
509
|
-
"time",
|
|
510
|
-
"keywords",
|
|
511
|
-
]),
|
|
504
|
+
var prop = getMulti(node, ["name", "cmt", "desc", "type", "time", "keywords"]),
|
|
512
505
|
links = get(node, "link");
|
|
513
506
|
if (links.length) prop.links = [];
|
|
514
507
|
for (var i = 0, link; i < links.length; i++) {
|
|
@@ -4,6 +4,7 @@ import PropTypes from "prop-types";
|
|
|
4
4
|
import { v4 as uuidv4 } from "uuid";
|
|
5
5
|
import * as turf from "@turf/turf";
|
|
6
6
|
import { MapContext } from "@mapcomponents/react-core";
|
|
7
|
+
import useMapState from "../../hooks/useMapState";
|
|
7
8
|
|
|
8
9
|
import { _transitionToGeojson } from "./util/transitionFunctions";
|
|
9
10
|
|
|
@@ -17,6 +18,14 @@ const msPerStep = 50;
|
|
|
17
18
|
const MlGeoJsonLayer = (props) => {
|
|
18
19
|
// Use a useRef hook to reference the layer object to be able to access it later inside useEffect hooks
|
|
19
20
|
const mapContext = useContext(MapContext);
|
|
21
|
+
const mapState = useMapState({
|
|
22
|
+
mapId: props.mapId,
|
|
23
|
+
watch: {
|
|
24
|
+
viewport: false,
|
|
25
|
+
layers: true,
|
|
26
|
+
sources: false,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
20
29
|
const oldGeojsonRef = useRef(null);
|
|
21
30
|
const mapRef = useRef(null);
|
|
22
31
|
const initializedRef = useRef(false);
|
|
@@ -34,11 +43,10 @@ const MlGeoJsonLayer = (props) => {
|
|
|
34
43
|
let _componentId = componentId.current;
|
|
35
44
|
return () => {
|
|
36
45
|
// This is the cleanup function, it is called when this react component is removed from react-dom
|
|
37
|
-
if(transitionTimeoutRef.current){
|
|
38
|
-
clearTimeout(transitionTimeoutRef.current)
|
|
46
|
+
if (transitionTimeoutRef.current) {
|
|
47
|
+
clearTimeout(transitionTimeoutRef.current);
|
|
39
48
|
}
|
|
40
49
|
if (mapRef.current) {
|
|
41
|
-
|
|
42
50
|
mapRef.current.cleanup(_componentId);
|
|
43
51
|
|
|
44
52
|
mapRef.current = null;
|
|
@@ -48,11 +56,17 @@ const MlGeoJsonLayer = (props) => {
|
|
|
48
56
|
|
|
49
57
|
useEffect(() => {
|
|
50
58
|
if (!mapRef.current || !initializedRef.current) return;
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
|
|
60
|
+
for (var key in props.layout) {
|
|
61
|
+
mapContext.getMap(props.mapId).setLayoutProperty(layerId.current, key, props.layout[key]);
|
|
62
|
+
}
|
|
63
|
+
}, [props.layout, mapContext, props.mapId]);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!mapRef.current || !initializedRef.current) return;
|
|
53
67
|
|
|
54
68
|
for (var key in props.paint) {
|
|
55
|
-
mapContext.getMap(props.mapId).setPaintProperty(
|
|
69
|
+
mapContext.getMap(props.mapId).setPaintProperty(layerId.current, key, props.paint[key]);
|
|
56
70
|
}
|
|
57
71
|
}, [props.paint, mapContext, props.mapId]);
|
|
58
72
|
|
|
@@ -109,6 +123,19 @@ const MlGeoJsonLayer = (props) => {
|
|
|
109
123
|
// initialize the layer and add it to the MapLibre-gl instance or do something else with it
|
|
110
124
|
|
|
111
125
|
if (props.geojson) {
|
|
126
|
+
//check if insertBeforeLayer exists
|
|
127
|
+
if (props.insertBeforeLayer) {
|
|
128
|
+
let layerFound = false;
|
|
129
|
+
|
|
130
|
+
mapState?.layers?.forEach((layer) => {
|
|
131
|
+
if (layer.id === props.insertBeforeLayer) {
|
|
132
|
+
layerFound = true;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
if (!layerFound) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
112
139
|
initializedRef.current = true;
|
|
113
140
|
let geojson = props.geojson;
|
|
114
141
|
|
|
@@ -136,6 +163,7 @@ const MlGeoJsonLayer = (props) => {
|
|
|
136
163
|
"line-color": "rgb(100,200,100)",
|
|
137
164
|
"line-width": 10,
|
|
138
165
|
},
|
|
166
|
+
layout: props.layout || {},
|
|
139
167
|
},
|
|
140
168
|
props.insertBeforeLayer,
|
|
141
169
|
componentId.current
|
|
@@ -162,7 +190,7 @@ const MlGeoJsonLayer = (props) => {
|
|
|
162
190
|
oldGeojsonRef.current = props.geojson;
|
|
163
191
|
}
|
|
164
192
|
}
|
|
165
|
-
}, [mapContext.mapIds, mapContext, props, transitionToGeojson]);
|
|
193
|
+
}, [mapContext.mapIds, mapContext, props, transitionToGeojson, mapState.layers]);
|
|
166
194
|
|
|
167
195
|
return <></>;
|
|
168
196
|
};
|
|
@@ -178,8 +206,16 @@ MlGeoJsonLayer.propTypes = {
|
|
|
178
206
|
*/
|
|
179
207
|
type: PropTypes.string,
|
|
180
208
|
/**
|
|
181
|
-
*
|
|
182
|
-
* Possible
|
|
209
|
+
* Layout property object, that is passed to the addLayer call.
|
|
210
|
+
* Possible props depend on the layer type.
|
|
211
|
+
* https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#line
|
|
212
|
+
* https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#circle
|
|
213
|
+
* https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#fill
|
|
214
|
+
*/
|
|
215
|
+
layout: PropTypes.object,
|
|
216
|
+
/**
|
|
217
|
+
* Paint property object, that is passed to the addLayer call.
|
|
218
|
+
* Possible props depend on the layer type.
|
|
183
219
|
* https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#line
|
|
184
220
|
* https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#circle
|
|
185
221
|
* https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#fill
|
|
@@ -1,36 +1,18 @@
|
|
|
1
|
-
import React, { useRef, useCallback, useEffect
|
|
1
|
+
import React, { useRef, useCallback, useEffect } from "react";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import { MapContext } from "@mapcomponents/react-core";
|
|
3
|
+
import useMap from "../../hooks/useMap";
|
|
5
4
|
|
|
6
5
|
const MlImageMarkerLayer = (props) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const componentId = useRef(
|
|
10
|
-
(props.idPrefix ? props.idPrefix : "MlOsmLayer-") + uuidv4()
|
|
11
|
-
);
|
|
12
|
-
const mapContext = useContext(MapContext);
|
|
6
|
+
const mapHook = useMap({ mapId: props.mapId, waitForLayer: props.insertBeforeLayer });
|
|
7
|
+
|
|
13
8
|
const layerInitializedRef = useRef(false);
|
|
14
|
-
const idSuffixRef = useRef(props.idSuffix || new Date().getTime());
|
|
15
9
|
const imageIdRef = useRef(props.imageId || "img_" + new Date().getTime());
|
|
16
|
-
const layerId = useRef(
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
let _componentId = componentId.current;
|
|
20
|
-
return () => {
|
|
21
|
-
// This is the cleanup function, it is called when this react component is removed from react-dom
|
|
22
|
-
if (mapRef.current) {
|
|
23
|
-
mapRef.current.cleanup(_componentId);
|
|
24
|
-
|
|
25
|
-
mapRef.current = null;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}, []);
|
|
10
|
+
const layerId = useRef(props.layerId || "MlImageMarkerLayer-" + mapHook.componentId);
|
|
29
11
|
|
|
30
12
|
useEffect(() => {
|
|
31
13
|
if (
|
|
32
|
-
!
|
|
33
|
-
(
|
|
14
|
+
!mapHook.mapIsReady ||
|
|
15
|
+
(mapHook.map && !mapHook.map.getLayer(layerId.current)) ||
|
|
34
16
|
!props.options
|
|
35
17
|
)
|
|
36
18
|
return;
|
|
@@ -40,19 +22,15 @@ const MlImageMarkerLayer = (props) => {
|
|
|
40
22
|
|
|
41
23
|
if (props.options.layout) {
|
|
42
24
|
for (key in props.options.layout) {
|
|
43
|
-
|
|
44
|
-
.getMap(props.mapId)
|
|
45
|
-
.setLayoutProperty(layerId.current, key, props.options.layout[key]);
|
|
25
|
+
mapHook.map.setLayoutProperty(layerId.current, key, props.options.layout[key]);
|
|
46
26
|
}
|
|
47
27
|
}
|
|
48
28
|
if (props.options.paint) {
|
|
49
29
|
for (key in props.options.paint) {
|
|
50
|
-
|
|
51
|
-
.getMap(props.mapId)
|
|
52
|
-
.setPaintProperty(layerId.current, key, props.options.paint[key]);
|
|
30
|
+
mapHook.map.setPaintProperty(layerId.current, key, props.options.paint[key]);
|
|
53
31
|
}
|
|
54
32
|
}
|
|
55
|
-
}, [props.options, layerId.current,
|
|
33
|
+
}, [props.options, layerId.current, props.mapId]);
|
|
56
34
|
|
|
57
35
|
const addLayer = useCallback(() => {
|
|
58
36
|
let tmpOptions = {
|
|
@@ -61,49 +39,35 @@ const MlImageMarkerLayer = (props) => {
|
|
|
61
39
|
...props.options,
|
|
62
40
|
};
|
|
63
41
|
tmpOptions.layout["icon-image"] = imageIdRef.current;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
props.insertBeforeLayer,
|
|
67
|
-
componentId.current
|
|
68
|
-
);
|
|
69
|
-
}, [props]);
|
|
42
|
+
mapHook.map.addLayer(tmpOptions, props.insertBeforeLayer, mapHook.componentId);
|
|
43
|
+
}, [props, mapHook.mapIsReady, mapHook.map]);
|
|
70
44
|
|
|
71
45
|
useEffect(() => {
|
|
72
|
-
if (
|
|
73
|
-
!props.options ||
|
|
74
|
-
!mapContext.mapExists(props.mapId) ||
|
|
75
|
-
layerInitializedRef.current
|
|
76
|
-
)
|
|
77
|
-
return;
|
|
78
|
-
|
|
79
|
-
// the MapLibre-gl instance (mapContext.map) is accessible here
|
|
80
|
-
// initialize the layer and add it to the MapLibre-gl instance or do something else with it
|
|
81
|
-
mapRef.current = mapContext.getMap(props.mapId);
|
|
46
|
+
if (!props.options || !mapHook.mapIsReady || layerInitializedRef.current) return;
|
|
82
47
|
|
|
83
48
|
layerInitializedRef.current = true;
|
|
84
49
|
|
|
85
50
|
if (props.imgSrc) {
|
|
86
|
-
|
|
51
|
+
mapHook.map.loadImage(props.imgSrc, function (error, image) {
|
|
87
52
|
if (error) throw error;
|
|
88
|
-
|
|
53
|
+
mapHook.map.addImage(imageIdRef.current, image, mapHook.componentId);
|
|
89
54
|
});
|
|
90
55
|
}
|
|
56
|
+
|
|
91
57
|
addLayer();
|
|
92
|
-
}, [
|
|
58
|
+
}, [mapHook.mapIsReady, mapHook.map, addLayer, props]);
|
|
93
59
|
|
|
94
60
|
useEffect(() => {
|
|
95
61
|
if (
|
|
96
|
-
!
|
|
97
|
-
(
|
|
62
|
+
!mapHook.mapIsReady ||
|
|
63
|
+
(mapHook.map && !mapHook.map.getLayer(layerId.current)) ||
|
|
98
64
|
!props.options
|
|
99
65
|
) {
|
|
100
66
|
return;
|
|
101
67
|
}
|
|
102
|
-
// the MapLibre-gl instance (mapContext.map) is accessible here
|
|
103
|
-
// initialize the layer and add it to the MapLibre-gl instance or do something else with it
|
|
104
68
|
|
|
105
|
-
|
|
106
|
-
}, [props.options.source.data,
|
|
69
|
+
mapHook.map.getSource(layerId.current).setData(props.options.source.data);
|
|
70
|
+
}, [props.options.source.data, props]);
|
|
107
71
|
|
|
108
72
|
return <></>;
|
|
109
73
|
};
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { layerRemovalTest, sourceRemovalTest } from "../../util";
|
|
2
|
+
import { uuid_regex } from "../../setupTests";
|
|
2
3
|
|
|
3
4
|
import MlImageMarkerLayer from "./MlImageMarkerLayer";
|
|
4
5
|
|
|
5
|
-
const testComponent =
|
|
6
|
-
<MlImageMarkerLayer options={{ source: {} }} imgSrc="testImage" />
|
|
7
|
-
);
|
|
6
|
+
const testComponent = <MlImageMarkerLayer options={{ source: {} }} imgSrc="testImage" />;
|
|
8
7
|
|
|
9
8
|
layerRemovalTest(
|
|
10
9
|
"<MlImageMarkerLayer />",
|
|
11
10
|
testComponent,
|
|
12
|
-
|
|
13
|
-
"MlImageMarkerLayer-{
|
|
11
|
+
new RegExp('^.*"MlImageMarkerLayer-' + uuid_regex + '".*$'),
|
|
12
|
+
"MlImageMarkerLayer-{uuid}"
|
|
14
13
|
);
|
|
15
14
|
sourceRemovalTest(
|
|
16
15
|
"<MlImageMarkerLayer />",
|
|
17
16
|
testComponent,
|
|
18
|
-
|
|
19
|
-
"MlImageMarkerLayer-{
|
|
17
|
+
new RegExp('^.*"MlImageMarkerLayer-' + uuid_regex + '".*$'),
|
|
18
|
+
"MlImageMarkerLayer-{uuid}"
|
|
20
19
|
);
|
|
@@ -2,17 +2,25 @@ import React, { useRef, useEffect, useContext } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { v4 as uuidv4 } from "uuid";
|
|
4
4
|
import { MapContext } from "@mapcomponents/react-core";
|
|
5
|
+
import useMapState from "../../hooks/useMapState";
|
|
5
6
|
|
|
6
7
|
const MlLayer = (props) => {
|
|
7
8
|
// Use a useRef hook to reference the layer object to be able to access it later inside useEffect hooks
|
|
8
9
|
const mapContext = useContext(MapContext);
|
|
10
|
+
|
|
11
|
+
const mapState = useMapState({
|
|
12
|
+
mapId: props.mapId,
|
|
13
|
+
watch: {
|
|
14
|
+
viewport: false,
|
|
15
|
+
layers: true,
|
|
16
|
+
sources: false,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
9
19
|
const layerInitializedRef = useRef(false);
|
|
10
20
|
const mapRef = useRef(null);
|
|
11
|
-
const componentId = useRef(
|
|
12
|
-
(props.layerId ? props.layerId : "MlLayer-") + uuidv4()
|
|
13
|
-
);
|
|
21
|
+
const componentId = useRef((props.layerId ? props.layerId : "MlLayer-") + uuidv4());
|
|
14
22
|
const idSuffixRef = useRef(props.idSuffix || new Date().getTime());
|
|
15
|
-
const layerId = (props.layerId ||
|
|
23
|
+
const layerId = useRef(props.layerId || componentId.current);
|
|
16
24
|
const layerPaintConfRef = useRef(undefined);
|
|
17
25
|
const layerLayoutConfRef = useRef(undefined);
|
|
18
26
|
|
|
@@ -60,12 +68,26 @@ const MlLayer = (props) => {
|
|
|
60
68
|
// the MapLibre-gl instance (mapContext.map) is accessible here
|
|
61
69
|
// initialize the layer and add it to the MapLibre-gl instance or do something else with it
|
|
62
70
|
|
|
71
|
+
//check if insertBeforeLayer exists
|
|
72
|
+
if (props.insertBeforeLayer) {
|
|
73
|
+
let layerFound = false;
|
|
74
|
+
|
|
75
|
+
mapState?.layers?.forEach((layer) => {
|
|
76
|
+
if (layer.id === props.insertBeforeLayer) {
|
|
77
|
+
layerFound = true;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
if (!layerFound) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
63
85
|
mapRef.current = mapContext.getMap(props.mapId);
|
|
64
86
|
if (mapRef.current) {
|
|
65
87
|
layerInitializedRef.current = true;
|
|
66
88
|
mapRef.current.addLayer(
|
|
67
89
|
{
|
|
68
|
-
id: layerId,
|
|
90
|
+
id: layerId.current,
|
|
69
91
|
type: "background",
|
|
70
92
|
paint: {
|
|
71
93
|
"background-color": "rgba(0,0,0,0)",
|
|
@@ -78,7 +100,7 @@ const MlLayer = (props) => {
|
|
|
78
100
|
layerPaintConfRef.current = JSON.stringify(props.options?.paint);
|
|
79
101
|
layerLayoutConfRef.current = JSON.stringify(props.options?.layout);
|
|
80
102
|
}
|
|
81
|
-
}, [mapContext.mapIds, mapContext, props,
|
|
103
|
+
}, [mapContext.mapIds, mapContext, props, mapState.layers]);
|
|
82
104
|
|
|
83
105
|
return <></>;
|
|
84
106
|
};
|
|
@@ -5,6 +5,8 @@ import { MapContext, MapComponentsProvider } from "@mapcomponents/react-core";
|
|
|
5
5
|
import MapLibreMap from "./../MapLibreMap/MapLibreMap";
|
|
6
6
|
import MlLayer from "./MlLayer";
|
|
7
7
|
|
|
8
|
+
import { uuid_regex } from "../../setupTests";
|
|
9
|
+
|
|
8
10
|
const MlLayerTestComponent = (props) => {
|
|
9
11
|
const [layerVisible, setLayerVisible] = useState(true);
|
|
10
12
|
const [refreshTrigger, setRefreshTrigger] = useState(0);
|
|
@@ -59,57 +61,57 @@ const createWrapper = () =>
|
|
|
59
61
|
);
|
|
60
62
|
|
|
61
63
|
describe("<MlLayer>", () => {
|
|
62
|
-
it("should add a Layer with the id 'MlLayer-{
|
|
64
|
+
it("should add a Layer with the id 'MlLayer-{uuid}' to the MapLibre instance", async () => {
|
|
63
65
|
const wrapper = createWrapper();
|
|
64
66
|
|
|
65
67
|
wrapper.find(".trigger_refresh").simulate("click");
|
|
66
68
|
|
|
67
69
|
expect(
|
|
68
|
-
|
|
70
|
+
new RegExp('^.*"MlLayer-' + uuid_regex + '".*$').test(wrapper.find(".layers_json").text())
|
|
69
71
|
).toEqual(true);
|
|
70
72
|
});
|
|
71
73
|
|
|
72
|
-
it("should remove a Layer with the id 'MlLayer-{
|
|
74
|
+
it("should remove a Layer with the id 'MlLayer-{uuid}' from the MapLibre instance", async () => {
|
|
73
75
|
const wrapper = createWrapper();
|
|
74
76
|
|
|
75
77
|
wrapper.find(".trigger_refresh").simulate("click");
|
|
76
78
|
|
|
77
79
|
expect(
|
|
78
|
-
|
|
80
|
+
new RegExp('^.*"MlLayer-' + uuid_regex + '".*$').test(wrapper.find(".layers_json").text())
|
|
79
81
|
).toEqual(true);
|
|
80
82
|
|
|
81
83
|
wrapper.find(".toggle_layer_visible").simulate("click");
|
|
82
84
|
wrapper.find(".trigger_refresh").simulate("click");
|
|
83
85
|
|
|
84
86
|
expect(
|
|
85
|
-
|
|
87
|
+
new RegExp('^.*"MlLayer-' + uuid_regex + '".*$').test(wrapper.find(".layers_json").text())
|
|
86
88
|
).toEqual(false);
|
|
87
89
|
});
|
|
88
90
|
|
|
89
|
-
it("should add a Source with the id 'MlLayer-{
|
|
91
|
+
it("should add a Source with the id 'MlLayer-{uuid}' to the MapLibre instance", async () => {
|
|
90
92
|
const wrapper = createWrapper();
|
|
91
93
|
|
|
92
94
|
wrapper.find(".trigger_refresh").simulate("click");
|
|
93
95
|
|
|
94
96
|
expect(
|
|
95
|
-
|
|
97
|
+
new RegExp('^.*"MlLayer-' + uuid_regex + '".*$').test(wrapper.find(".sources_json").text())
|
|
96
98
|
).toEqual(true);
|
|
97
99
|
});
|
|
98
100
|
|
|
99
|
-
it("should remove a Source with the id 'MlLayer-{
|
|
101
|
+
it("should remove a Source with the id 'MlLayer-{uuid}' from the MapLibre instance", async () => {
|
|
100
102
|
const wrapper = createWrapper();
|
|
101
103
|
|
|
102
104
|
wrapper.find(".trigger_refresh").simulate("click");
|
|
103
105
|
|
|
104
106
|
expect(
|
|
105
|
-
|
|
107
|
+
new RegExp('^.*"MlLayer-' + uuid_regex + '".*$').test(wrapper.find(".sources_json").text())
|
|
106
108
|
).toEqual(true);
|
|
107
109
|
|
|
108
110
|
wrapper.find(".toggle_layer_visible").simulate("click");
|
|
109
111
|
wrapper.find(".trigger_refresh").simulate("click");
|
|
110
112
|
|
|
111
113
|
expect(
|
|
112
|
-
|
|
114
|
+
new RegExp('^.*"MlLayer-' + uuid_regex + '".*$').test(wrapper.find(".sources_json").text())
|
|
113
115
|
).toEqual(false);
|
|
114
116
|
});
|
|
115
117
|
});
|
|
@@ -29,7 +29,7 @@ const MlLayerMagnify = (props) => {
|
|
|
29
29
|
if (!props.map1Id || !props.map2Id) {
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
|
-
if (!mapContext.
|
|
32
|
+
if (!mapContext.getMap(props.map1Id) || !mapContext.getMap(props.map2Id)) {
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -100,8 +100,8 @@ const MlLayerMagnify = (props) => {
|
|
|
100
100
|
|
|
101
101
|
syncMoveInitializedRef.current = true;
|
|
102
102
|
syncCleanupFunctionRef.current = syncMove(
|
|
103
|
-
mapContext.getMap(props.map1Id),
|
|
104
|
-
mapContext.getMap(props.map2Id)
|
|
103
|
+
mapContext.getMap(props.map1Id).map,
|
|
104
|
+
mapContext.getMap(props.map2Id).map
|
|
105
105
|
);
|
|
106
106
|
|
|
107
107
|
if (
|