react-spatial 1.5.2 → 1.5.3

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 (295) hide show
  1. package/.github/workflows/conventional-pr-title.yml +21 -0
  2. package/.github/workflows/main.yml +28 -0
  3. package/.husky/commit-msg +4 -0
  4. package/.husky/post-checkout +4 -0
  5. package/.husky/post-merge +4 -0
  6. package/.husky/post-rebase +4 -0
  7. package/.husky/pre-commit +4 -0
  8. package/.nvmrc +1 -0
  9. package/.whitesource +8 -0
  10. package/CHANGELOG.md +65 -0
  11. package/DEVELOP.md +113 -0
  12. package/__mocks__/mapbox-gl.js +11 -0
  13. package/__mocks__/resize-observer-polyfill.js +9 -0
  14. package/babel.config.js +3 -0
  15. package/commitlint.config.js +1 -0
  16. package/data/topic1.js +119 -0
  17. package/data/topic2.js +28 -0
  18. package/doc/README.md +21 -0
  19. package/doc/doc-config.json +4 -0
  20. package/package.json +4 -3
  21. package/pull_request_template.md +16 -0
  22. package/renovate.json +4 -0
  23. package/scripts/read-pkg-json.js +17 -0
  24. package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.js +322 -0
  25. package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.test.js +69 -0
  26. package/src/components/BaseLayerSwitcher/README.md +61 -0
  27. package/src/components/BaseLayerSwitcher/__snapshots__/BaseLayerSwitcher.test.js.snap +88 -0
  28. package/src/components/BaseLayerSwitcher/index.js +1 -0
  29. package/src/components/BasicMap/BasicMap.js +413 -0
  30. package/src/components/BasicMap/BasicMap.test.js +281 -0
  31. package/src/components/BasicMap/README.md +18 -0
  32. package/src/components/BasicMap/index.js +1 -0
  33. package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.js +320 -93
  34. package/src/components/CanvasSaveButton/CanvasSaveButton.test.js +148 -0
  35. package/src/components/CanvasSaveButton/README.md +76 -0
  36. package/src/components/CanvasSaveButton/__snapshots__/CanvasSaveButton.test.js.snap +76 -0
  37. package/src/components/CanvasSaveButton/index.js +1 -0
  38. package/src/components/Copyright/Copyright.js +89 -0
  39. package/src/components/Copyright/Copyright.test.js +134 -0
  40. package/src/components/Copyright/README.md +36 -0
  41. package/src/components/Copyright/index.js +1 -0
  42. package/src/components/FeatureExportButton/FeatureExportButton.js +118 -0
  43. package/src/components/FeatureExportButton/FeatureExportButton.test.js +417 -0
  44. package/src/components/FeatureExportButton/README.md +76 -0
  45. package/src/components/FeatureExportButton/__snapshots__/FeatureExportButton.test.js.snap +67 -0
  46. package/src/components/FeatureExportButton/index.js +1 -0
  47. package/src/components/FitExtent/FitExtent.js +62 -0
  48. package/src/components/FitExtent/FitExtent.test.js +48 -0
  49. package/src/components/FitExtent/README.md +34 -0
  50. package/src/components/FitExtent/__snapshots__/FitExtent.test.js.snap +13 -0
  51. package/src/components/FitExtent/index.js +1 -0
  52. package/{components → src/components}/Geolocation/Geolocation.js +144 -61
  53. package/src/components/Geolocation/Geolocation.test.js +267 -0
  54. package/src/components/Geolocation/README.md +25 -0
  55. package/src/components/Geolocation/__snapshots__/Geolocation.test.js.snap +92 -0
  56. package/src/components/Geolocation/index.js +1 -0
  57. package/src/components/LayerTree/LayerTree.js +487 -0
  58. package/src/components/LayerTree/LayerTree.test.js +337 -0
  59. package/src/components/LayerTree/README.md +92 -0
  60. package/src/components/LayerTree/__snapshots__/LayerTree.test.js.snap +1746 -0
  61. package/src/components/LayerTree/index.js +1 -0
  62. package/src/components/MousePosition/MousePosition.js +175 -0
  63. package/src/components/MousePosition/MousePosition.test.js +132 -0
  64. package/src/components/MousePosition/README.md +50 -0
  65. package/src/components/MousePosition/__snapshots__/MousePosition.test.js.snap +76 -0
  66. package/src/components/MousePosition/index.js +1 -0
  67. package/src/components/NorthArrow/NorthArrow.js +75 -0
  68. package/src/components/NorthArrow/NorthArrow.test.js +104 -0
  69. package/src/components/NorthArrow/README.md +59 -0
  70. package/src/components/NorthArrow/__snapshots__/NorthArrow.test.js.snap +117 -0
  71. package/src/components/NorthArrow/index.js +1 -0
  72. package/src/components/Overlay/Overlay.js +176 -0
  73. package/src/components/Overlay/Overlay.test.js +149 -0
  74. package/src/components/Overlay/README.md +59 -0
  75. package/src/components/Overlay/__snapshots__/Overlay.test.js.snap +9 -0
  76. package/src/components/Overlay/index.js +1 -0
  77. package/src/components/Permalink/Permalink.js +326 -0
  78. package/src/components/Permalink/Permalink.test.js +285 -0
  79. package/src/components/Permalink/README.md +105 -0
  80. package/src/components/Permalink/index.js +1 -0
  81. package/{components → src/components}/Popup/Popup.js +165 -55
  82. package/src/components/Popup/Popup.test.js +307 -0
  83. package/src/components/Popup/README.md +93 -0
  84. package/src/components/Popup/__snapshots__/Popup.test.js.snap +180 -0
  85. package/src/components/Popup/index.js +1 -0
  86. package/src/components/README.md +41 -0
  87. package/{components → src/components}/ResizeHandler/ResizeHandler.js +50 -15
  88. package/src/components/ResizeHandler/ResizeHandler.test.js +344 -0
  89. package/src/components/ResizeHandler/index.js +1 -0
  90. package/src/components/RouteSchedule/README.md +118 -0
  91. package/src/components/RouteSchedule/RouteSchedule.js +370 -0
  92. package/src/components/RouteSchedule/RouteSchedule.test.js +113 -0
  93. package/src/components/RouteSchedule/__snapshots__/RouteSchedule.test.js.snap +248 -0
  94. package/src/components/RouteSchedule/index.js +1 -0
  95. package/src/components/ScaleLine/README.md +29 -0
  96. package/src/components/ScaleLine/ScaleLine.js +50 -0
  97. package/src/components/ScaleLine/ScaleLine.test.js +30 -0
  98. package/src/components/ScaleLine/__snapshots__/ScaleLine.test.js.snap +7 -0
  99. package/src/components/ScaleLine/index.js +1 -0
  100. package/src/components/StopsFinder/README.md +50 -0
  101. package/src/components/StopsFinder/StopsFinder.js +284 -0
  102. package/src/components/StopsFinder/StopsFinder.test.js +17 -0
  103. package/src/components/StopsFinder/StopsFinderOption.js +61 -0
  104. package/src/components/StopsFinder/__snapshots__/StopsFinder.test.js.snap +133 -0
  105. package/src/components/StopsFinder/index.js +1 -0
  106. package/src/components/Zoom/README.md +25 -0
  107. package/src/components/Zoom/Zoom.js +180 -0
  108. package/src/components/Zoom/Zoom.test.js +141 -0
  109. package/src/components/Zoom/__snapshots__/Zoom.test.js.snap +201 -0
  110. package/src/components/Zoom/index.js +1 -0
  111. package/{propTypes.js → src/propTypes.js} +16 -12
  112. package/{setupTests.js → src/setupTests.js} +1 -1
  113. package/src/styleguidist/ComponentsList.js +52 -0
  114. package/src/styleguidist/StyleGuide.js +277 -0
  115. package/src/styleguidist/styleguidist.css +38 -0
  116. package/src/utils/GlobalsForOle.js +99 -0
  117. package/src/utils/KML.js +594 -0
  118. package/src/utils/KML.test.js +337 -0
  119. package/src/utils/KMLFormat.js +100 -0
  120. package/src/utils/KMLFormat.test.js +50 -0
  121. package/{utils → src/utils}/Styles.js +20 -14
  122. package/src/utils/__snapshots__/KML.test.js.snap.KML-readFeatures()-and-writeFeatures()-should-read-and-write-lineDash-and-fillPattern-style-for-polygon.canvas-image.png +0 -0
  123. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-2-(cross)-color-and-(light-blue)-opacity.canvas-image.png +0 -0
  124. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-3-(diagonal-line-from-bottom-left-tot-top-right)-with-color-(light-blue)-and-opacity.canvas-image.png +0 -0
  125. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-4-(diagonal-line-from-top-left-to-bottom-right)-with-color-(light-blue)-and-opacity.canvas-image.png +0 -0
  126. package/{utils → src/utils}/getPolygonPattern.js +34 -6
  127. package/src/utils/getPolygonPattern.test.js +61 -0
  128. package/src/utils/timeUtils.js +52 -0
  129. package/src/utils/timeUtils.test.js +30 -0
  130. package/styleguide.config.js +251 -0
  131. package/components/BaseLayerSwitcher/BaseLayerSwitcher.js +0 -231
  132. package/components/BaseLayerSwitcher/BaseLayerSwitcher.js.map +0 -7
  133. package/components/BaseLayerSwitcher/index.js +0 -1
  134. package/components/BaseLayerSwitcher/index.js.map +0 -7
  135. package/components/BasicMap/BasicMap.js +0 -278
  136. package/components/BasicMap/BasicMap.js.map +0 -7
  137. package/components/BasicMap/index.js +0 -1
  138. package/components/BasicMap/index.js.map +0 -7
  139. package/components/CanvasSaveButton/CanvasSaveButton.js.map +0 -7
  140. package/components/CanvasSaveButton/index.js +0 -1
  141. package/components/CanvasSaveButton/index.js.map +0 -7
  142. package/components/Copyright/Copyright.js +0 -55
  143. package/components/Copyright/Copyright.js.map +0 -7
  144. package/components/Copyright/index.js +0 -1
  145. package/components/Copyright/index.js.map +0 -7
  146. package/components/FeatureExportButton/FeatureExportButton.js +0 -62
  147. package/components/FeatureExportButton/FeatureExportButton.js.map +0 -7
  148. package/components/FeatureExportButton/index.js +0 -1
  149. package/components/FeatureExportButton/index.js.map +0 -7
  150. package/components/FitExtent/FitExtent.js +0 -32
  151. package/components/FitExtent/FitExtent.js.map +0 -7
  152. package/components/FitExtent/index.js +0 -1
  153. package/components/FitExtent/index.js.map +0 -7
  154. package/components/Geolocation/Geolocation.js.map +0 -7
  155. package/components/Geolocation/index.js +0 -1
  156. package/components/Geolocation/index.js.map +0 -7
  157. package/components/LayerTree/LayerTree.js +0 -278
  158. package/components/LayerTree/LayerTree.js.map +0 -7
  159. package/components/LayerTree/index.js +0 -1
  160. package/components/LayerTree/index.js.map +0 -7
  161. package/components/MousePosition/MousePosition.js +0 -110
  162. package/components/MousePosition/MousePosition.js.map +0 -7
  163. package/components/MousePosition/index.js +0 -1
  164. package/components/MousePosition/index.js.map +0 -7
  165. package/components/NorthArrow/NorthArrow.js +0 -43
  166. package/components/NorthArrow/NorthArrow.js.map +0 -7
  167. package/components/NorthArrow/index.js +0 -1
  168. package/components/NorthArrow/index.js.map +0 -7
  169. package/components/Overlay/Overlay.js +0 -122
  170. package/components/Overlay/Overlay.js.map +0 -7
  171. package/components/Overlay/index.js +0 -1
  172. package/components/Overlay/index.js.map +0 -7
  173. package/components/Permalink/Permalink.js +0 -206
  174. package/components/Permalink/Permalink.js.map +0 -7
  175. package/components/Permalink/index.js +0 -1
  176. package/components/Permalink/index.js.map +0 -7
  177. package/components/Popup/Popup.js.map +0 -7
  178. package/components/Popup/index.js +0 -1
  179. package/components/Popup/index.js.map +0 -7
  180. package/components/ResizeHandler/ResizeHandler.js.map +0 -7
  181. package/components/ResizeHandler/index.js +0 -1
  182. package/components/ResizeHandler/index.js.map +0 -7
  183. package/components/RouteSchedule/RouteSchedule.js +0 -220
  184. package/components/RouteSchedule/RouteSchedule.js.map +0 -7
  185. package/components/RouteSchedule/index.js +0 -1
  186. package/components/RouteSchedule/index.js.map +0 -7
  187. package/components/ScaleLine/ScaleLine.js +0 -32
  188. package/components/ScaleLine/ScaleLine.js.map +0 -7
  189. package/components/ScaleLine/index.js +0 -1
  190. package/components/ScaleLine/index.js.map +0 -7
  191. package/components/StopsFinder/StopsFinder.js +0 -210
  192. package/components/StopsFinder/StopsFinder.js.map +0 -7
  193. package/components/StopsFinder/StopsFinderOption.js +0 -51
  194. package/components/StopsFinder/StopsFinderOption.js.map +0 -7
  195. package/components/StopsFinder/index.js +0 -1
  196. package/components/StopsFinder/index.js.map +0 -7
  197. package/components/Zoom/Zoom.js +0 -130
  198. package/components/Zoom/Zoom.js.map +0 -7
  199. package/components/Zoom/index.js +0 -1
  200. package/components/Zoom/index.js.map +0 -7
  201. package/propTypes.js.map +0 -7
  202. package/setupTests.js.map +0 -7
  203. package/utils/GlobalsForOle.js +0 -94
  204. package/utils/GlobalsForOle.js.map +0 -7
  205. package/utils/KML.js +0 -412
  206. package/utils/KML.js.map +0 -7
  207. package/utils/KMLFormat.js +0 -69
  208. package/utils/KMLFormat.js.map +0 -7
  209. package/utils/Styles.js.map +0 -7
  210. package/utils/getPolygonPattern.js.map +0 -7
  211. package/utils/timeUtils.js +0 -31
  212. package/utils/timeUtils.js.map +0 -7
  213. /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.md.scss +0 -0
  214. /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.scss +0 -0
  215. /package/{components → src/components}/BasicMap/BasicMap.md.scss +0 -0
  216. /package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.md.scss +0 -0
  217. /package/{components → src/components}/Copyright/Copyright.md.scss +0 -0
  218. /package/{components → src/components}/FeatureExportButton/FeatureExportButton.md.scss +0 -0
  219. /package/{components → src/components}/FitExtent/FitExtent.md.scss +0 -0
  220. /package/{components → src/components}/Geolocation/Geolocation.md.scss +0 -0
  221. /package/{components → src/components}/Geolocation/Geolocation.scss +0 -0
  222. /package/{components → src/components}/LayerTree/LayerTree.md.scss +0 -0
  223. /package/{components → src/components}/LayerTree/LayerTree.scss +0 -0
  224. /package/{components → src/components}/MousePosition/MousePosition.md.scss +0 -0
  225. /package/{components → src/components}/NorthArrow/NorthArrow.scss +0 -0
  226. /package/{components → src/components}/Overlay/Overlay.md.scss +0 -0
  227. /package/{components → src/components}/Overlay/Overlay.scss +0 -0
  228. /package/{components → src/components}/Permalink/Permalink.md.scss +0 -0
  229. /package/{components → src/components}/Popup/Popup.md.scss +0 -0
  230. /package/{components → src/components}/Popup/Popup.scss +0 -0
  231. /package/{components → src/components}/RouteSchedule/RouteSchedule.md.scss +0 -0
  232. /package/{components → src/components}/RouteSchedule/RouteSchedule.scss +0 -0
  233. /package/{components → src/components}/ScaleLine/ScaleLine.scss +0 -0
  234. /package/{components → src/components}/Zoom/Zoom.md.scss +0 -0
  235. /package/{components → src/components}/Zoom/Zoom.scss +0 -0
  236. /package/{images → src/images}/RouteSchedule/firstStation.png +0 -0
  237. /package/{images → src/images}/RouteSchedule/lastStation.png +0 -0
  238. /package/{images → src/images}/RouteSchedule/line.png +0 -0
  239. /package/{images → src/images}/RouteSchedule/station.png +0 -0
  240. /package/{images → src/images}/baselayer/baselayer.basebright.png +0 -0
  241. /package/{images → src/images}/baselayer/baselayer.osm.png +0 -0
  242. /package/{images → src/images}/baselayer/baselayer.travic.png +0 -0
  243. /package/{images → src/images}/baselayer/open.topo.map.png +0 -0
  244. /package/{images → src/images}/baselayer/osm.baselayer.hot.png +0 -0
  245. /package/{images → src/images}/baselayer/osm.baselayer.png +0 -0
  246. /package/{images → src/images}/favicon.png +0 -0
  247. /package/{images → src/images}/geops_logo.png +0 -0
  248. /package/{images → src/images}/geops_logo.svg +0 -0
  249. /package/{images → src/images}/geops_qr.png +0 -0
  250. /package/{images → src/images}/mots/bus_poi-blue-01.svg +0 -0
  251. /package/{images → src/images}/mots/bus_poi-grey-01.svg +0 -0
  252. /package/{images → src/images}/mots/bus_round-blue-01.svg +0 -0
  253. /package/{images → src/images}/mots/bus_round-grey-01.svg +0 -0
  254. /package/{images → src/images}/mots/bus_square-blue-01.svg +0 -0
  255. /package/{images → src/images}/mots/bus_square-grey-01.svg +0 -0
  256. /package/{images → src/images}/mots/cable_car_poi-blue-01.svg +0 -0
  257. /package/{images → src/images}/mots/cable_car_poi-grey-01.svg +0 -0
  258. /package/{images → src/images}/mots/cable_car_round-blue-01.svg +0 -0
  259. /package/{images → src/images}/mots/cable_car_round-grey-01.svg +0 -0
  260. /package/{images → src/images}/mots/cable_car_square-blue-01.svg +0 -0
  261. /package/{images → src/images}/mots/cable_car_square-grey-01.svg +0 -0
  262. /package/{images → src/images}/mots/ferry_poi-blue-01.svg +0 -0
  263. /package/{images → src/images}/mots/ferry_poi-grey-01.svg +0 -0
  264. /package/{images → src/images}/mots/ferry_round-blue-01.svg +0 -0
  265. /package/{images → src/images}/mots/ferry_round-grey-01.svg +0 -0
  266. /package/{images → src/images}/mots/ferry_square-blue-01.svg +0 -0
  267. /package/{images → src/images}/mots/ferry_square-grey-01.svg +0 -0
  268. /package/{images → src/images}/mots/funicular_round-blue-01.svg +0 -0
  269. /package/{images → src/images}/mots/funicular_round-grey-01.svg +0 -0
  270. /package/{images → src/images}/mots/funicular_square-blue-01.svg +0 -0
  271. /package/{images → src/images}/mots/gondola_round-blue-01.svg +0 -0
  272. /package/{images → src/images}/mots/rail_poi-blue-01.svg +0 -0
  273. /package/{images → src/images}/mots/rail_poi-grey-01.svg +0 -0
  274. /package/{images → src/images}/mots/rail_round-blue-01.svg +0 -0
  275. /package/{images → src/images}/mots/rail_round-grey-01.svg +0 -0
  276. /package/{images → src/images}/mots/rail_square-blue-01.svg +0 -0
  277. /package/{images → src/images}/mots/rail_square-grey-01.svg +0 -0
  278. /package/{images → src/images}/mots/subway_round blue-01.svg +0 -0
  279. /package/{images → src/images}/mots/subway_round-blue-01.svg +0 -0
  280. /package/{images → src/images}/mots/tram_poi-blue-01.svg +0 -0
  281. /package/{images → src/images}/mots/tram_poi-grey-01.svg +0 -0
  282. /package/{images → src/images}/mots/tram_round-blue-01.svg +0 -0
  283. /package/{images → src/images}/mots/tram_round-grey-01.svg +0 -0
  284. /package/{images → src/images}/mots/tram_square-blue-01.svg +0 -0
  285. /package/{images → src/images}/mots/tram_square-grey-01.svg +0 -0
  286. /package/{images → src/images}/northArrow.svg +0 -0
  287. /package/{images → src/images}/northArrow.url.svg +0 -0
  288. /package/{images → src/images}/northArrowCircle.svg +0 -0
  289. /package/{images → src/images}/northArrowCircle.url.svg +0 -0
  290. /package/{themes → src/themes}/README.md +0 -0
  291. /package/{themes → src/themes}/default/components.scss +0 -0
  292. /package/{themes → src/themes}/default/examples.scss +0 -0
  293. /package/{themes → src/themes}/default/index.scss +0 -0
  294. /package/{themes → src/themes}/default/mixins.scss +0 -0
  295. /package/{themes → src/themes}/default/variables.scss +0 -0
@@ -0,0 +1 @@
1
+ export { default } from './LayerTree';
@@ -0,0 +1,175 @@
1
+ import React, { useState, useRef, useEffect, useCallback } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import OLMap from 'ol/Map';
4
+ import { createStringXY } from 'ol/coordinate';
5
+ import OLMousePosition from 'ol/control/MousePosition';
6
+
7
+ const propTypes = {
8
+ /**
9
+ * An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
10
+ */
11
+ map: PropTypes.instanceOf(OLMap).isRequired,
12
+
13
+ /**
14
+ * List of projections to display.
15
+ */
16
+ projections: PropTypes.arrayOf(
17
+ PropTypes.shape({
18
+ /**
19
+ * The label to display in the select box.
20
+ */
21
+ label: PropTypes.string.isRequired,
22
+
23
+ /**
24
+ * The value used to create the options´s projection of the MousePosition control.
25
+ * See [doc](https://openlayers.org/en/latest/apidoc/module-ol_control_MousePosition.html).
26
+ */
27
+ value: PropTypes.string.isRequired,
28
+
29
+ /**
30
+ * A function following the [CoordinateFormat](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~CoordinateFormat).
31
+ */
32
+ format: PropTypes.func,
33
+ }),
34
+ ),
35
+
36
+ /**
37
+ * The initially selected projection
38
+ */
39
+ projectionValue: PropTypes.shape({
40
+ /**
41
+ * The label to display in the select box.
42
+ */
43
+ label: PropTypes.string.isRequired,
44
+
45
+ /**
46
+ * The value used to create the options´s projection of the MousePosition control.
47
+ * See [doc](https://openlayers.org/en/latest/apidoc/module-ol_control_MousePosition.html).
48
+ */
49
+ value: PropTypes.string.isRequired,
50
+
51
+ /**
52
+ * A function following the [CoordinateFormat](https://openlayers.org/en/latest/apidoc/module-ol_coordinate.html#~CoordinateFormat).
53
+ */
54
+ format: PropTypes.func,
55
+ }),
56
+
57
+ /**
58
+ * Function triggered on projection's change event.
59
+ * @param {Event} event The change event object.
60
+ * @param {Object} projection The selected projection object.
61
+ */
62
+ onChange: PropTypes.func,
63
+ };
64
+
65
+ const defaultProps = {
66
+ onChange: () => {},
67
+ projections: [
68
+ {
69
+ label: 'EPSG:4326',
70
+ value: 'EPSG:4326',
71
+ },
72
+ {
73
+ label: 'EPSG:3857',
74
+ value: 'EPSG:3857',
75
+ },
76
+ ],
77
+ projectionValue: null,
78
+ };
79
+
80
+ /**
81
+ * The MousePosition component renders a select box with map projection options
82
+ * and the cursor position in coordinates using the selected projection.
83
+ */
84
+ function MousePosition({
85
+ map,
86
+ projections,
87
+ projectionValue,
88
+ onChange,
89
+ ...other
90
+ }) {
91
+ const [projection, setProjection] = useState(
92
+ projections &&
93
+ ((projectionValue &&
94
+ projections.find((p) => {
95
+ return p.value === projectionValue.value;
96
+ })) ||
97
+ projections[0]),
98
+ );
99
+ const [control, setControl] = useState();
100
+ const ref = useRef();
101
+
102
+ useEffect(() => {
103
+ const mousePosition = new OLMousePosition({
104
+ target: ref.current,
105
+ undefinedHTML: ' ',
106
+ className: '',
107
+ });
108
+ map.addControl(mousePosition);
109
+ setControl(mousePosition);
110
+
111
+ return () => {
112
+ map.removeControl(mousePosition);
113
+ };
114
+ }, [map]);
115
+
116
+ useEffect(() => {
117
+ if (!projection || !control) {
118
+ return;
119
+ }
120
+ control.setProjection(projection.value);
121
+ control.setCoordinateFormat(projection.format || createStringXY(4));
122
+ }, [projection, control]);
123
+
124
+ useEffect(() => {
125
+ if (projections) {
126
+ const proj =
127
+ (projectionValue &&
128
+ projections.find((p) => {
129
+ return p.value === projectionValue.value;
130
+ })) ||
131
+ projections[0];
132
+ setProjection(proj);
133
+ }
134
+ }, [projections, projectionValue]);
135
+
136
+ const onChangeCb = useCallback(
137
+ (evt) => {
138
+ const newProj = projections.find((opt) => {
139
+ return evt.target.value === opt.value;
140
+ });
141
+ setProjection(newProj);
142
+ onChange(evt, newProj);
143
+ },
144
+ [onChange, projections],
145
+ );
146
+
147
+ if (!projection || !projections || !projections.length) {
148
+ return null;
149
+ }
150
+
151
+ return (
152
+ // eslint-disable-next-line react/jsx-props-no-spreading
153
+ <div className="rs-mouse-position" {...other}>
154
+ <select
155
+ className="rs-select"
156
+ value={projection.value}
157
+ onChange={onChangeCb}
158
+ >
159
+ {projections.map((option) => {
160
+ return (
161
+ <option key={option.value} value={option.value}>
162
+ {option.label}
163
+ </option>
164
+ );
165
+ })}
166
+ </select>
167
+ <span ref={ref} className="rs-coordinates" />
168
+ </div>
169
+ );
170
+ }
171
+
172
+ MousePosition.propTypes = propTypes;
173
+ MousePosition.defaultProps = defaultProps;
174
+
175
+ export default React.memo(MousePosition);
@@ -0,0 +1,132 @@
1
+ /* eslint-disable react/jsx-props-no-spreading */
2
+ import React from 'react';
3
+ import renderer from 'react-test-renderer';
4
+ import { configure, mount } from 'enzyme';
5
+ import Adapter from '@cfaester/enzyme-adapter-react-18';
6
+ import 'jest-canvas-mock';
7
+ import OLMap from 'ol/Map';
8
+ import OLMousePosition from 'ol/control/MousePosition';
9
+ import MousePosition from './MousePosition';
10
+
11
+ configure({ adapter: new Adapter() });
12
+ const expectSnapshot = (props) => {
13
+ const map = new OLMap({});
14
+ const component = renderer.create(<MousePosition map={map} {...props} />);
15
+ const tree = component.toJSON();
16
+ expect(tree).toMatchSnapshot();
17
+ };
18
+
19
+ describe('MousePosition', () => {
20
+ describe('matches snapshots', () => {
21
+ test('using default values.', () => {
22
+ expectSnapshot({});
23
+ });
24
+
25
+ test('using no projections.', () => {
26
+ expectSnapshot({
27
+ projections: [],
28
+ });
29
+ });
30
+
31
+ test('using only one projection', () => {
32
+ expectSnapshot({
33
+ projections: [{ label: 'foo', value: 'foo' }],
34
+ });
35
+ });
36
+
37
+ test('using multiple projections.', () => {
38
+ expectSnapshot({
39
+ projections: [
40
+ { label: 'foo', value: 'foo' },
41
+ { label: 'bar', value: 'bar' },
42
+ ],
43
+ });
44
+ });
45
+ });
46
+
47
+ test('add MousePosition control to the map.', () => {
48
+ const map = new OLMap({});
49
+ const spy = jest.spyOn(map, 'removeControl');
50
+ const spy2 = jest.spyOn(map, 'addControl');
51
+ const fn = jest.fn();
52
+ mount(
53
+ <MousePosition
54
+ map={map}
55
+ projections={[
56
+ {
57
+ label: 'EPSG:4326',
58
+ value: 'EPSG:4326',
59
+ format: fn,
60
+ },
61
+ ]}
62
+ />,
63
+ );
64
+ const ctrl = spy2.mock.calls[0][0];
65
+ expect(spy).toHaveBeenCalledTimes(0);
66
+ expect(spy2).toHaveBeenCalledTimes(1);
67
+ expect(ctrl).toBeInstanceOf(OLMousePosition);
68
+ expect(ctrl.getProjection().getCode()).toBe('EPSG:4326');
69
+ expect(ctrl.getCoordinateFormat()).toBe(fn);
70
+ });
71
+
72
+ test('add/remove MousePosition control on mount/unmount.', () => {
73
+ const map = new OLMap({});
74
+ const spy = jest.spyOn(map, 'removeControl');
75
+ const spy2 = jest.spyOn(map, 'addControl');
76
+ const wrapper = mount(<MousePosition map={map} />);
77
+ expect(spy).toHaveBeenCalledTimes(0);
78
+ expect(spy2).toHaveBeenCalledTimes(1);
79
+ wrapper.unmount();
80
+ expect(spy).toHaveBeenCalledTimes(1);
81
+ expect(spy.mock.calls[0][0]).toBe(spy2.mock.calls[0][0]);
82
+ });
83
+
84
+ test('triggers onChange when select projection.', () => {
85
+ const map = new OLMap({});
86
+ const onChange = jest.fn(() => {});
87
+ const wrapper = mount(
88
+ <MousePosition
89
+ map={map}
90
+ onChange={onChange}
91
+ projections={[
92
+ {
93
+ label: 'EPSG:4326',
94
+ value: 'EPSG:4326',
95
+ format: jest.fn(),
96
+ },
97
+ ]}
98
+ />,
99
+ );
100
+ // onChange triggered on instantiation.
101
+ expect(onChange).toHaveBeenCalledTimes(0);
102
+ wrapper.find('select').simulate('change', {});
103
+ expect(onChange).toHaveBeenCalledTimes(1);
104
+ });
105
+
106
+ test('applies new format and value when we select a new projection.', () => {
107
+ const map = new OLMap({});
108
+ const spy = jest.spyOn(map, 'addControl');
109
+ const projs = [
110
+ {
111
+ label: 'EPSG:4326',
112
+ value: 'EPSG:4326',
113
+ format: jest.fn(),
114
+ },
115
+ {
116
+ label: 'EPSG:3857',
117
+ value: 'EPSG:3857',
118
+ format: jest.fn(),
119
+ },
120
+ ];
121
+ const wrapper = mount(<MousePosition map={map} projections={projs} />);
122
+
123
+ const ctrl = spy.mock.calls[0][0];
124
+ expect(ctrl.getProjection().getCode()).toBe(projs[0].value);
125
+ expect(ctrl.getCoordinateFormat()).toBe(projs[0].format);
126
+ wrapper
127
+ .find('select')
128
+ .simulate('change', { target: { value: 'EPSG:3857' } });
129
+ expect(ctrl.getProjection().getCode()).toBe(projs[1].value);
130
+ expect(ctrl.getCoordinateFormat()).toBe(projs[1].format);
131
+ });
132
+ });
@@ -0,0 +1,50 @@
1
+
2
+ The following example demonstrates the use of MousePosition.
3
+
4
+ ```jsx
5
+ import React from 'react';
6
+ import { MapboxLayer } from 'mobility-toolbox-js/ol';
7
+ import Tile from 'ol/layer/Tile';
8
+ import OSM from 'ol/source/OSM';
9
+ import Map from 'ol/Map';
10
+ import BasicMap from 'react-spatial/components/BasicMap';
11
+ import MousePosition from 'react-spatial/components/MousePosition';
12
+
13
+ const map = new Map({ controls: [] });
14
+
15
+ const layers = [
16
+ new MapboxLayer({
17
+ url: `https://maps.geops.io/styles/travic_v2/style.json?key=${apiKey}`,
18
+ }),
19
+ ];
20
+
21
+ <div className="rs-mouse-position-example">
22
+ <BasicMap map={map} center={[1149722.7037660484, 6618091.313553318]} zoom={6} layers={layers} tabIndex={0} />
23
+ <MousePosition
24
+ map={map}
25
+ projections={[
26
+ {
27
+ label: 'World Geodetic System 1984',
28
+ value: 'EPSG:4326',
29
+ },
30
+ {
31
+ label: 'Web mercator with custom output',
32
+ value: 'EPSG:3857',
33
+ format: coordinates => {
34
+ const decimals = 4;
35
+ const text = [];
36
+ coordinates.forEach(input => {
37
+ const coord =
38
+ Math.round(parseFloat(input) * 10 ** decimals) /
39
+ 10 ** decimals;
40
+ const parts = coord.toString().split('.');
41
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, "'");
42
+ text.push(parts.join());
43
+ });
44
+ return `Coordinates: ${text.join(' ')}`;
45
+ },
46
+ },
47
+ ]}
48
+ />
49
+ </div>
50
+ ```
@@ -0,0 +1,76 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`MousePosition matches snapshots using default values. 1`] = `
4
+ <div
5
+ className="rs-mouse-position"
6
+ >
7
+ <select
8
+ className="rs-select"
9
+ onChange={[Function]}
10
+ value="EPSG:4326"
11
+ >
12
+ <option
13
+ value="EPSG:4326"
14
+ >
15
+ EPSG:4326
16
+ </option>
17
+ <option
18
+ value="EPSG:3857"
19
+ >
20
+ EPSG:3857
21
+ </option>
22
+ </select>
23
+ <span
24
+ className="rs-coordinates"
25
+ />
26
+ </div>
27
+ `;
28
+
29
+ exports[`MousePosition matches snapshots using multiple projections. 1`] = `
30
+ <div
31
+ className="rs-mouse-position"
32
+ >
33
+ <select
34
+ className="rs-select"
35
+ onChange={[Function]}
36
+ value="foo"
37
+ >
38
+ <option
39
+ value="foo"
40
+ >
41
+ foo
42
+ </option>
43
+ <option
44
+ value="bar"
45
+ >
46
+ bar
47
+ </option>
48
+ </select>
49
+ <span
50
+ className="rs-coordinates"
51
+ />
52
+ </div>
53
+ `;
54
+
55
+ exports[`MousePosition matches snapshots using no projections. 1`] = `null`;
56
+
57
+ exports[`MousePosition matches snapshots using only one projection 1`] = `
58
+ <div
59
+ className="rs-mouse-position"
60
+ >
61
+ <select
62
+ className="rs-select"
63
+ onChange={[Function]}
64
+ value="foo"
65
+ >
66
+ <option
67
+ value="foo"
68
+ >
69
+ foo
70
+ </option>
71
+ </select>
72
+ <span
73
+ className="rs-coordinates"
74
+ />
75
+ </div>
76
+ `;
@@ -0,0 +1 @@
1
+ export { default } from './MousePosition';
@@ -0,0 +1,75 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import OLMap from 'ol/Map';
4
+ import { unByKey } from 'ol/Observable';
5
+ import { toDegrees } from 'ol/math';
6
+ import NorthArrowSimple from '../../images/northArrow.svg';
7
+ import NorthArrowCircle from '../../images/northArrowCircle.svg';
8
+
9
+ const propTypes = {
10
+ /**
11
+ * An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
12
+ */
13
+ map: PropTypes.instanceOf(OLMap).isRequired,
14
+
15
+ /**
16
+ * Rotation of the north arrow in degrees.
17
+ */
18
+ rotationOffset: PropTypes.number,
19
+
20
+ /**
21
+ * Display circle around the north arrow. Not used if pass children.
22
+ */
23
+ circled: PropTypes.bool,
24
+
25
+ /**
26
+ * Children content of the north arrow.
27
+ */
28
+ children: PropTypes.node,
29
+ };
30
+
31
+ const defaultProps = {
32
+ rotationOffset: 0,
33
+ circled: false,
34
+ children: null,
35
+ };
36
+
37
+ const getRotation = (map, rotationOffset) => {
38
+ return toDegrees(map.getView().getRotation()) + rotationOffset;
39
+ };
40
+
41
+ /**
42
+ * This NorthArrow component inserts an arrow pointing north into an
43
+ * [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
44
+ */
45
+ function NorthArrow({ map, rotationOffset, circled, children, ...other }) {
46
+ const [rotation, setRotation] = useState(rotationOffset);
47
+
48
+ useEffect(() => {
49
+ if (!map) {
50
+ return null;
51
+ }
52
+ const key = map.on('postrender', () => {
53
+ setRotation(getRotation(map, rotationOffset));
54
+ });
55
+ return () => {
56
+ unByKey(key);
57
+ };
58
+ }, [map, rotationOffset]);
59
+
60
+ return (
61
+ <div
62
+ className="rs-north-arrow"
63
+ // eslint-disable-next-line react/jsx-props-no-spreading
64
+ {...other}
65
+ style={{ transform: `rotate(${rotation}deg)` }}
66
+ >
67
+ {children || (circled ? <NorthArrowCircle /> : <NorthArrowSimple />)}
68
+ </div>
69
+ );
70
+ }
71
+
72
+ NorthArrow.propTypes = propTypes;
73
+ NorthArrow.defaultProps = defaultProps;
74
+
75
+ export default React.memo(NorthArrow);
@@ -0,0 +1,104 @@
1
+ import 'jest-canvas-mock';
2
+ import React from 'react';
3
+ import renderer from 'react-test-renderer';
4
+ import { act } from 'react-dom/test-utils';
5
+ import { configure, mount } from 'enzyme';
6
+ import Adapter from '@cfaester/enzyme-adapter-react-18';
7
+ import MapEvent from 'ol/MapEvent';
8
+ import OLMap from 'ol/Map';
9
+ import OLView from 'ol/View';
10
+ import { TiImage } from 'react-icons/ti';
11
+ import NorthArrow from './NorthArrow';
12
+
13
+ configure({ adapter: new Adapter() });
14
+ let olView;
15
+ let olMap;
16
+
17
+ describe('NorthArrow', () => {
18
+ beforeEach(() => {
19
+ olView = new OLView();
20
+ olMap = new OLMap({ view: olView });
21
+ });
22
+
23
+ test('should match snapshot with default value.', () => {
24
+ let component;
25
+ renderer.act(() => {
26
+ component = renderer.create(<NorthArrow map={olMap} />);
27
+ });
28
+ const tree = component.toJSON();
29
+ expect(tree).toMatchSnapshot();
30
+ });
31
+
32
+ test('should match snapshot with custom attributes.', () => {
33
+ let component;
34
+ renderer.act(() => {
35
+ component = renderer.create(
36
+ <NorthArrow map={olMap} className="test-class" tabIndex={0} />,
37
+ );
38
+ });
39
+ const tree = component.toJSON();
40
+ expect(tree).toMatchSnapshot();
41
+ });
42
+
43
+ test('should match snapshot with children.', () => {
44
+ let component;
45
+ renderer.act(() => {
46
+ component = renderer.create(
47
+ <NorthArrow map={olMap}>
48
+ <TiImage />
49
+ </NorthArrow>,
50
+ );
51
+ });
52
+ const tree = component.toJSON();
53
+ expect(tree).toMatchSnapshot();
54
+ });
55
+
56
+ test('should match snapshot rotated.', () => {
57
+ let component;
58
+ renderer.act(() => {
59
+ component = renderer.create(
60
+ <NorthArrow map={olMap} rotationOffset={45} />,
61
+ );
62
+ });
63
+ const tree = component.toJSON();
64
+ expect(tree).toMatchSnapshot();
65
+ });
66
+
67
+ test('should match snapshot with circle.', () => {
68
+ let component;
69
+ renderer.act(() => {
70
+ component = renderer.create(<NorthArrow circled map={olMap} />);
71
+ });
72
+ const tree = component.toJSON();
73
+ expect(tree).toMatchSnapshot();
74
+ });
75
+
76
+ test('should react on view rotation (transform: `rotate(20deg)`)', () => {
77
+ const wrapper = mount(<NorthArrow map={olMap} />);
78
+ // Trigger view rotation
79
+ olMap.getView().setRotation(0.3490658503988659);
80
+ act(() => {
81
+ olMap.dispatchEvent(new MapEvent('postrender', olMap));
82
+ // 20 degrees = 0.3490658503988659 radians
83
+ });
84
+ expect(wrapper.html()).toMatchSnapshot();
85
+ });
86
+
87
+ test('should react on view rotation with offset (transform: `rotate(10deg)`)', () => {
88
+ const wrapper = mount(<NorthArrow map={olMap} rotationOffset={-10} />);
89
+ olMap.getView().setRotation(0.3490658503988659);
90
+ act(() => {
91
+ olMap.dispatchEvent(new MapEvent('postrender', olMap));
92
+ });
93
+ expect(wrapper.html()).toMatchSnapshot();
94
+ });
95
+
96
+ test('should remove post render event on unmount', () => {
97
+ const wrapper = mount(<NorthArrow map={olMap} rotationOffset={-10} />);
98
+ // eslint-disable-next-line no-underscore-dangle
99
+ expect(olMap.listeners_.postrender.length).toBe(4);
100
+ wrapper.unmount();
101
+ // eslint-disable-next-line no-underscore-dangle
102
+ expect(olMap.listeners_.postrender.length).toBe(3);
103
+ });
104
+ });
@@ -0,0 +1,59 @@
1
+
2
+ The following example demonstrates the use of NorthArrowExample (Alt + Shift + click to rotate).
3
+
4
+ ```jsx
5
+ import React from 'react';
6
+ import { Layer } from 'mobility-toolbox-js/ol';
7
+ import Map from 'ol/Map';
8
+ import { DragRotate, defaults } from 'ol/interaction';
9
+ import Tile from 'ol/layer/Tile';
10
+ import TileGrid from 'ol/tilegrid/TileGrid';
11
+ import TileImageSource from 'ol/source/TileImage';
12
+ import { getCenter} from 'ol/extent';
13
+ import BasicMap from 'react-spatial/components/BasicMap';
14
+ import NorthArrow from 'react-spatial/components/NorthArrow';
15
+
16
+ const extent = [599500, 199309, 600714, 200002];
17
+
18
+ const map = new Map({ controls: [] });
19
+
20
+ const layers = [
21
+ new Layer({
22
+ olLayer: new Tile({
23
+ extent,
24
+ source: new TileImageSource({
25
+ tileUrlFunction: c =>
26
+ '//plans.trafimage.ch/static/tiles/' +
27
+ `bern_aussenplan/${c[0]}/${c[1]}/${-c[2]-1}.png`,
28
+ tileGrid: new TileGrid({
29
+ origin: [extent[0], extent[1]],
30
+ resolutions: [
31
+ 6.927661,
32
+ 3.4638305,
33
+ 1.73191525,
34
+ 0.865957625,
35
+ 0.4329788125,
36
+ 0.21648940625,
37
+ 0.108244703125,
38
+ ],
39
+ }),
40
+ }),
41
+ }),
42
+ }),
43
+ ];
44
+
45
+ <div style={{position:'relative'}}>
46
+ <BasicMap
47
+ map={map}
48
+ center={getCenter(extent)}
49
+ zoom={17}
50
+ layers={layers}
51
+ tabIndex={0}
52
+ />
53
+ <NorthArrow
54
+ map={map}
55
+ rotationOffset={20}
56
+ circled
57
+ />
58
+ </div>;
59
+ ```