@vcmap/core 5.0.0-rc.0

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 (146) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +44 -0
  3. package/build/postinstall.js +44 -0
  4. package/index.js +139 -0
  5. package/package.json +92 -0
  6. package/src/cesium/cesium3DTileFeature.js +9 -0
  7. package/src/cesium/cesium3DTilePointFeature.js +9 -0
  8. package/src/cesium/cesiumVcsCameraPrimitive.js +146 -0
  9. package/src/cesium/wallpaperMaterial.js +64 -0
  10. package/src/ol/feature.js +47 -0
  11. package/src/ol/geom/circle.js +24 -0
  12. package/src/ol/geom/geometryCollection.js +33 -0
  13. package/src/ol/render/canvas/canvasTileRenderer.js +179 -0
  14. package/src/ol/source/ClusterEnhancedVectorSource.js +39 -0
  15. package/src/ol/source/VcsCluster.js +37 -0
  16. package/src/vcs/vcm/classRegistry.js +106 -0
  17. package/src/vcs/vcm/event/vcsEvent.js +89 -0
  18. package/src/vcs/vcm/globalCollections.js +11 -0
  19. package/src/vcs/vcm/interaction/abstractInteraction.js +149 -0
  20. package/src/vcs/vcm/interaction/coordinateAtPixel.js +102 -0
  21. package/src/vcs/vcm/interaction/eventHandler.js +425 -0
  22. package/src/vcs/vcm/interaction/featureAtPixelInteraction.js +286 -0
  23. package/src/vcs/vcm/interaction/featureProviderInteraction.js +54 -0
  24. package/src/vcs/vcm/interaction/interactionChain.js +124 -0
  25. package/src/vcs/vcm/interaction/interactionType.js +114 -0
  26. package/src/vcs/vcm/layer/buildings.js +17 -0
  27. package/src/vcs/vcm/layer/cesium/cesiumTilesetCesium.js +359 -0
  28. package/src/vcs/vcm/layer/cesium/clusterContext.js +95 -0
  29. package/src/vcs/vcm/layer/cesium/dataSourceCesium.js +171 -0
  30. package/src/vcs/vcm/layer/cesium/openStreetMapCesium.js +29 -0
  31. package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +58 -0
  32. package/src/vcs/vcm/layer/cesium/rasterLayerCesium.js +110 -0
  33. package/src/vcs/vcm/layer/cesium/singleImageCesium.js +49 -0
  34. package/src/vcs/vcm/layer/cesium/terrainCesium.js +80 -0
  35. package/src/vcs/vcm/layer/cesium/tmsCesium.js +54 -0
  36. package/src/vcs/vcm/layer/cesium/vectorCesium.js +255 -0
  37. package/src/vcs/vcm/layer/cesium/vectorContext.js +167 -0
  38. package/src/vcs/vcm/layer/cesium/vectorRasterTileCesium.js +116 -0
  39. package/src/vcs/vcm/layer/cesium/vectorTileImageryProvider.js +246 -0
  40. package/src/vcs/vcm/layer/cesium/wmsCesium.js +71 -0
  41. package/src/vcs/vcm/layer/cesium/wmtsCesium.js +101 -0
  42. package/src/vcs/vcm/layer/cesium/x3dmHelper.js +22 -0
  43. package/src/vcs/vcm/layer/cesiumTileset.js +376 -0
  44. package/src/vcs/vcm/layer/czml.js +141 -0
  45. package/src/vcs/vcm/layer/dataSource.js +259 -0
  46. package/src/vcs/vcm/layer/featureLayer.js +261 -0
  47. package/src/vcs/vcm/layer/featureStore.js +647 -0
  48. package/src/vcs/vcm/layer/featureStoreChanges.js +360 -0
  49. package/src/vcs/vcm/layer/featureStoreState.js +19 -0
  50. package/src/vcs/vcm/layer/featureVisibility.js +435 -0
  51. package/src/vcs/vcm/layer/geojson.js +185 -0
  52. package/src/vcs/vcm/layer/geojsonHelpers.js +450 -0
  53. package/src/vcs/vcm/layer/globalHider.js +157 -0
  54. package/src/vcs/vcm/layer/layer.js +752 -0
  55. package/src/vcs/vcm/layer/layerImplementation.js +102 -0
  56. package/src/vcs/vcm/layer/layerState.js +17 -0
  57. package/src/vcs/vcm/layer/layerSymbols.js +6 -0
  58. package/src/vcs/vcm/layer/oblique/layerOblique.js +76 -0
  59. package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +175 -0
  60. package/src/vcs/vcm/layer/oblique/vectorOblique.js +469 -0
  61. package/src/vcs/vcm/layer/openStreetMap.js +194 -0
  62. package/src/vcs/vcm/layer/openlayers/layerOpenlayers.js +79 -0
  63. package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +27 -0
  64. package/src/vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js +121 -0
  65. package/src/vcs/vcm/layer/openlayers/singleImageOpenlayers.js +49 -0
  66. package/src/vcs/vcm/layer/openlayers/tileDebugOpenlayers.js +39 -0
  67. package/src/vcs/vcm/layer/openlayers/tmsOpenlayers.js +62 -0
  68. package/src/vcs/vcm/layer/openlayers/vectorOpenlayers.js +118 -0
  69. package/src/vcs/vcm/layer/openlayers/vectorTileOpenlayers.js +177 -0
  70. package/src/vcs/vcm/layer/openlayers/wmsOpenlayers.js +55 -0
  71. package/src/vcs/vcm/layer/openlayers/wmtsOpenlayers.js +141 -0
  72. package/src/vcs/vcm/layer/pointCloud.js +162 -0
  73. package/src/vcs/vcm/layer/rasterLayer.js +294 -0
  74. package/src/vcs/vcm/layer/singleImage.js +119 -0
  75. package/src/vcs/vcm/layer/terrain.js +122 -0
  76. package/src/vcs/vcm/layer/terrainHelpers.js +123 -0
  77. package/src/vcs/vcm/layer/tileLoadedHelper.js +72 -0
  78. package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +104 -0
  79. package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +67 -0
  80. package/src/vcs/vcm/layer/tileProvider/tileProvider.js +584 -0
  81. package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +28 -0
  82. package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +106 -0
  83. package/src/vcs/vcm/layer/tms.js +121 -0
  84. package/src/vcs/vcm/layer/vector.js +632 -0
  85. package/src/vcs/vcm/layer/vectorHelpers.js +206 -0
  86. package/src/vcs/vcm/layer/vectorProperties.js +1391 -0
  87. package/src/vcs/vcm/layer/vectorSymbols.js +40 -0
  88. package/src/vcs/vcm/layer/vectorTile.js +480 -0
  89. package/src/vcs/vcm/layer/wfs.js +165 -0
  90. package/src/vcs/vcm/layer/wms.js +270 -0
  91. package/src/vcs/vcm/layer/wmsHelpers.js +65 -0
  92. package/src/vcs/vcm/layer/wmts.js +235 -0
  93. package/src/vcs/vcm/maps/baseOLMap.js +257 -0
  94. package/src/vcs/vcm/maps/cameraLimiter.js +219 -0
  95. package/src/vcs/vcm/maps/cesium.js +1192 -0
  96. package/src/vcs/vcm/maps/map.js +511 -0
  97. package/src/vcs/vcm/maps/mapState.js +17 -0
  98. package/src/vcs/vcm/maps/oblique.js +536 -0
  99. package/src/vcs/vcm/maps/openlayers.js +205 -0
  100. package/src/vcs/vcm/object.js +92 -0
  101. package/src/vcs/vcm/oblique/ObliqueCollection.js +572 -0
  102. package/src/vcs/vcm/oblique/ObliqueDataSet.js +357 -0
  103. package/src/vcs/vcm/oblique/ObliqueImage.js +247 -0
  104. package/src/vcs/vcm/oblique/ObliqueImageMeta.js +126 -0
  105. package/src/vcs/vcm/oblique/ObliqueProvider.js +433 -0
  106. package/src/vcs/vcm/oblique/ObliqueView.js +130 -0
  107. package/src/vcs/vcm/oblique/ObliqueViewDirection.js +40 -0
  108. package/src/vcs/vcm/oblique/helpers.js +483 -0
  109. package/src/vcs/vcm/oblique/parseImageJson.js +248 -0
  110. package/src/vcs/vcm/util/clipping/clippingObject.js +386 -0
  111. package/src/vcs/vcm/util/clipping/clippingObjectManager.js +312 -0
  112. package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +413 -0
  113. package/src/vcs/vcm/util/collection.js +193 -0
  114. package/src/vcs/vcm/util/dateTime.js +60 -0
  115. package/src/vcs/vcm/util/exclusiveManager.js +135 -0
  116. package/src/vcs/vcm/util/extent.js +124 -0
  117. package/src/vcs/vcm/util/featureProvider/abstractFeatureProvider.js +196 -0
  118. package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +51 -0
  119. package/src/vcs/vcm/util/featureProvider/featureProviderSymbols.js +11 -0
  120. package/src/vcs/vcm/util/featureProvider/tileProviderFeatureProvider.js +62 -0
  121. package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +280 -0
  122. package/src/vcs/vcm/util/featureconverter/circleToCesium.js +215 -0
  123. package/src/vcs/vcm/util/featureconverter/convert.js +83 -0
  124. package/src/vcs/vcm/util/featureconverter/extent3d.js +154 -0
  125. package/src/vcs/vcm/util/featureconverter/featureconverterHelper.js +591 -0
  126. package/src/vcs/vcm/util/featureconverter/lineStringToCesium.js +171 -0
  127. package/src/vcs/vcm/util/featureconverter/pointToCesium.js +359 -0
  128. package/src/vcs/vcm/util/featureconverter/polygonToCesium.js +229 -0
  129. package/src/vcs/vcm/util/geometryHelpers.js +172 -0
  130. package/src/vcs/vcm/util/indexedCollection.js +158 -0
  131. package/src/vcs/vcm/util/isMobile.js +12 -0
  132. package/src/vcs/vcm/util/layerCollection.js +216 -0
  133. package/src/vcs/vcm/util/locale.js +53 -0
  134. package/src/vcs/vcm/util/mapCollection.js +363 -0
  135. package/src/vcs/vcm/util/math.js +71 -0
  136. package/src/vcs/vcm/util/projection.js +348 -0
  137. package/src/vcs/vcm/util/splitScreen.js +233 -0
  138. package/src/vcs/vcm/util/style/declarativeStyleItem.js +631 -0
  139. package/src/vcs/vcm/util/style/shapesCategory.js +67 -0
  140. package/src/vcs/vcm/util/style/styleFactory.js +48 -0
  141. package/src/vcs/vcm/util/style/styleHelpers.js +555 -0
  142. package/src/vcs/vcm/util/style/styleItem.js +226 -0
  143. package/src/vcs/vcm/util/style/vectorStyleItem.js +927 -0
  144. package/src/vcs/vcm/util/style/writeStyle.js +48 -0
  145. package/src/vcs/vcm/util/urlHelpers.js +16 -0
  146. package/src/vcs/vcm/util/viewpoint.js +333 -0
@@ -0,0 +1,229 @@
1
+ import {
2
+ Cartesian3,
3
+ PolygonGeometry,
4
+ PerInstanceColorAppearance,
5
+ PolygonOutlineGeometry,
6
+ GroundPolylineGeometry,
7
+ PolygonHierarchy,
8
+ PolylineGeometry,
9
+ } from '@vcmap/cesium';
10
+ import GeometryType from 'ol/geom/GeometryType.js';
11
+ import { parseNumber } from '@vcsuite/parsers';
12
+ import { addPrimitivesToContext } from './featureconverterHelper.js';
13
+ import Projection from '../projection.js';
14
+ import { getFlatCoordinatesFromSimpleGeometry } from '../geometryHelpers.js';
15
+
16
+ /**
17
+ * @param {Object} options
18
+ * @param {number} height
19
+ * @param {boolean} perPositionHeight
20
+ * @param {number=} extrudedHeight
21
+ * @returns {Array<import("@vcmap/cesium").PolygonGeometry>}
22
+ * @private
23
+ */
24
+ export function createSolidGeometries(options, height, perPositionHeight, extrudedHeight) {
25
+ const polygonOptions = {
26
+ ...options,
27
+ perPositionHeight,
28
+ extrudedHeight,
29
+ };
30
+ if (!perPositionHeight) {
31
+ polygonOptions.height = height;
32
+ }
33
+ return [new PolygonGeometry(polygonOptions)];
34
+ }
35
+
36
+ /**
37
+ * @param {Object} options
38
+ * @param {number} height
39
+ * @param {boolean} perPositionHeight
40
+ * @param {number=} extrudedHeight
41
+ * @returns {Array<import("@vcmap/cesium").PolygonOutlineGeometry>}
42
+ * @private
43
+ */
44
+ export function createOutlineGeometries(options, height, perPositionHeight, extrudedHeight) {
45
+ return [new PolygonOutlineGeometry({
46
+ ...options,
47
+ height: perPositionHeight ? undefined : height,
48
+ extrudedHeight,
49
+ perPositionHeight,
50
+ vertexFormat: PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
51
+ })];
52
+ }
53
+
54
+ /**
55
+ * @param {Object} options
56
+ * @param {number} height
57
+ * @param {boolean} perPositionHeight
58
+ * @returns {Array<import("@vcmap/cesium").PolygonGeometry>}
59
+ * @private
60
+ */
61
+ export function createFillGeometries(options, height, perPositionHeight) {
62
+ return createSolidGeometries(options, height, perPositionHeight, undefined);
63
+ }
64
+
65
+ /**
66
+ * @param {Object} options
67
+ * @param {import("ol/style/Style").default} style
68
+ * @returns {Array<Object>}
69
+ * @private
70
+ */
71
+ export function getLineGeometryOptions(options, style) {
72
+ const width = parseNumber(style.getStroke().getWidth(), 1.0);
73
+ const geometryOptions = [];
74
+ geometryOptions.push({
75
+ positions: options.polygonHierarchy.positions,
76
+ width,
77
+ });
78
+ options.polygonHierarchy.holes.forEach((polygonHierarchy) => {
79
+ geometryOptions.push({
80
+ positions: polygonHierarchy.positions,
81
+ width,
82
+ });
83
+ });
84
+ return geometryOptions;
85
+ }
86
+
87
+ /**
88
+ * @param {Object} options
89
+ * @param {import("ol/style/Style").default} style
90
+ * @returns {Array<GroundPolylineGeometry>}
91
+ * @private
92
+ */
93
+ export function createGroundLineGeometries(options, style) {
94
+ return getLineGeometryOptions(options, style).map((option) => {
95
+ return new GroundPolylineGeometry(option);
96
+ });
97
+ }
98
+
99
+ /**
100
+ * @param {Object} options
101
+ * @param {import("ol/style/Style").default} style
102
+ * @returns {Array<PolylineGeometry>}
103
+ * @private
104
+ */
105
+ export function createLineGeometries(options, style) {
106
+ return getLineGeometryOptions(options, style).map((option) => {
107
+ return new PolylineGeometry(option);
108
+ });
109
+ }
110
+
111
+
112
+ /**
113
+ * @param {import("ol/geom/Polygon").default} geometry
114
+ * @param {number} positionHeightAdjustment
115
+ * @returns {Object}
116
+ * @private
117
+ */
118
+ export function getGeometryOptions(geometry, positionHeightAdjustment) {
119
+ let hieraryPositions;
120
+ const holes = [];
121
+ const rings = geometry.getLinearRings();
122
+ for (let i = 0; i < rings.length; i++) {
123
+ const coords = rings[i].getCoordinates();
124
+ const positions = coords.map((coord) => {
125
+ const wgs84Coords = Projection.mercatorToWgs84(coord);
126
+ if (wgs84Coords[2] != null) {
127
+ wgs84Coords[2] += positionHeightAdjustment;
128
+ }
129
+ return Cartesian3.fromDegrees(wgs84Coords[0], wgs84Coords[1], wgs84Coords[2]);
130
+ });
131
+ // make sure the last and first vertex is identical.
132
+ if (!Cartesian3.equals(positions[0], positions[positions.length - 1])) {
133
+ positions.push(positions[0]);
134
+ }
135
+ if (i === 0) {
136
+ hieraryPositions = positions;
137
+ } else {
138
+ holes.push(new PolygonHierarchy(positions));
139
+ }
140
+ }
141
+ return {
142
+ polygonHierarchy: new PolygonHierarchy(hieraryPositions, holes),
143
+ };
144
+ }
145
+
146
+ /**
147
+ * @param {Array<import("ol/geom/Polygon").default>} geometries
148
+ * @returns {Array<import("ol/coordinate").Coordinate>}
149
+ * @private
150
+ */
151
+ export function getCoordinates(geometries) {
152
+ const coordinates = [];
153
+ geometries.forEach((polygon) => {
154
+ coordinates.push(...getFlatCoordinatesFromSimpleGeometry(polygon));
155
+ });
156
+ return coordinates;
157
+ }
158
+
159
+ /**
160
+ * @type {VectorGeometryFactoryType|null}
161
+ */
162
+ let geometryFactory = null;
163
+
164
+ /**
165
+ * @returns {VectorGeometryFactoryType}
166
+ */
167
+ function getGeometryFactory() {
168
+ if (!geometryFactory) {
169
+ geometryFactory = {
170
+ getCoordinates,
171
+ getGeometryOptions,
172
+ createSolidGeometries,
173
+ createOutlineGeometries,
174
+ createFillGeometries,
175
+ createGroundLineGeometries,
176
+ createLineGeometries,
177
+ };
178
+ }
179
+ return geometryFactory;
180
+ }
181
+
182
+ /**
183
+ * TODO maybe add validation Functions to Openlayers
184
+ * validates if a polygon is renderable
185
+ * @param {import("ol/geom/Polygon").default} polygon
186
+ * @returns {boolean}
187
+ */
188
+ export function validatePolygon(polygon) {
189
+ if (polygon.getType() !== GeometryType.POLYGON) {
190
+ return false;
191
+ }
192
+ const flatCoordinates = polygon.getFlatCoordinates();
193
+ const ends = polygon.getEnds();
194
+ const stride = polygon.getStride();
195
+ const valid = ends.every((end, index) => {
196
+ const previous = index ? ends[index - 1] : 0;
197
+ const currentRingSize = end - previous;
198
+ return currentRingSize >= stride * 3;
199
+ });
200
+ if (!valid) {
201
+ return false;
202
+ }
203
+ // should have at least three coordinates for each linearRing and every value should be a number
204
+ const minimumValues = stride * 3 * polygon.getLinearRingCount();
205
+ if (flatCoordinates && flatCoordinates.length >= minimumValues && polygon.getLinearRingCount()) {
206
+ return flatCoordinates.every(value => Number.isFinite(value));
207
+ }
208
+ return false;
209
+ }
210
+
211
+ /**
212
+ * converts a polygon to a a cesium primitive, with optional labels
213
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
214
+ * @param {import("ol/style/Style").default} style
215
+ * @param {Array<import("ol/geom/Polygon").default>} geometries
216
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
217
+ * @param {import("@vcmap/cesium").Scene} scene
218
+ * @param {import("@vcmap/core").VectorContext|import("@vcmap/core").ClusterContext} context
219
+ */
220
+ export default function polygonToCesium(feature, style, geometries, vectorProperties, scene, context) {
221
+ if (!style.getFill() && !style.getStroke()) {
222
+ return;
223
+ }
224
+ const polygonGeometryFactory = getGeometryFactory();
225
+ const validGeometries = geometries.filter(polygon => validatePolygon(polygon));
226
+ addPrimitivesToContext(
227
+ feature, style, validGeometries, vectorProperties, scene, polygonGeometryFactory, context,
228
+ );
229
+ }
@@ -0,0 +1,172 @@
1
+ import { offset } from 'ol/sphere.js';
2
+ import Circle from 'ol/geom/Circle.js';
3
+ import Point from 'ol/geom/Point.js';
4
+ import LineString from 'ol/geom/LineString.js';
5
+ import Polygon, { fromCircle } from 'ol/geom/Polygon.js';
6
+ import MultiPoint from 'ol/geom/MultiPoint.js';
7
+ import MultiLineString from 'ol/geom/MultiLineString.js';
8
+ import MultiPolygon from 'ol/geom/MultiPolygon.js';
9
+ import GeometryCollection from 'ol/geom/GeometryCollection.js';
10
+ import Projection from './projection.js';
11
+
12
+ /**
13
+ * @param {import("ol/geom/SimpleGeometry").default} geometry
14
+ * @returns {Array<import("ol/coordinate").Coordinate>}
15
+ */
16
+ export function getFlatCoordinatesFromSimpleGeometry(geometry) {
17
+ const stride = geometry.getStride();
18
+ const flatCoordinates = geometry.getFlatCoordinates();
19
+ if (flatCoordinates.length) {
20
+ const numberOfCoordinates = Math.floor(flatCoordinates.length / stride);
21
+ const coordinates = new Array(numberOfCoordinates);
22
+ for (let i = 0; i < numberOfCoordinates; i++) {
23
+ const flatIndex = i * stride;
24
+ const coord = new Array(stride);
25
+ for (let j = 0; j < stride; j++) {
26
+ coord[j] = flatCoordinates[flatIndex + j];
27
+ }
28
+ coordinates[i] = coord;
29
+ }
30
+ return coordinates;
31
+ }
32
+ return [];
33
+ }
34
+
35
+ /**
36
+ * @param {import("ol/geom/Geometry").default} geometry
37
+ * @param {Array=} inputCoordinates
38
+ * @returns {Array.<import("ol/coordinate").Coordinate>}
39
+ */
40
+ export function getFlatCoordinatesFromGeometry(geometry, inputCoordinates) {
41
+ const coordinates = inputCoordinates || geometry.getCoordinates();
42
+ let flattenCoordinates = null;
43
+ if (geometry instanceof Point) {
44
+ flattenCoordinates = [coordinates];
45
+ } else if (geometry instanceof LineString) {
46
+ flattenCoordinates = coordinates;
47
+ } else if (geometry instanceof Polygon) {
48
+ flattenCoordinates = coordinates.reduce((current, next) => current.concat(next));
49
+ } else if (geometry instanceof MultiPoint) {
50
+ flattenCoordinates = coordinates;
51
+ } else if (geometry instanceof MultiLineString) {
52
+ flattenCoordinates = coordinates.reduce((current, next) => current.concat(next));
53
+ } else if (geometry instanceof MultiPolygon) {
54
+ flattenCoordinates = coordinates
55
+ .reduce((current, next) => current.concat(next))
56
+ .reduce((current, next) => current.concat(next));
57
+ } else if (geometry instanceof Circle) {
58
+ flattenCoordinates = coordinates;
59
+ } else if (geometry instanceof GeometryCollection) {
60
+ flattenCoordinates = geometry.getGeometries()
61
+ .map((g, i) => getFlatCoordinatesFromGeometry(g, coordinates[i]))
62
+ .reduce((current, next) => current.concat(next));
63
+ }
64
+ return flattenCoordinates;
65
+ }
66
+
67
+ /**
68
+ * @param {import("ol/coordinate").Coordinate} center
69
+ * @param {number} radius
70
+ * @returns {import("ol/geom/Circle").default}
71
+ */
72
+ export function circleFromCenterRadius(center, radius) {
73
+ const offsetWGS84 = offset(Projection.mercatorToWgs84(center), radius, Math.PI / 2);
74
+ const of = Projection.wgs84ToMercator(offsetWGS84);
75
+ const dx = center[0] - of[0];
76
+ const dy = center[1] - of[1];
77
+ const dx2 = dx * dx;
78
+ const dy2 = dy * dy;
79
+ const radiusProjected = Math.sqrt(dx2 + dy2);
80
+ return new Circle(
81
+ center,
82
+ radiusProjected,
83
+ 'XYZ',
84
+ );
85
+ }
86
+
87
+ /**
88
+ * @param {import("ol/geom/Geometry").default} geometry
89
+ * @returns {import("ol/geom/Geometry").default}
90
+ */
91
+ export function convertGeometryToPolygon(geometry) {
92
+ if (geometry instanceof Circle) {
93
+ return fromCircle(geometry);
94
+ } else if (geometry instanceof Polygon) {
95
+ geometry.unset('_vcsGeomType');
96
+ }
97
+ return geometry;
98
+ }
99
+
100
+ /**
101
+ * @param {Array<import("ol/coordinate").Coordinate>} linearRing
102
+ */
103
+ export function enforceEndingVertex(linearRing) {
104
+ const [lastX, lastY] = linearRing[linearRing.length - 1];
105
+ if (!(linearRing[0][0] === lastX && linearRing[0][1] === lastY)) {
106
+ linearRing.push(linearRing[0].slice());
107
+ }
108
+ }
109
+
110
+ /**
111
+ * @param {Array<import("ol/coordinate").Coordinate>} linearRing
112
+ */
113
+ export function removeEndingVertex(linearRing) {
114
+ const [lastX, lastY] = linearRing[linearRing.length - 1];
115
+ if (linearRing[0][0] === lastX && linearRing[0][1] === lastY) {
116
+ linearRing.pop();
117
+ }
118
+ }
119
+
120
+ /**
121
+ * @param {import("ol/geom/Geometry").default} geometry
122
+ */
123
+ export function removeEndingVertexFromGeometry(geometry) {
124
+ if (geometry instanceof Polygon) {
125
+ const coordinates = geometry.getCoordinates();
126
+ coordinates.forEach((ring) => {
127
+ removeEndingVertex(ring);
128
+ });
129
+ geometry.setCoordinates(coordinates);
130
+ } else if (geometry instanceof MultiPolygon) {
131
+ const coordinates = geometry.getCoordinates();
132
+ coordinates.forEach((poly) => {
133
+ poly.forEach((ring) => {
134
+ removeEndingVertex(ring);
135
+ });
136
+ });
137
+ geometry.setCoordinates(coordinates);
138
+ }
139
+ }
140
+
141
+ /**
142
+ * from @mapbox/geojson-area
143
+ * @param {Array<Array<number>>}ring
144
+ * @returns {number}
145
+ */
146
+ function ringArea(ring) {
147
+ let area = 0;
148
+ const positions = ring.length;
149
+
150
+ for (let i = 0; i <= positions - 2; i++) {
151
+ const p1 = ring[i];
152
+ const p2 = ring[i + 1];
153
+ area += ((p1[0] * p2[1]) - (p1[1] * p2[0]));
154
+ }
155
+
156
+ area /= 2;
157
+ return area;
158
+ }
159
+
160
+ /**
161
+ * enforce a ring to be counter-clockwise
162
+ * @param {Array<import("ol/coordinate").Coordinate>} ring
163
+ * @returns {Array<import("ol/coordinate").Coordinate>}
164
+ */
165
+ export function enforceRightHand(ring) {
166
+ const area = ringArea(ring);
167
+ if (area < 0) {
168
+ ring.reverse();
169
+ }
170
+
171
+ return ring;
172
+ }
@@ -0,0 +1,158 @@
1
+ import VcsEvent from '../event/vcsEvent.js';
2
+ import Collection from './collection.js';
3
+
4
+ /**
5
+ * A generic array based collection. Implements the Symbol.iterator (e.g. [...collection])
6
+ * @class
7
+ * @export
8
+ * @template {*} T
9
+ * @extends {Collection<T>}
10
+ * @api
11
+ */
12
+ class IndexedCollection extends Collection {
13
+ /**
14
+ * Creates a Collection from an iterable, such as an Array.
15
+ * @template {*} T
16
+ * @param {Iterable<T>} iterable
17
+ * @param {(string|symbol|boolean)=} [uniqueKey='name'] - a key to maintain uniquely within the collection. passing false disables uniqueness.
18
+ * @returns {IndexedCollection<T>}
19
+ * @override
20
+ * @api
21
+ */
22
+ static from(iterable, uniqueKey) {
23
+ const collection = /** @type {IndexedCollection<T>} */ (new IndexedCollection(uniqueKey));
24
+ if (iterable) {
25
+ // eslint-disable-next-line no-restricted-syntax
26
+ for (const i of iterable) {
27
+ collection.add(i);
28
+ }
29
+ }
30
+ return collection;
31
+ }
32
+
33
+ /**
34
+ * @param {(string|symbol|boolean)=} [uniqueKey='name'] - a key to maintain uniquely within the collection. passing false disables uniqueness.
35
+ */
36
+ constructor(uniqueKey) {
37
+ super(uniqueKey);
38
+
39
+ /**
40
+ * Event raised if an item is relocated within the collection. Is passed the moved item.
41
+ * @type {VcsEvent<T>}
42
+ * @api
43
+ */
44
+ this.moved = new VcsEvent();
45
+ }
46
+
47
+ /**
48
+ * Returns an item at index.
49
+ * @param {number} index
50
+ * @returns {T}
51
+ * @api
52
+ */
53
+ get(index) {
54
+ return this._array[index];
55
+ }
56
+
57
+ /**
58
+ * Adds an item to the collection. Can optionally be passed an index at which to insert the item.
59
+ * @param {T} item - the item to be inserted
60
+ * @param {number=} index - an optional index at which to insert the item. clipped to the last entry
61
+ * @returns {number|null} the index at which the item was inserted
62
+ * @api
63
+ */
64
+ add(item, index) {
65
+ if (this._checkUniqueness(item)) {
66
+ let actualIndex = this._array.length;
67
+ if (index != null && index < this._array.length) {
68
+ actualIndex = index >= 0 ? index : 0;
69
+ this._array.splice(actualIndex, 0, item);
70
+ } else {
71
+ this._array.push(item);
72
+ }
73
+ this.added.raiseEvent(item);
74
+ return actualIndex;
75
+ }
76
+ return null;
77
+ }
78
+
79
+ /**
80
+ * @param {T} item
81
+ * @param {number} itemIndex
82
+ * @param {number} targetIndex
83
+ * @returns {number}
84
+ * @protected
85
+ */
86
+ _move(item, itemIndex, targetIndex) {
87
+ let target = targetIndex;
88
+ target = target >= 0 ? target : 0;
89
+ target = target < this._array.length ? target : this._array.length - 1;
90
+ this._array.splice(itemIndex, 1);
91
+ this._array.splice(target, 0, item);
92
+ this.moved.raiseEvent(item);
93
+ return target;
94
+ }
95
+
96
+ /**
97
+ * Lowers an item within the array
98
+ * @param {T} item
99
+ * @param {number} [steps=1] - an integer number to lower by
100
+ * @returns {number|null} the new index of the item
101
+ * @api
102
+ */
103
+ lower(item, steps = 1) {
104
+ const index = this._array.indexOf(item);
105
+ if (index > -1) {
106
+ return this._move(item, index, index - Math.ceil(steps));
107
+ }
108
+ return null;
109
+ }
110
+
111
+ /**
112
+ * Raises an item within the array
113
+ * @param {T} item
114
+ * @param {number} [steps=1] - an integer number to lower by
115
+ * @returns {number|null} the new index of the item
116
+ * @api
117
+ */
118
+ raise(item, steps = 1) {
119
+ const index = this._array.indexOf(item);
120
+ if (index > -1) {
121
+ return this._move(item, index, index + Math.ceil(steps));
122
+ }
123
+ return null;
124
+ }
125
+
126
+ /**
127
+ * Returns the index of an item or -1 if it is not part of this collection
128
+ * @param {T} item
129
+ * @returns {number}
130
+ * @api
131
+ */
132
+ indexOf(item) {
133
+ return this._array.indexOf(item);
134
+ }
135
+
136
+ /**
137
+ * Returns the index of a key. Returns undefined, if there is no uniqueness constraint
138
+ * @param {*} value
139
+ * @returns {number}
140
+ * @api
141
+ */
142
+ indexOfKey(value) {
143
+ if (!this.uniqueKey) {
144
+ return undefined;
145
+ }
146
+ return this._array.findIndex(e => e[this.uniqueKey] === value);
147
+ }
148
+
149
+ /**
150
+ * @inheritDoc
151
+ */
152
+ destroy() {
153
+ super.destroy();
154
+ this.moved.destroy();
155
+ }
156
+ }
157
+
158
+ export default IndexedCollection;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * returns true if we are on a mobile device including tablets
3
+ * @returns {boolean}
4
+ * @api
5
+ */
6
+ // eslint-disable-next-line import/prefer-default-export
7
+ export function isMobile() {
8
+ // @ts-ignore
9
+ const agent = navigator.userAgent || navigator.vendor || window.opera;
10
+ return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(agent) ||
11
+ /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(agent.substr(0, 4));
12
+ }