@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,927 @@
1
+ /* eslint-disable no-template-curly-in-string */
2
+ import Stroke from 'ol/style/Stroke.js';
3
+ import { Color, VerticalOrigin } from '@vcmap/cesium';
4
+ import Icon from 'ol/style/Icon.js';
5
+ import Style from 'ol/style/Style.js';
6
+ import OLText from 'ol/style/Text.js';
7
+ import OLImage from 'ol/style/Image.js';
8
+ import Fill from 'ol/style/Fill.js';
9
+ import Circle from 'ol/style/Circle.js';
10
+ import RegularShape from 'ol/style/RegularShape.js';
11
+
12
+ import { check, checkMaybe } from '@vcsuite/check';
13
+ import StyleItem, { StyleType } from './styleItem.js';
14
+ import {
15
+ parseColor,
16
+ PatternType,
17
+ createPattern,
18
+ getFillOptions,
19
+ getStrokeOptions,
20
+ getTextOptions,
21
+ getTextFromOptions,
22
+ getStringColor,
23
+ getDefaultCondition,
24
+ getDefaultVectorStyleItemOptions,
25
+ } from './styleHelpers.js';
26
+ import { getShapeFromOptions } from './shapesCategory.js';
27
+
28
+ /**
29
+ * @typedef {Object} VectorStyleItemPattern
30
+ * @property {PatternType} type
31
+ * @property {import("ol/color").Color|import("ol/colorlike").ColorLike} color
32
+ * @property {number} width
33
+ * @property {number} size
34
+ * @api
35
+ */
36
+
37
+ /**
38
+ * @typedef {Object} VectorStyleItemFill
39
+ * @property {import("ol/color").Color|import("ol/colorlike").ColorLike} color
40
+ * @property {VectorStyleItemPattern|undefined} pattern
41
+ * @api
42
+ */
43
+
44
+ /**
45
+ * This is either <b>olx.style.IconOptions</b> or <b>olx.style.CircleOptions</b>
46
+ * @typedef {Object} VectorStyleItemImage
47
+ * @property {string|undefined} src
48
+ * @property {number|import("ol/size").Size|undefined} scale
49
+ * @property {number|undefined} opacity
50
+ * @property {import("ol/color").Color|import("ol/colorlike").ColorLike|undefined} color
51
+ * @property {import("ol/style/Fill").Options|import("ol/style/Fill").default|undefined} fill
52
+ * @property {import("ol/style/Stroke").Options|import("ol/style/Stroke").default|undefined} stroke
53
+ * @property {number|undefined} radius
54
+ * @property {number|undefined} points
55
+ * @property {number|undefined} angle
56
+ * @property {Array<number>|undefined} anchor
57
+ * @property {VectorStyleItemImage|undefined} circle - vcs:undocumented legacy
58
+ * @property {VectorStyleItemImage|undefined} icon - vcs:undocumented legacy
59
+ * @property {string|undefined} currentImage - vcs:undocumented styleEditor
60
+ * @api
61
+ */
62
+
63
+ /**
64
+ * @typedef {Object} VectorStyleItemText
65
+ * @property {string|undefined} text
66
+ * @property {string|FontObject|undefined} font
67
+ * @property {import("ol/style/Fill").Options|import("ol/style/Fill").default|undefined} fill
68
+ * @property {import("ol/style/Stroke").Options|import("ol/style/Stroke").default|undefined} stroke
69
+ * @property {string|undefined} textBaseline
70
+ * @property {number|undefined} offsetX
71
+ * @property {number|undefined} offsetY
72
+ * @api
73
+ */
74
+
75
+ /**
76
+ * @typedef {Object} VectorStyleItemExclusion
77
+ * @property {boolean} fill
78
+ * @property {boolean} stroke
79
+ * @property {boolean} image
80
+ * @api
81
+ */
82
+
83
+ /**
84
+ * @typedef {StyleItemSections} VectorStyleItemSections
85
+ * @property {boolean|undefined} fill
86
+ * @property {boolean|undefined} stroke
87
+ * @property {boolean|undefined} text
88
+ * @property {boolean|undefined} image
89
+ * @property {boolean|undefined} label
90
+ * @api
91
+ */
92
+
93
+ /**
94
+ * @enum {number}
95
+ * @property {number} POLYGON
96
+ * @property {number} POLYLINE
97
+ * @property {number} POINT
98
+ */
99
+ export const olcsGeometryType = {
100
+ POLYGON: 1,
101
+ POLYLINE: 2,
102
+ POINT: 3,
103
+ };
104
+
105
+ /**
106
+ * @typedef {StyleItemOptions} VectorStyleItemOptions
107
+ * @property {VectorStyleItemFill|false|undefined} fill
108
+ * @property {import("ol/style/Stroke").Options|false|undefined} stroke
109
+ * @property {VectorStyleItemImage|false|undefined} image
110
+ * @property {VectorStyleItemText|undefined} text
111
+ * @property {string|undefined} label
112
+ * @api
113
+ */
114
+
115
+ /**
116
+ * Is set on a feature and is used to signal that the feature has a specific vectorStyleItem.
117
+ * Is set by the Editor if the layerStyle is overwritten. The Vector layer assures this style is set, if
118
+ * the style on the layer is not a DeclarativeStyle
119
+ * @type {symbol}
120
+ * @export
121
+ */
122
+ export const vectorStyleSymbol = Symbol('VcsVectorStyleItem');
123
+
124
+ /**
125
+ * @class
126
+ * @extends {StyleItem}
127
+ * @export
128
+ * @api
129
+ */
130
+ class VectorStyleItem extends StyleItem {
131
+ static get className() { return 'vcs.vcm.util.style.VectorStyleItem'; }
132
+
133
+ /**
134
+ * @param {VectorStyleItemOptions} options
135
+ */
136
+ constructor(options) {
137
+ super(options);
138
+
139
+ this.validateOptions(options);
140
+ /**
141
+ * @type {VectorStyleItemExclusion}
142
+ * @api
143
+ */
144
+ this.exclude = {
145
+ fill: options.fill === false,
146
+ stroke: options.stroke === false,
147
+ image: options.image === false,
148
+ };
149
+ /**
150
+ * @type {VectorStyleItemFill|null}
151
+ * @private
152
+ */
153
+ this._fillOptions = null;
154
+ /**
155
+ * @type {import("ol/style/Fill").default|undefined}
156
+ * @private
157
+ */
158
+ this._fill = undefined;
159
+
160
+ /**
161
+ * @type {import("ol/style/Stroke").default|undefined}
162
+ * @private
163
+ */
164
+ this._stroke = options.stroke ? new Stroke(options.stroke) : undefined;
165
+
166
+ /**
167
+ * @type {import("ol/style/Text").default|undefined}
168
+ * @private
169
+ */
170
+ this._text = undefined;
171
+ if (options.text) {
172
+ this._text = getTextFromOptions(options.text);
173
+ }
174
+
175
+ /**
176
+ * @type {string|undefined}
177
+ * @private
178
+ */
179
+ this._label = options.label;
180
+ this.label = this._label;
181
+
182
+ /**
183
+ * @type {import("@vcmap/cesium").Color}
184
+ * @private
185
+ */
186
+ this._cesiumColor = new Color();
187
+
188
+ /**
189
+ * @type {import("ol/style/Icon").default|import("ol/style/RegularShape").default|undefined}
190
+ * @private
191
+ */
192
+ this._image = undefined;
193
+ if (options.image) {
194
+ this._image = options.image.radius ?
195
+ getShapeFromOptions({ ...options.image }) :
196
+ new Icon(/** @type {import("ol/style/Icon").Options} */ (options.image));
197
+ }
198
+
199
+ /**
200
+ * @type {import("ol/style/Style").default|import("ol/style/Style").StyleFunction}
201
+ */
202
+ this._style = new Style({
203
+ image: this._image,
204
+ stroke: this._stroke,
205
+ text: this._text,
206
+ });
207
+
208
+ if (options.fill) {
209
+ this._fillOptions = options.fill;
210
+ this._setFill();
211
+ } else {
212
+ this.updateCesiumStyle();
213
+ }
214
+ }
215
+
216
+ /**
217
+ * @param {VectorStyleItemOptions} options
218
+ */
219
+ validateOptions(options) {
220
+ const checkColor = (option) => {
221
+ try {
222
+ option.color = parseColor(option.color);
223
+ check(option.color, [Number]);
224
+ check(option.color.length, [3, 4]);
225
+ } catch (e) {
226
+ this.getLogger().error(e.message);
227
+ option.color = /** @type {import("ol/color").Color} */ ([255, 255, 255, 0.4]);
228
+ }
229
+ };
230
+
231
+ const checkStroke = (option) => {
232
+ checkColor(option);
233
+ if (!option.width) {
234
+ this.getLogger().error('missing width for stroke, setting to 1.5');
235
+ option.width = 1.5;
236
+ }
237
+ };
238
+
239
+ if (options.fill) {
240
+ checkColor(options.fill);
241
+ if (options.fill.pattern) {
242
+ checkStroke(options.fill.pattern);
243
+ if (!(options.fill.pattern.type && Object.values(PatternType).includes(options.fill.pattern.type))) {
244
+ this.getLogger().error(`Cannot find pattern ${options.fill.pattern.type}`);
245
+ options.fill.pattern.type = PatternType.NWSE;
246
+ }
247
+ }
248
+ }
249
+
250
+ if (options.stroke) {
251
+ checkStroke(options.stroke);
252
+ }
253
+
254
+ if (options.image) {
255
+ // XXX Legacy...
256
+ if (options.image.icon) {
257
+ options.image = options.image.icon;
258
+ } else if (options.image.circle) {
259
+ options.image = options.image.circle;
260
+ }
261
+
262
+ if (!(options.image.src || options.image.radius)) {
263
+ this.getLogger().error('missing source or label in style, setting default circle');
264
+ options.image = {
265
+ fill: {
266
+ color: 'rgba(255,255,255,0.4)',
267
+ },
268
+ stroke: {
269
+ color: '#3399CC',
270
+ width: 1,
271
+ },
272
+ radius: 5,
273
+ };
274
+ }
275
+
276
+ if (options.image.radius) {
277
+ options.image.radius = Number(options.image.radius);
278
+ if (!Number.isFinite(options.image.radius)) {
279
+ this.getLogger().error('radius must be a number');
280
+ options.image.radius = 5;
281
+ }
282
+ if (options.image.fill) {
283
+ checkColor(options.image.fill);
284
+ }
285
+ if (options.image.stroke) {
286
+ checkStroke(options.image.stroke);
287
+ }
288
+ }
289
+ }
290
+ // TODO text validation
291
+ }
292
+
293
+ /**
294
+ * the current fill color, not the pattern
295
+ * @type {import("ol/color").Color|null}
296
+ * @api
297
+ */
298
+ get fillColor() {
299
+ return this._fillOptions ? /** @type {import("ol/color").Color} */ (this._fillOptions.color) : null;
300
+ }
301
+
302
+ /**
303
+ * the current fill color as a cesium color
304
+ * @readonly
305
+ * @type {import("@vcmap/cesium").Color}
306
+ * @api
307
+ */
308
+ get cesiumFillColor() {
309
+ const fillColor = this.fillColor ? this.fillColor.slice() : null;
310
+ if (fillColor) {
311
+ fillColor[3] = fillColor[3] || 1;
312
+ fillColor[3] *= 255; // cesium alpha range between 0 and 255
313
+ // @ts-ignore
314
+ return Color.fromBytes(...fillColor, this._cesiumColor);
315
+ }
316
+ return Color.RED.clone(this._cesiumColor); // TODO should not be red - transparent?
317
+ }
318
+
319
+ /**
320
+ * @param {(import("ol/color").Color|import("ol/colorlike").ColorLike)=} color
321
+ */
322
+ set fillColor(color) {
323
+ this.exclude.fill = false;
324
+ if (this._style instanceof Style) {
325
+ if (!color) {
326
+ this._fillOptions = null;
327
+ this._fill = undefined;
328
+ this._style.setFill(this._fill);
329
+ this.updateCesiumStyleColor(true);
330
+ } else {
331
+ if (!this._fillOptions) {
332
+ this._fillOptions = { color: parseColor(color) };
333
+ } else {
334
+ this._fillOptions.color = parseColor(color);
335
+ }
336
+ this._setFill();
337
+ }
338
+ } else {
339
+ this.getLogger().info('trying to set fill on a style function');
340
+ }
341
+ }
342
+
343
+ /**
344
+ * @type {VectorStyleItemPattern}
345
+ * @api
346
+ */
347
+ get pattern() {
348
+ return this._fillOptions && this._fillOptions.pattern ? this._fillOptions.pattern : null;
349
+ }
350
+
351
+ /**
352
+ * @param {VectorStyleItemPattern} patternOptions
353
+ */
354
+ set pattern(patternOptions) {
355
+ if (!this._fillOptions) {
356
+ this.getLogger().error('Missing fill color');
357
+ return;
358
+ }
359
+ if (patternOptions) {
360
+ checkMaybe(patternOptions, {
361
+ color: [String, [Number]],
362
+ width: Number,
363
+ type: Number,
364
+ size: [Number, undefined, null],
365
+ }, true);
366
+ this._fillOptions.pattern = patternOptions;
367
+ } else {
368
+ this._fillOptions.pattern = undefined;
369
+ }
370
+ this._setFill();
371
+ }
372
+
373
+ /**
374
+ * @type {import("ol/style/Stroke").default}
375
+ * @api
376
+ */
377
+ get stroke() { return this._stroke; }
378
+
379
+ /**
380
+ * @param {import("ol/style/Stroke").default=} stroke
381
+ */
382
+ set stroke(stroke) {
383
+ this.exclude.stroke = false;
384
+ if (this._style instanceof Style) {
385
+ checkMaybe(stroke, Stroke);
386
+ this._style.setStroke(stroke);
387
+ this._stroke = stroke;
388
+ this.updateCesiumStyleColor(true);
389
+ } else {
390
+ this.getLogger().info('trying to set stroke on a style function');
391
+ }
392
+ }
393
+
394
+ /**
395
+ * @type {string}
396
+ * @api
397
+ */
398
+ get label() { return this._label; }
399
+
400
+ /**
401
+ * @param {string} label
402
+ */
403
+ set label(label) {
404
+ checkMaybe(label, String);
405
+ if (!label) {
406
+ this._label = undefined;
407
+ } else {
408
+ this._label = label;
409
+ }
410
+ if (this._text) {
411
+ this._text.setText(label);
412
+ }
413
+ }
414
+
415
+ /**
416
+ * @type {import("ol/style/Text").default}
417
+ * @api
418
+ */
419
+ get text() { return this._text; }
420
+
421
+ /**
422
+ * @param {import("ol/style/Text").default=} text
423
+ */
424
+ set text(text) {
425
+ if (this._style instanceof Style) {
426
+ checkMaybe(text, OLText);
427
+ this._text = text;
428
+ this._text.setText(this._label);
429
+ this._style.setText(this._text);
430
+ } else {
431
+ this.getLogger().info('trying to set text on a style function');
432
+ }
433
+ }
434
+
435
+ /**
436
+ * @type {(import("ol/style/Icon").default|import("ol/style/RegularShape").default)}
437
+ * @api
438
+ */
439
+ get image() { return this._image; }
440
+
441
+ /**
442
+ * @param {(import("ol/style/Icon").default|import("ol/style/RegularShape").default)=} image
443
+ */
444
+ set image(image) {
445
+ this.exclude.image = false;
446
+ if (this._style instanceof Style) {
447
+ checkMaybe(image, OLImage);
448
+ this._image = image;
449
+ this._style.setImage(this._image);
450
+ this.updateCesiumStyle();
451
+ } else {
452
+ this.getLogger().info('trying to set text on a style function');
453
+ }
454
+ }
455
+
456
+ /**
457
+ * @type {import("ol/style/Style").default|import("ol/style/Style").StyleFunction}
458
+ * @api
459
+ */
460
+ get style() { return this._style; }
461
+
462
+ /**
463
+ * @param {import("ol/style/Style").default|import("ol/style/Style").StyleFunction} style
464
+ */
465
+ set style(style) {
466
+ checkMaybe(style, [Style, Function]);
467
+ if (style instanceof Style) {
468
+ this._stroke = style.getStroke();
469
+ this._fill = style.getFill();
470
+ this._text = style.getText();
471
+ this._image = /** @type {import("ol/style/Icon").default|import("ol/style/Circle").default} */ (style.getImage());
472
+ } else {
473
+ this._stroke = undefined;
474
+ this._fill = undefined;
475
+ this._text = undefined;
476
+ this._image = undefined;
477
+ }
478
+ this._style = style;
479
+ if (this._fill && this._fill.getColor()) {
480
+ this._fillOptions = { color: parseColor(this._fill.getColor()) };
481
+ }
482
+ if (this._text) {
483
+ this._text.setText(this._label);
484
+ }
485
+ this.updateCesiumStyle();
486
+ }
487
+
488
+ /**
489
+ * @private
490
+ */
491
+ _setFill() {
492
+ if (this._style instanceof Style) {
493
+ const color = this._fillOptions.pattern ?
494
+ createPattern(this._fillOptions) :
495
+ this._fillOptions.color;
496
+ if (this._fill) {
497
+ this._fill.setColor(color);
498
+ } else {
499
+ this._fill = new Fill({ color });
500
+ this._style.setFill(this._fill);
501
+ }
502
+
503
+ if (this._fillOptions.pattern) {
504
+ this._fill.fallBackColor = this._fillOptions.color;
505
+ }
506
+ this.updateCesiumStyle();
507
+ }
508
+ }
509
+
510
+ updateCesiumStyle() {
511
+ this.updateCesiumStyleColor(true);
512
+ this.updateCesiumStyleImage(true);
513
+ this.updateCesiumStyleText(true);
514
+ this._styleChanged();
515
+ }
516
+
517
+ /**
518
+ *
519
+ * @param {boolean} silent
520
+ */
521
+ updateCesiumStyleColor(silent) {
522
+ const colorConditions = getDefaultCondition('olcs_color', true);
523
+ if (this.stroke && this.stroke.getColor()) {
524
+ colorConditions.splice(1, 0, [`\${olcs_geometryType}===${olcsGeometryType.POLYLINE}`, getStringColor(this.stroke.getColor())]);
525
+ }
526
+ if (this._image instanceof Circle && this._image.getFill()) {
527
+ colorConditions.splice(
528
+ 1, 0,
529
+ [`\${olcs_geometryType}===${olcsGeometryType.POINT}`, getStringColor(this._image.getFill().getColor())],
530
+ );
531
+ }
532
+ if (this.fillColor) {
533
+ colorConditions.splice(-1, 1, ['true', getStringColor(this.fillColor)]);
534
+ }
535
+ // @ts-ignore
536
+ this.cesiumStyle.color = { conditions: colorConditions };
537
+
538
+ if (!silent) {
539
+ this._styleChanged();
540
+ }
541
+ }
542
+
543
+ updateCesiumStyleImage(silent) {
544
+ /* this.cesiumStyle.show = {
545
+ conditions: [
546
+ ['${olcs_color}===false', false],
547
+ ['true', 'true'],
548
+ ],
549
+ } */
550
+ const scaleConditions = getDefaultCondition('olcs_scale');
551
+ const pointOutlineWidthConditions = getDefaultCondition('olcs_outlineWidth');
552
+ const pointOutlineColorConditions = getDefaultCondition('olcs_outlineColor', true);
553
+ const pointSizeConditions = getDefaultCondition('olcs_pointSize');
554
+ const imageConditions = getDefaultCondition('olcs_image');
555
+ /* commented out, because we simulate the anchorline via a line in the tileset, TODO Evaluate again
556
+ const heightOffsetCondition = [
557
+ [defaultExtrudedHeightCondition, '${attributes.olcs_extrudedHeight}'],
558
+ ['true', '0'],
559
+ ];
560
+ const anchorLineEnabledConditions = [
561
+ [defaultExtrudedHeightCondition, 'true'],
562
+ ['true', 'false'],
563
+ ];
564
+ const anchorLineColorConditions = getDefaultCondition('olcs_anchorLineColor', true);
565
+ */
566
+ if (this._image) {
567
+ if (this._image.getScale() != null) {
568
+ scaleConditions.splice(1, 1, ['true', `${this._image.getScale()}`]);
569
+ }
570
+ if (this._image instanceof Circle) {
571
+ const stroke = this._image.getStroke();
572
+ let size = this._image.getRadius() * 2;
573
+ if (stroke) {
574
+ if (this._image.getStroke().getColor()) {
575
+ pointOutlineColorConditions.splice(1, 1, ['true', getStringColor(this._image.getStroke().getColor())]);
576
+ }
577
+ const width = this._image.getStroke().getWidth();
578
+ pointOutlineWidthConditions.splice(1, 1, ['true', `${width}`]);
579
+ size -= width;
580
+ }
581
+ pointSizeConditions.splice(1, 1, ['true', `${size}`]);
582
+ } else if (this._image instanceof RegularShape) {
583
+ const dataUrl = /** @type {HTMLCanvasElement} */ (this._image.getImage(1)).toDataURL();
584
+ imageConditions.splice(1, 1, ['true', `"${dataUrl}"`]);
585
+ } else if (this._image instanceof Icon) {
586
+ imageConditions.splice(1, 1, ['true', `"${this._image.getSrc()}"`]);
587
+ }
588
+ }
589
+ /*
590
+ if (this._stroke && this._stroke.getColor()) {
591
+ anchorLineColorConditions.splice(1, 1, ['true', getStringColor(this._stroke.getColor())]);
592
+ }
593
+ */
594
+ // @ts-ignore
595
+ this.cesiumStyle.scale = { conditions: scaleConditions };
596
+ // @ts-ignore
597
+ this.cesiumStyle.pointOutlineWidth = { conditions: pointOutlineWidthConditions };
598
+ // @ts-ignore
599
+ this.cesiumStyle.pointOutlineColor = { conditions: pointOutlineColorConditions };
600
+ // @ts-ignore
601
+ this.cesiumStyle.pointSize = { conditions: pointSizeConditions };
602
+ // @ts-ignore
603
+ this.cesiumStyle.image = { conditions: imageConditions };
604
+ /*
605
+ // @ts-ignore
606
+ this.cesiumStyle.heightOffset = { conditions: heightOffsetCondition };
607
+ // @ts-ignore
608
+ this.cesiumStyle.anchorLineEnabled = { conditions: anchorLineEnabledConditions };
609
+ // @ts-ignore
610
+ this.cesiumStyle.anchorLineColor = { conditions: anchorLineColorConditions };
611
+ */
612
+ // @ts-ignore
613
+ this.cesiumStyle.verticalOrigin = '1';
614
+ // @ts-ignore
615
+ this.cesiumStyle.horizontalOrigin = '0';
616
+ if (!silent) {
617
+ this._styleChanged();
618
+ }
619
+ }
620
+
621
+ updateCesiumStyleText(silent) {
622
+ const fontConditions = getDefaultCondition('olcs_font');
623
+ const labelTextConditions = getDefaultCondition('olcs_labelText');
624
+ const labelColorConditions = getDefaultCondition('olcs_fontColor', true);
625
+ const labelOutlineWidthConditions = getDefaultCondition('olcs_fontOutlineWidth');
626
+ const labelOutlineColorConditions = getDefaultCondition('olcs_fontOutlineColor', true);
627
+
628
+ if (this._text) {
629
+ if (this._text.getFont()) {
630
+ fontConditions.splice(1, 1, ['true', `'${this._text.getFont()}'`]);
631
+ }
632
+ if (this._text.getText()) {
633
+ labelTextConditions.splice(1, 1, ['true', `'${this._text.getText()}'`]);
634
+ }
635
+ if (this._text.getFill() && this._text.getFill().getColor()) {
636
+ labelColorConditions.splice(1, 1, ['true', getStringColor(this._text.getFill().getColor())]);
637
+ }
638
+
639
+ if (this._text.getStroke() && this._text.getStroke().getColor()) {
640
+ labelOutlineColorConditions.splice(1, 1, ['true', getStringColor(this._text.getStroke().getColor())]);
641
+ labelOutlineWidthConditions.splice(1, 1, ['true', `${this._text.getStroke().getWidth() || 1.25}`]);
642
+ }
643
+ }
644
+
645
+ // @ts-ignore
646
+ this.cesiumStyle.font = { conditions: fontConditions };
647
+ // @ts-ignore
648
+ this.cesiumStyle.labelText = { conditions: labelTextConditions };
649
+ // @ts-ignore
650
+ this.cesiumStyle.labelColor = { conditions: labelColorConditions };
651
+
652
+ // @ts-ignore
653
+ this.cesiumStyle.labelOutlineWidth = { conditions: labelOutlineWidthConditions };
654
+ // @ts-ignore
655
+ this.cesiumStyle.labelOutlineColor = { conditions: labelOutlineColorConditions };
656
+ // @ts-ignore
657
+ this.cesiumStyle.labelStyle = 'Boolean(${olcs_fontOutlineWidth}) === true ? 2 : 0';
658
+ // @ts-ignore
659
+ this.cesiumStyle.labelHorizontalOrigin = '0';
660
+
661
+ let verticalOrigin = VerticalOrigin.CENTER;
662
+ if (this._text) {
663
+ switch (this._text.getTextBaseline()) {
664
+ case 'top':
665
+ verticalOrigin = VerticalOrigin.TOP;
666
+ break;
667
+ case 'middle':
668
+ verticalOrigin = VerticalOrigin.CENTER;
669
+ break;
670
+ case 'bottom':
671
+ verticalOrigin = VerticalOrigin.BOTTOM;
672
+ break;
673
+ case 'alphabetic':
674
+ verticalOrigin = VerticalOrigin.TOP;
675
+ break;
676
+ case 'hanging':
677
+ verticalOrigin = VerticalOrigin.BOTTOM;
678
+ break;
679
+ default:
680
+ break;
681
+ }
682
+ }
683
+ // @ts-ignore
684
+ this.cesiumStyle.labelVerticalOrigin = verticalOrigin;
685
+
686
+ if (!silent) {
687
+ this._styleChanged();
688
+ }
689
+ }
690
+
691
+ /**
692
+ * @param {VectorStyleItem=} result
693
+ * @returns {VectorStyleItem}
694
+ * @api
695
+ */
696
+ clone(result) {
697
+ if (result) {
698
+ result.style = this._style instanceof Style ? this._style.clone() : this._style;
699
+ if (this._fillOptions && this._fillOptions.color) {
700
+ result.fillColor = /** @type {import("ol/color").Color} */ (this._fillOptions.color).slice();
701
+ if (this._fillOptions.pattern) {
702
+ result.pattern = { ...this._fillOptions.pattern };
703
+ }
704
+ }
705
+
706
+ Object.keys(this.exclude).forEach((section) => {
707
+ if (this.exclude[section]) {
708
+ result.unset(section);
709
+ }
710
+ });
711
+ return result;
712
+ }
713
+ return new VectorStyleItem(this.getOptions());
714
+ }
715
+
716
+ /**
717
+ * @param {VectorStyleItem} result
718
+ * @returns {VectorStyleItem}
719
+ * @api
720
+ */
721
+ assign(result) {
722
+ if (result.fillColor) {
723
+ this.fillColor = result.fillColor.slice();
724
+ }
725
+
726
+ if (result.pattern) {
727
+ this.pattern = { ...result.pattern };
728
+ } else {
729
+ this.pattern = undefined;
730
+ }
731
+
732
+ if (result.stroke) {
733
+ this.stroke = result.stroke.clone();
734
+ }
735
+
736
+ if (result.image) {
737
+ this.image = result.image.clone();
738
+ }
739
+
740
+ if (result.text) {
741
+ this.text = result.text.clone();
742
+ }
743
+
744
+ if (result.label) {
745
+ this.label = result.label;
746
+ }
747
+
748
+ Object.keys(result.exclude).forEach((section) => {
749
+ if (result.exclude[section]) {
750
+ this.unset(section);
751
+ }
752
+ });
753
+
754
+ return this;
755
+ }
756
+
757
+ /**
758
+ * @param {VectorStyleItemSections=} sections
759
+ * @returns {VectorStyleItemOptions}
760
+ * @api
761
+ */
762
+ getOptions(sections) {
763
+ // TODO clean default, only copy relevant keys
764
+ const options = /** @type {VectorStyleItemOptions} */ (super.getOptions(sections));
765
+ options.type = StyleType.VECTOR;
766
+ /** @type {VectorStyleItemSections} */
767
+ const usedSections = sections || {
768
+ fill: true,
769
+ stroke: true,
770
+ text: true,
771
+ image: true,
772
+ };
773
+
774
+ if (usedSections.fill) {
775
+ if (this._fillOptions) {
776
+ options.fill = {
777
+ color: /** @type {import("ol/color").Color} */ (parseColor(this._fillOptions.color).slice()),
778
+ };
779
+ if (this._fillOptions.pattern) {
780
+ options.fill.pattern = { ...this._fillOptions.pattern };
781
+ }
782
+ } else if (this.exclude.fill) {
783
+ options.fill = false;
784
+ }
785
+ }
786
+
787
+ if (usedSections.stroke) {
788
+ if (this._stroke) {
789
+ options.stroke = getStrokeOptions(this._stroke);
790
+ } else if (this.exclude.stroke) {
791
+ options.stroke = false;
792
+ }
793
+ }
794
+
795
+ if (usedSections.text) {
796
+ if (this._text) {
797
+ options.text = getTextOptions(this._text);
798
+ }
799
+ }
800
+
801
+ if (usedSections.label) {
802
+ options.label = this._label;
803
+ }
804
+
805
+ if (usedSections.image) { // TODO this should be nicer...
806
+ if (this._image instanceof Icon) {
807
+ options.image = {
808
+ src: this._image.getSrc(), // XXX this is an issue... we dont want a data URI in the geoJSON
809
+ scale: this._image.getScale(),
810
+ opacity: this._image.getOpacity(),
811
+ };
812
+ } else if (this._image instanceof Circle) {
813
+ options.image = {
814
+ scale: this._image.getScale(),
815
+ fill: getFillOptions(this._image),
816
+ radius: this._image.getRadius(),
817
+ stroke: this._image.getStroke() ? getStrokeOptions(this._image.getStroke()) : undefined,
818
+ };
819
+ } else if (this._image instanceof RegularShape) {
820
+ options.image = {
821
+ scale: this._image.getScale(),
822
+ fill: getFillOptions(this._image),
823
+ points: this._image.getPoints(),
824
+ angle: this._image.getAngle(),
825
+ radius: this._image.getRadius(),
826
+ stroke: this._image.getStroke() ? getStrokeOptions(this._image.getStroke()) : undefined,
827
+ };
828
+ } else if (this.exclude.image) {
829
+ options.image = false;
830
+ }
831
+ }
832
+
833
+ return options;
834
+ }
835
+
836
+ /**
837
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
838
+ * @returns {VectorStyleItemOptions}
839
+ */
840
+ getOptionsForFeature(feature) {
841
+ const type = feature.getGeometry().getType();
842
+ const extrusion = feature.get('olcs_extrudedHeight') ||
843
+ (feature.get('olcs_storeyHeight') && feature.get('olcs_storeyNumber'));
844
+ const sections = {};
845
+
846
+ if (type === 'Point' || type === 'MultiPoint') {
847
+ if (feature[vectorStyleSymbol].label != null) {
848
+ sections.text = true;
849
+ sections.label = true;
850
+ }
851
+ sections.image = true;
852
+
853
+ if (extrusion) {
854
+ sections.stroke = true;
855
+ }
856
+ } else if (type === 'LineString' || type === 'MultiLineString') {
857
+ sections.stroke = true;
858
+ if (extrusion) {
859
+ sections.fill = true;
860
+ }
861
+ } else if (type === 'Polygon' || type === 'MultiPolygon' || type === 'Circle') {
862
+ sections.stroke = true;
863
+ sections.fill = true;
864
+ } else if (type === 'GeometryCollection') {
865
+ sections.stroke = true;
866
+ sections.fill = true;
867
+ sections.image = true;
868
+ sections.text = true;
869
+ }
870
+ return this.getOptions(sections);
871
+ }
872
+
873
+ /**
874
+ * Exclude a section from this style. Excluded section are not returned and cannot be assigned via .assign.
875
+ * Setting the section over a property will remove it from the excluded sections.
876
+ * @param {string} section - one of fill, stroke, image
877
+ * @api
878
+ */
879
+ unset(section) {
880
+ check(section, Object.keys(this.exclude));
881
+ if (section === 'fill') {
882
+ this.fillColor = undefined;
883
+ } else {
884
+ this[section] = undefined;
885
+ }
886
+ this.exclude[section] = true;
887
+ }
888
+
889
+ /**
890
+ * @inheritDoc
891
+ */
892
+ destroy() {
893
+ this._image = null;
894
+ this._stroke = null;
895
+ this._fill = null;
896
+ this._label = null;
897
+ this._text = null;
898
+ this._style = null;
899
+ super.destroy();
900
+ }
901
+ }
902
+
903
+ export default VectorStyleItem;
904
+
905
+ /**
906
+ * @type {VectorStyleItem}
907
+ * @export
908
+ */
909
+ export const defaultVectorStyle = new VectorStyleItem(getDefaultVectorStyleItemOptions());
910
+
911
+ /**
912
+ * @param {import("@vcmap/cesium").Color} cesiumColor
913
+ * @returns {VectorStyleItem}
914
+ * @export
915
+ */
916
+ export function fromCesiumColor(cesiumColor) {
917
+ const color = /** @type {import("ol/color").Color} */ (cesiumColor.toBytes());
918
+ color[3] /= 255;
919
+ return new VectorStyleItem({
920
+ fill: { color },
921
+ stroke: {
922
+ color,
923
+ width: defaultVectorStyle.stroke.getWidth(),
924
+ },
925
+ });
926
+ }
927
+