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,34 @@
1
+
2
+ The following example demonstrates the use of FitExtent.
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 { geopsTheme, Header, Footer } from '@geops/geops-ui';
11
+ import { ThemeProvider } from '@material-ui/core/styles';
12
+ import Button from '@material-ui/core/Button';
13
+ import FitExtent from 'react-spatial/components/FitExtent';
14
+ import BasicMap from 'react-spatial/components/BasicMap';
15
+
16
+ const extent = [-15380353.1391, 2230738.2886, -6496535.908, 6927029.2369];
17
+
18
+ const map = new Map({ controls: [] });
19
+
20
+ const layers = [
21
+ new MapboxLayer({
22
+ url: `https://maps.geops.io/styles/travic_v2/style.json?key=${apiKey}`,
23
+ }),
24
+ ];
25
+
26
+ <ThemeProvider theme={geopsTheme}>
27
+ <BasicMap map={map} layers={layers} tabIndex={0} />
28
+ <FitExtent map={map} extent={extent}>
29
+ <Button>
30
+ Fit to US
31
+ </Button>
32
+ </FitExtent>
33
+ </ThemeProvider>
34
+ ```
@@ -0,0 +1,13 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Button should match snapshot. 1`] = `
4
+ <div
5
+ className="rs-fit-extent"
6
+ onClick={[Function]}
7
+ onKeyPress={[Function]}
8
+ role="button"
9
+ tabIndex="0"
10
+ >
11
+ FitExtent
12
+ </div>
13
+ `;
@@ -0,0 +1 @@
1
+ export { default } from './FitExtent';
@@ -1,68 +1,119 @@
1
- import React, { PureComponent } from "react";
2
- import PropTypes from "prop-types";
3
- import OLMap from "ol/Map";
4
- import { transform } from "ol/proj";
5
- import Point from "ol/geom/Point";
6
- import Feature from "ol/Feature";
7
- import { unByKey } from "ol/Observable";
8
- import Style from "ol/style/Style";
9
- import Circle from "ol/style/Circle";
10
- import Fill from "ol/style/Fill";
11
- import Stroke from "ol/style/Stroke";
12
- import VectorLayer from "ol/layer/Vector";
13
- import VectorSource from "ol/source/Vector";
14
- import { FaRegDotCircle } from "react-icons/fa";
1
+ import React, { PureComponent } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import OLMap from 'ol/Map';
5
+ import { transform } from 'ol/proj';
6
+ import Point from 'ol/geom/Point';
7
+ import Feature from 'ol/Feature';
8
+ import { unByKey } from 'ol/Observable';
9
+
10
+ import Style from 'ol/style/Style';
11
+ import Circle from 'ol/style/Circle';
12
+ import Fill from 'ol/style/Fill';
13
+ import Stroke from 'ol/style/Stroke';
14
+
15
+ import VectorLayer from 'ol/layer/Vector';
16
+ import VectorSource from 'ol/source/Vector';
17
+
18
+ import { FaRegDotCircle } from 'react-icons/fa';
19
+
15
20
  const propTypes = {
21
+ /**
22
+ * CSS class of the button.
23
+ */
16
24
  className: PropTypes.string,
25
+
26
+ /**
27
+ * Children content of the Geolocation button.
28
+ */
17
29
  children: PropTypes.node,
30
+
31
+ /**
32
+ * An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
33
+ */
18
34
  map: PropTypes.instanceOf(OLMap).isRequired,
35
+
36
+ /**
37
+ * Function triggered when geolocating is not successful.
38
+ */
19
39
  onError: PropTypes.func,
40
+
41
+ /**
42
+ * Function triggered after successful geoLocation calls. Takes the ol/map, the current lat/lon coordinate and the component instance as arguments.
43
+ */
20
44
  onSuccess: PropTypes.func,
45
+
46
+ /**
47
+ * Function triggered after the geolocation is activated. Takes the ol/map and the component instance as arguments.
48
+ */
21
49
  onActivate: PropTypes.func,
50
+
51
+ /**
52
+ * Function triggered after the geolocation is deactivated. Takes the ol/map and the component instance as arguments..
53
+ */
22
54
  onDeactivate: PropTypes.func,
55
+
56
+ /**
57
+ * If true, the map is not centered after it has been dragged once.
58
+ */
23
59
  noCenterAfterDrag: PropTypes.bool,
60
+
61
+ /**
62
+ * If true, the map will constantly recenter to the current Position
63
+ */
24
64
  alwaysRecenterToPosition: PropTypes.bool,
65
+
66
+ /**
67
+ * Color (Number array with rgb values) or style function.
68
+ * If a color is given, the style is animated.
69
+ */
25
70
  colorOrStyleFunc: PropTypes.oneOfType([
26
71
  PropTypes.arrayOf(PropTypes.number),
27
- PropTypes.func
28
- ])
72
+ PropTypes.func,
73
+ ]),
29
74
  };
75
+
30
76
  const defaultProps = {
31
- className: "rs-geolocation",
32
- children: /* @__PURE__ */ React.createElement(FaRegDotCircle, {
33
- focusable: false
34
- }),
35
- onError: () => {
36
- },
37
- onSuccess: () => {
38
- },
39
- onActivate: () => {
40
- },
41
- onDeactivate: () => {
42
- },
77
+ className: 'rs-geolocation',
78
+ children: <FaRegDotCircle focusable={false} />,
79
+ onError: () => {},
80
+ onSuccess: () => {},
81
+ onActivate: () => {},
82
+ onDeactivate: () => {},
43
83
  noCenterAfterDrag: false,
44
84
  alwaysRecenterToPosition: true,
45
- colorOrStyleFunc: [235, 0, 0]
85
+ colorOrStyleFunc: [235, 0, 0],
46
86
  };
87
+
88
+ /**
89
+ * The GeoLocation component creates a button to display the current device's location on an
90
+ * [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
91
+ */
47
92
  class Geolocation extends PureComponent {
48
93
  constructor(props) {
49
94
  super(props);
95
+
50
96
  this.layer = new VectorLayer({
51
- source: new VectorSource()
97
+ source: new VectorSource(),
52
98
  });
99
+
53
100
  this.isRecenteringToPosition = true;
101
+
54
102
  this.state = {
55
- active: false
103
+ active: false,
56
104
  };
57
- this.point = void 0;
105
+ this.point = undefined;
58
106
  }
107
+
59
108
  componentWillUnmount() {
60
109
  this.deactivate();
61
110
  }
111
+
62
112
  toggle() {
63
113
  const { active } = this.state;
64
114
  const { onError } = this.props;
65
- const geolocation = "geolocation" in navigator;
115
+ const geolocation = 'geolocation' in navigator;
116
+
66
117
  if (!geolocation) {
67
118
  onError();
68
119
  } else if (!active) {
@@ -71,71 +122,89 @@ class Geolocation extends PureComponent {
71
122
  this.deactivate();
72
123
  }
73
124
  }
125
+
74
126
  error() {
75
127
  const { onError } = this.props;
128
+
76
129
  this.deactivate();
77
130
  onError();
78
131
  }
132
+
79
133
  deactivate() {
80
134
  const { map, onDeactivate } = this.props;
81
135
  window.clearInterval(this.interval);
82
136
  this.layer.setMap(null);
83
137
  navigator.geolocation.clearWatch(this.watch);
138
+
84
139
  this.setState({
85
- active: false
140
+ active: false,
86
141
  });
142
+
87
143
  this.isRecenteringToPosition = true;
88
- this.point = void 0;
144
+ this.point = undefined;
89
145
  onDeactivate(map, this);
90
146
  unByKey(this.dragListener);
91
147
  }
148
+
92
149
  activate() {
93
150
  const { map, noCenterAfterDrag, onActivate } = this.props;
151
+
94
152
  this.projection = map.getView().getProjection().getCode();
95
153
  this.point = new Point([0, 0]);
96
154
  this.highlight();
97
155
  this.layer.setMap(map);
98
156
  this.setState({ active: true });
157
+
99
158
  this.watch = navigator.geolocation.watchPosition(
100
159
  this.update.bind(this),
101
160
  this.error.bind(this),
102
161
  {
103
- enableHighAccuracy: true
104
- }
162
+ enableHighAccuracy: true,
163
+ },
105
164
  );
165
+
106
166
  if (noCenterAfterDrag) {
107
- this.dragListener = map.on("pointerdrag", () => {
167
+ this.dragListener = map.on('pointerdrag', () => {
108
168
  this.isRecenteringToPosition = false;
109
169
  });
110
170
  }
171
+
111
172
  onActivate(map, this);
112
173
  }
174
+
113
175
  update({ coords: { latitude, longitude } }) {
114
176
  const { map, alwaysRecenterToPosition, onSuccess } = this.props;
177
+
115
178
  const position = transform(
116
179
  [longitude, latitude],
117
- "EPSG:4326",
118
- this.projection
180
+ 'EPSG:4326',
181
+ this.projection,
119
182
  );
120
183
  this.point.setCoordinates(position);
184
+
121
185
  if (this.isRecenteringToPosition) {
122
186
  map.getView().setCenter(position);
123
187
  if (!alwaysRecenterToPosition) {
124
188
  this.isRecenteringToPosition = false;
125
189
  }
126
190
  }
191
+
127
192
  onSuccess(map, [latitude, longitude], this);
128
193
  }
194
+
129
195
  highlight() {
130
196
  const { colorOrStyleFunc } = this.props;
131
197
  const feature = new Feature({
132
- geometry: this.point
198
+ geometry: this.point,
133
199
  });
200
+
134
201
  if (Array.isArray(colorOrStyleFunc)) {
135
202
  const color = colorOrStyleFunc;
203
+
136
204
  let decrease = true;
137
205
  let opacity = 0.5;
138
206
  let rotation = 0;
207
+
139
208
  window.clearInterval(this.interval);
140
209
  this.interval = window.setInterval(() => {
141
210
  rotation += 0.03;
@@ -146,60 +215,74 @@ class Geolocation extends PureComponent {
146
215
  feature.changed();
147
216
  }
148
217
  }, 50);
218
+
149
219
  feature.setStyle(() => {
150
220
  const circleStyle = new Style({
151
221
  image: new Circle({
152
222
  radius: 20,
153
223
  rotation,
154
224
  fill: new Fill({
155
- color: "rgba(255, 255, 255, 0.01)"
225
+ color: 'rgba(255, 255, 255, 0.01)',
156
226
  }),
157
227
  stroke: new Stroke({
158
228
  lineDash: [30, 10],
159
229
  width: 6,
160
- color: `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${opacity})`
161
- })
162
- })
230
+ color: `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${opacity})`,
231
+ }),
232
+ }),
163
233
  });
234
+
164
235
  circleStyle.getImage().setRotation(rotation);
236
+
165
237
  return [
166
238
  new Style({
167
239
  image: new Circle({
168
240
  radius: 10,
169
241
  fill: new Fill({
170
- color: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.5)`
171
- })
172
- })
242
+ color: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.5)`,
243
+ }),
244
+ }),
173
245
  }),
174
- circleStyle
246
+ circleStyle,
175
247
  ];
176
248
  });
177
249
  } else {
178
250
  feature.setStyle(colorOrStyleFunc);
179
251
  }
252
+
180
253
  this.layer.getSource().clear();
181
254
  this.layer.getSource().addFeature(feature);
182
255
  }
256
+
183
257
  render() {
184
258
  const { children, className } = this.props;
259
+ // Remove component props from other HTML props.
185
260
  const other = Object.entries(this.props).reduce((props, [key, value]) => {
186
261
  return propTypes[key] ? props : { ...props, [key]: value };
187
262
  }, {});
188
263
  const { active } = this.state;
189
- return /* @__PURE__ */ React.createElement("div", {
190
- role: "button",
191
- tabIndex: "0",
192
- className: `${className} ${active ? "rs-active" : ""}`,
193
- onClick: () => {
194
- return this.toggle();
195
- },
196
- onKeyPress: (e) => {
197
- return e.which === 13 && this.toggle();
198
- },
199
- ...other
200
- }, children);
264
+
265
+ return (
266
+ <div
267
+ role="button"
268
+ tabIndex="0"
269
+ className={`${className} ${active ? 'rs-active' : ''}`}
270
+ onClick={() => {
271
+ return this.toggle();
272
+ }}
273
+ onKeyPress={(e) => {
274
+ return e.which === 13 && this.toggle();
275
+ }}
276
+ // eslint-disable-next-line react/jsx-props-no-spreading
277
+ {...other}
278
+ >
279
+ {children}
280
+ </div>
281
+ );
201
282
  }
202
283
  }
284
+
203
285
  Geolocation.propTypes = propTypes;
204
286
  Geolocation.defaultProps = defaultProps;
287
+
205
288
  export default Geolocation;
@@ -0,0 +1,267 @@
1
+ import React from 'react';
2
+ import renderer from 'react-test-renderer';
3
+ import { configure, mount, shallow } from 'enzyme';
4
+ import Adapter from '@cfaester/enzyme-adapter-react-18';
5
+
6
+ import 'jest-canvas-mock';
7
+ import Map from 'ol/Map';
8
+ import View from 'ol/View';
9
+ import MapEvent from 'ol/MapEvent';
10
+ import Geolocation from './Geolocation';
11
+
12
+ configure({ adapter: new Adapter() });
13
+
14
+ const geolocationBackup = global.navigator.geolocation;
15
+
16
+ const mockGeolocation = () => {
17
+ const mock = {
18
+ clearWatch: jest.fn(),
19
+ getCurrentPosition: jest.fn(),
20
+ watchPosition: (onSuccess) => {
21
+ onSuccess({
22
+ coords: {
23
+ latitude: 47.9913611,
24
+ longitude: 7.84868,
25
+ accuracy: 55,
26
+ },
27
+ timestamp: 1552660077044,
28
+ });
29
+ },
30
+ };
31
+
32
+ global.navigator.geolocation = mock;
33
+ };
34
+
35
+ const mockMissingGeolocation = () => {
36
+ delete global.navigator.geolocation;
37
+ };
38
+
39
+ const restoreGeolocation = () => {
40
+ global.navigator.geolocation = geolocationBackup;
41
+ };
42
+
43
+ class CallbackHandler {
44
+ static onError() {}
45
+
46
+ static onSuccess() {}
47
+
48
+ static onActivate() {}
49
+
50
+ static onDeactivate() {}
51
+ }
52
+
53
+ describe('Geolocation', () => {
54
+ let map;
55
+
56
+ beforeEach(() => {
57
+ const target = document.createElement('div');
58
+ const { style } = target;
59
+ style.position = 'absolute';
60
+ style.left = '-1000px';
61
+ style.top = '-1000px';
62
+ style.width = '100px';
63
+ style.height = '100px';
64
+ document.body.appendChild(target);
65
+
66
+ map = new Map({
67
+ target,
68
+ view: new View({
69
+ center: [0, 0],
70
+ resolutions: [1],
71
+ zoom: 0,
72
+ }),
73
+ });
74
+ map.renderSync();
75
+ });
76
+
77
+ afterEach(() => {
78
+ const target = map.getTarget();
79
+ map.setTarget(null);
80
+ if (target && target.parentNode) {
81
+ target.parentNode.removeChild(target);
82
+ }
83
+ map.dispose();
84
+ });
85
+
86
+ describe('should match snapshot', () => {
87
+ test('minimum props', () => {
88
+ const component = renderer.create(<Geolocation map={map} />);
89
+ const tree = component.toJSON();
90
+ expect(tree).toMatchSnapshot();
91
+ });
92
+
93
+ test('with title', () => {
94
+ const component = renderer.create(
95
+ <Geolocation map={map} title="Lokalisieren" />,
96
+ );
97
+ const tree = component.toJSON();
98
+ expect(tree).toMatchSnapshot();
99
+ });
100
+
101
+ test('with class name', () => {
102
+ const component = renderer.create(
103
+ <Geolocation map={map} className="my-class-name" />,
104
+ );
105
+ const tree = component.toJSON();
106
+ expect(tree).toMatchSnapshot();
107
+ });
108
+ });
109
+
110
+ test('should use children', () => {
111
+ mockGeolocation();
112
+
113
+ const wrapper = mount(<Geolocation map={map}>test</Geolocation>);
114
+
115
+ const text = wrapper.find('.rs-geolocation').first().text();
116
+
117
+ expect(text).toBe('test');
118
+
119
+ restoreGeolocation();
120
+ });
121
+
122
+ describe('button classes', () => {
123
+ test('class should be active', () => {
124
+ mockGeolocation();
125
+
126
+ const wrapper = mount(<Geolocation map={map} />);
127
+ const basic = wrapper.getDOMNode();
128
+
129
+ wrapper.find('.rs-geolocation').first().simulate('click');
130
+
131
+ expect(basic.className).toBe('rs-geolocation rs-active');
132
+
133
+ restoreGeolocation();
134
+ });
135
+
136
+ test('class should not be active', () => {
137
+ mockGeolocation();
138
+
139
+ const wrapper = mount(<Geolocation map={map} />);
140
+ const basic = wrapper.getDOMNode();
141
+
142
+ wrapper
143
+ .find('.rs-geolocation')
144
+ .first()
145
+ .simulate('click')
146
+ .simulate('click');
147
+
148
+ expect(basic.className).toBe('rs-geolocation ');
149
+
150
+ restoreGeolocation();
151
+ });
152
+ });
153
+
154
+ test(`highlight on first toggle`, () => {
155
+ mockGeolocation();
156
+
157
+ const component = shallow(<Geolocation map={map} />);
158
+ const instance = component.instance();
159
+ const spy = jest.spyOn(instance, 'highlight');
160
+ instance.toggle();
161
+ expect(spy).toHaveBeenCalled();
162
+
163
+ restoreGeolocation();
164
+ });
165
+
166
+ test(`success/activate/deactivate callback functions should be called`, () => {
167
+ mockGeolocation();
168
+ const spyOnSuccess = jest.spyOn(CallbackHandler, 'onSuccess');
169
+ const spyOnActivate = jest.spyOn(CallbackHandler, 'onActivate');
170
+ const spyOnDeactivate = jest.spyOn(CallbackHandler, 'onDeactivate');
171
+
172
+ const wrapper = mount(
173
+ <Geolocation
174
+ map={map}
175
+ onSuccess={() => {
176
+ return CallbackHandler.onSuccess();
177
+ }}
178
+ onActivate={() => {
179
+ return CallbackHandler.onActivate();
180
+ }}
181
+ onDeactivate={() => {
182
+ return CallbackHandler.onDeactivate();
183
+ }}
184
+ />,
185
+ );
186
+
187
+ wrapper.find('.rs-geolocation').first().simulate('click');
188
+
189
+ expect(spyOnActivate).toHaveBeenCalled();
190
+ expect(spyOnSuccess).toHaveBeenCalled();
191
+
192
+ wrapper.find('.rs-geolocation').first().simulate('click');
193
+
194
+ expect(spyOnDeactivate).toHaveBeenCalled();
195
+
196
+ restoreGeolocation();
197
+ });
198
+
199
+ test(`error function should be called`, () => {
200
+ mockMissingGeolocation();
201
+
202
+ const spy = jest.spyOn(CallbackHandler, 'onError');
203
+
204
+ const wrapper = mount(
205
+ <Geolocation
206
+ map={map}
207
+ onError={() => {
208
+ return CallbackHandler.onError();
209
+ }}
210
+ />,
211
+ );
212
+
213
+ wrapper.find('.rs-geolocation').first().simulate('click');
214
+
215
+ expect(spy).toHaveBeenCalled();
216
+
217
+ restoreGeolocation();
218
+ });
219
+
220
+ describe('map centering', () => {
221
+ test('centers map', () => {
222
+ mockGeolocation();
223
+
224
+ const center1 = [742952.8821531708, 6330118.608483334];
225
+ map.getView().setCenter(center1);
226
+
227
+ const component = shallow(<Geolocation map={map} />);
228
+ component.instance().toggle();
229
+
230
+ const center2 = map.getView().getCenter();
231
+ expect(center1).not.toEqual(center2);
232
+
233
+ restoreGeolocation();
234
+ });
235
+
236
+ test('sets isRecenteringToPosition=false after pointerdrag event with the noCenterAfterDrag prop', () => {
237
+ mockGeolocation();
238
+
239
+ const component = shallow(<Geolocation map={map} noCenterAfterDrag />);
240
+ component.instance().toggle();
241
+
242
+ expect(component.instance().isRecenteringToPosition).toEqual(true);
243
+
244
+ map.dispatchEvent(new MapEvent('pointerdrag', map));
245
+ expect(component.instance().isRecenteringToPosition).toEqual(false);
246
+
247
+ restoreGeolocation();
248
+ });
249
+ });
250
+
251
+ test('custom style function', () => {
252
+ mockGeolocation();
253
+
254
+ const styleFunc = jest.fn();
255
+
256
+ const component = shallow(
257
+ <Geolocation map={map} colorOrStyleFunc={styleFunc} />,
258
+ );
259
+ const instance = component.instance();
260
+ instance.toggle();
261
+ const style = instance.layer.getSource().getFeatures()[0].getStyle();
262
+
263
+ expect(style).toBe(styleFunc);
264
+
265
+ restoreGeolocation();
266
+ });
267
+ });
@@ -0,0 +1,25 @@
1
+
2
+ The following example demonstrates the use of Geolocation.
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 Geolocation from 'react-spatial/components/Geolocation';
11
+ import BasicMap from 'react-spatial/components/BasicMap';
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-geolocation-example">
22
+ <BasicMap map={map} layers={layers} tabIndex={0} />
23
+ <Geolocation map={map} />
24
+ </div>
25
+ ```