@vcmap/core 5.0.0-rc.3 → 5.0.0-rc.6

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 (44) hide show
  1. package/index.d.ts +280 -75
  2. package/index.js +12 -3
  3. package/package.json +7 -14
  4. package/src/vcs/vcm/category/appBackedCategory.js +41 -0
  5. package/src/vcs/vcm/category/category.js +374 -0
  6. package/src/vcs/vcm/category/categoryCollection.js +145 -0
  7. package/src/vcs/vcm/context.js +73 -0
  8. package/src/vcs/vcm/globalCollections.js +1 -5
  9. package/src/vcs/vcm/layer/cesiumTileset.js +1 -1
  10. package/src/vcs/vcm/layer/featureStore.js +3 -3
  11. package/src/vcs/vcm/layer/featureStoreChanges.js +89 -73
  12. package/src/vcs/vcm/layer/geojson.js +3 -5
  13. package/src/vcs/vcm/layer/geojsonHelpers.js +3 -3
  14. package/src/vcs/vcm/layer/singleImage.js +2 -1
  15. package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +3 -3
  16. package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +3 -3
  17. package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +3 -3
  18. package/src/vcs/vcm/layer/vector.js +1 -1
  19. package/src/vcs/vcm/layer/vectorHelpers.js +4 -4
  20. package/src/vcs/vcm/layer/wfs.js +5 -5
  21. package/src/vcs/vcm/maps/cameraLimiter.js +5 -5
  22. package/src/vcs/vcm/maps/map.js +26 -11
  23. package/src/vcs/vcm/maps/oblique.js +19 -24
  24. package/src/vcs/vcm/object.js +1 -1
  25. package/src/vcs/vcm/oblique/ObliqueCollection.js +25 -1
  26. package/src/vcs/vcm/oblique/ObliqueDataSet.js +7 -7
  27. package/src/vcs/vcm/oblique/ObliqueImageMeta.js +2 -2
  28. package/src/vcs/vcm/oblique/ObliqueProvider.js +2 -1
  29. package/src/vcs/vcm/oblique/ObliqueView.js +31 -1
  30. package/src/vcs/vcm/oblique/defaultObliqueCollection.js +62 -0
  31. package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +4 -4
  32. package/src/vcs/vcm/util/extent.js +7 -10
  33. package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +3 -4
  34. package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +11 -6
  35. package/src/vcs/vcm/util/featureconverter/extent3D.js +181 -0
  36. package/src/vcs/vcm/util/fetch.js +32 -0
  37. package/src/vcs/vcm/util/overrideCollection.js +224 -0
  38. package/src/vcs/vcm/util/style/declarativeStyleItem.js +2 -0
  39. package/src/vcs/vcm/util/style/styleFactory.js +1 -1
  40. package/src/vcs/vcm/util/style/styleItem.js +2 -0
  41. package/src/vcs/vcm/util/style/vectorStyleItem.js +2 -0
  42. package/src/vcs/vcm/vcsApp.js +373 -0
  43. package/src/vcs/vcm/vcsAppContextHelpers.js +108 -0
  44. package/src/vcs/vcm/util/featureconverter/extent3d.js +0 -154
@@ -1,10 +1,10 @@
1
- import axios from 'axios';
2
1
  import { createXYZ } from 'ol/tilegrid.js';
3
2
  import { cartesian2DDistance } from '../util/math.js';
4
3
  import { parseImageData, parseImageMeta, parseLegacyImageData, getVersionFromImageJson } from './parseImageJson.js';
5
4
  import VcsEvent from '../event/vcsEvent.js';
6
5
  import { getTerrainProviderForUrl } from '../layer/terrainHelpers.js';
7
6
  import Projection from '../util/projection.js';
7
+ import { requestJson } from '../util/fetch.js';
8
8
 
9
9
  /**
10
10
  * @typedef {Object} ObliqueDataSetImagesLoaded
@@ -156,9 +156,10 @@ class ObliqueDataSet {
156
156
  if (!this._loadingPromise) {
157
157
  this._state = DataState.LOADING;
158
158
 
159
- this._loadingPromise = axios.get(this.url)
160
- .then(({ data }) => {
161
- this._initialize(data);
159
+ this._loadingPromise = requestJson(this.url)
160
+ .then(data => this._initialize(data))
161
+ .catch((err) => {
162
+ return Promise.reject(err);
162
163
  });
163
164
  }
164
165
  return this._loadingPromise;
@@ -326,9 +327,8 @@ class ObliqueDataSet {
326
327
  }
327
328
 
328
329
  this._tiles.set(stringTileCoordinates, DataState.LOADING);
329
- const promise = axios
330
- .get(`${this.baseUrl}/${stringTileCoordinates}.json`)
331
- .then(({ data }) => {
330
+ const promise = requestJson(`${this.baseUrl}/${stringTileCoordinates}.json`)
331
+ .then((data) => {
332
332
  const images = parseImageData(data, this._imageMetas);
333
333
  if (images.length > 0) {
334
334
  this._images = this._images.concat(images);
@@ -11,7 +11,7 @@ import { cartesian2DDistance } from '../util/math.js';
11
11
  * @property {Array<number>} tileResolution
12
12
  * @property {import("@vcmap/core").Projection} projection
13
13
  * @property {string} url
14
- * @property {import("@vcmap/cesium").CesiumTerrainProvider} terrainProvider
14
+ * @property {import("@vcmap/cesium").CesiumTerrainProvider} [terrainProvider]
15
15
  * @property {string} name
16
16
  * @property {string|undefined} [format='jpg']
17
17
  * @api
@@ -75,7 +75,7 @@ class ObliqueImageMeta {
75
75
  this.url = options.url;
76
76
  /**
77
77
  * An optional terrain provider
78
- * @type {import("@vcmap/cesium").CesiumTerrainProvider}
78
+ * @type {import("@vcmap/cesium").CesiumTerrainProvider|undefined}
79
79
  * @api
80
80
  */
81
81
  this.terrainProvider = options.terrainProvider;
@@ -7,6 +7,7 @@ import { transformFromImage } from './helpers.js';
7
7
  import { getHeightFromTerrainProvider } from '../layer/terrainHelpers.js';
8
8
  import { mercatorProjection } from '../util/projection.js';
9
9
  import VcsEvent from '../event/vcsEvent.js';
10
+ import { isDefaultImageSymbol } from './defaultObliqueCollection.js';
10
11
 
11
12
  /**
12
13
  * @typedef {Object} ObliqueViewPoint
@@ -293,7 +294,7 @@ class ObliqueProvider {
293
294
  const previousView = this._currentView;
294
295
  this._currentView = olView;
295
296
  if (isNewImage) {
296
- this._currentView.setImageName(this._currentImage.name);
297
+ this._currentView.setImageName(this._currentImage.name, this._currentImage[isDefaultImageSymbol]);
297
298
  }
298
299
 
299
300
  const [width, height] = this._currentImage.meta.size;
@@ -6,6 +6,29 @@ import TileImage from 'ol/source/TileImage.js';
6
6
  import Tile from 'ol/layer/Tile.js';
7
7
  import { hasSameOrigin } from './helpers.js';
8
8
 
9
+ /** @type {string} */
10
+ let defaultImage = '';
11
+
12
+ /**
13
+ * @returns {string}
14
+ */
15
+ function getDefaultImage() {
16
+ if (!defaultImage) {
17
+ const canvas = document.createElement('canvas');
18
+ canvas.height = 512;
19
+ canvas.width = 512;
20
+ const context = canvas.getContext('2d');
21
+ context.fillStyle = '#409D76';
22
+ context.fillRect(0, 0, 512, 512);
23
+ context.font = 'bold 46px Monospace, Courier New';
24
+ context.fillStyle = '#424242';
25
+ context.textAlign = 'center';
26
+ context.fillText('No Image', 256, 256);
27
+ defaultImage = canvas.toDataURL('png');
28
+ }
29
+ return defaultImage;
30
+ }
31
+
9
32
  /**
10
33
  * @typedef {Object} ObliqueViewOptions
11
34
  * @property {number} minZoom
@@ -108,9 +131,16 @@ class ObliqueView {
108
131
  /**
109
132
  * Sets the layers source to request data for this image
110
133
  * @param {string} name
134
+ * @param {boolean} [isDefaultImage=false]
111
135
  * @api
112
136
  */
113
- setImageName(name) {
137
+ setImageName(name, isDefaultImage = false) {
138
+ if (isDefaultImage) {
139
+ this.tileImageSource.setTileLoadFunction(/** @param {import("ol").ImageTile} tile */ (tile) => {
140
+ /** @type {HTMLImageElement} */ (tile.getImage()).src = getDefaultImage();
141
+ tile.load();
142
+ });
143
+ }
114
144
  this.tileImageSource.setTileUrlFunction((coords) => {
115
145
  const [z, x, yInverted] = coords;
116
146
  const y = -yInverted - 1;
@@ -0,0 +1,62 @@
1
+ import ObliqueCollection from './ObliqueCollection.js';
2
+ import ObliqueImage from './ObliqueImage.js';
3
+ import ObliqueImageMeta from './ObliqueImageMeta.js';
4
+ import { ObliqueViewDirection } from './ObliqueViewDirection.js';
5
+ import { mercatorProjection } from '../util/projection.js';
6
+
7
+ const defaultMeta = new ObliqueImageMeta({
8
+ name: 'defaultObliqueMeta',
9
+ size: [512, 512],
10
+ tileSize: [512, 512],
11
+ tileResolution: [1],
12
+ projection: mercatorProjection,
13
+ format: 'png',
14
+ url: '',
15
+ });
16
+
17
+ /**
18
+ * @type {symbol}
19
+ * @private
20
+ */
21
+ export const isDefaultImageSymbol = Symbol('isDefaultImage');
22
+
23
+ /**
24
+ * This is a special oblique collection wich is shown, if no other oblique collection is set on an Oblique map.
25
+ * It will render a single image which indicates that no images can be loaded.
26
+ * @class
27
+ * @extends {ObliqueCollection}
28
+ */
29
+ class DefaultObliqueCollection extends ObliqueCollection {
30
+ constructor() {
31
+ super({});
32
+ }
33
+
34
+ /**
35
+ * @param {import("ol/coordinate").Coordinate} mercatorCoordinate
36
+ * @param {ObliqueViewDirection} viewDirection
37
+ * @returns {ObliqueImage}
38
+ */
39
+ // eslint-disable-next-line no-unused-vars
40
+ getImageForCoordinate(mercatorCoordinate, viewDirection) {
41
+ const groundCoordinates = [
42
+ [mercatorCoordinate[0] - 100, mercatorCoordinate[1] - 100, 0],
43
+ [mercatorCoordinate[0] + 100, mercatorCoordinate[1] - 100, 0],
44
+ [mercatorCoordinate[0] + 100, mercatorCoordinate[1] + 100, 0],
45
+ [mercatorCoordinate[0] - 100, mercatorCoordinate[1] + 100, 0],
46
+ ];
47
+
48
+ const image = new ObliqueImage({
49
+ meta: defaultMeta,
50
+ viewDirection: ObliqueViewDirection.NORTH,
51
+ viewDirectionAngle: 0,
52
+ name: this.name,
53
+ groundCoordinates,
54
+ centerPointOnGround: mercatorCoordinate,
55
+ });
56
+
57
+ image[isDefaultImageSymbol] = true;
58
+ return image;
59
+ }
60
+ }
61
+
62
+ export default DefaultObliqueCollection;
@@ -19,7 +19,7 @@ import Polygon from 'ol/geom/Polygon.js';
19
19
 
20
20
  import { check, checkMaybe } from '@vcsuite/check';
21
21
  import Projection, { mercatorProjection, wgs84Projection } from '../projection.js';
22
- import { createOrUpdateFromGeometry } from '../featureconverter/extent3d.js';
22
+ import Extent3D from '../featureconverter/extent3D.js';
23
23
  import { enforceEndingVertex, enforceRightHand, getFlatCoordinatesFromGeometry } from '../geometryHelpers.js';
24
24
 
25
25
  /**
@@ -75,9 +75,9 @@ function createVerticalPlanes(coords) {
75
75
  */
76
76
  function createHorizontalPlanes(feature, coords, options) {
77
77
  const clippingPlanes = [];
78
- const extent = createOrUpdateFromGeometry(feature.getGeometry());
79
- let min = Number.isFinite(extent[2]) ? extent[2] : 0;
80
- let max = Number.isFinite(extent[5]) ? extent[5] : 0;
78
+ const extent = Extent3D.fromGeometry(feature.getGeometry());
79
+ let min = Number.isFinite(extent.minZ) ? extent.minZ : 0;
80
+ let max = Number.isFinite(extent.maxZ) ? extent.maxZ : 0;
81
81
  const extruded = feature.get('olcs_extrudedHeight');
82
82
  if (extruded) {
83
83
  max += extruded;
@@ -1,8 +1,10 @@
1
1
  import Projection from './projection.js';
2
2
 
3
3
  /**
4
- * @typedef {ProjectionOptions} ExtentOptions
5
- * @property {import("ol/extent").Extent|undefined} coordinates - if not specified, the extent of the projection is used
4
+ * @typedef {Object} ExtentOptions
5
+ * @property {string} [type]
6
+ * @property {import("ol/extent").Extent|undefined} [coordinates] - if not specified, the extent of the projection is used
7
+ * @property {ProjectionOptions} [projection] - if not specified the default projection is assumed
6
8
  * @api
7
9
  */
8
10
 
@@ -45,12 +47,7 @@ class Extent {
45
47
  */
46
48
  constructor(options = {}) {
47
49
  /** @type {Projection} */
48
- this.projection = new Projection({
49
- epsg: options.epsg,
50
- proj4: options.proj4,
51
- alias: options.alias,
52
- prefix: options.prefix,
53
- });
50
+ this.projection = new Projection(options.projection);
54
51
 
55
52
  /** @type {import("ol/extent").Extent|null} */
56
53
  this.extent = options.coordinates || this.projection.proj.getExtent();
@@ -87,7 +84,7 @@ class Extent {
87
84
  toJSON() {
88
85
  return {
89
86
  coordinates: this.extent.slice(),
90
- ...this.projection.toJSON(),
87
+ projection: this.projection.toJSON(),
91
88
  type: Extent.className,
92
89
  };
93
90
  }
@@ -122,7 +119,7 @@ class Extent {
122
119
  * @api
123
120
  */
124
121
  static validateOptions(options) {
125
- return Projection.validateOptions(options) && checkExtentValidity(options.coordinates);
122
+ return Projection.validateOptions(options.projection || {}) && checkExtentValidity(options.coordinates);
126
123
  }
127
124
 
128
125
  /**
@@ -1,6 +1,6 @@
1
1
  import { getCenter } from 'ol/extent.js';
2
2
  import Projection from '../projection.js';
3
- import { createOrUpdateFromGeometry } from '../featureconverter/extent3d.js';
3
+ import Extent3D from '../featureconverter/extent3D.js';
4
4
 
5
5
  /**
6
6
  * @param {VectorClickedObject} feature
@@ -32,9 +32,8 @@ export function getGenericFeatureFromProvidedFeature(feature, layer) {
32
32
 
33
33
  let heightOffset = clickedPosition.height;
34
34
  if (!isModel) {
35
- const extent = createOrUpdateFromGeometry(geometry);
36
- const max = Number.isFinite(extent[5]) ? extent[5] : 0;
37
- heightOffset = max;
35
+ const extent = Extent3D.fromGeometry(geometry);
36
+ heightOffset = Number.isFinite(extent.maxZ) ? extent.maxZ : 0;
38
37
  }
39
38
  const relativeToGround = !isModel && feature.get('olcs_altitudeMode') === 'relativeToGround';
40
39
 
@@ -1,4 +1,3 @@
1
- import axios from 'axios';
2
1
  import GML2 from 'ol/format/GML2.js';
3
2
  import WFS from 'ol/format/WFS.js';
4
3
  import GeoJSON from 'ol/format/GeoJSON.js';
@@ -10,6 +9,7 @@ import AbstractFeatureProvider from './abstractFeatureProvider.js';
10
9
  import Projection, { mercatorProjection } from '../projection.js';
11
10
  import { getWMSSource } from '../../layer/wmsHelpers.js';
12
11
  import Extent from '../extent.js';
12
+ import { requestJson } from '../fetch.js';
13
13
 
14
14
  /**
15
15
  * @typedef {AbstractFeatureProviderOptions} WMSFeatureProviderOptions
@@ -155,12 +155,11 @@ class WMSFeatureProvider extends AbstractFeatureProvider {
155
155
  }
156
156
 
157
157
  /**
158
- * @param {import("axios").AxiosResponse<*>} response
158
+ * @param {import("ol/format/GeoJSON").GeoJSONObject} data
159
159
  * @param {import("ol/coordinate").Coordinate} coordinate
160
160
  * @returns {Array<import("ol").Feature<import("ol/geom/Geometry").default>>}
161
161
  */
162
- featureResponseCallback(response, coordinate) {
163
- const { data } = response;
162
+ featureResponseCallback(data, coordinate) {
164
163
  /** @type {Array<import("ol").Feature<import("ol/geom/Geometry").default>>} */
165
164
  let features;
166
165
 
@@ -211,8 +210,14 @@ class WMSFeatureProvider extends AbstractFeatureProvider {
211
210
  );
212
211
 
213
212
  if (url) {
214
- const response = await axios.get(url);
215
- return this.featureResponseCallback(response, coordinate)
213
+ let data;
214
+ try {
215
+ data = await requestJson(url);
216
+ } catch (ex) {
217
+ this.getLogger().error(`Failed fetching WMS FeatureInfo ${url}`);
218
+ return [];
219
+ }
220
+ return this.featureResponseCallback(data, coordinate)
216
221
  .map(f => this.getProviderFeature(f));
217
222
  }
218
223
  return [];
@@ -0,0 +1,181 @@
1
+ import GeometryType from 'ol/geom/GeometryType.js';
2
+ import { check } from '@vcsuite/check';
3
+
4
+
5
+ class Extent3D {
6
+ /**
7
+ * @param {Array<number>} array
8
+ * @returns {Extent3D}
9
+ */
10
+ static fromArray(array) {
11
+ check(array, [Number]);
12
+ check(array.length, 6);
13
+ return new Extent3D(array[0], array[1], array[2], array[3], array[4], array[5]);
14
+ }
15
+
16
+ /**
17
+ * @param {import("ol/geom").Geometry} geometry
18
+ * @returns {Extent3D}
19
+ */
20
+ static fromGeometry(geometry) {
21
+ const extent = new Extent3D();
22
+ extent.extendWithGeometry(geometry);
23
+ return extent;
24
+ }
25
+
26
+ /**
27
+ * @param {VectorHeightInfo} heightInfo
28
+ * @returns {Extent3D}
29
+ */
30
+ static fromHeightInfo(heightInfo) {
31
+ const extent = new Extent3D();
32
+ extent.extendWithHeightInfo(heightInfo);
33
+ return extent;
34
+ }
35
+
36
+ /**
37
+ * @param {number} minX
38
+ * @param {number} minY
39
+ * @param {number} minZ
40
+ * @param {number} maxX
41
+ * @param {number} maxY
42
+ * @param {number} maxZ
43
+ */
44
+ constructor(minX = Infinity, minY = Infinity, minZ = Infinity, maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity) {
45
+ /**
46
+ * @type {number}
47
+ */
48
+ this.minX = minX;
49
+ /**
50
+ * @type {number}
51
+ */
52
+ this.minY = minY;
53
+ /**
54
+ * @type {number}
55
+ */
56
+ this.minZ = minZ;
57
+ /**
58
+ * @type {number}
59
+ */
60
+ this.maxX = maxX;
61
+ /**
62
+ * @type {number}
63
+ */
64
+ this.maxY = maxY;
65
+ /**
66
+ * @type {number}
67
+ */
68
+ this.maxZ = maxZ;
69
+ }
70
+
71
+ /**
72
+ * @param {import("ol/geom").Geometry} geometry
73
+ */
74
+ extendWithGeometry(geometry) {
75
+ if (geometry.getType() === GeometryType.GEOMETRY_COLLECTION) {
76
+ /** @type {import("ol/geom/GeometryCollection").default} */ (geometry)
77
+ .getGeometriesArray().forEach((geom) => { this.extendWithGeometry(geom); });
78
+ } else if (geometry.getType() === GeometryType.CIRCLE) {
79
+ const flatCoordinates = /** @type {import("ol/geom/Circle").default} */ (geometry).getFlatCoordinates();
80
+ const stride = /** @type {import("ol/geom/Circle").default} */ (geometry).getStride();
81
+ const radius = flatCoordinates[stride] - flatCoordinates[0];
82
+ this.extendXY(
83
+ flatCoordinates[0] - radius,
84
+ flatCoordinates[1] - radius,
85
+ );
86
+ this.extendXY(
87
+ flatCoordinates[0] + radius,
88
+ flatCoordinates[1] + radius,
89
+ );
90
+ if (stride > 2) {
91
+ this.extendZ(flatCoordinates[2]);
92
+ }
93
+ } else {
94
+ const flatCoordinates = /** @type {import("ol/geom/SimpleGeometry").default} */ (geometry).getFlatCoordinates();
95
+ const stride = /** @type {import("ol/geom/SimpleGeometry").default} */ (geometry).getStride();
96
+ this.extendFlatCoordinates(flatCoordinates, stride);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * @param {VectorHeightInfo} heightInfo
102
+ */
103
+ extendWithHeightInfo(heightInfo) {
104
+ if (heightInfo.extruded) {
105
+ const calculatedFeatureMaxHeight =
106
+ heightInfo.groundLevel + heightInfo.storeyHeightsAboveGround.reduce((accumulator, currentValue) => {
107
+ return accumulator + currentValue;
108
+ }, 0);
109
+ this.extendZ(calculatedFeatureMaxHeight);
110
+ const calculatedFeatureMinHeight =
111
+ heightInfo.groundLevel - heightInfo.storeyHeightsBelowGround.reduce((accumulator, currentValue) => {
112
+ return accumulator + currentValue;
113
+ }, 0);
114
+ this.extendZ(calculatedFeatureMinHeight);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * @param {number} x
120
+ * @param {number} y
121
+ * @param {number} z
122
+ */
123
+ extendXYZ(x, y, z) {
124
+ this.minX = Math.min(this.minX, x);
125
+ this.minY = Math.min(this.minY, y);
126
+ this.minZ = Math.min(this.minZ, z);
127
+ this.maxX = Math.max(this.maxX, x);
128
+ this.maxY = Math.max(this.maxY, y);
129
+ this.maxZ = Math.max(this.maxZ, z);
130
+ }
131
+
132
+ /**
133
+ * @param {number} x
134
+ * @param {number} y
135
+ */
136
+ extendXY(x, y) {
137
+ this.minX = Math.min(this.minX, x);
138
+ this.minY = Math.min(this.minY, y);
139
+ this.maxX = Math.max(this.maxX, x);
140
+ this.maxY = Math.max(this.maxY, y);
141
+ }
142
+
143
+ /**
144
+ * @param {number} z
145
+ */
146
+ extendZ(z) {
147
+ this.minZ = Math.min(this.minZ, z);
148
+ this.maxZ = Math.max(this.maxZ, z);
149
+ }
150
+
151
+ /**
152
+ * @param {Array<number>} flatCoordinates
153
+ * @param {number} stride
154
+ */
155
+ extendFlatCoordinates(flatCoordinates, stride) {
156
+ const { length } = flatCoordinates;
157
+ for (let offset = 0; offset < length; offset += stride) {
158
+ if (stride > 2) {
159
+ this.extendXYZ(flatCoordinates[offset], flatCoordinates[offset + 1], flatCoordinates[offset + 2]);
160
+ } else {
161
+ this.extendXY(flatCoordinates[offset], flatCoordinates[offset + 1]);
162
+ }
163
+ }
164
+ }
165
+
166
+ /**
167
+ * @returns {import("ol/extent").Extent}
168
+ */
169
+ to2D() {
170
+ return [this.minX, this.minY, this.maxX, this.maxY];
171
+ }
172
+
173
+ /**
174
+ * @returns {Array<number>}
175
+ */
176
+ toArray() {
177
+ return [this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ];
178
+ }
179
+ }
180
+
181
+ export default Extent3D;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @param {string} url
3
+ * @param {RequestInit=} init
4
+ * @returns {Promise<Response>}
5
+ */
6
+ export async function requestUrl(url, init) {
7
+ const response = await fetch(url, init);
8
+ if (!response.ok) {
9
+ throw new Error(`Failed fetching url ${url} with status: ${response.status}`);
10
+ }
11
+ return response;
12
+ }
13
+
14
+ /**
15
+ * @param {string} url
16
+ * @param {RequestInit=} init
17
+ * @returns {Promise<any>}
18
+ */
19
+ export async function requestJson(url, init) {
20
+ const response = await requestUrl(url, init);
21
+ return response.json();
22
+ }
23
+
24
+ /**
25
+ * @param {string} url
26
+ * @param {RequestInit=} init
27
+ * @returns {Promise<ArrayBuffer>}
28
+ */
29
+ export async function requestArrayBuffer(url, init) {
30
+ const response = await requestUrl(url, init);
31
+ return response.arrayBuffer();
32
+ }