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