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,99 @@
1
+ import OLVectorLayer from 'ol/layer/Vector';
2
+ import VectorSource from 'ol/source/Vector';
3
+ import Control from 'ol/control/Control';
4
+ import Draw from 'ol/interaction/Draw';
5
+ import Snap from 'ol/interaction/Snap';
6
+ import Pointer from 'ol/interaction/Pointer';
7
+ import Select from 'ol/interaction/Select';
8
+ import Modify from 'ol/interaction/Modify';
9
+ import Style from 'ol/style/Style';
10
+ import Fill from 'ol/style/Fill';
11
+ import Stroke from 'ol/style/Stroke';
12
+ import Circle from 'ol/style/Circle';
13
+ import Icon from 'ol/style/Icon';
14
+ import RegularShape from 'ol/style/RegularShape';
15
+ import Collection from 'ol/Collection';
16
+ import Feature from 'ol/Feature';
17
+ import Observable, { unByKey } from 'ol/Observable';
18
+ import { getCenter } from 'ol/extent';
19
+ import {
20
+ Point,
21
+ LineString,
22
+ Polygon,
23
+ MultiPoint,
24
+ MultiLineString,
25
+ MultiPolygon,
26
+ } from 'ol/geom';
27
+ import LinearRing from 'ol/geom/LinearRing';
28
+ import { fromExtent } from 'ol/geom/Polygon';
29
+ import * as events from 'ol/events';
30
+ import * as condition from 'ol/events/condition';
31
+ import { OL3Parser } from 'jsts/org/locationtech/jts/io';
32
+ import { BufferOp } from 'jsts/org/locationtech/jts/operation/buffer';
33
+ import { OverlayOp } from 'jsts/org/locationtech/jts/operation/overlay';
34
+
35
+ /**
36
+ * This module create window.ol and window.jsts variables for ole editor.
37
+ */
38
+ if (!window.ol) {
39
+ window.ol = {
40
+ Feature,
41
+ Collection,
42
+ layer: {
43
+ Vector: OLVectorLayer,
44
+ },
45
+ source: {
46
+ Vector: VectorSource,
47
+ },
48
+ interaction: {
49
+ Draw,
50
+ Snap,
51
+ Pointer,
52
+ Select,
53
+ Modify,
54
+ },
55
+ control: {
56
+ Control,
57
+ },
58
+ style: {
59
+ Style,
60
+ Fill,
61
+ Stroke,
62
+ Circle,
63
+ RegularShape,
64
+ Icon,
65
+ },
66
+ geom: {
67
+ Point,
68
+ LineString,
69
+ Polygon,
70
+ MultiPoint,
71
+ MultiLineString,
72
+ MultiPolygon,
73
+ LinearRing,
74
+ },
75
+ extent: {
76
+ getCenter,
77
+ },
78
+ Observable: {
79
+ ...Observable,
80
+ unByKey,
81
+ },
82
+ events: {
83
+ ...events,
84
+ condition: {
85
+ ...condition,
86
+ },
87
+ },
88
+ };
89
+ window.ol.geom.Polygon.fromExtent = fromExtent;
90
+ }
91
+
92
+ if (!window.jsts) {
93
+ window.jsts = {
94
+ io: {
95
+ OL3Parser,
96
+ },
97
+ operation: { buffer: { BufferOp }, overlay: { OverlayOp } },
98
+ };
99
+ }
@@ -0,0 +1,594 @@
1
+ import KML from 'ol/format/KML';
2
+ import { Feature } from 'ol';
3
+ import Point from 'ol/geom/Point';
4
+ import MultiPoint from 'ol/geom/MultiPoint';
5
+ import GeometryCollection from 'ol/geom/GeometryCollection';
6
+ import { Style, Text, Icon, Circle, Fill, Stroke } from 'ol/style';
7
+ import { asString } from 'ol/color';
8
+ import { parse } from 'ol/xml';
9
+ import { kmlStyle } from './Styles';
10
+ import getPolygonPattern from './getPolygonPattern';
11
+
12
+ const applyTextStyleForIcon = (olIcon, olText) => {
13
+ const size = olIcon.getSize() || [48, 48];
14
+ const scale = olIcon.getScale() || 1;
15
+ const anchor = olIcon.getAnchor() || [
16
+ (size[0] * scale) / 2,
17
+ (size[1] * scale) / 2,
18
+ ];
19
+ const offset = [
20
+ scale * (size[0] - anchor[0]) + 5,
21
+ scale * (size[1] / 2 - anchor[1]),
22
+ ];
23
+ olText.setOffsetX(offset[0]);
24
+ olText.setOffsetY(offset[1]);
25
+ olText.setTextAlign('left');
26
+ };
27
+
28
+ const getVertexCoord = (geom, start = true, index = 0) => {
29
+ const coords = geom.getCoordinates();
30
+ const len = coords.length - 1;
31
+ return start ? coords[index] : coords[len - index];
32
+ };
33
+
34
+ const getLineIcon = (feature, icon, color, start = true) => {
35
+ const geom = feature.getGeometry();
36
+ const coordA = getVertexCoord(geom, start, 1);
37
+ const coordB = getVertexCoord(geom, start);
38
+ const dx = start ? coordA[0] - coordB[0] : coordB[0] - coordA[0];
39
+ const dy = start ? coordA[1] - coordB[1] : coordB[1] - coordA[1];
40
+ const rotation = Math.atan2(dy, dx);
41
+
42
+ return new Style({
43
+ geometry: (feat) => {
44
+ const ge = feat.getGeometry();
45
+ return new Point(getVertexCoord(ge, start));
46
+ },
47
+ image: new Icon({
48
+ src: icon.url,
49
+ color,
50
+ rotation: -rotation,
51
+ rotateWithView: true,
52
+ scale: icon.scale,
53
+ imgSize: icon.size, // ie 11
54
+ }),
55
+ zIndex: icon.zIndex,
56
+ });
57
+ };
58
+
59
+ // Clean the unneeded feature's style and properties created by the KML parser.
60
+ const sanitizeFeature = (feature) => {
61
+ const geom = feature.getGeometry();
62
+ let styles = feature.getStyleFunction();
63
+
64
+ // Store maxZoom in properties
65
+ if (feature.get('maxZoom')) {
66
+ feature.set('maxZoom', parseFloat(feature.get('maxZoom'), 10));
67
+ }
68
+
69
+ // Store minZoom in properties
70
+ if (feature.get('minZoom')) {
71
+ feature.set('minZoom', parseFloat(feature.get('minZoom'), 10));
72
+ }
73
+
74
+ // The use of clone is part of the scale fix line 156
75
+ const tmpStyles = styles(feature);
76
+ const style = (Array.isArray(tmpStyles) ? tmpStyles[0] : tmpStyles).clone();
77
+
78
+ let stroke = style.getStroke();
79
+ if (stroke && feature.get('lineDash')) {
80
+ stroke.setLineDash(
81
+ feature
82
+ .get('lineDash')
83
+ .split(',')
84
+ .map((l) => {
85
+ return parseInt(l, 10);
86
+ }),
87
+ );
88
+ }
89
+
90
+ // The canvas draws a stroke width=1 by default if width=0, so we
91
+ // remove the stroke style in that case.
92
+ if (stroke && stroke.getWidth() === 0) {
93
+ stroke = undefined;
94
+ }
95
+
96
+ if (feature.get('zIndex')) {
97
+ style.setZIndex(parseInt(feature.get('zIndex'), 10));
98
+ }
99
+
100
+ // if the feature is a Point and we are offline, we use default vector
101
+ // style.
102
+ // if the feature is a Point and has a name with a text style, we
103
+ // create a correct text style.
104
+ // TODO Handle GeometryCollection displaying name on the first Point
105
+ // geometry.
106
+ if (style && (geom instanceof Point || geom instanceof MultiPoint)) {
107
+ let image = style.getImage();
108
+ let text = null;
109
+ let fill = style.getFill();
110
+
111
+ // If the feature has name we display it on the map as Google does
112
+ if (
113
+ feature.get('name') &&
114
+ style.getText() &&
115
+ style.getText().getScale() !== 0
116
+ ) {
117
+ if (image && image.getScale() === 0) {
118
+ // transparentCircle is used to allow selection
119
+ image = new Circle({
120
+ radius: 1,
121
+ fill: new Fill({ color: [0, 0, 0, 0] }),
122
+ stroke: new Stroke({ color: [0, 0, 0, 0] }),
123
+ });
124
+ }
125
+
126
+ // We replace empty white spaces used to keep normal spaces before and after the name.
127
+ let name = feature.get('name');
128
+ if (/\u200B/g.test(name)) {
129
+ name = name.replace(/\u200B/g, '');
130
+ feature.set('name', name);
131
+ }
132
+
133
+ text = new Text({
134
+ font: feature.get('textFont') || 'normal 16px Helvetica',
135
+ text: feature.get('name'),
136
+ fill: style.getText().getFill(),
137
+ // rotation unsupported by KML, taken instead from custom field.
138
+ rotation: feature.get('textRotation') || 0,
139
+ // since ol 6.3.1 : https://github.com/openlayers/openlayers/pull/10613/files#diff-1883da8b57e690db7ea0c35ce53c880aR925
140
+ // a default textstroke is added to mimic google earth.
141
+ // it was not the case before, the stroke was always null. So to keep
142
+ // the same behavior we don't copy the stroke style.
143
+ // TODO : maybe we should use this functionnality in the futur.
144
+ // stroke: style.getText().getStroke(),
145
+ scale: style.getText().getScale(),
146
+ });
147
+
148
+ if (feature.get('textStrokeColor') && feature.get('textStrokeWidth')) {
149
+ text.setStroke(
150
+ new Stroke({
151
+ color: feature.get('textStrokeColor'),
152
+ width: parseFloat(feature.get('textStrokeWidth')),
153
+ }),
154
+ );
155
+ }
156
+
157
+ if (feature.get('textAlign')) {
158
+ text.setTextAlign(feature.get('textAlign'));
159
+ }
160
+
161
+ if (feature.get('textOffsetX')) {
162
+ text.setOffsetX(parseFloat(feature.get('textOffsetX')));
163
+ }
164
+
165
+ if (feature.get('textOffsetY')) {
166
+ text.setOffsetY(parseFloat(feature.get('textOffsetY')));
167
+ }
168
+
169
+ if (feature.get('textBackgroundFillColor')) {
170
+ text.setBackgroundFill(
171
+ new Fill({
172
+ color: feature.get('textBackgroundFillColor'),
173
+ }),
174
+ );
175
+ }
176
+
177
+ if (feature.get('textPadding')) {
178
+ text.setPadding(
179
+ feature
180
+ .get('textPadding')
181
+ .split(',')
182
+ .map((n) => {
183
+ return parseFloat(n);
184
+ }),
185
+ );
186
+ }
187
+
188
+ if (image instanceof Icon) {
189
+ applyTextStyleForIcon(image, text);
190
+ }
191
+ }
192
+
193
+ if (image instanceof Icon) {
194
+ /* Apply icon rotation if defined (by default only written as
195
+ * <heading> tag, which is not read as rotation value by the ol KML module)
196
+ */
197
+ image.setRotation(parseFloat(feature.get('iconRotation')) || 0);
198
+ }
199
+
200
+ fill = undefined;
201
+ stroke = undefined;
202
+
203
+ styles = (feat, resolution) => {
204
+ /* Options to be used for picture scaling with map, should have at least
205
+ * a resolution attribute (this is the map resolution at the zoom level when
206
+ * the picture is created), can take an optional constant for further scale
207
+ * adjustment.
208
+ * e.g. { resolution: 0.123, defaultScale: 1 / 6 }
209
+ */
210
+
211
+ if (feat.get('pictureOptions')) {
212
+ let pictureOptions = feat.get('pictureOptions');
213
+ if (typeof pictureOptions === 'string') {
214
+ pictureOptions = JSON.parse(pictureOptions);
215
+ }
216
+ feat.set('pictureOptions', pictureOptions);
217
+ if (pictureOptions.resolution) {
218
+ image.setScale(
219
+ (pictureOptions.resolution / resolution) *
220
+ pictureOptions.defaultScale || 1,
221
+ );
222
+ }
223
+ }
224
+
225
+ return new Style({
226
+ fill,
227
+ stroke,
228
+ image,
229
+ text,
230
+ zIndex: style.getZIndex(),
231
+ });
232
+ };
233
+ }
234
+
235
+ // Remove image and text styles for polygons and lines
236
+ if (
237
+ !(
238
+ geom instanceof Point ||
239
+ geom instanceof MultiPoint ||
240
+ geom instanceof GeometryCollection
241
+ )
242
+ ) {
243
+ styles = [
244
+ new Style({
245
+ fill: style.getFill(),
246
+ stroke,
247
+ image: null,
248
+ text: null,
249
+ zIndex: style.getZIndex(),
250
+ }),
251
+ ];
252
+
253
+ // Parse the fillPattern json string and store parsed object
254
+ let fillPattern = feature.get('fillPattern');
255
+ if (fillPattern) {
256
+ fillPattern = JSON.parse(fillPattern);
257
+ feature.set('fillPattern', fillPattern);
258
+
259
+ /* We set the fill pattern for polygons */
260
+ if (!style.getFill()) {
261
+ styles[0].setFill(new Fill());
262
+ }
263
+ const patternOrColor = fillPattern.empty
264
+ ? [0, 0, 0, 0]
265
+ : getPolygonPattern(fillPattern.id, fillPattern.color);
266
+ styles[0].getFill().setColor(patternOrColor);
267
+ }
268
+
269
+ // Add line's icons styles
270
+ if (feature.get('lineStartIcon')) {
271
+ styles.push(
272
+ getLineIcon(
273
+ feature,
274
+ JSON.parse(feature.get('lineStartIcon')),
275
+ stroke.getColor(),
276
+ ),
277
+ );
278
+ }
279
+
280
+ if (feature.get('lineEndIcon')) {
281
+ styles.push(
282
+ getLineIcon(
283
+ feature,
284
+ JSON.parse(feature.get('lineEndIcon')),
285
+ stroke.getColor(),
286
+ false,
287
+ ),
288
+ );
289
+ }
290
+ }
291
+ feature.setStyle(styles);
292
+ };
293
+
294
+ /**
295
+ * Read a KML string.
296
+ * @param {String} kmlString A string representing a KML file.
297
+ * @param {<ol.Projection|String>} featureProjection The projection used by the map.
298
+ */
299
+ const readFeatures = (kmlString, featureProjection) => {
300
+ const features = new KML().readFeatures(kmlString, {
301
+ featureProjection,
302
+ });
303
+ features.forEach((feature) => {
304
+ sanitizeFeature(feature);
305
+ });
306
+ return features;
307
+ };
308
+
309
+ /**
310
+ * Create a KML string.
311
+ * @param {VectorLayer} layer A react-spatial VectorLayer.
312
+ * @param {<ol.Projection|String>} featureProjection The current projection used by the features.
313
+ */
314
+ const writeFeatures = (layer, featureProjection, mapResolution) => {
315
+ let featString;
316
+ const { olLayer } = layer;
317
+ const exportFeatures = [];
318
+
319
+ olLayer.getSource().forEachFeature((feature) => {
320
+ // We silently ignore Circle elements as they are
321
+ // not supported in kml.
322
+ if (feature.getGeometry().getType() === 'Circle') {
323
+ return;
324
+ }
325
+
326
+ const clone = feature.clone();
327
+ clone.setId(feature.getId());
328
+ clone.getGeometry().setProperties(feature.getGeometry().getProperties());
329
+ clone.getGeometry().transform(featureProjection, 'EPSG:4326');
330
+
331
+ // We remove all ExtendedData not related to style.
332
+ Object.keys(feature.getProperties()).forEach((key) => {
333
+ if (!/^(geometry|name|description)$/.test(key)) {
334
+ clone.unset(key, true);
335
+ }
336
+ });
337
+
338
+ let styles;
339
+
340
+ if (feature.getStyleFunction()) {
341
+ styles = feature.getStyleFunction()(feature, mapResolution);
342
+ } else if (olLayer && olLayer.getStyleFunction()) {
343
+ styles = olLayer.getStyleFunction()(feature, mapResolution);
344
+ }
345
+
346
+ const mainStyle = styles[0] || styles;
347
+
348
+ const newStyle = {
349
+ fill: mainStyle.getFill(),
350
+ stroke: mainStyle.getStroke(),
351
+ text: mainStyle.getText(),
352
+ image: mainStyle.getImage(),
353
+ zIndex: mainStyle.getZIndex(),
354
+ };
355
+
356
+ if (newStyle.zIndex) {
357
+ clone.set('zIndex', newStyle.zIndex);
358
+ }
359
+
360
+ // If we see spaces at the beginning or at the end we add a empty
361
+ // white space at the beginning and at the end.
362
+ if (newStyle.text && /^\s|\s$/g.test(newStyle.text.getText())) {
363
+ newStyle.text.setText(`\u200B${newStyle.text.getText()}\u200B`);
364
+ }
365
+
366
+ // Set custom properties to be converted in extendedData in KML.
367
+ if (newStyle.text && newStyle.text.getRotation()) {
368
+ clone.set('textRotation', newStyle.text.getRotation());
369
+ }
370
+
371
+ if (newStyle.text && newStyle.text.getFont()) {
372
+ clone.set('textFont', newStyle.text.getFont());
373
+ }
374
+
375
+ if (newStyle.text && newStyle.text.getTextAlign()) {
376
+ clone.set('textAlign', newStyle.text.getTextAlign());
377
+ }
378
+
379
+ if (newStyle.text && newStyle.text.getOffsetX()) {
380
+ clone.set('textOffsetX', newStyle.text.getOffsetX());
381
+ }
382
+
383
+ if (newStyle.text && newStyle.text.getOffsetY()) {
384
+ clone.set('textOffsetY', newStyle.text.getOffsetY());
385
+ }
386
+
387
+ if (newStyle.text && newStyle.text.getStroke()) {
388
+ if (newStyle.text.getStroke().getColor()) {
389
+ clone.set(
390
+ 'textStrokeColor',
391
+ asString(newStyle.text.getStroke().getColor()),
392
+ );
393
+ }
394
+
395
+ if (newStyle.text.getStroke().getWidth()) {
396
+ clone.set('textStrokeWidth', newStyle.text.getStroke().getWidth());
397
+ }
398
+ }
399
+
400
+ if (newStyle.text && newStyle.text.getBackgroundFill()) {
401
+ clone.set(
402
+ 'textBackgroundFillColor',
403
+ asString(newStyle.text.getBackgroundFill().getColor()),
404
+ );
405
+ }
406
+
407
+ if (newStyle.text && newStyle.text.getPadding()) {
408
+ clone.set('textPadding', newStyle.text.getPadding().join());
409
+ }
410
+
411
+ if (newStyle.stroke && newStyle.stroke.getLineDash()) {
412
+ clone.set('lineDash', newStyle.stroke.getLineDash().join(','));
413
+ }
414
+
415
+ if (newStyle.image instanceof Circle) {
416
+ newStyle.image = null;
417
+ }
418
+
419
+ if (newStyle.image) {
420
+ const imgSource = newStyle.image.getSrc();
421
+ if (!/(http(s?)):\/\//gi.test(imgSource)) {
422
+ // eslint-disable-next-line no-console
423
+ console.log(
424
+ 'Local image source not supported for KML export.' +
425
+ 'Should use remote web server',
426
+ );
427
+ }
428
+
429
+ if (newStyle.image.getRotation()) {
430
+ // We set the icon rotation as extended data
431
+ clone.set('iconRotation', newStyle.image.getRotation());
432
+ }
433
+
434
+ // Set map resolution to use for icon-to-map proportional scaling
435
+ if (feature.get('pictureOptions')) {
436
+ clone.set(
437
+ 'pictureOptions',
438
+ JSON.stringify(feature.get('pictureOptions')),
439
+ );
440
+ }
441
+ }
442
+
443
+ // In case a fill pattern should be applied (use fillPattern attribute to store pattern id, color etc)
444
+ if (feature.get('fillPattern')) {
445
+ clone.set('fillPattern', JSON.stringify(feature.get('fillPattern')));
446
+ newStyle.fill = null;
447
+ }
448
+
449
+ // maxZoom: maximum zoom level at which the feature is displayed
450
+ if (feature.get('maxZoom')) {
451
+ clone.set('maxZoom', parseFloat(feature.get('maxZoom'), 10));
452
+ }
453
+
454
+ // minZoom: minimum zoom level at which the feature is displayed
455
+ if (feature.get('minZoom')) {
456
+ clone.set('minZoom', parseFloat(feature.get('minZoom'), 10));
457
+ }
458
+
459
+ // If only text is displayed we must specify an
460
+ // image style with scale=0
461
+ if (newStyle.text && !newStyle.image) {
462
+ newStyle.image = new Icon({
463
+ src: 'noimage',
464
+ scale: 0,
465
+ });
466
+ }
467
+
468
+ // In case we use line's icon .
469
+ const extraLineStyles = (Array.isArray(styles) && styles.slice(1)) || [];
470
+ extraLineStyles.forEach((extraLineStyle) => {
471
+ if (
472
+ extraLineStyle &&
473
+ extraLineStyle.getImage() instanceof Icon &&
474
+ extraLineStyle.getGeometry()
475
+ ) {
476
+ const coord = extraLineStyle.getGeometry()(feature).getCoordinates();
477
+ const startCoord = feature.getGeometry().getFirstCoordinate();
478
+ if (coord[0] === startCoord[0] && coord[1] === startCoord[1]) {
479
+ clone.set(
480
+ 'lineStartIcon',
481
+ JSON.stringify({
482
+ url: extraLineStyle.getImage().getSrc(),
483
+ scale: extraLineStyle.getImage().getScale(),
484
+ size: extraLineStyle.getImage().getSize(),
485
+ zIndex: extraLineStyle.getZIndex(),
486
+ }),
487
+ );
488
+ } else {
489
+ clone.set(
490
+ 'lineEndIcon',
491
+ JSON.stringify({
492
+ url: extraLineStyle.getImage().getSrc(),
493
+ scale: extraLineStyle.getImage().getScale(),
494
+ size: extraLineStyle.getImage().getSize(),
495
+ zIndex: extraLineStyle.getZIndex(),
496
+ }),
497
+ );
498
+ }
499
+ }
500
+ });
501
+
502
+ const olStyle = new Style(newStyle);
503
+ clone.setStyle(olStyle);
504
+
505
+ if (
506
+ !(
507
+ clone.getGeometry() instanceof Point &&
508
+ olStyle.getText() &&
509
+ !olStyle.getText().getText()
510
+ )
511
+ ) {
512
+ exportFeatures.push(clone);
513
+ }
514
+ });
515
+
516
+ if (exportFeatures.length > 0) {
517
+ if (exportFeatures.length === 1) {
518
+ // force the add of a <Document> node
519
+ exportFeatures.push(new Feature());
520
+ }
521
+
522
+ featString = new KML({
523
+ extractStyles: true,
524
+ defaultStyle: [kmlStyle],
525
+ }).writeFeatures(exportFeatures);
526
+
527
+ // Remove no image hack
528
+ featString = featString.replace(
529
+ /<Icon>\s*<href>noimage<\/href>\s*<\/Icon>/g,
530
+ '',
531
+ );
532
+
533
+ // Remove empty placemark added to have
534
+ // <Document> tag
535
+ featString = featString.replace(/<Placemark\/>/g, '');
536
+
537
+ // Add KML document name
538
+ if (layer.name) {
539
+ featString = featString.replace(
540
+ /<Document>/,
541
+ `<Document><name>${layer.name}</name>`,
542
+ );
543
+ }
544
+ }
545
+
546
+ return featString;
547
+ };
548
+
549
+ /**
550
+ * Removes the <Camera> tag from a KML string. Returns the KML string with removed <Camera> tag.
551
+ * @param {String} kmlString A string representing a KML file.
552
+ */
553
+ const removeDocumentCamera = (kmlString) => {
554
+ const kmlDoc = parse(kmlString);
555
+ // Remove old Camera node
556
+ const oldCameraNode = kmlDoc.getElementsByTagName('Camera')[0];
557
+ if (oldCameraNode) {
558
+ oldCameraNode.remove();
559
+ }
560
+ return new XMLSerializer().serializeToString(kmlDoc);
561
+ };
562
+
563
+ /**
564
+ * Write the <Camera> tag into a KML string. Returns the KML string with added <Camera> tag.
565
+ * @param {String} kmlString A string representing a KML file.
566
+ * @param {Object} cameraAttributes Object containing the camera tags (longitude, latitude, altitude, heading, tilt, altitudeMode, roll)
567
+ * as keys with corresponding values. See https://developers.google.com/kml/documentation/kmlreference#camera
568
+ */
569
+ const writeDocumentCamera = (kmlString, cameraAttributes) => {
570
+ const kmlDoc = parse(removeDocumentCamera(kmlString));
571
+
572
+ if (cameraAttributes) {
573
+ // Create Camera node with child attributes if the cameraAttributes object is defined
574
+ const cameraNode = kmlDoc.createElement('Camera');
575
+ Object.keys(cameraAttributes).forEach((key) => {
576
+ const cameraAttribute = kmlDoc.createElement(
577
+ `${key.charAt(0).toUpperCase() + key.slice(1)}`,
578
+ );
579
+ cameraAttribute.innerHTML = cameraAttributes[key];
580
+ cameraNode.appendChild(cameraAttribute);
581
+ });
582
+ const documentNode = kmlDoc.getElementsByTagName('Document')[0];
583
+ documentNode.appendChild(cameraNode);
584
+ }
585
+
586
+ return new XMLSerializer().serializeToString(kmlDoc);
587
+ };
588
+
589
+ export default {
590
+ readFeatures,
591
+ writeFeatures,
592
+ writeDocumentCamera,
593
+ removeDocumentCamera,
594
+ };