@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,55 @@
1
+ import Tile from 'ol/layer/Tile.js';
2
+ import RasterLayerOpenlayers from './rasterLayerOpenlayers.js';
3
+ import { getWMSSource } from '../wmsHelpers.js';
4
+
5
+ /**
6
+ * represents a specific Cesium WMSOpenlayers Layer class.
7
+ * @class
8
+ * @export
9
+ * @extends {RasterLayerOpenlayers}
10
+ */
11
+ class WMSOpenlayers extends RasterLayerOpenlayers {
12
+ static get className() { return 'vcs.vcm.layer.openlayers.WMSOpenlayers'; }
13
+
14
+ /**
15
+ * @param {import("@vcmap/core").Openlayers} map
16
+ * @param {WMSImplementationOptions} options
17
+ */
18
+ constructor(map, options) {
19
+ super(map, options);
20
+ /**
21
+ * @type {Object<string, *>}
22
+ */
23
+ this.parameters = options.parameters;
24
+ /**
25
+ * @type {string}
26
+ */
27
+ this.version = options.version;
28
+ /**
29
+ * @type {import("ol/size").Size}
30
+ */
31
+ this.tileSize = options.tileSize;
32
+ }
33
+
34
+ /**
35
+ * @returns {import("ol/layer/Tile").default}
36
+ */
37
+ getOLLayer() {
38
+ return new Tile({
39
+ visible: false,
40
+ source: getWMSSource({
41
+ url: this.url,
42
+ parameters: this.parameters,
43
+ version: this.version,
44
+ extent: this.extent,
45
+ tileSize: this.tileSize,
46
+ minLevel: this.minLevel,
47
+ maxLevel: this.maxLevel,
48
+ tilingSchema: this.tilingSchema,
49
+ }),
50
+ opacity: this.opacity,
51
+ });
52
+ }
53
+ }
54
+
55
+ export default WMSOpenlayers;
@@ -0,0 +1,141 @@
1
+ import { getTopLeft, getWidth } from 'ol/extent.js';
2
+ import WMTSTileGrid from 'ol/tilegrid/WMTS.js';
3
+ import Tile from 'ol/layer/Tile.js';
4
+ import WMTSSource from 'ol/source/WMTS.js';
5
+ import { wgs84Projection, mercatorProjection } from '../../util/projection.js';
6
+ import RasterLayerOpenlayers from './rasterLayerOpenlayers.js';
7
+ import { TilingScheme } from '../rasterLayer.js';
8
+ import { isSameOrigin } from '../../util/urlHelpers.js';
9
+
10
+ /**
11
+ * WMTS implementation for {@link Openlayers}.
12
+ * @class
13
+ * @export
14
+ * @extends {RasterLayerOpenlayers}
15
+ */
16
+ class WMTSOpenlayers extends RasterLayerOpenlayers {
17
+ static get className() { return 'vcs.vcm.layer.openlayers.WMTSOpenlayers'; }
18
+
19
+ /**
20
+ * @param {import("@vcmap/core").Openlayers} map
21
+ * @param {WMTSImplementationOptions} options
22
+ */
23
+ constructor(map, options) {
24
+ super(map, options);
25
+
26
+ /**
27
+ * @type {string}
28
+ */
29
+ this.layer = options.layer;
30
+
31
+ /**
32
+ * @type {string}
33
+ */
34
+ this.style = options.style;
35
+
36
+ /**
37
+ * @type {string}
38
+ */
39
+ this.format = options.format;
40
+
41
+ /**
42
+ * @type {string}
43
+ */
44
+ this.tileMatrixSetID = options.tileMatrixSetID;
45
+
46
+ /**
47
+ * @type {import("ol/size").Size}
48
+ */
49
+ this.tileSize = options.tileSize;
50
+
51
+ /**
52
+ * @type {number}
53
+ */
54
+ this.numberOfLevelZeroTilesX = options.numberOfLevelZeroTilesX;
55
+
56
+ /**
57
+ * @type {number}
58
+ */
59
+ this.numberOfLevelZeroTilesY = options.numberOfLevelZeroTilesY;
60
+
61
+ /**
62
+ * @type {Array<string>}
63
+ */
64
+ this.matrixIds = options.matrixIds;
65
+
66
+ /**
67
+ * @type {Object}
68
+ */
69
+ this.openlayersOptions = options.openlayersOptions;
70
+ }
71
+
72
+ /**
73
+ * @returns {import("ol/layer/Tile").default}
74
+ */
75
+ getOLLayer() {
76
+ const projection = this.tilingSchema === TilingScheme.GEOGRAPHIC ? wgs84Projection : mercatorProjection;
77
+ const projectionExtent = projection.proj.getExtent();
78
+ let size = getWidth(projectionExtent) / this.tileSize[0];
79
+ if (this.numberOfLevelZeroTilesX > 1) {
80
+ size /= this.numberOfLevelZeroTilesX;
81
+ }
82
+ if (this.tilingSchema === TilingScheme.GEOGRAPHIC) {
83
+ size = getWidth(projectionExtent) / (this.tileSize[0] * 2);
84
+ }
85
+
86
+ const maxZoom = this.maxLevel + 1;
87
+ const resolutions = new Array(maxZoom).fill(undefined).map((value, index) => {
88
+ return size / (2 ** index);
89
+ });
90
+
91
+ const extent = this.extent.getCoordinatesInProjection(projection);
92
+ const tileGridOptions = {
93
+ origin: getTopLeft(projectionExtent),
94
+ extent,
95
+ resolutions,
96
+ matrixIds: this.matrixIds,
97
+ minZoom: this.minLevel,
98
+ tileSize: this.tileSize,
99
+ };
100
+
101
+ if (this.numberOfLevelZeroTilesX > 1 || this.numberOfLevelZeroTilesY > 1) {
102
+ const sizes = [];
103
+ let sizeX = this.numberOfLevelZeroTilesX;
104
+ let sizeY = this.numberOfLevelZeroTilesY;
105
+ for (let i = 0; i <= maxZoom; i++) {
106
+ sizes.push([sizeX, sizeY]);
107
+ sizeX *= 2;
108
+ sizeY *= 2;
109
+ }
110
+ tileGridOptions.sizes = sizes;
111
+ }
112
+ const tileGrid = new WMTSTileGrid(tileGridOptions);
113
+
114
+ const requestEncoding = this.url.indexOf('{') >= 0 ? 'REST' : 'KVP';
115
+ const wmtsOptions = {
116
+ tileGrid,
117
+ requestEncoding,
118
+ layer: this.layer,
119
+ style: this.style,
120
+ format: this.format,
121
+ matrixSet: this.tileMatrixSetID,
122
+ url: this.url,
123
+ };
124
+
125
+ if (!isSameOrigin(this.url)) {
126
+ wmtsOptions.crossOrigin = 'anonymous';
127
+ }
128
+
129
+ if (this.tilingSchema === TilingScheme.GEOGRAPHIC) {
130
+ wmtsOptions.projection = 'EPSG:4326';
131
+ }
132
+
133
+ Object.assign(wmtsOptions, this.openlayersOptions);
134
+ return new Tile({
135
+ opacity: this.opacity,
136
+ source: new WMTSSource(wmtsOptions),
137
+ });
138
+ }
139
+ }
140
+
141
+ export default WMTSOpenlayers;
@@ -0,0 +1,162 @@
1
+ import { checkMaybe } from '@vcsuite/check';
2
+ import CesiumTileset from './cesiumTileset.js';
3
+ import DeclarativeStyleItem from '../util/style/declarativeStyleItem.js';
4
+ import VectorStyleItem from '../util/style/vectorStyleItem.js';
5
+ import CesiumMap from '../maps/cesium.js';
6
+ import PointCloudCesium from './cesium/pointCloudCesium.js';
7
+ import { VcsClassRegistry } from '../classRegistry.js';
8
+
9
+ /**
10
+ * @typedef {CesiumTilesetOptions} PointCloudOptions
11
+ * @property {number|string|undefined} pointSize - Pointsize of the pointcloud in pixel default is 1
12
+ * @api
13
+ */
14
+
15
+ /**
16
+ * @typedef {CesiumTilesetImplementationOptions} PointCloudImplementationOptions
17
+ * @property {string|number|undefined} pointSize
18
+ * @api
19
+ */
20
+
21
+ /**
22
+ * @type {DeclarativeStyleItem}
23
+ */
24
+ export const defaultPointCloudStyle = new DeclarativeStyleItem({});
25
+
26
+ /**
27
+ * represents a specific PointCloud layer for cesium.
28
+ * <h3>Config Parameter</h3>
29
+ * <ul>
30
+ * <li>url: string: url to the p3dm dataset
31
+ * <li>pointSize: number: size of the points to display
32
+ * </ul>
33
+ *
34
+ * @class
35
+ * @export
36
+ * @extends {CesiumTileset}
37
+ * @api stable
38
+ */
39
+ class PointCloud extends CesiumTileset {
40
+ static get className() { return 'vcs.vcm.layer.PointCloud'; }
41
+
42
+ /**
43
+ * @returns {PointCloudOptions}
44
+ */
45
+ static getDefaultOptions() {
46
+ return {
47
+ ...CesiumTileset.getDefaultOptions(),
48
+ pointSize: null,
49
+ };
50
+ }
51
+
52
+ /**
53
+ * @param {PointCloudOptions} options
54
+ */
55
+ constructor(options) {
56
+ super(options);
57
+
58
+ const defaultOptions = PointCloud.getDefaultOptions();
59
+ /**
60
+ * The default point size to fall back on, if no point size is given. Uses Cesium default of 1 if null.
61
+ * @api
62
+ * @type {number|string|null}
63
+ */
64
+ this.defaultPointSize = options.pointSize != null ? options.pointSize : defaultOptions.pointSize;
65
+ /** @type {number|string|null} */
66
+ this._pointSize = this.defaultPointSize;
67
+
68
+ this._supportedMaps = [
69
+ CesiumMap.className,
70
+ ];
71
+ }
72
+
73
+ /**
74
+ * @inheritDoc
75
+ * @param {(Reference|DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem|string)=} styleOptions
76
+ * @param {(VectorStyleItem|DeclarativeStyleItem)=} defaultStyle
77
+ * @returns {import("@vcmap/core").StyleItem}
78
+ */
79
+ getStyleOrDefaultStyle(styleOptions, defaultStyle) {
80
+ return super.getStyleOrDefaultStyle(styleOptions, defaultStyle || defaultPointCloudStyle);
81
+ }
82
+
83
+ /**
84
+ * @type {number|string|null}
85
+ * @api
86
+ */
87
+ get pointSize() { return this._pointSize; }
88
+
89
+ /**
90
+ * @param {string|number|undefined} size
91
+ */
92
+ set pointSize(size) {
93
+ checkMaybe(size, [Number, String]);
94
+ this._pointSize = size;
95
+ this.getImplementations().forEach((impl) => {
96
+ /** @type {PointCloudCesium} */ (impl).updatePointSize(size);
97
+ });
98
+ }
99
+
100
+ /**
101
+ * @returns {PointCloudImplementationOptions}
102
+ */
103
+ getImplementationOptions() {
104
+ return {
105
+ ...super.getImplementationOptions(),
106
+ pointSize: this.pointSize,
107
+ };
108
+ }
109
+
110
+ /**
111
+ * @param {import("@vcmap/core").VcsMap} map
112
+ * @returns {Array<PointCloudCesium>}
113
+ */
114
+ createImplementationsForMap(map) {
115
+ if (map instanceof CesiumMap) {
116
+ return [new PointCloudCesium(map, this.getImplementationOptions())];
117
+ }
118
+
119
+ return [];
120
+ }
121
+
122
+ /**
123
+ * Clears the style of this layer resets the point size to the defaultPointSize
124
+ * @api stable
125
+ */
126
+ clearStyle() {
127
+ super.clearStyle();
128
+ this.pointSize = this.defaultPointSize;
129
+ }
130
+
131
+ /**
132
+ * Sets a new declarative style. Cannot set a Vector style on PointCloud layers.
133
+ * @param {string|import("ol/style/Style").default|import("ol/style/Style").StyleFunction|import("@vcmap/core").StyleItem} style
134
+ * @param {boolean=} silent
135
+ * @api
136
+ */
137
+ setStyle(style, silent) {
138
+ if (style instanceof VectorStyleItem) {
139
+ this.getLogger().warning('trying to apply vector style to point cloud layer.');
140
+ } else {
141
+ super.setStyle(style, silent);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * @inheritDoc
147
+ * @returns {PointCloudOptions}
148
+ */
149
+ getConfigObject() {
150
+ const config = /** @type {PointCloudOptions} */ (super.getConfigObject());
151
+ const defaultOptions = PointCloud.getDefaultOptions();
152
+
153
+ if (this.defaultPointSize !== defaultOptions.pointSize) {
154
+ config.pointSize = this.defaultPointSize;
155
+ }
156
+
157
+ return config;
158
+ }
159
+ }
160
+
161
+ VcsClassRegistry.registerClass(PointCloud.className, PointCloud);
162
+ export default PointCloud;
@@ -0,0 +1,294 @@
1
+ import { ImagerySplitDirection, WebMercatorTilingScheme, GeographicTilingScheme, Cartographic } from '@vcmap/cesium';
2
+ import { getBottomLeft, getBottomRight, getTopLeft, getTopRight } from 'ol/extent.js';
3
+
4
+ import { parseInteger, parseNumberRange, parseEnumValue } from '@vcsuite/parsers';
5
+ import { wgs84Projection } from '../util/projection.js';
6
+ import Layer from './layer.js';
7
+ import VcsEvent from '../event/vcsEvent.js';
8
+ import Extent from '../util/extent.js';
9
+ import { VcsClassRegistry } from '../classRegistry.js';
10
+
11
+ /**
12
+ * @typedef {LayerOptions} RasterLayerOptions
13
+ * @property {number|undefined} [minLevel=0] - minLevel to show (if not specified, calculated from extent)
14
+ * @property {number} [maxLevel=18] - maxLevel to show
15
+ * @property {string} [tilingSchema='geographic'] - either "geographic" or "mercator"
16
+ * @property {number} [opacity=1.0] - opacity between 0 and 1
17
+ * @property {string|undefined} splitDirection - either 'left' or 'right', none if omitted
18
+ * @api
19
+ */
20
+
21
+ /**
22
+ * @typedef {LayerImplementationOptions} RasterLayerImplementationOptions
23
+ * @property {number} minLevel
24
+ * @property {number} maxLevel
25
+ * @property {string} tilingSchema
26
+ * @property {number} opacity
27
+ * @property {import("@vcmap/cesium").ImagerySplitDirection} splitDirection
28
+ * @property {Extent|undefined} extent
29
+ */
30
+
31
+ /**
32
+ * @typedef {import("@vcmap/core").LayerImplementation<import("@vcmap/core").VcsMap>} RasterLayerImplementation
33
+ * @property {function(number):void} updateOpacity
34
+ * @property {function(import("@vcmap/cesium").ImagerySplitDirection):void} updateSplitDirection
35
+ * @api
36
+ */
37
+
38
+ /**
39
+ * Enumeration of tiling schemes.
40
+ * @enum {string}
41
+ * @api
42
+ * @property {string} GEOGRAPHIC
43
+ * @property {string} MERCATOR
44
+ * @export
45
+ */
46
+ export const TilingScheme = {
47
+ GEOGRAPHIC: 'geographic',
48
+ MERCATOR: 'mercator',
49
+ };
50
+
51
+ /**
52
+ * Gets the tiling scheme associated with this layerConfig
53
+ * @param {Object} layerOptions
54
+ * @returns {import("@vcmap/cesium").WebMercatorTilingScheme|import("@vcmap/cesium").GeographicTilingScheme}
55
+ */
56
+ export function getTilingScheme(layerOptions) {
57
+ const tilingSchemeOptions = {};
58
+ if (layerOptions.numberOfLevelZeroTilesX && layerOptions.numberOfLevelZeroTilesX > 1) {
59
+ tilingSchemeOptions.numberOfLevelZeroTilesX = layerOptions.numberOfLevelZeroTilesX;
60
+ }
61
+ if (layerOptions.numberOfLevelZeroTilesY && layerOptions.numberOfLevelZeroTilesY > 1) {
62
+ tilingSchemeOptions.numberOfLevelZeroTilesY = layerOptions.numberOfLevelZeroTilesY;
63
+ }
64
+ if (layerOptions.tilingSchema === TilingScheme.MERCATOR) {
65
+ return new WebMercatorTilingScheme(tilingSchemeOptions);
66
+ }
67
+ return new GeographicTilingScheme(tilingSchemeOptions);
68
+ }
69
+
70
+ /**
71
+ * @param {Extent} extent
72
+ * @param {import("@vcmap/cesium").GeographicTilingScheme|import("@vcmap/cesium").WebMercatorTilingScheme} tilingScheme
73
+ * @param {number} maxLevel
74
+ * @param {number} [minLevel=0]
75
+ * @returns {number}
76
+ */
77
+ export function calculateMinLevel(extent, tilingScheme, maxLevel, minLevel = 0) {
78
+ if (!extent.isValid()) {
79
+ return minLevel;
80
+ }
81
+ const wgs84Extent = extent.getCoordinatesInProjection(wgs84Projection);
82
+ if (wgs84Extent[1] < -85) {
83
+ wgs84Extent[1] = -85;
84
+ }
85
+ if (wgs84Extent[3] > 85) {
86
+ wgs84Extent[3] = 85;
87
+ }
88
+ const olCoords = [
89
+ getBottomLeft(wgs84Extent),
90
+ getBottomRight(wgs84Extent),
91
+ getTopRight(wgs84Extent),
92
+ getTopLeft(wgs84Extent),
93
+ ];
94
+ const extentCoords = olCoords.map(coord => Cartographic.fromDegrees(coord[0], coord[1]));
95
+ let usedMinLevel = minLevel;
96
+ while (usedMinLevel < maxLevel) {
97
+ // eslint-disable-next-line no-loop-func
98
+ const tileCoords = extentCoords.map(position => tilingScheme.positionToTileXY(position, usedMinLevel));
99
+ const distances = [];
100
+ distances.push(Math.abs(tileCoords[0].x - tileCoords[1].x));
101
+ distances.push(Math.abs(tileCoords[0].y - tileCoords[3].y));
102
+ if (distances[0] > 1 || distances[1] > 1) {
103
+ usedMinLevel -= 1;
104
+ break;
105
+ }
106
+ usedMinLevel += 1;
107
+ }
108
+ return usedMinLevel;
109
+ }
110
+
111
+ /**
112
+ * This abstract class allows for automatic loading scheme determination
113
+ * for raster layers
114
+ * @class
115
+ * @export
116
+ * @extends {Layer}
117
+ * @implements {SplitLayer}
118
+ * @abstract
119
+ */
120
+ class RasterLayer extends Layer {
121
+ static get className() { return 'vcs.vcm.layer.RasterLayer'; }
122
+
123
+ /**
124
+ * @returns {RasterLayerOptions}
125
+ */
126
+ static getDefaultOptions() {
127
+ return {
128
+ ...Layer.getDefaultOptions(),
129
+ minLevel: 0,
130
+ maxLevel: 18,
131
+ tilingSchema: TilingScheme.GEOGRAPHIC,
132
+ opacity: 1,
133
+ splitDirection: undefined,
134
+ };
135
+ }
136
+
137
+ /**
138
+ * @param {RasterLayerOptions} options
139
+ */
140
+ constructor(options) {
141
+ options.url = options.url || '';
142
+ super(options);
143
+ const defaultOptions = RasterLayer.getDefaultOptions();
144
+ this.extent = this.extent || new Extent();
145
+ /**
146
+ * The {@link RasterLayer.TilingScheme} of this layer
147
+ * @type {string}
148
+ * @api
149
+ */
150
+ this.tilingSchema = parseEnumValue(options.tilingSchema, TilingScheme, defaultOptions.tilingSchema);
151
+ /** @type {number} */
152
+ this.maxLevel = parseInteger(options.maxLevel, defaultOptions.maxLevel);
153
+ /**
154
+ * @type {number}
155
+ * @private
156
+ */
157
+ this._minLevel = parseInteger(options.minLevel, defaultOptions.minLevel);
158
+
159
+ const cesiumTilingScheme = getTilingScheme(options);
160
+ /** @type {number} */
161
+ this.minLevel = calculateMinLevel(this.extent, cesiumTilingScheme, this.maxLevel, this._minLevel);
162
+
163
+ /**
164
+ * @type {number}
165
+ * @private
166
+ */
167
+ this._opacity = parseNumberRange(options.opacity, defaultOptions.opacity, 0.0, 1.0);
168
+
169
+ /** @type {import("@vcmap/cesium").ImagerySplitDirection} */
170
+ this._splitDirection = ImagerySplitDirection.NONE;
171
+
172
+ if (options.splitDirection) {
173
+ this._splitDirection = options.splitDirection === 'left' ?
174
+ ImagerySplitDirection.LEFT :
175
+ ImagerySplitDirection.RIGHT;
176
+ }
177
+
178
+ /**
179
+ * raised if the split direction changes, is passed the split direction as its only argument
180
+ * @type {VcsEvent<import("@vcmap/cesium").ImagerySplitDirection>}
181
+ * @api
182
+ */
183
+ this.splitDirectionChanged = new VcsEvent();
184
+ }
185
+
186
+ /**
187
+ * The split directions of this layer
188
+ * @api
189
+ * @type {import("@vcmap/cesium").ImagerySplitDirection}
190
+ */
191
+ get splitDirection() { return this._splitDirection; }
192
+
193
+ /**
194
+ * @param {import("@vcmap/cesium").ImagerySplitDirection} direction
195
+ */
196
+ set splitDirection(direction) {
197
+ if (direction !== this._splitDirection) {
198
+ this._splitDirection = direction;
199
+ this.getImplementations().forEach((impl) => {
200
+ /** @type {RasterLayerImplementation} */
201
+ (impl).updateSplitDirection(direction);
202
+ });
203
+ this.splitDirectionChanged.raiseEvent(this._splitDirection);
204
+ }
205
+ }
206
+
207
+ /**
208
+ * The opacity between 0 (fully transparent) and 1 (fully opaque)
209
+ * @api
210
+ * @type {number}
211
+ */
212
+ get opacity() { return this._opacity; }
213
+
214
+ /**
215
+ * @param {number} opacity
216
+ */
217
+ set opacity(opacity) {
218
+ const parsedValue = parseNumberRange(opacity, this._opacity, 0, 1);
219
+ if (this._opacity !== parsedValue) {
220
+ this._opacity = parsedValue;
221
+ this.getImplementations().forEach((impl) => {
222
+ /** @type {RasterLayerImplementation} */
223
+ (impl).updateOpacity(parsedValue);
224
+ });
225
+ }
226
+ }
227
+
228
+ /**
229
+ * @returns {RasterLayerImplementationOptions}
230
+ */
231
+ getImplementationOptions() {
232
+ const options = /** @type {RasterLayerImplementationOptions} */ ({
233
+ ...super.getImplementationOptions(),
234
+ minLevel: this.minLevel,
235
+ maxLevel: this.maxLevel,
236
+ tilingSchema: this.tilingSchema,
237
+ opacity: this.opacity,
238
+ splitDirection: this._splitDirection,
239
+ });
240
+
241
+ if (this.extent.isValid()) {
242
+ options.extent = this.extent;
243
+ }
244
+ return options;
245
+ }
246
+
247
+ /**
248
+ * @inheritDoc
249
+ * @returns {RasterLayerOptions}
250
+ */
251
+ getConfigObject() {
252
+ const config = /** @type {RasterLayerOptions} */ (super.getConfigObject());
253
+ const defaultOptions = RasterLayer.getDefaultOptions();
254
+
255
+ if (this.extent.equals(new Extent())) {
256
+ delete config.extent;
257
+ }
258
+
259
+ if (this._minLevel !== defaultOptions.minLevel) {
260
+ config.minLevel = this._minLevel;
261
+ }
262
+
263
+ if (this.maxLevel !== defaultOptions.maxLevel) {
264
+ config.maxLevel = this.maxLevel;
265
+ }
266
+
267
+ if (this.tilingSchema !== defaultOptions.tilingSchema) {
268
+ config.tilingSchema = this.tilingSchema;
269
+ }
270
+
271
+ if (this.opacity !== defaultOptions.opacity) {
272
+ config.opacity = this.opacity;
273
+ }
274
+
275
+ if (this._splitDirection !== ImagerySplitDirection.NONE) {
276
+ config.splitDirection = this._splitDirection === ImagerySplitDirection.RIGHT ?
277
+ 'right' :
278
+ 'left';
279
+ }
280
+
281
+ return config;
282
+ }
283
+
284
+ /**
285
+ * @inheritDoc
286
+ */
287
+ destroy() {
288
+ this.splitDirectionChanged.destroy();
289
+ super.destroy();
290
+ }
291
+ }
292
+
293
+ VcsClassRegistry.registerClass(RasterLayer.className, RasterLayer);
294
+ export default RasterLayer;