react-spatial 1.12.0-beta.0 → 1.12.1
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/components/BaseLayerSwitcher/BaseLayerSwitcher.js +51 -51
- package/components/BaseLayerSwitcher/BaseLayerSwitcher.js.map +2 -2
- package/components/BasicMap/BasicMap.js +80 -80
- package/components/BasicMap/BasicMap.js.map +2 -2
- package/components/CanvasSaveButton/CanvasSaveButton.js +68 -68
- package/components/CanvasSaveButton/CanvasSaveButton.js.map +2 -2
- package/components/Copyright/Copyright.js +12 -12
- package/components/Copyright/Copyright.js.map +2 -2
- package/components/FeatureExportButton/FeatureExportButton.js +5 -5
- package/components/FeatureExportButton/FeatureExportButton.js.map +2 -2
- package/components/FitExtent/FitExtent.js +15 -15
- package/components/FitExtent/FitExtent.js.map +2 -2
- package/components/Geolocation/Geolocation.js +96 -96
- package/components/Geolocation/Geolocation.js.map +2 -2
- package/components/LayerTree/LayerTree.js +172 -172
- package/components/LayerTree/LayerTree.js.map +2 -2
- package/components/MousePosition/MousePosition.js +27 -27
- package/components/MousePosition/MousePosition.js.map +2 -2
- package/components/NorthArrow/NorthArrow.js +13 -13
- package/components/NorthArrow/NorthArrow.js.map +2 -2
- package/components/Overlay/Overlay.js +49 -49
- package/components/Overlay/Overlay.js.map +2 -2
- package/components/Permalink/Permalink.js +70 -70
- package/components/Permalink/Permalink.js.map +2 -2
- package/components/Popup/Popup.js +73 -73
- package/components/Popup/Popup.js.map +2 -2
- package/components/ResizeHandler/ResizeHandler.js +51 -49
- package/components/ResizeHandler/ResizeHandler.js.map +2 -2
- package/components/RouteSchedule/RouteSchedule.js +86 -74
- package/components/RouteSchedule/RouteSchedule.js.map +2 -2
- package/components/RouteSchedule/RouteSchedule.scss +0 -20
- package/components/ScaleLine/ScaleLine.js +2 -2
- package/components/ScaleLine/ScaleLine.js.map +2 -2
- package/components/StopsFinder/StopsFinder.js +21 -21
- package/components/StopsFinder/StopsFinder.js.map +2 -2
- package/components/StopsFinder/StopsFinderOption.js +3 -3
- package/components/StopsFinder/StopsFinderOption.js.map +2 -2
- package/components/Zoom/Zoom.js +35 -35
- package/components/Zoom/Zoom.js.map +2 -2
- package/package.json +33 -29
- package/propTypes.js +10 -10
- package/propTypes.js.map +2 -2
- package/utils/GlobalsForOle.js +57 -57
- package/utils/GlobalsForOle.js.map +2 -2
- package/utils/KML.js +32 -32
- package/utils/KML.js.map +2 -2
- package/utils/Styles.js +7 -7
- package/utils/Styles.js.map +2 -2
- package/utils/timeUtils.js +6 -6
- package/utils/timeUtils.js.map +2 -2
|
@@ -1,43 +1,30 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
|
-
import { FaChevronLeft } from "react-icons/fa";
|
|
4
1
|
import { Layer } from "mobility-toolbox-js/ol";
|
|
5
2
|
import { unByKey } from "ol/Observable";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import React, { useEffect, useState } from "react";
|
|
5
|
+
import { FaChevronLeft } from "react-icons/fa";
|
|
6
6
|
const propTypes = {
|
|
7
|
-
/**
|
|
8
|
-
* An array of [mobility-toolbox-js layers](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers).
|
|
9
|
-
*/
|
|
10
|
-
layers: PropTypes.arrayOf(PropTypes.instanceOf(Layer)).isRequired,
|
|
11
|
-
/**
|
|
12
|
-
* Object containing relative paths to the base layer images. Object
|
|
13
|
-
* keys need to correspond to layer keys
|
|
14
|
-
*/
|
|
15
|
-
layerImages: PropTypes.objectOf(PropTypes.string),
|
|
16
|
-
/**
|
|
17
|
-
* CSS class to apply on the container.
|
|
18
|
-
*/
|
|
19
|
-
className: PropTypes.string,
|
|
20
7
|
/**
|
|
21
8
|
* Alternative text rendered if layer images can't be loaded
|
|
22
9
|
*/
|
|
23
10
|
altText: PropTypes.string,
|
|
24
11
|
/**
|
|
25
|
-
*
|
|
12
|
+
* CSS class to apply on the container.
|
|
26
13
|
*/
|
|
27
|
-
|
|
28
|
-
button: PropTypes.string,
|
|
29
|
-
openSwitcher: PropTypes.string,
|
|
30
|
-
closeSwitcher: PropTypes.string
|
|
31
|
-
}),
|
|
14
|
+
className: PropTypes.string,
|
|
32
15
|
/**
|
|
33
16
|
* Image (node) rendered in the switcher close button.
|
|
34
17
|
*/
|
|
35
18
|
closeButtonImage: PropTypes.node,
|
|
36
19
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
20
|
+
* Object containing relative paths to the base layer images. Object
|
|
21
|
+
* keys need to correspond to layer keys
|
|
39
22
|
*/
|
|
40
|
-
|
|
23
|
+
layerImages: PropTypes.objectOf(PropTypes.string),
|
|
24
|
+
/**
|
|
25
|
+
* An array of [mobility-toolbox-js layers](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers).
|
|
26
|
+
*/
|
|
27
|
+
layers: PropTypes.arrayOf(PropTypes.instanceOf(Layer)).isRequired,
|
|
41
28
|
/**
|
|
42
29
|
* Callback function on close button click.
|
|
43
30
|
* @param {function} Callback function triggered when a switcher button is clicked. Takes the event as argument.
|
|
@@ -52,7 +39,20 @@ const propTypes = {
|
|
|
52
39
|
* Callback function on main switcher button click.
|
|
53
40
|
* @param {function} Callback function triggered when a switcher button is clicked. Takes the event as argument.
|
|
54
41
|
*/
|
|
55
|
-
onSwitcherButtonClick: PropTypes.func
|
|
42
|
+
onSwitcherButtonClick: PropTypes.func,
|
|
43
|
+
/**
|
|
44
|
+
* Translation function.
|
|
45
|
+
* @param {function} Translation function returning the translated string.
|
|
46
|
+
*/
|
|
47
|
+
t: PropTypes.func,
|
|
48
|
+
/**
|
|
49
|
+
* Button titles.
|
|
50
|
+
*/
|
|
51
|
+
titles: PropTypes.shape({
|
|
52
|
+
button: PropTypes.string,
|
|
53
|
+
closeSwitcher: PropTypes.string,
|
|
54
|
+
openSwitcher: PropTypes.string
|
|
55
|
+
})
|
|
56
56
|
};
|
|
57
57
|
const getVisibleLayer = (layers) => {
|
|
58
58
|
return layers.find((layer) => {
|
|
@@ -71,49 +71,49 @@ const getNextImage = (currentLayer, layers, layerImages) => {
|
|
|
71
71
|
const getImageStyle = (url) => {
|
|
72
72
|
return url ? {
|
|
73
73
|
backgroundImage: `url(${url})`,
|
|
74
|
-
|
|
74
|
+
backgroundPosition: "center",
|
|
75
75
|
backgroundRepeat: "no-repeat",
|
|
76
|
-
|
|
76
|
+
backgroundSize: "cover"
|
|
77
77
|
} : null;
|
|
78
78
|
};
|
|
79
|
-
function CloseButton({ onClick, tabIndex, title
|
|
79
|
+
function CloseButton({ children, onClick, tabIndex, title }) {
|
|
80
80
|
return /* @__PURE__ */ React.createElement(
|
|
81
81
|
"div",
|
|
82
82
|
{
|
|
83
|
+
"aria-label": title,
|
|
83
84
|
className: "rs-base-layer-switcher-close-btn",
|
|
84
|
-
role: "button",
|
|
85
85
|
onClick,
|
|
86
86
|
onKeyPress: (e) => {
|
|
87
87
|
return e.which === 13 && onClick();
|
|
88
88
|
},
|
|
89
|
+
role: "button",
|
|
89
90
|
tabIndex,
|
|
90
|
-
"aria-label": title,
|
|
91
91
|
title
|
|
92
92
|
},
|
|
93
93
|
children
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
96
|
CloseButton.propTypes = {
|
|
97
|
+
children: PropTypes.node.isRequired,
|
|
97
98
|
onClick: PropTypes.func.isRequired,
|
|
98
99
|
tabIndex: PropTypes.string.isRequired,
|
|
99
|
-
title: PropTypes.string.isRequired
|
|
100
|
-
children: PropTypes.node.isRequired
|
|
100
|
+
title: PropTypes.string.isRequired
|
|
101
101
|
};
|
|
102
102
|
function BaseLayerSwitcher({
|
|
103
|
-
layers,
|
|
104
|
-
layerImages = void 0,
|
|
105
|
-
className = "rs-base-layer-switcher",
|
|
106
103
|
altText = "Source not found",
|
|
107
|
-
|
|
108
|
-
button: "Base layers",
|
|
109
|
-
openSwitcher: "Open Baselayer-Switcher",
|
|
110
|
-
closeSwitcher: "Close Baselayer-Switcher"
|
|
111
|
-
},
|
|
104
|
+
className = "rs-base-layer-switcher",
|
|
112
105
|
closeButtonImage = /* @__PURE__ */ React.createElement(FaChevronLeft, null),
|
|
106
|
+
layerImages = void 0,
|
|
107
|
+
layers,
|
|
113
108
|
onCloseButtonClick = null,
|
|
114
109
|
onLayerButtonClick = null,
|
|
115
110
|
onSwitcherButtonClick = null,
|
|
116
|
-
t = (s) => s
|
|
111
|
+
t = (s) => s,
|
|
112
|
+
titles = {
|
|
113
|
+
button: "Base layers",
|
|
114
|
+
closeSwitcher: "Close Baselayer-Switcher",
|
|
115
|
+
openSwitcher: "Open Baselayer-Switcher"
|
|
116
|
+
}
|
|
117
117
|
}) {
|
|
118
118
|
const [switcherOpen, setSwitcherOpen] = useState(false);
|
|
119
119
|
const [isClosed, setIsClosed] = useState(true);
|
|
@@ -215,18 +215,18 @@ function BaseLayerSwitcher({
|
|
|
215
215
|
return /* @__PURE__ */ React.createElement("div", { className: `${className}${openClass}` }, /* @__PURE__ */ React.createElement(
|
|
216
216
|
"div",
|
|
217
217
|
{
|
|
218
|
-
className: `rs-base-layer-switcher-button rs-opener${openClass}`,
|
|
219
|
-
role: "button",
|
|
220
|
-
title: titles.openSwitcher,
|
|
221
218
|
"aria-label": titles.openSwitcher,
|
|
219
|
+
className: `rs-base-layer-switcher-button rs-opener${openClass}`,
|
|
222
220
|
onClick: handleSwitcherClick,
|
|
223
221
|
onKeyPress: (e) => {
|
|
224
222
|
if (e.which === 13) {
|
|
225
223
|
handleSwitcherClick();
|
|
226
224
|
}
|
|
227
225
|
},
|
|
226
|
+
role: "button",
|
|
228
227
|
style: getImageStyle(nextImage),
|
|
229
|
-
tabIndex: "0"
|
|
228
|
+
tabIndex: "0",
|
|
229
|
+
title: titles.openSwitcher
|
|
230
230
|
},
|
|
231
231
|
/* @__PURE__ */ React.createElement("div", { className: "rs-base-layer-switcher-title" }, layers.length !== 2 ? titles.button : layers.find((layer) => {
|
|
232
232
|
return !layer.visible;
|
|
@@ -245,8 +245,8 @@ function BaseLayerSwitcher({
|
|
|
245
245
|
return /* @__PURE__ */ React.createElement(
|
|
246
246
|
"div",
|
|
247
247
|
{
|
|
248
|
-
key: layer.key,
|
|
249
248
|
className: "rs-base-layer-switcher-btn-wrapper",
|
|
249
|
+
key: layer.key,
|
|
250
250
|
style: {
|
|
251
251
|
/* stylelint-disable-next-line value-keyword-case */
|
|
252
252
|
overflow: hiddenStyle,
|
|
@@ -257,10 +257,8 @@ function BaseLayerSwitcher({
|
|
|
257
257
|
/* @__PURE__ */ React.createElement(
|
|
258
258
|
"div",
|
|
259
259
|
{
|
|
260
|
-
className: `rs-base-layer-switcher-button${openClass}`,
|
|
261
|
-
role: "button",
|
|
262
|
-
title: t(layerName),
|
|
263
260
|
"aria-label": t(layerName),
|
|
261
|
+
className: `rs-base-layer-switcher-button${openClass}`,
|
|
264
262
|
onClick: (evt) => {
|
|
265
263
|
return onLayerSelect(layer, evt);
|
|
266
264
|
},
|
|
@@ -269,8 +267,10 @@ function BaseLayerSwitcher({
|
|
|
269
267
|
onLayerSelect(layer, evt);
|
|
270
268
|
}
|
|
271
269
|
},
|
|
270
|
+
role: "button",
|
|
272
271
|
style: imageStyle,
|
|
273
|
-
tabIndex: switcherOpen ? "0" : "-1"
|
|
272
|
+
tabIndex: switcherOpen ? "0" : "-1",
|
|
273
|
+
title: t(layerName)
|
|
274
274
|
},
|
|
275
275
|
/* @__PURE__ */ React.createElement("div", { className: `rs-base-layer-switcher-title${activeClass}` }, t(layerName)),
|
|
276
276
|
imageStyle ? null : /* @__PURE__ */ React.createElement("span", { className: "rs-alt-text" }, t(altText))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/BaseLayerSwitcher/BaseLayerSwitcher.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable jsx-a11y/interactive-supports-focus */\nimport React, { useState, useEffect } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { FaChevronLeft } from \"react-icons/fa\";\nimport { Layer } from \"mobility-toolbox-js/ol\";\nimport { unByKey } from \"ol/Observable\";\n\nconst propTypes = {\n /**\n * An array of [mobility-toolbox-js layers](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers).\n */\n layers: PropTypes.arrayOf(PropTypes.instanceOf(Layer)).isRequired,\n\n /**\n * Object containing relative paths to the base layer images. Object\n * keys need to correspond to layer keys\n */\n layerImages: PropTypes.objectOf(PropTypes.string),\n\n /**\n * CSS class to apply on the container.\n */\n className: PropTypes.string,\n\n /**\n * Alternative text rendered if layer images can't be loaded\n */\n altText: PropTypes.string,\n\n /**\n * Button titles.\n */\n titles: PropTypes.shape({\n button: PropTypes.string,\n openSwitcher: PropTypes.string,\n closeSwitcher: PropTypes.string,\n }),\n\n /**\n * Image (node) rendered in the switcher close button.\n */\n closeButtonImage: PropTypes.node,\n\n /**\n * Translation function.\n * @param {function} Translation function returning the translated string.\n */\n t: PropTypes.func,\n\n /**\n * Callback function on close button click.\n * @param {function} Callback function triggered when a switcher button is clicked. Takes the event as argument.\n */\n onCloseButtonClick: PropTypes.func,\n\n /**\n * Callback function on layer button click.\n * @param {function} Callback function triggered when a switcher button is clicked. Takes the event and the layer as arguments.\n */\n onLayerButtonClick: PropTypes.func,\n\n /**\n * Callback function on main switcher button click.\n * @param {function} Callback function triggered when a switcher button is clicked. Takes the event as argument.\n */\n onSwitcherButtonClick: PropTypes.func,\n};\n\nconst getVisibleLayer = (layers) => {\n return layers.find((layer) => {\n return layer.visible;\n });\n};\n\nconst getNextImage = (currentLayer, layers, layerImages) => {\n const currentIndex = layers.indexOf(\n layers.find((layer) => {\n return layer === currentLayer;\n }),\n );\n const nextIndex = currentIndex + 1 === layers.length ? 0 : currentIndex + 1;\n return layerImages[nextIndex];\n};\n\nconst getImageStyle = (url) => {\n return url\n ? {\n backgroundImage: `url(${url})`,\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\",\n backgroundPosition: \"center\",\n }\n : null;\n};\n\nfunction CloseButton({ onClick, tabIndex, title, children }) {\n return (\n <div\n className=\"rs-base-layer-switcher-close-btn\"\n role=\"button\"\n onClick={onClick}\n onKeyPress={(e) => {\n return e.which === 13 && onClick();\n }}\n tabIndex={tabIndex}\n aria-label={title}\n title={title}\n >\n {children}\n </div>\n );\n}\n\nCloseButton.propTypes = {\n onClick: PropTypes.func.isRequired,\n tabIndex: PropTypes.string.isRequired,\n title: PropTypes.string.isRequired,\n children: PropTypes.node.isRequired,\n};\n\n/**\n * The BaseLayerSwitcher component renders a button interface for switching the visible\n * [mobility-toolbox-js layer](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers)\n * when defined as base layer.\n */\n\nfunction BaseLayerSwitcher({\n layers,\n layerImages = undefined,\n className = \"rs-base-layer-switcher\",\n altText = \"Source not found\",\n titles = {\n button: \"Base layers\",\n openSwitcher: \"Open Baselayer-Switcher\",\n closeSwitcher: \"Close Baselayer-Switcher\",\n },\n closeButtonImage = <FaChevronLeft />,\n onCloseButtonClick = null,\n onLayerButtonClick = null,\n onSwitcherButtonClick = null,\n t = (s) => s,\n}) {\n const [switcherOpen, setSwitcherOpen] = useState(false);\n const [isClosed, setIsClosed] = useState(true);\n const [currentLayer, setCurrentLayer] = useState(\n getVisibleLayer(layers) || layers[0],\n );\n\n /* Images are loaded from props if provided, fallback from layer */\n const images = layerImages\n ? Object.keys(layerImages).map((layerImage) => {\n return layerImages[layerImage];\n })\n : layers.map((layer) => {\n return layer.get(\"previewImage\");\n });\n\n const openClass = switcherOpen ? \" rs-open\" : \"\";\n const hiddenStyle = switcherOpen && !isClosed ? \"visible\" : \"hidden\";\n\n const handleSwitcherClick = (evt) => {\n const nextLayer = layers.find((layer) => {\n return !layer.visible;\n });\n const onButtonClick =\n layers.length === 2 ? onLayerButtonClick : onSwitcherButtonClick;\n if (onButtonClick) {\n onButtonClick(evt, nextLayer);\n }\n if (layers.length === 2) {\n /* On only two layer options the opener becomes a layer toggle button */\n if (currentLayer.setVisible) {\n currentLayer.setVisible(false);\n } else {\n currentLayer.visible = false;\n }\n setCurrentLayer(nextLayer);\n if (nextLayer.setVisible) {\n nextLayer.setVisible(true);\n } else {\n nextLayer.visible = true;\n }\n return;\n }\n // eslint-disable-next-line consistent-return\n return setSwitcherOpen(true) && setIsClosed(false);\n };\n\n const onLayerSelect = (layer, evt) => {\n if (onLayerButtonClick) {\n onLayerButtonClick(evt, layer);\n }\n if (!switcherOpen) {\n setSwitcherOpen(true);\n return;\n }\n setCurrentLayer(layer);\n if (layer.setVisible) {\n layer.setVisible(true);\n } else {\n // eslint-disable-next-line no-param-reassign\n layer.visible = true;\n }\n layers\n .filter((l) => {\n return l !== layer;\n })\n .forEach((l) => {\n if (l.setVisible) {\n l.setVisible(false);\n } else {\n // eslint-disable-next-line no-param-reassign\n l.visible = false;\n }\n });\n setSwitcherOpen(false);\n };\n\n /* Get next image for closed button */\n const nextImage = getNextImage(currentLayer, layers, images);\n\n useEffect(() => {\n /* Ensure correct layer is active on app load */\n if (currentLayer !== getVisibleLayer(layers)) {\n setCurrentLayer(getVisibleLayer(layers) || layers[0]);\n }\n }, [currentLayer, layers]);\n\n useEffect(() => {\n /* Used for correct layer image render with animation */\n let timeout;\n if (!switcherOpen) {\n timeout = setTimeout(() => {\n setIsClosed(true);\n }, 200);\n } else {\n timeout = setTimeout(() => {\n setIsClosed(false);\n }, 800);\n }\n return () => {\n return clearTimeout(timeout);\n };\n }, [switcherOpen]);\n\n useEffect(() => {\n // Update the layer selected when a visibility changes.\n const olKeys = (layers || []).map((layer) => {\n return layer.on(\"change:visible\", (evt) => {\n if (evt.target.visible && currentLayer !== evt.target) {\n setCurrentLayer(evt.target);\n }\n });\n });\n return () => {\n unByKey(olKeys);\n };\n }, [currentLayer, layers]);\n\n if (!layers || layers.length < 2 || !currentLayer) {\n return null;\n }\n\n return (\n <div className={`${className}${openClass}`}>\n <div\n className={`rs-base-layer-switcher-button rs-opener${openClass}`}\n role=\"button\"\n title={titles.openSwitcher}\n aria-label={titles.openSwitcher}\n onClick={handleSwitcherClick}\n onKeyPress={(e) => {\n if (e.which === 13) {\n handleSwitcherClick();\n }\n }}\n style={getImageStyle(nextImage)}\n tabIndex=\"0\"\n >\n <div className=\"rs-base-layer-switcher-title\">\n {layers.length !== 2\n ? titles.button\n : layers.find((layer) => {\n return !layer.visible;\n }) &&\n t(\n layers.find((layer) => {\n return !layer.visible;\n }).name,\n )}\n </div>\n {nextImage ? null : <span className=\"rs-alt-text\">{t(altText)}</span>}\n </div>\n {layers.map((layer, idx) => {\n const layerName = layer.name;\n const activeClass = layerName === currentLayer.name ? \" rs-active\" : \"\";\n const imageStyle = getImageStyle(\n layerImages ? layerImages[`${layer.key}`] : layer.get(\"previewImage\"),\n );\n return (\n <div\n key={layer.key}\n className=\"rs-base-layer-switcher-btn-wrapper\"\n style={{\n /* stylelint-disable-next-line value-keyword-case */\n overflow: hiddenStyle,\n /* stylelint-disable-next-line value-keyword-case */\n zIndex: layers.length - idx,\n }}\n >\n <div\n className={`rs-base-layer-switcher-button${openClass}`}\n role=\"button\"\n title={t(layerName)}\n aria-label={t(layerName)}\n onClick={(evt) => {\n return onLayerSelect(layer, evt);\n }}\n onKeyPress={(evt) => {\n if (evt.which === 13) {\n onLayerSelect(layer, evt);\n }\n }}\n style={imageStyle}\n tabIndex={switcherOpen ? \"0\" : \"-1\"}\n >\n <div className={`rs-base-layer-switcher-title${activeClass}`}>\n {t(layerName)}\n </div>\n {imageStyle ? null : (\n <span className=\"rs-alt-text\">{t(altText)}</span>\n )}\n </div>\n </div>\n );\n })}\n <CloseButton\n onClick={(evt) => {\n if (onCloseButtonClick) {\n onCloseButtonClick(evt);\n }\n setSwitcherOpen(false);\n }}\n tabIndex={switcherOpen ? \"0\" : \"-1\"}\n title={titles.closeSwitcher}\n >\n {closeButtonImage}\n </CloseButton>\n </div>\n );\n}\n\nBaseLayerSwitcher.propTypes = propTypes;\n\nexport default BaseLayerSwitcher;\n"],
|
|
5
|
-
"mappings": "AACA,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable jsx-a11y/interactive-supports-focus */\nimport { Layer } from \"mobility-toolbox-js/ol\";\nimport { unByKey } from \"ol/Observable\";\nimport PropTypes from \"prop-types\";\nimport React, { useEffect, useState } from \"react\";\nimport { FaChevronLeft } from \"react-icons/fa\";\n\nconst propTypes = {\n /**\n * Alternative text rendered if layer images can't be loaded\n */\n altText: PropTypes.string,\n\n /**\n * CSS class to apply on the container.\n */\n className: PropTypes.string,\n\n /**\n * Image (node) rendered in the switcher close button.\n */\n closeButtonImage: PropTypes.node,\n\n /**\n * Object containing relative paths to the base layer images. Object\n * keys need to correspond to layer keys\n */\n layerImages: PropTypes.objectOf(PropTypes.string),\n\n /**\n * An array of [mobility-toolbox-js layers](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers).\n */\n layers: PropTypes.arrayOf(PropTypes.instanceOf(Layer)).isRequired,\n\n /**\n * Callback function on close button click.\n * @param {function} Callback function triggered when a switcher button is clicked. Takes the event as argument.\n */\n onCloseButtonClick: PropTypes.func,\n\n /**\n * Callback function on layer button click.\n * @param {function} Callback function triggered when a switcher button is clicked. Takes the event and the layer as arguments.\n */\n onLayerButtonClick: PropTypes.func,\n\n /**\n * Callback function on main switcher button click.\n * @param {function} Callback function triggered when a switcher button is clicked. Takes the event as argument.\n */\n onSwitcherButtonClick: PropTypes.func,\n\n /**\n * Translation function.\n * @param {function} Translation function returning the translated string.\n */\n t: PropTypes.func,\n\n /**\n * Button titles.\n */\n titles: PropTypes.shape({\n button: PropTypes.string,\n closeSwitcher: PropTypes.string,\n openSwitcher: PropTypes.string,\n }),\n};\n\nconst getVisibleLayer = (layers) => {\n return layers.find((layer) => {\n return layer.visible;\n });\n};\n\nconst getNextImage = (currentLayer, layers, layerImages) => {\n const currentIndex = layers.indexOf(\n layers.find((layer) => {\n return layer === currentLayer;\n }),\n );\n const nextIndex = currentIndex + 1 === layers.length ? 0 : currentIndex + 1;\n return layerImages[nextIndex];\n};\n\nconst getImageStyle = (url) => {\n return url\n ? {\n backgroundImage: `url(${url})`,\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n backgroundSize: \"cover\",\n }\n : null;\n};\n\nfunction CloseButton({ children, onClick, tabIndex, title }) {\n return (\n <div\n aria-label={title}\n className=\"rs-base-layer-switcher-close-btn\"\n onClick={onClick}\n onKeyPress={(e) => {\n return e.which === 13 && onClick();\n }}\n role=\"button\"\n tabIndex={tabIndex}\n title={title}\n >\n {children}\n </div>\n );\n}\n\nCloseButton.propTypes = {\n children: PropTypes.node.isRequired,\n onClick: PropTypes.func.isRequired,\n tabIndex: PropTypes.string.isRequired,\n title: PropTypes.string.isRequired,\n};\n\n/**\n * The BaseLayerSwitcher component renders a button interface for switching the visible\n * [mobility-toolbox-js layer](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers)\n * when defined as base layer.\n */\n\nfunction BaseLayerSwitcher({\n altText = \"Source not found\",\n className = \"rs-base-layer-switcher\",\n closeButtonImage = <FaChevronLeft />,\n layerImages = undefined,\n layers,\n onCloseButtonClick = null,\n onLayerButtonClick = null,\n onSwitcherButtonClick = null,\n t = (s) => s,\n titles = {\n button: \"Base layers\",\n closeSwitcher: \"Close Baselayer-Switcher\",\n openSwitcher: \"Open Baselayer-Switcher\",\n },\n}) {\n const [switcherOpen, setSwitcherOpen] = useState(false);\n const [isClosed, setIsClosed] = useState(true);\n const [currentLayer, setCurrentLayer] = useState(\n getVisibleLayer(layers) || layers[0],\n );\n\n /* Images are loaded from props if provided, fallback from layer */\n const images = layerImages\n ? Object.keys(layerImages).map((layerImage) => {\n return layerImages[layerImage];\n })\n : layers.map((layer) => {\n return layer.get(\"previewImage\");\n });\n\n const openClass = switcherOpen ? \" rs-open\" : \"\";\n const hiddenStyle = switcherOpen && !isClosed ? \"visible\" : \"hidden\";\n\n const handleSwitcherClick = (evt) => {\n const nextLayer = layers.find((layer) => {\n return !layer.visible;\n });\n const onButtonClick =\n layers.length === 2 ? onLayerButtonClick : onSwitcherButtonClick;\n if (onButtonClick) {\n onButtonClick(evt, nextLayer);\n }\n if (layers.length === 2) {\n /* On only two layer options the opener becomes a layer toggle button */\n if (currentLayer.setVisible) {\n currentLayer.setVisible(false);\n } else {\n currentLayer.visible = false;\n }\n setCurrentLayer(nextLayer);\n if (nextLayer.setVisible) {\n nextLayer.setVisible(true);\n } else {\n nextLayer.visible = true;\n }\n return;\n }\n // eslint-disable-next-line consistent-return\n return setSwitcherOpen(true) && setIsClosed(false);\n };\n\n const onLayerSelect = (layer, evt) => {\n if (onLayerButtonClick) {\n onLayerButtonClick(evt, layer);\n }\n if (!switcherOpen) {\n setSwitcherOpen(true);\n return;\n }\n setCurrentLayer(layer);\n if (layer.setVisible) {\n layer.setVisible(true);\n } else {\n // eslint-disable-next-line no-param-reassign\n layer.visible = true;\n }\n layers\n .filter((l) => {\n return l !== layer;\n })\n .forEach((l) => {\n if (l.setVisible) {\n l.setVisible(false);\n } else {\n // eslint-disable-next-line no-param-reassign\n l.visible = false;\n }\n });\n setSwitcherOpen(false);\n };\n\n /* Get next image for closed button */\n const nextImage = getNextImage(currentLayer, layers, images);\n\n useEffect(() => {\n /* Ensure correct layer is active on app load */\n if (currentLayer !== getVisibleLayer(layers)) {\n setCurrentLayer(getVisibleLayer(layers) || layers[0]);\n }\n }, [currentLayer, layers]);\n\n useEffect(() => {\n /* Used for correct layer image render with animation */\n let timeout;\n if (!switcherOpen) {\n timeout = setTimeout(() => {\n setIsClosed(true);\n }, 200);\n } else {\n timeout = setTimeout(() => {\n setIsClosed(false);\n }, 800);\n }\n return () => {\n return clearTimeout(timeout);\n };\n }, [switcherOpen]);\n\n useEffect(() => {\n // Update the layer selected when a visibility changes.\n const olKeys = (layers || []).map((layer) => {\n return layer.on(\"change:visible\", (evt) => {\n if (evt.target.visible && currentLayer !== evt.target) {\n setCurrentLayer(evt.target);\n }\n });\n });\n return () => {\n unByKey(olKeys);\n };\n }, [currentLayer, layers]);\n\n if (!layers || layers.length < 2 || !currentLayer) {\n return null;\n }\n\n return (\n <div className={`${className}${openClass}`}>\n <div\n aria-label={titles.openSwitcher}\n className={`rs-base-layer-switcher-button rs-opener${openClass}`}\n onClick={handleSwitcherClick}\n onKeyPress={(e) => {\n if (e.which === 13) {\n handleSwitcherClick();\n }\n }}\n role=\"button\"\n style={getImageStyle(nextImage)}\n tabIndex=\"0\"\n title={titles.openSwitcher}\n >\n <div className=\"rs-base-layer-switcher-title\">\n {layers.length !== 2\n ? titles.button\n : layers.find((layer) => {\n return !layer.visible;\n }) &&\n t(\n layers.find((layer) => {\n return !layer.visible;\n }).name,\n )}\n </div>\n {nextImage ? null : <span className=\"rs-alt-text\">{t(altText)}</span>}\n </div>\n {layers.map((layer, idx) => {\n const layerName = layer.name;\n const activeClass = layerName === currentLayer.name ? \" rs-active\" : \"\";\n const imageStyle = getImageStyle(\n layerImages ? layerImages[`${layer.key}`] : layer.get(\"previewImage\"),\n );\n return (\n <div\n className=\"rs-base-layer-switcher-btn-wrapper\"\n key={layer.key}\n style={{\n /* stylelint-disable-next-line value-keyword-case */\n overflow: hiddenStyle,\n /* stylelint-disable-next-line value-keyword-case */\n zIndex: layers.length - idx,\n }}\n >\n <div\n aria-label={t(layerName)}\n className={`rs-base-layer-switcher-button${openClass}`}\n onClick={(evt) => {\n return onLayerSelect(layer, evt);\n }}\n onKeyPress={(evt) => {\n if (evt.which === 13) {\n onLayerSelect(layer, evt);\n }\n }}\n role=\"button\"\n style={imageStyle}\n tabIndex={switcherOpen ? \"0\" : \"-1\"}\n title={t(layerName)}\n >\n <div className={`rs-base-layer-switcher-title${activeClass}`}>\n {t(layerName)}\n </div>\n {imageStyle ? null : (\n <span className=\"rs-alt-text\">{t(altText)}</span>\n )}\n </div>\n </div>\n );\n })}\n <CloseButton\n onClick={(evt) => {\n if (onCloseButtonClick) {\n onCloseButtonClick(evt);\n }\n setSwitcherOpen(false);\n }}\n tabIndex={switcherOpen ? \"0\" : \"-1\"}\n title={titles.closeSwitcher}\n >\n {closeButtonImage}\n </CloseButton>\n </div>\n );\n}\n\nBaseLayerSwitcher.propTypes = propTypes;\n\nexport default BaseLayerSwitcher;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { defaults as defaultInteractions } from "ol/interaction";
|
|
1
|
+
import { Layer } from "mobility-toolbox-js/ol";
|
|
2
|
+
import OLCollection from "ol/Collection";
|
|
4
3
|
import { equals } from "ol/extent";
|
|
4
|
+
import { defaults as defaultInteractions } from "ol/interaction";
|
|
5
|
+
import Interaction from "ol/interaction/Interaction";
|
|
5
6
|
import OLMap from "ol/Map";
|
|
6
|
-
import OLCollection from "ol/Collection";
|
|
7
|
-
import View from "ol/View";
|
|
8
7
|
import { unByKey } from "ol/Observable";
|
|
9
|
-
import
|
|
10
|
-
import
|
|
8
|
+
import View from "ol/View";
|
|
9
|
+
import PropTypes from "prop-types";
|
|
10
|
+
import React, { PureComponent } from "react";
|
|
11
11
|
const propTypes = {
|
|
12
12
|
/** Map animation options */
|
|
13
13
|
animationOptions: PropTypes.shape({
|
|
@@ -15,12 +15,23 @@ const propTypes = {
|
|
|
15
15
|
resolution: PropTypes.number,
|
|
16
16
|
zoom: PropTypes.number
|
|
17
17
|
}),
|
|
18
|
+
/** HTML aria-label. */
|
|
19
|
+
ariaLabel: PropTypes.string,
|
|
18
20
|
/** Center of the [ol/View](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html). */
|
|
19
21
|
center: PropTypes.arrayOf(PropTypes.number),
|
|
20
22
|
/** Class name of the map container */
|
|
21
23
|
className: PropTypes.string,
|
|
22
24
|
/** Map extent */
|
|
23
25
|
extent: PropTypes.arrayOf(PropTypes.number),
|
|
26
|
+
/**
|
|
27
|
+
* Optional options to pass on feature click. Passed to ol's 'getFeaturesAtPixel' method.
|
|
28
|
+
* https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html#getFeaturesAtPixel
|
|
29
|
+
*/
|
|
30
|
+
featuresClickOptions: PropTypes.shape({
|
|
31
|
+
checkWrapped: PropTypes.bool,
|
|
32
|
+
hitTolerance: PropTypes.number,
|
|
33
|
+
layerFilter: PropTypes.func
|
|
34
|
+
}),
|
|
24
35
|
/** Openlayers [fit options](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#fit) when extent is updated */
|
|
25
36
|
fitOptions: PropTypes.object,
|
|
26
37
|
/** Array of [ol/interaction](https://openlayers.org/en/latest/apidoc/module-ol_interaction_Interaction-Interaction.html). */
|
|
@@ -38,15 +49,6 @@ const propTypes = {
|
|
|
38
49
|
* @param {ol.MapBrowserEvent} event The singleclick [ol/MapBrowserEvent](https://openlayers.org/en/latest/apidoc/module-ol_MapBrowserEvent-MapBrowserEvent.html#event:singleclick).
|
|
39
50
|
*/
|
|
40
51
|
onFeaturesClick: PropTypes.func,
|
|
41
|
-
/**
|
|
42
|
-
* Optional options to pass on feature click. Passed to ol's 'getFeaturesAtPixel' method.
|
|
43
|
-
* https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html#getFeaturesAtPixel
|
|
44
|
-
*/
|
|
45
|
-
featuresClickOptions: PropTypes.shape({
|
|
46
|
-
layerFilter: PropTypes.func,
|
|
47
|
-
hitTolerance: PropTypes.number,
|
|
48
|
-
checkWrapped: PropTypes.bool
|
|
49
|
-
}),
|
|
50
52
|
/**
|
|
51
53
|
* Callback when a [ol/Feature](https://openlayers.org/en/latest/apidoc/module-ol_Feature-Feature.html) is hovered.
|
|
52
54
|
* @param {OLFeature[]} features An array of [ol/Feature](https://openlayers.org/en/latest/apidoc/module-ol_Feature-Feature.html).
|
|
@@ -60,17 +62,15 @@ const propTypes = {
|
|
|
60
62
|
onMapMoved: PropTypes.func,
|
|
61
63
|
/** Map resolution */
|
|
62
64
|
resolution: PropTypes.number,
|
|
63
|
-
/** The tabIndex of the map. */
|
|
64
|
-
tabIndex: PropTypes.number,
|
|
65
65
|
/** The style of the map. */
|
|
66
66
|
style: PropTypes.object,
|
|
67
|
-
/**
|
|
68
|
-
|
|
67
|
+
/** The tabIndex of the map. */
|
|
68
|
+
tabIndex: PropTypes.number,
|
|
69
69
|
/** [ol/View](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html) constructor options */
|
|
70
70
|
viewOptions: PropTypes.shape({
|
|
71
|
-
minZoom: PropTypes.number,
|
|
72
|
-
maxZoom: PropTypes.number,
|
|
73
71
|
extent: PropTypes.array,
|
|
72
|
+
maxZoom: PropTypes.number,
|
|
73
|
+
minZoom: PropTypes.number,
|
|
74
74
|
projection: PropTypes.string
|
|
75
75
|
}),
|
|
76
76
|
/** Map zoom level */
|
|
@@ -78,31 +78,31 @@ const propTypes = {
|
|
|
78
78
|
};
|
|
79
79
|
const defaultProps = {
|
|
80
80
|
animationOptions: void 0,
|
|
81
|
+
ariaLabel: "map",
|
|
81
82
|
center: [0, 0],
|
|
82
83
|
className: "rs-map",
|
|
83
84
|
extent: void 0,
|
|
85
|
+
featuresClickOptions: {
|
|
86
|
+
hitTolerance: 0
|
|
87
|
+
},
|
|
84
88
|
fitOptions: {
|
|
85
89
|
duration: 1e3,
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
maxZoom: 23,
|
|
91
|
+
padding: [20, 20, 20, 20]
|
|
88
92
|
},
|
|
89
|
-
style: void 0,
|
|
90
93
|
interactions: null,
|
|
91
94
|
layers: [],
|
|
92
95
|
map: null,
|
|
93
96
|
onFeaturesClick: void 0,
|
|
94
|
-
featuresClickOptions: {
|
|
95
|
-
hitTolerance: 0
|
|
96
|
-
},
|
|
97
97
|
onFeaturesHover: void 0,
|
|
98
98
|
onMapMoved: void 0,
|
|
99
99
|
resolution: void 0,
|
|
100
|
+
style: void 0,
|
|
100
101
|
tabIndex: void 0,
|
|
101
|
-
ariaLabel: "map",
|
|
102
102
|
viewOptions: {
|
|
103
|
-
minZoom: 0,
|
|
104
|
-
maxZoom: 22,
|
|
105
103
|
extent: void 0,
|
|
104
|
+
maxZoom: 22,
|
|
105
|
+
minZoom: 0,
|
|
106
106
|
projection: "EPSG:3857"
|
|
107
107
|
},
|
|
108
108
|
zoom: 1
|
|
@@ -110,7 +110,7 @@ const defaultProps = {
|
|
|
110
110
|
class BasicMap extends PureComponent {
|
|
111
111
|
constructor(props) {
|
|
112
112
|
super(props);
|
|
113
|
-
const {
|
|
113
|
+
const { interactions, map } = this.props;
|
|
114
114
|
this.map = map || new OLMap({
|
|
115
115
|
controls: [],
|
|
116
116
|
interactions: interactions || defaultInteractions({
|
|
@@ -127,10 +127,10 @@ class BasicMap extends PureComponent {
|
|
|
127
127
|
this.setNode = this.setNode.bind(this);
|
|
128
128
|
}
|
|
129
129
|
componentDidMount() {
|
|
130
|
-
const {
|
|
130
|
+
const { center, extent, layers, resolution, viewOptions, zoom } = this.props;
|
|
131
131
|
const { node } = this.state;
|
|
132
132
|
this.map.setTarget(node);
|
|
133
|
-
this.map.setView(new View({ ...viewOptions, center,
|
|
133
|
+
this.map.setView(new View({ ...viewOptions, center, resolution, zoom }));
|
|
134
134
|
const viewPort = this.map.getViewport();
|
|
135
135
|
viewPort.style.touchAction = "none";
|
|
136
136
|
viewPort.style.msTouchAction = "none";
|
|
@@ -150,12 +150,12 @@ class BasicMap extends PureComponent {
|
|
|
150
150
|
extent,
|
|
151
151
|
fitOptions,
|
|
152
152
|
layers,
|
|
153
|
+
onFeaturesClick,
|
|
154
|
+
onFeaturesHover,
|
|
155
|
+
onMapMoved,
|
|
153
156
|
resolution,
|
|
154
157
|
viewOptions,
|
|
155
|
-
zoom
|
|
156
|
-
onMapMoved,
|
|
157
|
-
onFeaturesClick,
|
|
158
|
-
onFeaturesHover
|
|
158
|
+
zoom
|
|
159
159
|
} = this.props;
|
|
160
160
|
const { node } = this.state;
|
|
161
161
|
if (prevState.node !== node) {
|
|
@@ -212,17 +212,6 @@ class BasicMap extends PureComponent {
|
|
|
212
212
|
componentWillUnmount() {
|
|
213
213
|
unByKey([this.moveEndRef, this.singleClickRef, this.pointerMoveRef]);
|
|
214
214
|
}
|
|
215
|
-
setNode(node) {
|
|
216
|
-
this.setState({ node });
|
|
217
|
-
}
|
|
218
|
-
setLayers(layers = [], prevLayers = []) {
|
|
219
|
-
for (let i = 0; i < prevLayers.length; i += 1) {
|
|
220
|
-
this.terminateLayer(prevLayers[i]);
|
|
221
|
-
}
|
|
222
|
-
for (let i = 0; i < layers.length; i += 1) {
|
|
223
|
-
this.initLayer(layers[i]);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
215
|
initLayer(layer) {
|
|
227
216
|
if (layer.attachToMap) {
|
|
228
217
|
layer.attachToMap(this.map);
|
|
@@ -238,21 +227,6 @@ class BasicMap extends PureComponent {
|
|
|
238
227
|
this.initLayer(layers[i]);
|
|
239
228
|
}
|
|
240
229
|
}
|
|
241
|
-
terminateLayer(layer) {
|
|
242
|
-
const layers = layer.children || [];
|
|
243
|
-
for (let i = 0; i < layers.length; i += 1) {
|
|
244
|
-
this.terminateLayer(layers[i]);
|
|
245
|
-
}
|
|
246
|
-
if (layer.olLayer && this.map.getLayers() && this.map.getLayers().getArray().includes(layer.olLayer)) {
|
|
247
|
-
this.map.removeLayer(layer.olLayer);
|
|
248
|
-
}
|
|
249
|
-
if (layer.terminate) {
|
|
250
|
-
layer.terminate(this.map);
|
|
251
|
-
}
|
|
252
|
-
if (layer.detachFromMap) {
|
|
253
|
-
layer.detachFromMap(this.map);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
230
|
listenMoveEnd() {
|
|
257
231
|
const { onMapMoved } = this.props;
|
|
258
232
|
unByKey(this.moveEndRef);
|
|
@@ -263,8 +237,19 @@ class BasicMap extends PureComponent {
|
|
|
263
237
|
return onMapMoved(evt);
|
|
264
238
|
});
|
|
265
239
|
}
|
|
240
|
+
listenPointerMove() {
|
|
241
|
+
const { onFeaturesHover } = this.props;
|
|
242
|
+
unByKey(this.pointerMoveRef);
|
|
243
|
+
if (!onFeaturesHover) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
this.pointerMoveRef = this.map.on("pointermove", (evt) => {
|
|
247
|
+
const features = evt.map.getFeaturesAtPixel(evt.pixel);
|
|
248
|
+
onFeaturesHover(features || [], evt);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
266
251
|
listenSingleClick() {
|
|
267
|
-
const {
|
|
252
|
+
const { featuresClickOptions, onFeaturesClick } = this.props;
|
|
268
253
|
unByKey(this.singleClickRef);
|
|
269
254
|
if (!onFeaturesClick) {
|
|
270
255
|
return;
|
|
@@ -277,31 +262,46 @@ class BasicMap extends PureComponent {
|
|
|
277
262
|
onFeaturesClick(features || [], evt);
|
|
278
263
|
});
|
|
279
264
|
}
|
|
280
|
-
listenPointerMove() {
|
|
281
|
-
const { onFeaturesHover } = this.props;
|
|
282
|
-
unByKey(this.pointerMoveRef);
|
|
283
|
-
if (!onFeaturesHover) {
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
this.pointerMoveRef = this.map.on("pointermove", (evt) => {
|
|
287
|
-
const features = evt.map.getFeaturesAtPixel(evt.pixel);
|
|
288
|
-
onFeaturesHover(features || [], evt);
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
265
|
render() {
|
|
292
|
-
const {
|
|
266
|
+
const { ariaLabel, className, style, tabIndex } = this.props;
|
|
293
267
|
return /* @__PURE__ */ React.createElement(
|
|
294
268
|
"div",
|
|
295
269
|
{
|
|
270
|
+
"aria-label": ariaLabel,
|
|
296
271
|
className,
|
|
297
272
|
ref: this.setNode,
|
|
298
273
|
role: "presentation",
|
|
299
|
-
|
|
300
|
-
tabIndex
|
|
301
|
-
style
|
|
274
|
+
style,
|
|
275
|
+
tabIndex
|
|
302
276
|
}
|
|
303
277
|
);
|
|
304
278
|
}
|
|
279
|
+
setLayers(layers = [], prevLayers = []) {
|
|
280
|
+
for (let i = 0; i < prevLayers.length; i += 1) {
|
|
281
|
+
this.terminateLayer(prevLayers[i]);
|
|
282
|
+
}
|
|
283
|
+
for (let i = 0; i < layers.length; i += 1) {
|
|
284
|
+
this.initLayer(layers[i]);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
setNode(node) {
|
|
288
|
+
this.setState({ node });
|
|
289
|
+
}
|
|
290
|
+
terminateLayer(layer) {
|
|
291
|
+
const layers = layer.children || [];
|
|
292
|
+
for (let i = 0; i < layers.length; i += 1) {
|
|
293
|
+
this.terminateLayer(layers[i]);
|
|
294
|
+
}
|
|
295
|
+
if (layer.olLayer && this.map.getLayers() && this.map.getLayers().getArray().includes(layer.olLayer)) {
|
|
296
|
+
this.map.removeLayer(layer.olLayer);
|
|
297
|
+
}
|
|
298
|
+
if (layer.terminate) {
|
|
299
|
+
layer.terminate(this.map);
|
|
300
|
+
}
|
|
301
|
+
if (layer.detachFromMap) {
|
|
302
|
+
layer.detachFromMap(this.map);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
305
|
}
|
|
306
306
|
BasicMap.propTypes = propTypes;
|
|
307
307
|
BasicMap.defaultProps = defaultProps;
|