@gisatcz/deckgl-geolib 1.12.0-dev.5 → 2.0.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 (48) hide show
  1. package/README.md +67 -64
  2. package/dist/cjs/index.js +609 -672
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/index.min.js +3 -3
  5. package/dist/cjs/index.min.js.map +1 -1
  6. package/dist/{esm/types/cogtiles/cogtiles.d.ts → cjs/types/core/CogTiles.d.ts} +10 -26
  7. package/dist/cjs/types/{geoimage/geoimage.d.ts → core/GeoImage.d.ts} +6 -6
  8. package/dist/cjs/types/core/index.d.ts +2 -0
  9. package/dist/cjs/types/index.d.ts +2 -11
  10. package/dist/{esm/types/cogbitmaplayer → cjs/types/layers}/CogBitmapLayer.d.ts +3 -5
  11. package/dist/cjs/types/{cogterrainlayer → layers}/CogTerrainLayer.d.ts +13 -8
  12. package/dist/cjs/types/layers/index.d.ts +2 -0
  13. package/dist/esm/index.js +606 -672
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/index.min.js +3 -3
  16. package/dist/esm/index.min.js.map +1 -1
  17. package/dist/{cjs/types/cogtiles/cogtiles.d.ts → esm/types/core/CogTiles.d.ts} +10 -26
  18. package/dist/esm/types/{geoimage/geoimage.d.ts → core/GeoImage.d.ts} +6 -6
  19. package/dist/esm/types/core/index.d.ts +2 -0
  20. package/dist/esm/types/index.d.ts +2 -11
  21. package/dist/{cjs/types/cogbitmaplayer → esm/types/layers}/CogBitmapLayer.d.ts +3 -5
  22. package/dist/esm/types/{cogterrainlayer → layers}/CogTerrainLayer.d.ts +13 -8
  23. package/dist/esm/types/layers/index.d.ts +2 -0
  24. package/package.json +40 -4
  25. package/.eslintignore +0 -2
  26. package/.eslintrc.cjs +0 -3
  27. package/CHANGELOG.md +0 -166
  28. package/rollup.config.mjs +0 -77
  29. package/src/cogbitmaplayer/CogBitmapLayer.ts +0 -337
  30. package/src/cogbitmaplayer/README.md +0 -113
  31. package/src/cogterrainlayer/CogTerrainLayer.ts +0 -445
  32. package/src/cogterrainlayer/README.md +0 -118
  33. package/src/cogtiles/README.md +0 -72
  34. package/src/cogtiles/cogtiles.ts +0 -483
  35. package/src/cogtiles/lzw.js +0 -256
  36. package/src/geoimage/README.md +0 -129
  37. package/src/geoimage/delatin/index.ts +0 -495
  38. package/src/geoimage/geoimage.ts +0 -602
  39. package/src/geoimage/helpers/skirt.ts +0 -171
  40. package/src/index.ts +0 -11
  41. package/src/utilities/tileurls.ts +0 -21
  42. package/tsconfig.json +0 -6
  43. /package/dist/cjs/types/{geoimage → core}/delatin/index.d.ts +0 -0
  44. /package/dist/cjs/types/{geoimage → core}/helpers/skirt.d.ts +0 -0
  45. /package/dist/cjs/types/{utilities → utils}/tileurls.d.ts +0 -0
  46. /package/dist/esm/types/{geoimage → core}/delatin/index.d.ts +0 -0
  47. /package/dist/esm/types/{geoimage → core}/helpers/skirt.d.ts +0 -0
  48. /package/dist/esm/types/{utilities → utils}/tileurls.d.ts +0 -0
package/dist/cjs/index.js CHANGED
@@ -9,33 +9,6 @@ var schema = require('@loaders.gl/schema');
9
9
  var loaderUtils = require('@loaders.gl/loader-utils');
10
10
  var meshLayers = require('@deck.gl/mesh-layers');
11
11
 
12
- /******************************************************************************
13
- Copyright (c) Microsoft Corporation.
14
-
15
- Permission to use, copy, modify, and/or distribute this software for any
16
- purpose with or without fee is hereby granted.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
19
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
23
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24
- PERFORMANCE OF THIS SOFTWARE.
25
- ***************************************************************************** */
26
- /* global Reflect, Promise */
27
-
28
-
29
- function __awaiter(thisArg, _arguments, P, generator) {
30
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
31
- return new (P || (P = Promise))(function (resolve, reject) {
32
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
33
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
34
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
35
- step((generator = generator.apply(thisArg, _arguments || [])).next());
36
- });
37
- }
38
-
39
12
  /* eslint-disable no-restricted-globals, no-restricted-syntax */
40
13
  /* global SharedArrayBuffer */
41
14
 
@@ -165,6 +138,12 @@ uncurryThisGetter(
165
138
  SymbolToStringTag
166
139
  );
167
140
 
141
+ // Uint8Array
142
+ const NativeUint8Array = Uint8Array;
143
+
144
+ // Uint16Array
145
+ const NativeUint16Array = Uint16Array;
146
+
168
147
  // Uint32Array
169
148
  const NativeUint32Array = Uint32Array;
170
149
 
@@ -194,7 +173,6 @@ const DataViewPrototypeGetUint16 = uncurryThis(
194
173
  // WeakMap
195
174
  /**
196
175
  * Do not construct with arguments to avoid calling the "set" method
197
- *
198
176
  * @type {{new <K extends {}, V>(): WeakMap<K, V>}}
199
177
  */
200
178
  const NativeWeakMap = WeakMap;
@@ -224,7 +202,6 @@ const SafeIteratorPrototype = ObjectCreate(null, {
224
202
 
225
203
  /**
226
204
  * Wrap the Array around the SafeIterator If Array.prototype [@@iterator] has been modified
227
- *
228
205
  * @type {<T>(array: T[]) => Iterable<T>}
229
206
  */
230
207
  function safeIfNeeded(array) {
@@ -265,21 +242,20 @@ for (const key of ReflectOwnKeys(ArrayIteratorPrototype)) {
265
242
  ObjectDefineProperty(DummyArrayIteratorPrototype, key, ReflectGetOwnPropertyDescriptor(ArrayIteratorPrototype, key));
266
243
  }
267
244
 
268
- // algorithm: http://fox-toolkit.org/ftp/fasthalffloatconversion.pdf
269
-
245
+ // base algorithm: http://fox-toolkit.org/ftp/fasthalffloatconversion.pdf
270
246
 
271
247
  const buffer = new NativeArrayBuffer(4);
272
248
  const floatView = new NativeFloat32Array(buffer);
273
249
  const uint32View = new NativeUint32Array(buffer);
274
250
 
275
- const baseTable = new NativeUint32Array(512);
276
- const shiftTable = new NativeUint32Array(512);
251
+ const baseTable = new NativeUint16Array(512);
252
+ const shiftTable = new NativeUint8Array(512);
277
253
 
278
254
  for (let i = 0; i < 256; ++i) {
279
255
  const e = i - 127;
280
256
 
281
257
  // very small number (0, -0)
282
- if (e < -27) {
258
+ if (e < -24) {
283
259
  baseTable[i] = 0x0000;
284
260
  baseTable[i | 0x100] = 0x8000;
285
261
  shiftTable[i] = 24;
@@ -316,21 +292,18 @@ for (let i = 0; i < 256; ++i) {
316
292
  }
317
293
 
318
294
  const mantissaTable = new NativeUint32Array(2048);
319
- const exponentTable = new NativeUint32Array(64);
320
- const offsetTable = new NativeUint32Array(64);
321
-
322
295
  for (let i = 1; i < 1024; ++i) {
323
- let m = i << 13; // zero pad mantissa bits
324
- let e = 0; // zero exponent
296
+ let m = i << 13; // zero pad mantissa bits
297
+ let e = 0; // zero exponent
325
298
 
326
299
  // normalized
327
- while((m & 0x00800000) === 0) {
300
+ while ((m & 0x00800000) === 0) {
328
301
  m <<= 1;
329
- e -= 0x00800000; // decrement exponent
302
+ e -= 0x00800000; // decrement exponent
330
303
  }
331
304
 
332
- m &= ~0x00800000; // clear leading 1 bit
333
- e += 0x38800000; // adjust bias
305
+ m &= ~0x00800000; // clear leading 1 bit
306
+ e += 0x38800000; // adjust bias
334
307
 
335
308
  mantissaTable[i] = m | e;
336
309
  }
@@ -338,6 +311,7 @@ for (let i = 1024; i < 2048; ++i) {
338
311
  mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);
339
312
  }
340
313
 
314
+ const exponentTable = new NativeUint32Array(64);
341
315
  for (let i = 1; i < 31; ++i) {
342
316
  exponentTable[i] = i << 23;
343
317
  }
@@ -348,6 +322,7 @@ for (let i = 33; i < 63; ++i) {
348
322
  }
349
323
  exponentTable[63] = 0xc7800000;
350
324
 
325
+ const offsetTable = new NativeUint16Array(64);
351
326
  for (let i = 1; i < 64; ++i) {
352
327
  if (i !== 32) {
353
328
  offsetTable[i] = 1024;
@@ -356,19 +331,17 @@ for (let i = 1; i < 64; ++i) {
356
331
 
357
332
  /**
358
333
  * convert a half float number bits to a number
359
- *
360
334
  * @param {number} float16bits - half float number bits
361
335
  * @returns {number} double float
362
336
  */
363
337
  function convertToNumber(float16bits) {
364
- const m = float16bits >> 10;
365
- uint32View[0] = mantissaTable[offsetTable[m] + (float16bits & 0x3ff)] + exponentTable[m];
338
+ const i = float16bits >> 10;
339
+ uint32View[0] = mantissaTable[offsetTable[i] + (float16bits & 0x3ff)] + exponentTable[i];
366
340
  return floatView[0];
367
341
  }
368
342
 
369
343
  /**
370
344
  * returns an unsigned 16-bit float at the specified byte offset from the start of the DataView
371
- *
372
345
  * @param {DataView} dataView
373
346
  * @param {number} byteOffset
374
347
  * @param {[boolean]} opts
@@ -2638,6 +2611,8 @@ class QuickLRU extends Map {
2638
2611
  } else {
2639
2612
  this._set(key, {value, expiry});
2640
2613
  }
2614
+
2615
+ return this;
2641
2616
  }
2642
2617
 
2643
2618
  has(key) {
@@ -4436,6 +4411,29 @@ class Tile {
4436
4411
  // loaders.gl
4437
4412
  // SPDX-License-Identifier: MIT
4438
4413
  // Copyright (c) vis.gl contributors
4414
+ /**
4415
+ * Get geometry edges that located on a border of the mesh
4416
+ * @param {object} indices - edge indices from quantized mesh data
4417
+ * @param {TypedArray} position - position attribute geometry data
4418
+ * @returns {number[][]} - outside edges data
4419
+ */
4420
+ function getOutsideEdgesFromIndices(indices, position) {
4421
+ // Sort skirt indices to create adjacent triangles
4422
+ indices.westIndices.sort((a, b) => position[3 * a + 1] - position[3 * b + 1]);
4423
+ // Reverse (b - a) to match triangle winding
4424
+ indices.eastIndices.sort((a, b) => position[3 * b + 1] - position[3 * a + 1]);
4425
+ indices.southIndices.sort((a, b) => position[3 * b] - position[3 * a]);
4426
+ // Reverse (b - a) to match triangle winding
4427
+ indices.northIndices.sort((a, b) => position[3 * a] - position[3 * b]);
4428
+ const edges = [];
4429
+ for (const index in indices) {
4430
+ const indexGroup = indices[index];
4431
+ for (let i = 0; i < indexGroup.length - 1; i++) {
4432
+ edges.push([indexGroup[i], indexGroup[i + 1]]);
4433
+ }
4434
+ }
4435
+ return edges;
4436
+ }
4439
4437
  /**
4440
4438
  * Add skirt to existing mesh
4441
4439
  * @param {object} attributes - POSITION and TEXCOOD_0 attributes data
@@ -4481,7 +4479,6 @@ function addSkirt(attributes, triangles, skirtHeight, outsideIndices) {
4481
4479
  * @returns {number[][]} - outside edges data
4482
4480
  */
4483
4481
  function getOutsideEdgesFromTriangles(triangles) {
4484
- var _a, _b;
4485
4482
  const edges = [];
4486
4483
  for (let i = 0; i < triangles.length; i += 3) {
4487
4484
  edges.push([triangles[i], triangles[i + 1]]);
@@ -4492,7 +4489,7 @@ function getOutsideEdgesFromTriangles(triangles) {
4492
4489
  const outsideEdges = [];
4493
4490
  let index = 0;
4494
4491
  while (index < edges.length) {
4495
- if (edges[index][0] === ((_a = edges[index + 1]) === null || _a === void 0 ? void 0 : _a[1]) && edges[index][1] === ((_b = edges[index + 1]) === null || _b === void 0 ? void 0 : _b[0])) {
4492
+ if (edges[index][0] === edges[index + 1]?.[1] && edges[index][1] === edges[index + 1]?.[0]) {
4496
4493
  index += 2;
4497
4494
  }
4498
4495
  else {
@@ -4502,29 +4499,6 @@ function getOutsideEdgesFromTriangles(triangles) {
4502
4499
  }
4503
4500
  return outsideEdges;
4504
4501
  }
4505
- /**
4506
- * Get geometry edges that located on a border of the mesh
4507
- * @param {object} indices - edge indices from quantized mesh data
4508
- * @param {TypedArray} position - position attribute geometry data
4509
- * @returns {number[][]} - outside edges data
4510
- */
4511
- function getOutsideEdgesFromIndices(indices, position) {
4512
- // Sort skirt indices to create adjacent triangles
4513
- indices.westIndices.sort((a, b) => position[3 * a + 1] - position[3 * b + 1]);
4514
- // Reverse (b - a) to match triangle winding
4515
- indices.eastIndices.sort((a, b) => position[3 * b + 1] - position[3 * a + 1]);
4516
- indices.southIndices.sort((a, b) => position[3 * b] - position[3 * a]);
4517
- // Reverse (b - a) to match triangle winding
4518
- indices.northIndices.sort((a, b) => position[3 * a] - position[3 * b]);
4519
- const edges = [];
4520
- for (const index in indices) {
4521
- const indexGroup = indices[index];
4522
- for (let i = 0; i < indexGroup.length - 1; i++) {
4523
- edges.push([indexGroup[i], indexGroup[i + 1]]);
4524
- }
4525
- }
4526
- return edges;
4527
- }
4528
4502
  /**
4529
4503
  * Get geometry edges that located on a border of the mesh
4530
4504
  * @param {object} args
@@ -4565,7 +4539,12 @@ function updateAttributesForNewEdge({ edge, edgeIndex, attributes, skirtHeight,
4565
4539
  // Copyright (c) vis.gl contributors
4566
4540
  // ISC License
4567
4541
  // Copyright(c) 2019, Michael Fogleman, Vladimir Agafonkin
4542
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
4568
4543
  // @ts-nocheck
4544
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
4545
+ function orient(ax, ay, bx, by, cx, cy) {
4546
+ return (bx - cx) * (ay - cy) - (by - cy) * (ax - cx);
4547
+ }
4569
4548
  /* eslint-disable complexity, max-params, max-statements, max-depth, no-constant-condition */
4570
4549
  class Delatin {
4571
4550
  constructor(data, width, height = width) {
@@ -4953,9 +4932,6 @@ class Delatin {
4953
4932
  return i > i0;
4954
4933
  }
4955
4934
  }
4956
- function orient(ax, ay, bx, by, cx, cy) {
4957
- return (bx - cx) * (ay - cy) - (by - cy) * (ax - cx);
4958
- }
4959
4935
  function inCircle(ax, ay, bx, by, cx, cy, px, py) {
4960
4936
  const dx = ax - px;
4961
4937
  const dy = ay - py;
@@ -4969,7 +4945,7 @@ function inCircle(ax, ay, bx, by, cx, cy, px, py) {
4969
4945
  return dx * (ey * cp - bp * fy) - dy * (ex * cp - bp * fx) + ap * (ex * fy - ey * fx) < 0;
4970
4946
  }
4971
4947
 
4972
- /* eslint 'max-len': [1, { code: 105, comments: 999, ignoreStrings: true, ignoreUrls: true }] */
4948
+ // import { ExtentsLeftBottomRightTop } from '@deck.gl/core/utils/positions';
4973
4949
  // FIXME - tesselator as a parameter
4974
4950
  const tesselator = 'martini';
4975
4951
  const DefaultGeoImageOptions = {
@@ -5004,279 +4980,264 @@ const DefaultGeoImageOptions = {
5004
4980
  planarConfig: undefined,
5005
4981
  };
5006
4982
  class GeoImage {
5007
- constructor() {
5008
- this.scale = (num, inMin, inMax, outMin, outMax) => ((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
5009
- }
5010
- setUrl(url) {
5011
- return __awaiter(this, void 0, void 0, function* () {
5012
- // TODO - not tested
5013
- const response = yield fetch(url);
5014
- const arrayBuffer = yield response.arrayBuffer();
5015
- const tiff = yield fromArrayBuffer(arrayBuffer);
5016
- const data = yield tiff.getImage(0);
5017
- this.data = data;
5018
- });
5019
- }
5020
- getMap(input, options, meshMaxError) {
5021
- return __awaiter(this, void 0, void 0, function* () {
5022
- const mergedOptions = Object.assign(Object.assign({}, DefaultGeoImageOptions), options);
5023
- switch (mergedOptions.type) {
5024
- case 'image':
5025
- return this.getBitmap(input, mergedOptions);
5026
- case 'terrain':
5027
- return this.getHeightmap(input, mergedOptions, meshMaxError);
5028
- default:
5029
- return null;
5030
- }
5031
- });
4983
+ data;
4984
+ scale = (num, inMin, inMax, outMin, outMax) => ((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
4985
+ async setUrl(url) {
4986
+ // TODO - not tested
4987
+ const response = await fetch(url);
4988
+ const arrayBuffer = await response.arrayBuffer();
4989
+ const tiff = await fromArrayBuffer(arrayBuffer);
4990
+ const data = await tiff.getImage(0);
4991
+ this.data = data;
4992
+ }
4993
+ async getMap(input, options, meshMaxError) {
4994
+ const mergedOptions = { ...DefaultGeoImageOptions, ...options };
4995
+ switch (mergedOptions.type) {
4996
+ case 'image':
4997
+ return this.getBitmap(input, mergedOptions);
4998
+ case 'terrain':
4999
+ return this.getHeightmap(input, mergedOptions, meshMaxError);
5000
+ default:
5001
+ return null;
5002
+ }
5032
5003
  }
5033
5004
  // GetHeightmap uses only "useChannel" and "multiplier" options
5034
- getHeightmap(input, options, meshMaxError) {
5035
- var _a;
5036
- return __awaiter(this, void 0, void 0, function* () {
5037
- let rasters = [];
5038
- let width;
5039
- let height;
5040
- if (typeof (input) === 'string') {
5041
- // TODO not tested
5042
- // input is type of object
5043
- yield this.setUrl(input);
5044
- rasters = (yield this.data.readRasters());
5045
- width = this.data.getWidth();
5046
- height = this.data.getHeight();
5047
- }
5048
- else {
5049
- rasters = input.rasters;
5050
- width = input.width;
5051
- height = input.height;
5005
+ async getHeightmap(input, options, meshMaxError) {
5006
+ let rasters = [];
5007
+ let width;
5008
+ let height;
5009
+ if (typeof (input) === 'string') {
5010
+ // TODO not tested
5011
+ // input is type of object
5012
+ await this.setUrl(input);
5013
+ rasters = (await this.data.readRasters());
5014
+ width = this.data.getWidth();
5015
+ height = this.data.getHeight();
5016
+ }
5017
+ else {
5018
+ rasters = input.rasters;
5019
+ width = input.width;
5020
+ height = input.height;
5021
+ }
5022
+ const optionsLocal = { ...options };
5023
+ let channel = rasters[0];
5024
+ optionsLocal.useChannelIndex ??= optionsLocal.useChannel == null ? null : optionsLocal.useChannel - 1;
5025
+ if (options.useChannelIndex != null) {
5026
+ if (rasters[optionsLocal.useChannelIndex]) {
5027
+ channel = rasters[optionsLocal.useChannelIndex];
5052
5028
  }
5053
- const optionsLocal = Object.assign({}, options);
5054
- let channel = rasters[0];
5055
- (_a = optionsLocal.useChannelIndex) !== null && _a !== void 0 ? _a : (optionsLocal.useChannelIndex = optionsLocal.useChannel == null ? null : optionsLocal.useChannel - 1);
5056
- if (options.useChannelIndex != null) {
5057
- if (rasters[optionsLocal.useChannelIndex]) {
5058
- channel = rasters[optionsLocal.useChannelIndex];
5059
- }
5029
+ }
5030
+ const terrain = new Float32Array((width + 1) * (height + 1));
5031
+ const numOfChannels = channel.length / (width * height);
5032
+ let pixel = options.useChannelIndex === null ? 0 : options.useChannelIndex;
5033
+ for (let i = 0, y = 0; y < height; y++) {
5034
+ for (let x = 0; x < width; x++, i++) {
5035
+ const elevationValue = (options.noDataValue && channel[pixel] === options.noDataValue) ? options.terrainMinValue : channel[pixel] * options.multiplier;
5036
+ terrain[i + y] = elevationValue;
5037
+ pixel += numOfChannels;
5060
5038
  }
5061
- const terrain = new Float32Array((width + 1) * (height + 1));
5062
- const numOfChannels = channel.length / (width * height);
5063
- let pixel = options.useChannelIndex === null ? 0 : options.useChannelIndex;
5064
- for (let i = 0, y = 0; y < height; y++) {
5065
- for (let x = 0; x < width; x++, i++) {
5066
- const elevationValue = (options.noDataValue && channel[pixel] === options.noDataValue) ? options.terrainMinValue : channel[pixel] * options.multiplier;
5067
- terrain[i + y] = elevationValue;
5068
- pixel += numOfChannels;
5069
- }
5039
+ }
5040
+ {
5041
+ // backfill bottom border
5042
+ for (let i = (width + 1) * width, x = 0; x < width; x++, i++) {
5043
+ terrain[i] = terrain[i - width - 1];
5070
5044
  }
5071
- {
5072
- // backfill bottom border
5073
- for (let i = (width + 1) * width, x = 0; x < width; x++, i++) {
5074
- terrain[i] = terrain[i - width - 1];
5075
- }
5076
- // backfill right border
5077
- for (let i = height, y = 0; y < height + 1; y++, i += height + 1) {
5078
- terrain[i] = terrain[i - 1];
5079
- }
5045
+ // backfill right border
5046
+ for (let i = height, y = 0; y < height + 1; y++, i += height + 1) {
5047
+ terrain[i] = terrain[i - 1];
5080
5048
  }
5081
- // getMesh
5082
- const { terrainSkirtHeight } = options;
5083
- let mesh;
5084
- switch (tesselator) {
5085
- case 'martini':
5049
+ }
5050
+ // getMesh
5051
+ const { terrainSkirtHeight } = options;
5052
+ let mesh;
5053
+ switch (tesselator) {
5054
+ case 'martini':
5055
+ mesh = getMartiniTileMesh(meshMaxError, width, terrain);
5056
+ break;
5057
+ case 'delatin':
5058
+ mesh = getDelatinTileMesh(meshMaxError, width, height, terrain);
5059
+ break;
5060
+ default:
5061
+ if (width === height && !(height && (width - 1))) {
5062
+ // fixme get terrain to separate method
5063
+ // terrain = getTerrain(data, width, height, elevationDecoder, 'martini');
5086
5064
  mesh = getMartiniTileMesh(meshMaxError, width, terrain);
5087
- break;
5088
- case 'delatin':
5065
+ }
5066
+ else {
5067
+ // fixme get terrain to separate method
5068
+ // terrain = getTerrain(data, width, height, elevationDecoder, 'delatin');
5089
5069
  mesh = getDelatinTileMesh(meshMaxError, width, height, terrain);
5090
- break;
5091
- default:
5092
- if (width === height && !(height && (width - 1))) {
5093
- // fixme get terrain to separate method
5094
- // terrain = getTerrain(data, width, height, elevationDecoder, 'martini');
5095
- mesh = getMartiniTileMesh(meshMaxError, width, terrain);
5096
- }
5097
- else {
5098
- // fixme get terrain to separate method
5099
- // terrain = getTerrain(data, width, height, elevationDecoder, 'delatin');
5100
- mesh = getDelatinTileMesh(meshMaxError, width, height, terrain);
5101
- }
5102
- break;
5103
- }
5104
- // Martini
5105
- // Martini
5106
- // Delatin
5107
- // Delatin
5108
- const { vertices } = mesh;
5109
- let { triangles } = mesh;
5110
- let attributes = getMeshAttributes(vertices, terrain, width, height, input.bounds);
5111
- // Compute bounding box before adding skirt so that z values are not skewed
5112
- const boundingBox = schema.getMeshBoundingBox(attributes);
5113
- if (terrainSkirtHeight) {
5114
- const { attributes: newAttributes, triangles: newTriangles } = addSkirt(attributes, triangles, terrainSkirtHeight);
5115
- attributes = newAttributes;
5116
- triangles = newTriangles;
5117
- }
5118
- return {
5119
- // Data return by this loader implementation
5120
- loaderData: {
5121
- header: {},
5122
- },
5123
- header: {
5124
- vertexCount: triangles.length,
5125
- boundingBox,
5126
- },
5127
- mode: 4,
5128
- indices: { value: Uint32Array.from(triangles), size: 1 },
5129
- attributes,
5130
- };
5131
- });
5132
- }
5133
- getBitmap(input, options) {
5134
- var _a;
5135
- return __awaiter(this, void 0, void 0, function* () {
5136
- // console.time('bitmap-generated-in');
5137
- // const optionsLocal = { ...options };
5138
- const optionsLocal = Object.assign({}, options);
5139
- let rasters = [];
5140
- let channels;
5141
- let width;
5142
- let height;
5143
- if (typeof (input) === 'string') {
5144
- // TODO not tested
5145
- // input is type of object
5146
- yield this.setUrl(input);
5147
- rasters = (yield this.data.readRasters());
5148
- channels = rasters.length;
5149
- width = this.data.getWidth();
5150
- height = this.data.getHeight();
5151
- }
5152
- else {
5153
- rasters = input.rasters;
5154
- channels = rasters.length;
5155
- width = input.width;
5156
- height = input.height;
5157
- }
5158
- const canvas = document.createElement('canvas');
5159
- canvas.width = width;
5160
- canvas.height = height;
5161
- const c = canvas.getContext('2d');
5162
- const imageData = c.createImageData(width, height);
5163
- let r;
5164
- let g;
5165
- let b;
5166
- let a;
5167
- const size = width * height * 4;
5168
- // const size = width * height;
5169
- // if (!options.noDataValue) {
5170
- // console.log('Missing noData value. Raster might be displayed incorrectly.');
5171
- // }
5172
- optionsLocal.unidentifiedColor = this.getColorFromChromaType(optionsLocal.unidentifiedColor);
5173
- optionsLocal.nullColor = this.getColorFromChromaType(optionsLocal.nullColor);
5174
- optionsLocal.clippedColor = this.getColorFromChromaType(optionsLocal.clippedColor);
5175
- optionsLocal.color = this.getColorFromChromaType(optionsLocal.color);
5176
- (_a = optionsLocal.useChannelIndex) !== null && _a !== void 0 ? _a : (optionsLocal.useChannelIndex = options.useChannel === null ? null : options.useChannel - 1);
5177
- // console.log(rasters[0])
5178
- /* console.log("raster 0 length: " + rasters[0].length)
5179
- console.log("image width: " + width)
5180
- console.log("channels: " + channels)
5181
- console.log("format: " + rasters[0].length / (width * height))
5182
- */
5183
- if (optionsLocal.useChannelIndex == null) {
5184
- if (channels === 1) {
5185
- if (rasters[0].length / (width * height) === 1) {
5186
- const channel = rasters[0];
5187
- // AUTO RANGE
5188
- if (optionsLocal.useAutoRange) {
5189
- optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
5190
- // console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
5191
- }
5192
- // SINGLE CHANNEL
5193
- const colorData = this.getColorValue(channel, optionsLocal, size);
5194
- colorData.forEach((value, index) => {
5195
- imageData.data[index] = value;
5196
- });
5197
- }
5198
- // RGB values in one channel
5199
- if (rasters[0].length / (width * height) === 3) {
5200
- // console.log("geoImage: " + "RGB 1 array of length: " + rasters[0].length);
5201
- let pixel = 0;
5202
- for (let idx = 0; idx < size; idx += 4) {
5203
- const rgbColor = [rasters[0][pixel], rasters[0][pixel + 1], rasters[0][pixel + 2]];
5204
- const rgbaColor = this.hasPixelsNoData(rgbColor, optionsLocal.noDataValue)
5205
- ? optionsLocal.nullColor
5206
- : [...rgbColor, Math.floor(optionsLocal.alpha * 2.55)];
5207
- // eslint-disable-next-line max-len
5208
- [imageData.data[idx], imageData.data[idx + 1], imageData.data[idx + 2], imageData.data[idx + 3]] = rgbaColor;
5209
- pixel += 3;
5210
- }
5211
- }
5212
- if (rasters[0].length / (width * height) === 4) {
5213
- // console.log("geoImage: " + "RGBA 1 array");
5214
- rasters[0].forEach((value, index) => {
5215
- imageData.data[index] = value;
5216
- });
5217
- }
5218
5070
  }
5219
- if (channels === 3) {
5220
- // RGB
5221
- let pixel = 0;
5222
- for (let i = 0; i < size; i += 4) {
5223
- r = rasters[0][pixel];
5224
- g = rasters[1][pixel];
5225
- b = rasters[2][pixel];
5226
- a = Math.floor(optionsLocal.alpha * 2.55);
5227
- imageData.data[i] = r;
5228
- imageData.data[i + 1] = g;
5229
- imageData.data[i + 2] = b;
5230
- imageData.data[i + 3] = a;
5231
- pixel += 1;
5071
+ break;
5072
+ }
5073
+ const { vertices } = mesh;
5074
+ let { triangles } = mesh;
5075
+ let attributes = getMeshAttributes(vertices, terrain, width, height, input.bounds);
5076
+ // Compute bounding box before adding skirt so that z values are not skewed
5077
+ const boundingBox = schema.getMeshBoundingBox(attributes);
5078
+ if (terrainSkirtHeight) {
5079
+ const { attributes: newAttributes, triangles: newTriangles } = addSkirt(attributes, triangles, terrainSkirtHeight);
5080
+ attributes = newAttributes;
5081
+ triangles = newTriangles;
5082
+ }
5083
+ return {
5084
+ // Data return by this loader implementation
5085
+ loaderData: {
5086
+ header: {},
5087
+ },
5088
+ header: {
5089
+ vertexCount: triangles.length,
5090
+ boundingBox,
5091
+ },
5092
+ mode: 4, // TRIANGLES
5093
+ indices: { value: Uint32Array.from(triangles), size: 1 },
5094
+ attributes,
5095
+ };
5096
+ }
5097
+ async getBitmap(input, options) {
5098
+ // console.time('bitmap-generated-in');
5099
+ // const optionsLocal = { ...options };
5100
+ const optionsLocal = { ...options };
5101
+ let rasters = [];
5102
+ let channels;
5103
+ let width;
5104
+ let height;
5105
+ if (typeof (input) === 'string') {
5106
+ // TODO not tested
5107
+ // input is type of object
5108
+ await this.setUrl(input);
5109
+ rasters = (await this.data.readRasters());
5110
+ channels = rasters.length;
5111
+ width = this.data.getWidth();
5112
+ height = this.data.getHeight();
5113
+ }
5114
+ else {
5115
+ rasters = input.rasters;
5116
+ channels = rasters.length;
5117
+ width = input.width;
5118
+ height = input.height;
5119
+ }
5120
+ const canvas = document.createElement('canvas');
5121
+ canvas.width = width;
5122
+ canvas.height = height;
5123
+ const c = canvas.getContext('2d');
5124
+ const imageData = c.createImageData(width, height);
5125
+ let r;
5126
+ let g;
5127
+ let b;
5128
+ let a;
5129
+ const size = width * height * 4;
5130
+ // const size = width * height;
5131
+ // if (!options.noDataValue) {
5132
+ // console.log('Missing noData value. Raster might be displayed incorrectly.');
5133
+ // }
5134
+ optionsLocal.unidentifiedColor = this.getColorFromChromaType(optionsLocal.unidentifiedColor);
5135
+ optionsLocal.nullColor = this.getColorFromChromaType(optionsLocal.nullColor);
5136
+ optionsLocal.clippedColor = this.getColorFromChromaType(optionsLocal.clippedColor);
5137
+ optionsLocal.color = this.getColorFromChromaType(optionsLocal.color);
5138
+ optionsLocal.useChannelIndex ??= options.useChannel === null ? null : options.useChannel - 1;
5139
+ // console.log(rasters[0])
5140
+ /* console.log("raster 0 length: " + rasters[0].length)
5141
+ console.log("image width: " + width)
5142
+ console.log("channels: " + channels)
5143
+ console.log("format: " + rasters[0].length / (width * height))
5144
+ */
5145
+ if (optionsLocal.useChannelIndex == null) {
5146
+ if (channels === 1) {
5147
+ if (rasters[0].length / (width * height) === 1) {
5148
+ const channel = rasters[0];
5149
+ // AUTO RANGE
5150
+ if (optionsLocal.useAutoRange) {
5151
+ optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
5152
+ // console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
5232
5153
  }
5154
+ // SINGLE CHANNEL
5155
+ const colorData = this.getColorValue(channel, optionsLocal, size);
5156
+ colorData.forEach((value, index) => {
5157
+ imageData.data[index] = value;
5158
+ });
5233
5159
  }
5234
- if (channels === 4) {
5235
- // RGBA
5160
+ // RGB values in one channel
5161
+ if (rasters[0].length / (width * height) === 3) {
5162
+ // console.log("geoImage: " + "RGB 1 array of length: " + rasters[0].length);
5236
5163
  let pixel = 0;
5237
- for (let i = 0; i < size; i += 4) {
5238
- r = rasters[0][pixel];
5239
- g = rasters[1][pixel];
5240
- b = rasters[2][pixel];
5241
- a = Math.floor(optionsLocal.alpha * 2.55);
5242
- imageData.data[i] = r;
5243
- imageData.data[i + 1] = g;
5244
- imageData.data[i + 2] = b;
5245
- imageData.data[i + 3] = a;
5246
- pixel += 1;
5164
+ for (let idx = 0; idx < size; idx += 4) {
5165
+ const rgbColor = [rasters[0][pixel], rasters[0][pixel + 1], rasters[0][pixel + 2]];
5166
+ const rgbaColor = this.hasPixelsNoData(rgbColor, optionsLocal.noDataValue)
5167
+ ? optionsLocal.nullColor
5168
+ : [...rgbColor, Math.floor(optionsLocal.alpha * 2.55)];
5169
+ // eslint-disable-next-line max-len
5170
+ [imageData.data[idx], imageData.data[idx + 1], imageData.data[idx + 2], imageData.data[idx + 3]] = rgbaColor;
5171
+ pixel += 3;
5247
5172
  }
5248
5173
  }
5174
+ if (rasters[0].length / (width * height) === 4) {
5175
+ // console.log("geoImage: " + "RGBA 1 array");
5176
+ rasters[0].forEach((value, index) => {
5177
+ imageData.data[index] = value;
5178
+ });
5179
+ }
5249
5180
  }
5250
- else if (optionsLocal.useChannelIndex < optionsLocal.numOfChannels && optionsLocal.useChannelIndex >= 0) {
5251
- let channel = rasters[0];
5252
- if (rasters[optionsLocal.useChannelIndex]) {
5253
- channel = rasters[optionsLocal.useChannelIndex];
5181
+ if (channels === 3) {
5182
+ // RGB
5183
+ let pixel = 0;
5184
+ for (let i = 0; i < size; i += 4) {
5185
+ r = rasters[0][pixel];
5186
+ g = rasters[1][pixel];
5187
+ b = rasters[2][pixel];
5188
+ a = Math.floor(optionsLocal.alpha * 2.55);
5189
+ imageData.data[i] = r;
5190
+ imageData.data[i + 1] = g;
5191
+ imageData.data[i + 2] = b;
5192
+ imageData.data[i + 3] = a;
5193
+ pixel += 1;
5254
5194
  }
5255
- // AUTO RANGE
5256
- if (optionsLocal.useAutoRange) {
5257
- optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
5258
- // console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
5195
+ }
5196
+ if (channels === 4) {
5197
+ // RGBA
5198
+ let pixel = 0;
5199
+ for (let i = 0; i < size; i += 4) {
5200
+ r = rasters[0][pixel];
5201
+ g = rasters[1][pixel];
5202
+ b = rasters[2][pixel];
5203
+ a = Math.floor(optionsLocal.alpha * 2.55);
5204
+ imageData.data[i] = r;
5205
+ imageData.data[i + 1] = g;
5206
+ imageData.data[i + 2] = b;
5207
+ imageData.data[i + 3] = a;
5208
+ pixel += 1;
5259
5209
  }
5260
- // const numOfChannels = channel.length / (width * height);
5261
- const colorData = this.getColorValue(channel, optionsLocal, size, optionsLocal.numOfChannels);
5262
- colorData.forEach((value, index) => {
5263
- imageData.data[index] = value;
5264
- });
5265
5210
  }
5266
- else {
5267
- // if user defined channel does not exist
5268
- console.log(`Defined channel(${options.useChannel}) or channel index(${options.useChannelIndex}) does not exist, choose a different channel or set the useChannel property to null if you want to visualize RGB(A) imagery`);
5269
- const defaultColorData = this.getDefaultColor(size, optionsLocal.nullColor);
5270
- defaultColorData.forEach((value, index) => {
5271
- imageData.data[index] = value;
5272
- });
5211
+ }
5212
+ else if (optionsLocal.useChannelIndex < optionsLocal.numOfChannels && optionsLocal.useChannelIndex >= 0) {
5213
+ let channel = rasters[0];
5214
+ if (rasters[optionsLocal.useChannelIndex]) {
5215
+ channel = rasters[optionsLocal.useChannelIndex];
5273
5216
  }
5274
- // console.timeEnd('bitmap-generated-in');
5275
- c.putImageData(imageData, 0, 0);
5276
- const imageUrl = canvas.toDataURL('image/png');
5277
- // console.log('Bitmap generated.');
5278
- return imageUrl;
5279
- });
5217
+ // AUTO RANGE
5218
+ if (optionsLocal.useAutoRange) {
5219
+ optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
5220
+ // console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
5221
+ }
5222
+ // const numOfChannels = channel.length / (width * height);
5223
+ const colorData = this.getColorValue(channel, optionsLocal, size, optionsLocal.numOfChannels);
5224
+ colorData.forEach((value, index) => {
5225
+ imageData.data[index] = value;
5226
+ });
5227
+ }
5228
+ else {
5229
+ // if user defined channel does not exist
5230
+ console.log(`Defined channel(${options.useChannel}) or channel index(${options.useChannelIndex}) does not exist, choose a different channel or set the useChannel property to null if you want to visualize RGB(A) imagery`);
5231
+ const defaultColorData = this.getDefaultColor(size, optionsLocal.nullColor);
5232
+ defaultColorData.forEach((value, index) => {
5233
+ imageData.data[index] = value;
5234
+ });
5235
+ }
5236
+ // console.timeEnd('bitmap-generated-in');
5237
+ c.putImageData(imageData, 0, 0);
5238
+ const imageUrl = canvas.toDataURL('image/png');
5239
+ // console.log('Bitmap generated.');
5240
+ return imageUrl;
5280
5241
  }
5281
5242
  getMinMax(array, options) {
5282
5243
  let maxValue = options.maxValue ? options.maxValue : Number.MIN_VALUE;
@@ -5355,7 +5316,7 @@ class GeoImage {
5355
5316
  }
5356
5317
  // FIXME
5357
5318
  // eslint-disable-next-line
5358
- [colorsArray[i], colorsArray[i + 1], colorsArray[i + 2], colorsArray[i + 3]] = pixelColor;
5319
+ ([colorsArray[i], colorsArray[i + 1], colorsArray[i + 2], colorsArray[i + 3]] = pixelColor);
5359
5320
  pixel += numOfChannels;
5360
5321
  }
5361
5322
  return colorsArray;
@@ -5445,7 +5406,7 @@ function getMeshAttributes(vertices, terrain, width, height, bounds) {
5445
5406
  function getDelatinTileMesh(meshMaxError, width, height, terrain) {
5446
5407
  const tin = new Delatin(terrain, width + 1, height + 1);
5447
5408
  tin.run(meshMaxError);
5448
- // @ts-expect-error
5409
+ // @ts-expect-error: Delatin instance properties 'coords' and 'triangles' are not explicitly typed in the library port
5449
5410
  const { coords, triangles } = tin;
5450
5411
  const vertices = coords;
5451
5412
  return { vertices, triangles };
@@ -5459,31 +5420,30 @@ const CogTilesGeoImageOptionsDefaults = {
5459
5420
  blurredTexture: true,
5460
5421
  };
5461
5422
  class CogTiles {
5423
+ cog;
5424
+ cogZoomLookup = [0];
5425
+ cogResolutionLookup = [0];
5426
+ cogOrigin = [0, 0];
5427
+ zoomRange = [0, 0];
5428
+ tileSize;
5429
+ bounds;
5430
+ geo = new GeoImage();
5431
+ options;
5462
5432
  constructor(options) {
5463
- this.cogZoomLookup = [0];
5464
- this.cogResolutionLookup = [0];
5465
- this.cogOrigin = [0, 0];
5466
- this.zoomRange = [0, 0];
5467
- this.loaded = false;
5468
- this.geo = new GeoImage();
5469
- this.options = Object.assign(Object.assign({}, CogTilesGeoImageOptionsDefaults), options);
5470
- }
5471
- initializeCog(url) {
5472
- var _a, _b;
5473
- var _c, _d;
5474
- return __awaiter(this, void 0, void 0, function* () {
5475
- this.cog = yield fromUrl(url);
5476
- const image = yield this.cog.getImage(); // by default, the first image is read.
5477
- this.cogOrigin = image.getOrigin();
5478
- (_a = (_c = this.options).noDataValue) !== null && _a !== void 0 ? _a : (_c.noDataValue = this.getNoDataValue(image));
5479
- (_b = (_d = this.options).format) !== null && _b !== void 0 ? _b : (_d.format = this.getDataTypeFromTags(image));
5480
- this.options.numOfChannels = this.getNumberOfChannels(image);
5481
- this.options.planarConfig = this.getPlanarConfiguration(image);
5482
- [this.cogZoomLookup, this.cogResolutionLookup] = yield this.buildCogZoomResolutionLookup(this.cog);
5483
- this.tileSize = image.getTileWidth();
5484
- this.zoomRange = this.calculateZoomRange(image, yield this.cog.getImageCount());
5485
- this.bounds = this.calculateBoundsAsLatLon(image);
5486
- });
5433
+ this.options = { ...CogTilesGeoImageOptionsDefaults, ...options };
5434
+ }
5435
+ async initializeCog(url) {
5436
+ this.cog = await fromUrl(url);
5437
+ const image = await this.cog.getImage(); // by default, the first image is read.
5438
+ this.cogOrigin = image.getOrigin();
5439
+ this.options.noDataValue ??= this.getNoDataValue(image);
5440
+ this.options.format ??= this.getDataTypeFromTags(image);
5441
+ this.options.numOfChannels = this.getNumberOfChannels(image);
5442
+ this.options.planarConfig = this.getPlanarConfiguration(image);
5443
+ [this.cogZoomLookup, this.cogResolutionLookup] = await this.buildCogZoomResolutionLookup(this.cog);
5444
+ this.tileSize = image.getTileWidth();
5445
+ this.zoomRange = this.calculateZoomRange(image, await this.cog.getImageCount());
5446
+ this.bounds = this.calculateBoundsAsLatLon(image);
5487
5447
  }
5488
5448
  getZoomRange() {
5489
5449
  return this.zoomRange;
@@ -5535,33 +5495,31 @@ class CogTiles {
5535
5495
  * - The first array (`zoomLookup`) maps each image index to its computed zoom level.
5536
5496
  * - The second array (`resolutionLookup`) maps each image index to its estimated resolution (m/pixel).
5537
5497
  */
5538
- buildCogZoomResolutionLookup(cog) {
5539
- return __awaiter(this, void 0, void 0, function* () {
5540
- // Retrieve the total number of images (overviews) in the COG.
5541
- const imageCount = yield cog.getImageCount();
5542
- // Use the first image as the base reference.
5543
- const baseImage = yield cog.getImage(0);
5544
- const baseResolution = baseImage.getResolution()[0]; // Resolution (m/pixel) of the base image.
5545
- const baseWidth = baseImage.getWidth();
5546
- // Initialize arrays to store the zoom level and resolution for each image.
5547
- const zoomLookup = [];
5548
- const resolutionLookup = [];
5549
- // Iterate over each image (overview) in the COG.
5550
- for (let idx = 0; idx < imageCount; idx++) {
5551
- const image = yield cog.getImage(idx);
5552
- const width = image.getWidth();
5553
- // Calculate the scale factor relative to the base image.
5554
- const scaleFactor = baseWidth / width;
5555
- const estimatedResolution = baseResolution * scaleFactor;
5556
- // Calculate the zoom level using the Web Mercator resolution standard:
5557
- // webMercatorRes0 is the resolution at zoom level 0; each zoom level halves the resolution.
5558
- const zoomLevel = Math.round(Math.log2(webMercatorRes0 / estimatedResolution));
5559
- // console.log(`buildCogZoomResolutionLookup: Image index ${idx}: Estimated Resolution = ${estimatedResolution} m/pixel, Zoom Level = ${zoomLevel}`);
5560
- zoomLookup[idx] = zoomLevel;
5561
- resolutionLookup[idx] = estimatedResolution;
5562
- }
5563
- return [zoomLookup, resolutionLookup];
5564
- });
5498
+ async buildCogZoomResolutionLookup(cog) {
5499
+ // Retrieve the total number of images (overviews) in the COG.
5500
+ const imageCount = await cog.getImageCount();
5501
+ // Use the first image as the base reference.
5502
+ const baseImage = await cog.getImage(0);
5503
+ const baseResolution = baseImage.getResolution()[0]; // Resolution (m/pixel) of the base image.
5504
+ const baseWidth = baseImage.getWidth();
5505
+ // Initialize arrays to store the zoom level and resolution for each image.
5506
+ const zoomLookup = [];
5507
+ const resolutionLookup = [];
5508
+ // Iterate over each image (overview) in the COG.
5509
+ for (let idx = 0; idx < imageCount; idx++) {
5510
+ const image = await cog.getImage(idx);
5511
+ const width = image.getWidth();
5512
+ // Calculate the scale factor relative to the base image.
5513
+ const scaleFactor = baseWidth / width;
5514
+ const estimatedResolution = baseResolution * scaleFactor;
5515
+ // Calculate the zoom level using the Web Mercator resolution standard:
5516
+ // webMercatorRes0 is the resolution at zoom level 0; each zoom level halves the resolution.
5517
+ const zoomLevel = Math.round(Math.log2(webMercatorRes0 / estimatedResolution));
5518
+ // console.log(`buildCogZoomResolutionLookup: Image index ${idx}: Estimated Resolution = ${estimatedResolution} m/pixel, Zoom Level = ${zoomLevel}`);
5519
+ zoomLookup[idx] = zoomLevel;
5520
+ resolutionLookup[idx] = estimatedResolution;
5521
+ }
5522
+ return [zoomLookup, resolutionLookup];
5565
5523
  }
5566
5524
  /**
5567
5525
  * Determines the appropriate image index from the Cloud Optimized GeoTIFF (COG)
@@ -5590,93 +5548,138 @@ class CogTiles {
5590
5548
  }
5591
5549
  return exactMatchIndex;
5592
5550
  }
5593
- getTileFromImage(tileX, tileY, zoom) {
5594
- return __awaiter(this, void 0, void 0, function* () {
5595
- const imageIndex = this.getImageIndexForZoomLevel(zoom);
5596
- const targetImage = yield this.cog.getImage(imageIndex);
5597
- // Ensure the image is tiled
5598
- const tileWidth = targetImage.getTileWidth();
5599
- const tileHeight = targetImage.getTileHeight();
5600
- if (!tileWidth || !tileHeight) {
5601
- throw new Error('The image is not tiled.');
5602
- }
5603
- // Calculate the map offset between the global Web Mercator origin and the COG's origin.
5604
- // (Difference in map units.)
5605
- // if X offset is large and positive (COG is far to the right of global origin)
5606
- // if Y offset is large and positive (COG is far below global origin — expected)
5607
- const offsetXMap = this.cogOrigin[0] - webMercatorOrigin[0];
5608
- const offsetYMap = webMercatorOrigin[1] - this.cogOrigin[1];
5609
- const tileResolution = (EARTH_CIRCUMFERENCE / tileWidth) / Math.pow(2, zoom);
5610
- this.cogResolutionLookup[imageIndex];
5611
- // Convert map offsets into pixel offsets.
5612
- const offsetXPixel = Math.floor(offsetXMap / tileResolution);
5613
- const offsetYPixel = Math.floor(offsetYMap / tileResolution);
5614
- const imageHeight = targetImage.getHeight();
5615
- const imageWidth = targetImage.getWidth();
5616
- // approach by comparing bboxes of tile and cog image
5617
- const tilePixelBbox = [
5618
- tileX * tileWidth,
5619
- tileY * tileHeight,
5620
- (tileX + 1) * tileWidth,
5621
- (tileY + 1) * tileHeight,
5622
- ];
5623
- const cogPixelBBox = [
5624
- offsetXPixel,
5625
- offsetYPixel,
5626
- offsetXPixel + imageWidth,
5627
- offsetYPixel + imageHeight,
5628
- ];
5629
- const intersecion = this.getIntersectionBBox(tilePixelBbox, cogPixelBBox, offsetXPixel, offsetYPixel, tileWidth);
5630
- const [validWidth, validHeight, window, missingLeft, missingTop] = intersecion;
5631
- // Read the raster data for the tile window with shifted origin.
5632
- if (missingLeft > 0 || missingTop > 0 || validWidth < tileWidth || validHeight < tileHeight) {
5633
- // Prepare the final tile buffer and fill it with noDataValue.
5634
- const tileBuffer = this.createTileBuffer(this.options.format, tileWidth);
5635
- tileBuffer.fill(this.options.noDataValue);
5636
- // if the valid window is smaller than tile size, it gets the image size width and height, thus validRasterData.width must be used as below
5637
- const validRasterData = yield targetImage.readRasters({ window });
5638
- // FOR MULTI-BAND - the result is one array with sequentially typed bands, firstly all data for the band 0, then for band 1
5639
- // I think this is less practical then the commented solution above, but I do it so it works with the code in geoimage.ts in deck.gl-geoimage in function getColorValue.
5640
- const validImageData = Array(validRasterData.length * validRasterData[0].length);
5641
- validImageData.fill(this.options.noDataValue);
5642
- // Place the valid pixel data into the tile buffer.
5643
- for (let band = 0; band < validRasterData.length; band++) {
5644
- for (let row = 0; row < validHeight; row++) {
5645
- for (let col = 0; col < validWidth; col++) {
5646
- // Compute the destination position in the tile buffer.
5647
- // We shift by the number of missing pixels (if any) at the top/left.
5648
- const destRow = missingTop + row;
5649
- const destCol = missingLeft + col;
5650
- if (destRow < tileWidth && destCol < tileHeight) {
5651
- tileBuffer[destRow * tileWidth + destCol] = validRasterData[band][row * validRasterData.width + col];
5652
- }
5653
- else {
5654
- console.log('error in assigning data to tile buffer');
5655
- }
5551
+ async getTileFromImage(tileX, tileY, zoom) {
5552
+ const imageIndex = this.getImageIndexForZoomLevel(zoom);
5553
+ const targetImage = await this.cog.getImage(imageIndex);
5554
+ // 1. Validation: Ensure the image is tiled
5555
+ const tileWidth = targetImage.getTileWidth();
5556
+ const tileHeight = targetImage.getTileHeight();
5557
+ if (!tileWidth || !tileHeight) {
5558
+ throw new Error('GeoTIFF Error: The provided image is not tiled. '
5559
+ + 'Please use "rio cogeo create --web-optimized" to fix this.');
5560
+ }
5561
+ // --- STEP 1: CALCULATE BOUNDS IN METERS ---
5562
+ // 2. Get COG Metadata (image = COG)
5563
+ const imageResolution = this.cogResolutionLookup[imageIndex];
5564
+ const imageHeight = targetImage.getHeight();
5565
+ const imageWidth = targetImage.getWidth();
5566
+ const [imgOriginX, imgOriginY] = this.cogOrigin;
5567
+ // 3. Define Web Mercator Constants
5568
+ // We use the class property tileSize (usually 256) as the ground truth for grid calculations
5569
+ const TILE_SIZE = this.tileSize;
5570
+ const ORIGIN_X = webMercatorOrigin[0];
5571
+ const ORIGIN_Y = webMercatorOrigin[1];
5572
+ // 4. Calculate Tile BBox in World Meters
5573
+ // This defines where the map expects the tile to be physically located
5574
+ const tileGridResolution = (EARTH_CIRCUMFERENCE / TILE_SIZE) / (2 ** zoom);
5575
+ const tileMinXMeters = ORIGIN_X + (tileX * TILE_SIZE * tileGridResolution);
5576
+ const tileMaxYMeters = ORIGIN_Y - (tileY * TILE_SIZE * tileGridResolution);
5577
+ // Note: We don't strictly need MaxX/MinY meters for the start calculation,
5578
+ // but they are useful if debugging the full meter footprint.
5579
+ // --- STEP 2: CONVERT TO PIXEL COORDINATES ---
5580
+ // 5. Calculate precise floating-point start position relative to the image
5581
+ const windowMinX = (tileMinXMeters - imgOriginX) / imageResolution;
5582
+ const windowMinY = (imgOriginY - tileMaxYMeters) / imageResolution;
5583
+ // 6. Snap to Integer Grid (The "Force 256" Fix)
5584
+ // We round the start position to align with the nearest pixel.
5585
+ // Crucially, we calculate endX/endY by adding tileSize to startX/startY.
5586
+ // This guarantees the window is exactly 256x256, preventing "off-by-one" (257px) errors.
5587
+ const startX = Math.round(windowMinX);
5588
+ const startY = Math.round(windowMinY);
5589
+ const endX = startX + TILE_SIZE;
5590
+ const endY = startY + TILE_SIZE;
5591
+ // --- STEP 3: CALCULATE INTERSECTION ---
5592
+ // 7. Clamp the read window to the actual image dimensions
5593
+ // This defines the "Safe" area we can actually read from the file.
5594
+ const validReadX = Math.max(0, startX);
5595
+ const validReadY = Math.max(0, startY);
5596
+ const validReadMaxX = Math.min(imageWidth, endX);
5597
+ const validReadMaxY = Math.min(imageHeight, endY);
5598
+ const readWidth = validReadMaxX - validReadX;
5599
+ const readHeight = validReadMaxY - validReadY;
5600
+ // CHECK: If no overlap, return empty
5601
+ if (readWidth <= 0 || readHeight <= 0) {
5602
+ return [this.createEmptyTile()];
5603
+ }
5604
+ // 8. Calculate Offsets (Padding)
5605
+ // "missingLeft" is how many blank pixels we need to insert before the image data starts.
5606
+ // Logic: If we wanted to read from -50 (startX), but clamped to 0 (validReadX),
5607
+ // we are missing the first 50 pixels.
5608
+ const missingLeft = validReadX - startX;
5609
+ const missingTop = validReadY - startY;
5610
+ const window = [validReadX, validReadY, validReadMaxX, validReadMaxY];
5611
+ // --- STEP 4: READ AND COMPOSITE ---
5612
+ // Case A: Partial Overlap (Padding or Cropping required)
5613
+ // If the tile is hanging off the edge, we need to manually reconstruct it.
5614
+ if (missingLeft > 0 || missingTop > 0 || readWidth < tileWidth || readHeight < tileHeight) {
5615
+ /// Initialize a temporary buffer for a single band (filled with NoData)
5616
+ // We will reuse this buffer for each band to save memory allocations.
5617
+ const tileBuffer = this.createTileBuffer(this.options.format, tileWidth);
5618
+ tileBuffer.fill(this.options.noDataValue);
5619
+ // if the valid window is smaller than the tile size, it gets the image size width and height, thus validRasterData.width must be used as below
5620
+ const validRasterData = await targetImage.readRasters({ window });
5621
+ // FOR MULTI-BAND - the result is one array with sequentially typed bands, firstly all data for the band 0, then for band 1
5622
+ // I think this is less practical then the commented solution above, but I do it so it works with the code in GeoImage.ts in deck.gl-geoimage in function getColorValue.
5623
+ const validImageData = Array(validRasterData.length * validRasterData[0].length);
5624
+ validImageData.fill(this.options.noDataValue);
5625
+ // Place the valid pixel data into the tile buffer.
5626
+ for (let band = 0; band < validRasterData.length; band += 1) {
5627
+ for (let row = 0; row < readHeight; row += 1) {
5628
+ const destRow = missingTop + row;
5629
+ const destRowOffset = destRow * TILE_SIZE;
5630
+ const srcRowOffset = row * validRasterData.width;
5631
+ for (let col = 0; col < readWidth; col += 1) {
5632
+ // Compute the destination position in the tile buffer.
5633
+ // We shift by the number of missing pixels (if any) at the top/left.
5634
+ const destCol = missingLeft + col;
5635
+ // Bounds Check: Ensure we don't write outside the 256x256 buffer
5636
+ if (destRow < tileWidth && destCol < tileHeight) {
5637
+ tileBuffer[destRowOffset + destCol] = validRasterData[band][srcRowOffset + col];
5638
+ }
5639
+ else {
5640
+ console.log('error in assigning data to tile buffer');
5656
5641
  }
5657
5642
  }
5658
- tileBuffer.forEach((rasterValue, index) => {
5659
- validImageData[index * this.options.numOfChannels + band] = rasterValue;
5660
- });
5661
5643
  }
5662
- return [validImageData];
5644
+ for (let i = 0; i < tileBuffer.length; i += 1) {
5645
+ validImageData[i * this.options.numOfChannels + band] = tileBuffer[i];
5646
+ }
5663
5647
  }
5664
- // Read the raster data for the non shifted tile window.
5665
- const tileData = yield targetImage.readRasters({ window, interleave: true });
5666
- // console.log(`data that starts at the left top corner of the tile ${tileX}, ${tileY}`);
5667
- return [tileData];
5668
- });
5648
+ return [validImageData];
5649
+ }
5650
+ // Case B: Perfect Match (Optimization)
5651
+ // If the read window is exactly 256x256 and aligned, we can read directly interleaved.
5652
+ // console.log("Perfect aligned read");
5653
+ const tileData = await targetImage.readRasters({ window, interleave: true });
5654
+ // console.log(`data that starts at the left top corner of the tile ${tileX}, ${tileY}`);
5655
+ return [tileData];
5669
5656
  }
5670
- getTile(x, y, z, bounds, meshMaxError) {
5671
- return __awaiter(this, void 0, void 0, function* () {
5672
- const tileData = yield this.getTileFromImage(x, y, z);
5673
- return this.geo.getMap({
5674
- rasters: [tileData[0]],
5675
- width: this.tileSize,
5676
- height: this.tileSize,
5677
- bounds,
5678
- }, this.options, meshMaxError);
5679
- });
5657
+ /**
5658
+ * Creates a blank tile buffer filled with the "No Data" value.
5659
+ */
5660
+ createEmptyTile() {
5661
+ // 1. Determine the size
5662
+ // Default to 1 channel (grayscale) if not specified
5663
+ const channels = this.options.numOfChannels || 1;
5664
+ const size = this.tileSize * this.tileSize * channels;
5665
+ // 2. Create the array
5666
+ // Float32 is standard for GeoTIFF data handling in browsers
5667
+ const tileData = new Float32Array(size);
5668
+ // 3. Fill with "No Data" value
5669
+ // If noDataValue is undefined, it defaults to 0
5670
+ if (this.options.noDataValue !== undefined) {
5671
+ tileData.fill(this.options.noDataValue);
5672
+ }
5673
+ return tileData;
5674
+ }
5675
+ async getTile(x, y, z, bounds, meshMaxError) {
5676
+ const tileData = await this.getTileFromImage(x, y, z);
5677
+ return this.geo.getMap({
5678
+ rasters: [tileData[0]],
5679
+ width: this.tileSize,
5680
+ height: this.tileSize,
5681
+ bounds,
5682
+ }, this.options, meshMaxError);
5680
5683
  }
5681
5684
  /**
5682
5685
  * Determines the data type (e.g., "Int32", "Float64") of a GeoTIFF image
@@ -5759,53 +5762,6 @@ class CogTiles {
5759
5762
  getNumberOfChannels(image) {
5760
5763
  return image.getSamplesPerPixel();
5761
5764
  }
5762
- /**
5763
- * Calculates the intersection between a tile bounding box and a COG bounding box,
5764
- * returning the intersection window in image pixel space (relative to COG offsets),
5765
- * along with how much blank space (nodata) appears on the left and top of the tile.
5766
- *
5767
- * @param {number[]} tileBbox - Tile bounding box: [minX, minY, maxX, maxY]
5768
- * @param {number[]} cogBbox - COG bounding box: [minX, minY, maxX, maxY]
5769
- * @param {number} offsetXPixel - X offset of the COG origin in pixel space
5770
- * @param {number} offsetYPixel - Y offset of the COG origin in pixel space
5771
- * @param {number} tileSize - Size of the tile in pixels (default: 256)
5772
- * @returns {[number, number, number[] | null, number, number]}
5773
- * An array containing:
5774
- * - width of the intersection
5775
- * - height of the intersection
5776
- * - pixel-space window: [startX, startY, endX, endY] or null if no overlap
5777
- * - missingLeft: padding pixels on the left
5778
- * - missingTop: padding pixels on the top
5779
- */
5780
- getIntersectionBBox(tileBbox, cogBbox, offsetXPixel = 0, offsetYPixel = 0, tileSize = 256) {
5781
- const interLeft = Math.max(tileBbox[0], cogBbox[0]);
5782
- const interTop = Math.max(tileBbox[1], cogBbox[1]);
5783
- const interRight = Math.min(tileBbox[2], cogBbox[2]);
5784
- const interBottom = Math.min(tileBbox[3], cogBbox[3]);
5785
- const width = Math.max(0, interRight - interLeft);
5786
- const height = Math.max(0, interBottom - interTop);
5787
- let window = null;
5788
- let missingLeft = 0;
5789
- let missingTop = 0;
5790
- if (width > 0 && height > 0) {
5791
- window = [
5792
- interLeft - offsetXPixel,
5793
- interTop - offsetYPixel,
5794
- interRight - offsetXPixel,
5795
- interBottom - offsetYPixel,
5796
- ];
5797
- // Padding from the tile origin to valid data start
5798
- missingLeft = interLeft - tileBbox[0];
5799
- missingTop = interTop - tileBbox[1];
5800
- }
5801
- return [
5802
- width,
5803
- height,
5804
- window,
5805
- missingLeft,
5806
- missingTop,
5807
- ];
5808
- }
5809
5765
  /**
5810
5766
  * Retrieves the PlanarConfiguration value from a GeoTIFF image.
5811
5767
  *
@@ -5878,7 +5834,8 @@ const urlType$1 = {
5878
5834
  return true;
5879
5835
  },
5880
5836
  };
5881
- const defaultProps$1 = Object.assign(Object.assign({}, geoLayers.TileLayer.defaultProps), {
5837
+ const defaultProps$1 = {
5838
+ ...geoLayers.TileLayer.defaultProps,
5882
5839
  // Image url that encodes height data
5883
5840
  // elevationData: urlType,
5884
5841
  // Image url to use as texture
@@ -5888,10 +5845,9 @@ const defaultProps$1 = Object.assign(Object.assign({}, geoLayers.TileLayer.defau
5888
5845
  // Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
5889
5846
  bounds: {
5890
5847
  type: 'array', value: null, optional: true, compare: true,
5891
- }, rasterData: urlType$1,
5892
- // Color to use if texture is unavailable
5893
- // color: { type: 'color', value: [255, 255, 255] },
5894
- blurredTexture: true, opacity: 1, clampToTerrain: false,
5848
+ },
5849
+ rasterData: urlType$1,
5850
+ clampToTerrain: false,
5895
5851
  // Object to decode height data, from (r, g, b) to height in meters
5896
5852
  // elevationDecoder: {
5897
5853
  // type: 'object',
@@ -5903,40 +5859,31 @@ const defaultProps$1 = Object.assign(Object.assign({}, geoLayers.TileLayer.defau
5903
5859
  // },
5904
5860
  // },
5905
5861
  // Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
5906
- workerUrl: '' });
5862
+ workerUrl: '',
5863
+ // Same as SimpleMeshLayer wireframe
5864
+ // wireframe: false,
5865
+ // material: true,
5866
+ // loaders: [TerrainLoader],
5867
+ };
5907
5868
  /** Render bitmap texture from cog raster images. */
5908
5869
  class CogBitmapLayer extends core.CompositeLayer {
5909
- // private _isLoaded: boolean;
5910
- // id = '';
5911
- // url: string;
5912
- // static displayName: string;
5913
- // cogTiles: CogTiles;
5914
- //
5915
- // tileSize: number;
5916
- //
5917
- initializeState(context) {
5918
- const _super = Object.create(null, {
5919
- initializeState: { get: () => super.initializeState }
5920
- });
5921
- return __awaiter(this, void 0, void 0, function* () {
5922
- _super.initializeState.call(this, context);
5923
- this.setState({
5924
- bitmapCogTiles: new CogTiles(this.props.cogBitmapOptions),
5925
- initialized: false,
5926
- });
5927
- yield this.init();
5870
+ static defaultProps = defaultProps$1;
5871
+ static layerName = 'CogBitmapLayer';
5872
+ async initializeState(context) {
5873
+ super.initializeState(context);
5874
+ this.setState({
5875
+ bitmapCogTiles: new CogTiles(this.props.cogBitmapOptions),
5876
+ initialized: false,
5928
5877
  });
5878
+ await this.init();
5929
5879
  }
5930
- init() {
5931
- return __awaiter(this, void 0, void 0, function* () {
5932
- yield this.state.bitmapCogTiles.initializeCog(this.props.rasterData);
5933
- const zoomRange = this.state.bitmapCogTiles.getZoomRange();
5934
- const [minZoom, maxZoom] = zoomRange;
5935
- this.setState({ initialized: true, minZoom, maxZoom });
5936
- });
5880
+ async init() {
5881
+ await this.state.bitmapCogTiles.initializeCog(this.props.rasterData);
5882
+ const zoomRange = this.state.bitmapCogTiles.getZoomRange();
5883
+ const [minZoom, maxZoom] = zoomRange;
5884
+ this.setState({ initialized: true, minZoom, maxZoom });
5937
5885
  }
5938
5886
  updateState({ props, oldProps }) {
5939
- var _a, _b, _c;
5940
5887
  const rasterDataChanged = props.rasterData !== oldProps.rasterData;
5941
5888
  if (rasterDataChanged) {
5942
5889
  const { rasterData } = props;
@@ -5956,45 +5903,47 @@ class CogBitmapLayer extends core.CompositeLayer {
5956
5903
  // object in this way is not ideal and may need refactoring in the future to follow a more
5957
5904
  // declarative state management approach. Consider revisiting this if additional properties
5958
5905
  // need to be synchronized or if the state structure changes.
5959
- if (((_a = props === null || props === void 0 ? void 0 : props.cogBitmapOptions) === null || _a === void 0 ? void 0 : _a.useChannel) && (((_b = props.cogBitmapOptions) === null || _b === void 0 ? void 0 : _b.useChannel) !== ((_c = oldProps.cogBitmapOptions) === null || _c === void 0 ? void 0 : _c.useChannel))) {
5906
+ if (props?.cogBitmapOptions?.useChannel && (props.cogBitmapOptions?.useChannel !== oldProps.cogBitmapOptions?.useChannel)) {
5960
5907
  this.state.bitmapCogTiles.options.useChannel = props.cogBitmapOptions.useChannel;
5961
5908
  }
5962
- // TODO - remove in v9
5963
- // @ts-ignore
5964
5909
  if (props.workerUrl) {
5965
5910
  core.log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
5966
5911
  }
5967
5912
  }
5968
- getTiledBitmapData(tile) {
5969
- return __awaiter(this, void 0, void 0, function* () {
5970
- // TODO - pass signal to getTile
5971
- // abort request if signal is aborted
5972
- const tileData = yield this.state.bitmapCogTiles.getTile(tile.index.x, tile.index.y, tile.index.z);
5973
- return tileData;
5974
- });
5913
+ async getTiledBitmapData(tile) {
5914
+ // TODO - pass signal to getTile
5915
+ // abort request if signal is aborted
5916
+ const tileData = await this.state.bitmapCogTiles.getTile(tile.index.x, tile.index.y, tile.index.z);
5917
+ return tileData;
5975
5918
  }
5976
5919
  renderSubLayers(props) {
5977
5920
  const SubLayerClass = this.getSubLayerClass('image', layers.BitmapLayer);
5978
5921
  const { blurredTexture } = this.state.bitmapCogTiles.options;
5979
- const { opacity, clampToTerrain } = this.props;
5922
+ const { clampToTerrain } = this.props;
5923
+ const hasDrawMode = typeof clampToTerrain === 'object' && clampToTerrain !== null && 'terrainDrawMode' in clampToTerrain;
5980
5924
  const { data } = props;
5981
5925
  if (!data) {
5982
5926
  return null;
5983
5927
  }
5984
5928
  const { bbox: { west, south, east, north, }, } = props.tile;
5985
- return new SubLayerClass(Object.assign(Object.assign({}, props), { tileSize: this.state.bitmapCogTiles.tileSize }), Object.assign({ data: null, image: data, _instanced: false, bounds: [west, south, east, north], opacity, textureParameters: {
5929
+ return new SubLayerClass({ ...props, tileSize: this.state.bitmapCogTiles.tileSize }, {
5930
+ data: null,
5931
+ image: data,
5932
+ _instanced: false,
5933
+ bounds: [west, south, east, north],
5934
+ textureParameters: {
5986
5935
  minFilter: blurredTexture ? 'linear' : 'nearest',
5987
5936
  magFilter: blurredTexture ? 'linear' : 'nearest',
5988
- },
5937
+ },
5989
5938
  // TODO check if works!!!
5990
- extensions: clampToTerrain ? [new extensions._TerrainExtension()] : [] }, ((clampToTerrain === null || clampToTerrain === void 0 ? void 0 : clampToTerrain.terrainDrawMode)
5991
- ? { terrainDrawMode: clampToTerrain.terrainDrawMode }
5992
- : {})));
5939
+ extensions: clampToTerrain ? [new extensions._TerrainExtension()] : [],
5940
+ ...(hasDrawMode
5941
+ ? { terrainDrawMode: clampToTerrain.terrainDrawMode }
5942
+ : {}),
5943
+ });
5993
5944
  }
5994
5945
  renderLayers() {
5995
- const { rasterData, blurredTexture, opacity, clampToTerrain,
5996
- // tileSize,
5997
- maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, cogBitmapOptions, } = this.props;
5946
+ const { clampToTerrain, maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, cogBitmapOptions, } = this.props;
5998
5947
  if (this.state.isTiled && this.state.initialized) {
5999
5948
  const { tileSize } = this.state.bitmapCogTiles;
6000
5949
  return new geoLayers.TileLayer(this.getSubLayerProps({
@@ -6029,28 +5978,7 @@ class CogBitmapLayer extends core.CompositeLayer {
6029
5978
  return null;
6030
5979
  }
6031
5980
  }
6032
- CogBitmapLayer.defaultProps = defaultProps$1;
6033
- CogBitmapLayer.layerName = 'CogBitmapLayer';
6034
5981
 
6035
- // Copyright (c) 2015 - 2017 Uber Technologies, Inc.
6036
- //
6037
- // Permission is hereby granted, free of charge, to any person obtaining a copy
6038
- // of this software and associated documentation files (the "Software"), to deal
6039
- // in the Software without restriction, including without limitation the rights
6040
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6041
- // copies of the Software, and to permit persons to whom the Software is
6042
- // furnished to do so, subject to the following conditions:
6043
- //
6044
- // The above copyright notice and this permission notice shall be included in
6045
- // all copies or substantial portions of the Software.
6046
- //
6047
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6048
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6049
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6050
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6051
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6052
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
6053
- // THE SOFTWARE.
6054
5982
  const urlType = {
6055
5983
  type: 'object',
6056
5984
  value: null,
@@ -6077,19 +6005,20 @@ const urlType = {
6077
6005
  },
6078
6006
  };
6079
6007
  const DUMMY_DATA = [1];
6080
- const defaultProps = Object.assign(Object.assign({}, geoLayers.TileLayer.defaultProps), {
6008
+ const defaultProps = {
6009
+ ...geoLayers.TileLayer.defaultProps,
6081
6010
  // Image url that encodes height data
6082
- elevationData: urlType,
6011
+ elevationData: urlType,
6083
6012
  // Image url to use as texture
6084
- texture: Object.assign(Object.assign({}, urlType), { optional: true }),
6013
+ texture: { ...urlType, optional: true },
6085
6014
  // Martini error tolerance in meters, smaller number -> more detailed mesh
6086
- meshMaxError: { type: 'number', value: 4.0 },
6015
+ meshMaxError: { type: 'number', value: 4.0 },
6087
6016
  // Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
6088
6017
  bounds: {
6089
6018
  type: 'array', value: null, optional: true, compare: true,
6090
- },
6019
+ },
6091
6020
  // Color to use if texture is unavailable
6092
- color: { type: 'color', value: [255, 255, 255] },
6021
+ color: { type: 'color', value: [255, 255, 255] },
6093
6022
  // Object to decode height data, from (r, g, b) to height in meters
6094
6023
  elevationDecoder: {
6095
6024
  type: 'object',
@@ -6099,11 +6028,14 @@ const defaultProps = Object.assign(Object.assign({}, geoLayers.TileLayer.default
6099
6028
  bScaler: 0,
6100
6029
  offset: 0,
6101
6030
  },
6102
- },
6031
+ },
6103
6032
  // Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
6104
- workerUrl: '',
6033
+ workerUrl: '',
6105
6034
  // Same as SimpleMeshLayer wireframe
6106
- wireframe: false, material: true });
6035
+ wireframe: false,
6036
+ material: true,
6037
+ // loaders: [TerrainLoader],
6038
+ };
6107
6039
  // Turns array of templates into a single string to work around shallow change
6108
6040
  function urlTemplateToUpdateTrigger(template) {
6109
6041
  if (Array.isArray(template)) {
@@ -6115,28 +6047,25 @@ function urlTemplateToUpdateTrigger(template) {
6115
6047
  // TODO use meshMaxError
6116
6048
  // TODO - pass signal to getTile
6117
6049
  /** Render mesh surfaces from height map images. */
6118
- class TerrainLayer extends core.CompositeLayer {
6119
- initializeState(context) {
6120
- const _super = Object.create(null, {
6121
- initializeState: { get: () => super.initializeState }
6122
- });
6123
- return __awaiter(this, void 0, void 0, function* () {
6124
- _super.initializeState.call(this, context);
6125
- this.setState({
6126
- terrainCogTiles: new CogTiles(this.props.terrainOptions),
6127
- initialized: false,
6128
- });
6129
- yield this.init(this.terrainUrl);
6050
+ class CogTerrainLayer extends core.CompositeLayer {
6051
+ static defaultProps = defaultProps;
6052
+ static layerName = 'CogTerrainLayer';
6053
+ // terrainCogTiles: CogTiles;
6054
+ terrainUrl;
6055
+ async initializeState(context) {
6056
+ super.initializeState(context);
6057
+ this.setState({
6058
+ terrainCogTiles: new CogTiles(this.props.terrainOptions),
6059
+ initialized: false,
6130
6060
  });
6061
+ await this.init(this.terrainUrl);
6131
6062
  }
6132
- init(terrainUrl) {
6133
- return __awaiter(this, void 0, void 0, function* () {
6134
- yield this.state.terrainCogTiles.initializeCog(this.props.elevationData);
6135
- // this.tileSize = this.terrainCogTiles.getTileSize(cog);
6136
- const zoomRange = this.state.terrainCogTiles.getZoomRange();
6137
- const [minZoom, maxZoom] = zoomRange;
6138
- this.setState({ initialized: true, minZoom, maxZoom });
6139
- });
6063
+ async init() {
6064
+ await this.state.terrainCogTiles.initializeCog(this.props.elevationData);
6065
+ // this.tileSize = this.terrainCogTiles.getTileSize(cog);
6066
+ const zoomRange = this.state.terrainCogTiles.getZoomRange();
6067
+ const [minZoom, maxZoom] = zoomRange;
6068
+ this.setState({ initialized: true, minZoom, maxZoom });
6140
6069
  }
6141
6070
  updateState({ props, oldProps }) {
6142
6071
  const elevationDataChanged = props.elevationData !== oldProps.elevationData;
@@ -6153,8 +6082,6 @@ class TerrainLayer extends core.CompositeLayer {
6153
6082
  || props.elevationDecoder !== oldProps.elevationDecoder
6154
6083
  || props.bounds !== oldProps.bounds;
6155
6084
  if (!this.state.isTiled && shouldReload) ;
6156
- // TODO - remove in v9
6157
- // @ts-ignore
6158
6085
  if (props.workerUrl) {
6159
6086
  core.log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
6160
6087
  }
@@ -6164,36 +6091,47 @@ class TerrainLayer extends core.CompositeLayer {
6164
6091
  return null;
6165
6092
  }
6166
6093
  let loadOptions = this.getLoadOptions();
6167
- loadOptions = Object.assign(Object.assign({}, loadOptions), { _workerType: 'test', terrain: Object.assign(Object.assign({ skirtHeight: this.state.isTiled ? meshMaxError * 2 : 0 }, loadOptions === null || loadOptions === void 0 ? void 0 : loadOptions.terrain), { bounds,
6094
+ loadOptions = {
6095
+ ...loadOptions,
6096
+ _workerType: 'test',
6097
+ terrain: {
6098
+ skirtHeight: this.state.isTiled ? meshMaxError * 2 : 0,
6099
+ ...loadOptions?.terrain,
6100
+ bounds,
6168
6101
  meshMaxError,
6169
- elevationDecoder }) });
6102
+ elevationDecoder,
6103
+ },
6104
+ };
6170
6105
  const { fetch } = this.props;
6171
6106
  return fetch(elevationData, {
6172
6107
  propName: 'elevationData', layer: this, loadOptions, signal, loaders: [],
6173
6108
  });
6174
6109
  }
6175
- getTiledTerrainData(tile) {
6176
- return __awaiter(this, void 0, void 0, function* () {
6177
- this.props;
6178
- const { viewport } = this.context;
6179
- let bottomLeft = [0, 0];
6180
- let topRight = [0, 0];
6181
- if (viewport.isGeospatial) {
6182
- const bbox = tile.bbox;
6183
- bottomLeft = viewport.projectFlat([bbox.west, bbox.south]);
6184
- topRight = viewport.projectFlat([bbox.east, bbox.north]);
6185
- }
6186
- else {
6187
- const bbox = tile.bbox;
6188
- bottomLeft = [bbox.left, bbox.bottom];
6189
- topRight = [bbox.right, bbox.top];
6190
- }
6191
- const bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
6192
- // TODO - pass signal to getTile
6193
- // abort request if signal is aborted
6194
- const terrain = yield this.state.terrainCogTiles.getTile(tile.index.x, tile.index.y, tile.index.z, bounds, this.props.meshMaxError);
6195
- return Promise.all([terrain]);
6196
- });
6110
+ async getTiledTerrainData(tile) {
6111
+ // const {
6112
+ // elevationData, fetch, texture, elevationDecoder, meshMaxError,
6113
+ // } = this.props;
6114
+ const { viewport } = this.context;
6115
+ // const dataUrl = getURLFromTemplate(elevationData, tile);
6116
+ // const textureUrl = texture && getURLFromTemplate(texture, tile);
6117
+ // const { signal } = tile;
6118
+ let bottomLeft = [0, 0];
6119
+ let topRight = [0, 0];
6120
+ if (viewport.isGeospatial) {
6121
+ const bbox = tile.bbox;
6122
+ bottomLeft = viewport.projectFlat([bbox.west, bbox.south]);
6123
+ topRight = viewport.projectFlat([bbox.east, bbox.north]);
6124
+ }
6125
+ else {
6126
+ const bbox = tile.bbox;
6127
+ bottomLeft = [bbox.left, bbox.bottom];
6128
+ topRight = [bbox.right, bbox.top];
6129
+ }
6130
+ const bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
6131
+ // TODO - pass signal to getTile
6132
+ // abort request if signal is aborted
6133
+ const terrain = await this.state.terrainCogTiles.getTile(tile.index.x, tile.index.y, tile.index.z, bounds, this.props.meshMaxError);
6134
+ return Promise.all([terrain, null]);
6197
6135
  }
6198
6136
  renderSubLayers(props) {
6199
6137
  const SubLayerClass = this.getSubLayerClass('mesh', meshLayers.SimpleMeshLayer);
@@ -6204,13 +6142,13 @@ class TerrainLayer extends core.CompositeLayer {
6204
6142
  }
6205
6143
  // const [mesh, texture] = data;
6206
6144
  const [mesh] = data;
6207
- return new SubLayerClass(Object.assign(Object.assign({}, props), { tileSize: 256 }), {
6145
+ return new SubLayerClass({ ...props, tileSize: 256 }, {
6208
6146
  data: DUMMY_DATA,
6209
6147
  mesh,
6210
6148
  // texture,
6211
6149
  _instanced: false,
6212
6150
  coordinateSystem: core.COORDINATE_SYSTEM.CARTESIAN,
6213
- getPosition: (d) => [0, 0, 0],
6151
+ // getPosition: (d) => [0, 0, 0],
6214
6152
  getColor: color,
6215
6153
  wireframe,
6216
6154
  material,
@@ -6226,10 +6164,9 @@ class TerrainLayer extends core.CompositeLayer {
6226
6164
  .map((tile) => tile.content)
6227
6165
  .filter((x) => x && x[0])
6228
6166
  .map((arr) => {
6229
- var _a, _b;
6230
- // @ts-ignore
6231
- const bounds = (_b = (_a = arr[0]) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.boundingBox;
6232
- return bounds === null || bounds === void 0 ? void 0 : bounds.map((bound) => bound[2]);
6167
+ // @ts-expect-error: Tile content structure is not fully typed in the source layer
6168
+ const bounds = arr[0]?.header?.boundingBox;
6169
+ return bounds?.map((bound) => bound[2]);
6233
6170
  });
6234
6171
  if (ranges.length === 0) {
6235
6172
  return;
@@ -6241,7 +6178,13 @@ class TerrainLayer extends core.CompositeLayer {
6241
6178
  }
6242
6179
  }
6243
6180
  renderLayers() {
6244
- const { color, material, elevationData, texture, wireframe, meshMaxError, elevationDecoder, tileSize, extent, maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, } = this.props;
6181
+ const {
6182
+ // color,
6183
+ // material,
6184
+ elevationData,
6185
+ // texture,
6186
+ // wireframe,
6187
+ meshMaxError, elevationDecoder, tileSize, extent, maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, } = this.props;
6245
6188
  if (this.state.isTiled && this.state.initialized) {
6246
6189
  return new geoLayers.TileLayer(this.getSubLayerProps({
6247
6190
  id: 'tiles',
@@ -6292,15 +6235,6 @@ class TerrainLayer extends core.CompositeLayer {
6292
6235
  // );
6293
6236
  }
6294
6237
  }
6295
- TerrainLayer.defaultProps = defaultProps;
6296
- TerrainLayer.layerName = 'TerrainLayer';
6297
-
6298
- var index = {
6299
- CogBitmapLayer,
6300
- CogTerrainLayer: TerrainLayer,
6301
- cogtiles: CogTiles,
6302
- GeoImage,
6303
- };
6304
6238
 
6305
6239
  class RawDecoder extends BaseDecoder {
6306
6240
  decodeBlock(buffer) {
@@ -6309,8 +6243,8 @@ class RawDecoder extends BaseDecoder {
6309
6243
  }
6310
6244
 
6311
6245
  var raw = /*#__PURE__*/Object.freeze({
6312
- __proto__: null,
6313
- default: RawDecoder
6246
+ __proto__: null,
6247
+ default: RawDecoder
6314
6248
  });
6315
6249
 
6316
6250
  const MIN_BITS = 9;
@@ -6444,8 +6378,8 @@ class LZWDecoder extends BaseDecoder {
6444
6378
  }
6445
6379
 
6446
6380
  var lzw = /*#__PURE__*/Object.freeze({
6447
- __proto__: null,
6448
- default: LZWDecoder
6381
+ __proto__: null,
6382
+ default: LZWDecoder
6449
6383
  });
6450
6384
 
6451
6385
  /* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
@@ -7343,8 +7277,8 @@ class JpegDecoder extends BaseDecoder {
7343
7277
  }
7344
7278
 
7345
7279
  var jpeg = /*#__PURE__*/Object.freeze({
7346
- __proto__: null,
7347
- default: JpegDecoder
7280
+ __proto__: null,
7281
+ default: JpegDecoder
7348
7282
  });
7349
7283
 
7350
7284
  /*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */
@@ -14115,8 +14049,8 @@ class DeflateDecoder extends BaseDecoder {
14115
14049
  }
14116
14050
 
14117
14051
  var deflate = /*#__PURE__*/Object.freeze({
14118
- __proto__: null,
14119
- default: DeflateDecoder
14052
+ __proto__: null,
14053
+ default: DeflateDecoder
14120
14054
  });
14121
14055
 
14122
14056
  class PackbitsDecoder extends BaseDecoder {
@@ -14145,8 +14079,8 @@ class PackbitsDecoder extends BaseDecoder {
14145
14079
  }
14146
14080
 
14147
14081
  var packbits = /*#__PURE__*/Object.freeze({
14148
- __proto__: null,
14149
- default: PackbitsDecoder
14082
+ __proto__: null,
14083
+ default: PackbitsDecoder
14150
14084
  });
14151
14085
 
14152
14086
  var LercDecode = {exports: {}};
@@ -16589,9 +16523,9 @@ class LercDecoder extends BaseDecoder {
16589
16523
  }
16590
16524
 
16591
16525
  var lerc = /*#__PURE__*/Object.freeze({
16592
- __proto__: null,
16593
- default: LercDecoder,
16594
- zstd: zstd
16526
+ __proto__: null,
16527
+ default: LercDecoder,
16528
+ zstd: zstd
16595
16529
  });
16596
16530
 
16597
16531
  /**
@@ -16634,9 +16568,12 @@ class WebImageDecoder extends BaseDecoder {
16634
16568
  }
16635
16569
 
16636
16570
  var webimage = /*#__PURE__*/Object.freeze({
16637
- __proto__: null,
16638
- default: WebImageDecoder
16571
+ __proto__: null,
16572
+ default: WebImageDecoder
16639
16573
  });
16640
16574
 
16641
- module.exports = index;
16575
+ exports.CogBitmapLayer = CogBitmapLayer;
16576
+ exports.CogTerrainLayer = CogTerrainLayer;
16577
+ exports.CogTiles = CogTiles;
16578
+ exports.GeoImage = GeoImage;
16642
16579
  //# sourceMappingURL=index.js.map