@gisatcz/deckgl-geolib 1.12.0-dev.4 → 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.
- package/README.md +67 -64
- package/dist/cjs/index.js +631 -641
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +3 -3
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/{esm/types/cogtiles/cogtiles.d.ts → cjs/types/core/CogTiles.d.ts} +12 -9
- package/dist/cjs/types/{geoimage/geoimage.d.ts → core/GeoImage.d.ts} +6 -6
- package/dist/cjs/types/core/index.d.ts +2 -0
- package/dist/cjs/types/index.d.ts +2 -11
- package/dist/{esm/types/cogbitmaplayer → cjs/types/layers}/CogBitmapLayer.d.ts +3 -5
- package/dist/cjs/types/{cogterrainlayer → layers}/CogTerrainLayer.d.ts +13 -8
- package/dist/cjs/types/layers/index.d.ts +2 -0
- package/dist/esm/index.js +628 -641
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +3 -3
- package/dist/esm/index.min.js.map +1 -1
- package/dist/{cjs/types/cogtiles/cogtiles.d.ts → esm/types/core/CogTiles.d.ts} +12 -9
- package/dist/esm/types/{geoimage/geoimage.d.ts → core/GeoImage.d.ts} +6 -6
- package/dist/esm/types/core/index.d.ts +2 -0
- package/dist/esm/types/index.d.ts +2 -11
- package/dist/{cjs/types/cogbitmaplayer → esm/types/layers}/CogBitmapLayer.d.ts +3 -5
- package/dist/esm/types/{cogterrainlayer → layers}/CogTerrainLayer.d.ts +13 -8
- package/dist/esm/types/layers/index.d.ts +2 -0
- package/package.json +40 -4
- package/.eslintignore +0 -2
- package/.eslintrc.cjs +0 -3
- package/CHANGELOG.md +0 -166
- package/rollup.config.mjs +0 -77
- package/src/cogbitmaplayer/CogBitmapLayer.ts +0 -337
- package/src/cogbitmaplayer/README.md +0 -113
- package/src/cogterrainlayer/CogTerrainLayer.ts +0 -445
- package/src/cogterrainlayer/README.md +0 -118
- package/src/cogtiles/README.md +0 -72
- package/src/cogtiles/cogtiles.ts +0 -420
- package/src/cogtiles/lzw.js +0 -256
- package/src/geoimage/README.md +0 -129
- package/src/geoimage/delatin/index.ts +0 -495
- package/src/geoimage/geoimage.ts +0 -599
- package/src/geoimage/helpers/skirt.ts +0 -171
- package/src/index.ts +0 -11
- package/src/utilities/tileurls.ts +0 -21
- package/tsconfig.json +0 -6
- /package/dist/cjs/types/{geoimage → core}/delatin/index.d.ts +0 -0
- /package/dist/cjs/types/{geoimage → core}/helpers/skirt.d.ts +0 -0
- /package/dist/cjs/types/{utilities → utils}/tileurls.d.ts +0 -0
- /package/dist/esm/types/{geoimage → core}/delatin/index.d.ts +0 -0
- /package/dist/esm/types/{geoimage → core}/helpers/skirt.d.ts +0 -0
- /package/dist/esm/types/{utilities → utils}/tileurls.d.ts +0 -0
package/dist/esm/index.js
CHANGED
|
@@ -7,33 +7,6 @@ import { getMeshBoundingBox } from '@loaders.gl/schema';
|
|
|
7
7
|
import { concatenateTypedArrays } from '@loaders.gl/loader-utils';
|
|
8
8
|
import { SimpleMeshLayer } from '@deck.gl/mesh-layers';
|
|
9
9
|
|
|
10
|
-
/******************************************************************************
|
|
11
|
-
Copyright (c) Microsoft Corporation.
|
|
12
|
-
|
|
13
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
14
|
-
purpose with or without fee is hereby granted.
|
|
15
|
-
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
17
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
18
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
19
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
20
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
21
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
22
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
23
|
-
***************************************************************************** */
|
|
24
|
-
/* global Reflect, Promise */
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
28
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
29
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
30
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
31
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
32
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
33
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
10
|
/* eslint-disable no-restricted-globals, no-restricted-syntax */
|
|
38
11
|
/* global SharedArrayBuffer */
|
|
39
12
|
|
|
@@ -163,6 +136,12 @@ uncurryThisGetter(
|
|
|
163
136
|
SymbolToStringTag
|
|
164
137
|
);
|
|
165
138
|
|
|
139
|
+
// Uint8Array
|
|
140
|
+
const NativeUint8Array = Uint8Array;
|
|
141
|
+
|
|
142
|
+
// Uint16Array
|
|
143
|
+
const NativeUint16Array = Uint16Array;
|
|
144
|
+
|
|
166
145
|
// Uint32Array
|
|
167
146
|
const NativeUint32Array = Uint32Array;
|
|
168
147
|
|
|
@@ -192,7 +171,6 @@ const DataViewPrototypeGetUint16 = uncurryThis(
|
|
|
192
171
|
// WeakMap
|
|
193
172
|
/**
|
|
194
173
|
* Do not construct with arguments to avoid calling the "set" method
|
|
195
|
-
*
|
|
196
174
|
* @type {{new <K extends {}, V>(): WeakMap<K, V>}}
|
|
197
175
|
*/
|
|
198
176
|
const NativeWeakMap = WeakMap;
|
|
@@ -222,7 +200,6 @@ const SafeIteratorPrototype = ObjectCreate(null, {
|
|
|
222
200
|
|
|
223
201
|
/**
|
|
224
202
|
* Wrap the Array around the SafeIterator If Array.prototype [@@iterator] has been modified
|
|
225
|
-
*
|
|
226
203
|
* @type {<T>(array: T[]) => Iterable<T>}
|
|
227
204
|
*/
|
|
228
205
|
function safeIfNeeded(array) {
|
|
@@ -263,21 +240,20 @@ for (const key of ReflectOwnKeys(ArrayIteratorPrototype)) {
|
|
|
263
240
|
ObjectDefineProperty(DummyArrayIteratorPrototype, key, ReflectGetOwnPropertyDescriptor(ArrayIteratorPrototype, key));
|
|
264
241
|
}
|
|
265
242
|
|
|
266
|
-
// algorithm: http://fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
|
267
|
-
|
|
243
|
+
// base algorithm: http://fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
|
268
244
|
|
|
269
245
|
const buffer = new NativeArrayBuffer(4);
|
|
270
246
|
const floatView = new NativeFloat32Array(buffer);
|
|
271
247
|
const uint32View = new NativeUint32Array(buffer);
|
|
272
248
|
|
|
273
|
-
const baseTable = new
|
|
274
|
-
const shiftTable = new
|
|
249
|
+
const baseTable = new NativeUint16Array(512);
|
|
250
|
+
const shiftTable = new NativeUint8Array(512);
|
|
275
251
|
|
|
276
252
|
for (let i = 0; i < 256; ++i) {
|
|
277
253
|
const e = i - 127;
|
|
278
254
|
|
|
279
255
|
// very small number (0, -0)
|
|
280
|
-
if (e < -
|
|
256
|
+
if (e < -24) {
|
|
281
257
|
baseTable[i] = 0x0000;
|
|
282
258
|
baseTable[i | 0x100] = 0x8000;
|
|
283
259
|
shiftTable[i] = 24;
|
|
@@ -314,21 +290,18 @@ for (let i = 0; i < 256; ++i) {
|
|
|
314
290
|
}
|
|
315
291
|
|
|
316
292
|
const mantissaTable = new NativeUint32Array(2048);
|
|
317
|
-
const exponentTable = new NativeUint32Array(64);
|
|
318
|
-
const offsetTable = new NativeUint32Array(64);
|
|
319
|
-
|
|
320
293
|
for (let i = 1; i < 1024; ++i) {
|
|
321
|
-
let m = i << 13;
|
|
322
|
-
let e = 0;
|
|
294
|
+
let m = i << 13; // zero pad mantissa bits
|
|
295
|
+
let e = 0; // zero exponent
|
|
323
296
|
|
|
324
297
|
// normalized
|
|
325
|
-
while((m & 0x00800000) === 0) {
|
|
298
|
+
while ((m & 0x00800000) === 0) {
|
|
326
299
|
m <<= 1;
|
|
327
|
-
e -= 0x00800000;
|
|
300
|
+
e -= 0x00800000; // decrement exponent
|
|
328
301
|
}
|
|
329
302
|
|
|
330
|
-
m &= ~0x00800000;
|
|
331
|
-
e += 0x38800000;
|
|
303
|
+
m &= ~0x00800000; // clear leading 1 bit
|
|
304
|
+
e += 0x38800000; // adjust bias
|
|
332
305
|
|
|
333
306
|
mantissaTable[i] = m | e;
|
|
334
307
|
}
|
|
@@ -336,6 +309,7 @@ for (let i = 1024; i < 2048; ++i) {
|
|
|
336
309
|
mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);
|
|
337
310
|
}
|
|
338
311
|
|
|
312
|
+
const exponentTable = new NativeUint32Array(64);
|
|
339
313
|
for (let i = 1; i < 31; ++i) {
|
|
340
314
|
exponentTable[i] = i << 23;
|
|
341
315
|
}
|
|
@@ -346,6 +320,7 @@ for (let i = 33; i < 63; ++i) {
|
|
|
346
320
|
}
|
|
347
321
|
exponentTable[63] = 0xc7800000;
|
|
348
322
|
|
|
323
|
+
const offsetTable = new NativeUint16Array(64);
|
|
349
324
|
for (let i = 1; i < 64; ++i) {
|
|
350
325
|
if (i !== 32) {
|
|
351
326
|
offsetTable[i] = 1024;
|
|
@@ -354,19 +329,17 @@ for (let i = 1; i < 64; ++i) {
|
|
|
354
329
|
|
|
355
330
|
/**
|
|
356
331
|
* convert a half float number bits to a number
|
|
357
|
-
*
|
|
358
332
|
* @param {number} float16bits - half float number bits
|
|
359
333
|
* @returns {number} double float
|
|
360
334
|
*/
|
|
361
335
|
function convertToNumber(float16bits) {
|
|
362
|
-
const
|
|
363
|
-
uint32View[0] = mantissaTable[offsetTable[
|
|
336
|
+
const i = float16bits >> 10;
|
|
337
|
+
uint32View[0] = mantissaTable[offsetTable[i] + (float16bits & 0x3ff)] + exponentTable[i];
|
|
364
338
|
return floatView[0];
|
|
365
339
|
}
|
|
366
340
|
|
|
367
341
|
/**
|
|
368
342
|
* returns an unsigned 16-bit float at the specified byte offset from the start of the DataView
|
|
369
|
-
*
|
|
370
343
|
* @param {DataView} dataView
|
|
371
344
|
* @param {number} byteOffset
|
|
372
345
|
* @param {[boolean]} opts
|
|
@@ -2636,6 +2609,8 @@ class QuickLRU extends Map {
|
|
|
2636
2609
|
} else {
|
|
2637
2610
|
this._set(key, {value, expiry});
|
|
2638
2611
|
}
|
|
2612
|
+
|
|
2613
|
+
return this;
|
|
2639
2614
|
}
|
|
2640
2615
|
|
|
2641
2616
|
has(key) {
|
|
@@ -4434,6 +4409,29 @@ class Tile {
|
|
|
4434
4409
|
// loaders.gl
|
|
4435
4410
|
// SPDX-License-Identifier: MIT
|
|
4436
4411
|
// Copyright (c) vis.gl contributors
|
|
4412
|
+
/**
|
|
4413
|
+
* Get geometry edges that located on a border of the mesh
|
|
4414
|
+
* @param {object} indices - edge indices from quantized mesh data
|
|
4415
|
+
* @param {TypedArray} position - position attribute geometry data
|
|
4416
|
+
* @returns {number[][]} - outside edges data
|
|
4417
|
+
*/
|
|
4418
|
+
function getOutsideEdgesFromIndices(indices, position) {
|
|
4419
|
+
// Sort skirt indices to create adjacent triangles
|
|
4420
|
+
indices.westIndices.sort((a, b) => position[3 * a + 1] - position[3 * b + 1]);
|
|
4421
|
+
// Reverse (b - a) to match triangle winding
|
|
4422
|
+
indices.eastIndices.sort((a, b) => position[3 * b + 1] - position[3 * a + 1]);
|
|
4423
|
+
indices.southIndices.sort((a, b) => position[3 * b] - position[3 * a]);
|
|
4424
|
+
// Reverse (b - a) to match triangle winding
|
|
4425
|
+
indices.northIndices.sort((a, b) => position[3 * a] - position[3 * b]);
|
|
4426
|
+
const edges = [];
|
|
4427
|
+
for (const index in indices) {
|
|
4428
|
+
const indexGroup = indices[index];
|
|
4429
|
+
for (let i = 0; i < indexGroup.length - 1; i++) {
|
|
4430
|
+
edges.push([indexGroup[i], indexGroup[i + 1]]);
|
|
4431
|
+
}
|
|
4432
|
+
}
|
|
4433
|
+
return edges;
|
|
4434
|
+
}
|
|
4437
4435
|
/**
|
|
4438
4436
|
* Add skirt to existing mesh
|
|
4439
4437
|
* @param {object} attributes - POSITION and TEXCOOD_0 attributes data
|
|
@@ -4479,7 +4477,6 @@ function addSkirt(attributes, triangles, skirtHeight, outsideIndices) {
|
|
|
4479
4477
|
* @returns {number[][]} - outside edges data
|
|
4480
4478
|
*/
|
|
4481
4479
|
function getOutsideEdgesFromTriangles(triangles) {
|
|
4482
|
-
var _a, _b;
|
|
4483
4480
|
const edges = [];
|
|
4484
4481
|
for (let i = 0; i < triangles.length; i += 3) {
|
|
4485
4482
|
edges.push([triangles[i], triangles[i + 1]]);
|
|
@@ -4490,7 +4487,7 @@ function getOutsideEdgesFromTriangles(triangles) {
|
|
|
4490
4487
|
const outsideEdges = [];
|
|
4491
4488
|
let index = 0;
|
|
4492
4489
|
while (index < edges.length) {
|
|
4493
|
-
if (edges[index][0] ===
|
|
4490
|
+
if (edges[index][0] === edges[index + 1]?.[1] && edges[index][1] === edges[index + 1]?.[0]) {
|
|
4494
4491
|
index += 2;
|
|
4495
4492
|
}
|
|
4496
4493
|
else {
|
|
@@ -4500,29 +4497,6 @@ function getOutsideEdgesFromTriangles(triangles) {
|
|
|
4500
4497
|
}
|
|
4501
4498
|
return outsideEdges;
|
|
4502
4499
|
}
|
|
4503
|
-
/**
|
|
4504
|
-
* Get geometry edges that located on a border of the mesh
|
|
4505
|
-
* @param {object} indices - edge indices from quantized mesh data
|
|
4506
|
-
* @param {TypedArray} position - position attribute geometry data
|
|
4507
|
-
* @returns {number[][]} - outside edges data
|
|
4508
|
-
*/
|
|
4509
|
-
function getOutsideEdgesFromIndices(indices, position) {
|
|
4510
|
-
// Sort skirt indices to create adjacent triangles
|
|
4511
|
-
indices.westIndices.sort((a, b) => position[3 * a + 1] - position[3 * b + 1]);
|
|
4512
|
-
// Reverse (b - a) to match triangle winding
|
|
4513
|
-
indices.eastIndices.sort((a, b) => position[3 * b + 1] - position[3 * a + 1]);
|
|
4514
|
-
indices.southIndices.sort((a, b) => position[3 * b] - position[3 * a]);
|
|
4515
|
-
// Reverse (b - a) to match triangle winding
|
|
4516
|
-
indices.northIndices.sort((a, b) => position[3 * a] - position[3 * b]);
|
|
4517
|
-
const edges = [];
|
|
4518
|
-
for (const index in indices) {
|
|
4519
|
-
const indexGroup = indices[index];
|
|
4520
|
-
for (let i = 0; i < indexGroup.length - 1; i++) {
|
|
4521
|
-
edges.push([indexGroup[i], indexGroup[i + 1]]);
|
|
4522
|
-
}
|
|
4523
|
-
}
|
|
4524
|
-
return edges;
|
|
4525
|
-
}
|
|
4526
4500
|
/**
|
|
4527
4501
|
* Get geometry edges that located on a border of the mesh
|
|
4528
4502
|
* @param {object} args
|
|
@@ -4563,7 +4537,12 @@ function updateAttributesForNewEdge({ edge, edgeIndex, attributes, skirtHeight,
|
|
|
4563
4537
|
// Copyright (c) vis.gl contributors
|
|
4564
4538
|
// ISC License
|
|
4565
4539
|
// Copyright(c) 2019, Michael Fogleman, Vladimir Agafonkin
|
|
4540
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
4566
4541
|
// @ts-nocheck
|
|
4542
|
+
/* eslint-enable @typescript-eslint/ban-ts-comment */
|
|
4543
|
+
function orient(ax, ay, bx, by, cx, cy) {
|
|
4544
|
+
return (bx - cx) * (ay - cy) - (by - cy) * (ax - cx);
|
|
4545
|
+
}
|
|
4567
4546
|
/* eslint-disable complexity, max-params, max-statements, max-depth, no-constant-condition */
|
|
4568
4547
|
class Delatin {
|
|
4569
4548
|
constructor(data, width, height = width) {
|
|
@@ -4951,9 +4930,6 @@ class Delatin {
|
|
|
4951
4930
|
return i > i0;
|
|
4952
4931
|
}
|
|
4953
4932
|
}
|
|
4954
|
-
function orient(ax, ay, bx, by, cx, cy) {
|
|
4955
|
-
return (bx - cx) * (ay - cy) - (by - cy) * (ax - cx);
|
|
4956
|
-
}
|
|
4957
4933
|
function inCircle(ax, ay, bx, by, cx, cy, px, py) {
|
|
4958
4934
|
const dx = ax - px;
|
|
4959
4935
|
const dy = ay - py;
|
|
@@ -4967,7 +4943,7 @@ function inCircle(ax, ay, bx, by, cx, cy, px, py) {
|
|
|
4967
4943
|
return dx * (ey * cp - bp * fy) - dy * (ex * cp - bp * fx) + ap * (ex * fy - ey * fx) < 0;
|
|
4968
4944
|
}
|
|
4969
4945
|
|
|
4970
|
-
|
|
4946
|
+
// import { ExtentsLeftBottomRightTop } from '@deck.gl/core/utils/positions';
|
|
4971
4947
|
// FIXME - tesselator as a parameter
|
|
4972
4948
|
const tesselator = 'martini';
|
|
4973
4949
|
const DefaultGeoImageOptions = {
|
|
@@ -5002,279 +4978,264 @@ const DefaultGeoImageOptions = {
|
|
|
5002
4978
|
planarConfig: undefined,
|
|
5003
4979
|
};
|
|
5004
4980
|
class GeoImage {
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
}
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
return this.getHeightmap(input, mergedOptions, meshMaxError);
|
|
5026
|
-
default:
|
|
5027
|
-
return null;
|
|
5028
|
-
}
|
|
5029
|
-
});
|
|
4981
|
+
data;
|
|
4982
|
+
scale = (num, inMin, inMax, outMin, outMax) => ((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
|
|
4983
|
+
async setUrl(url) {
|
|
4984
|
+
// TODO - not tested
|
|
4985
|
+
const response = await fetch(url);
|
|
4986
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
4987
|
+
const tiff = await fromArrayBuffer(arrayBuffer);
|
|
4988
|
+
const data = await tiff.getImage(0);
|
|
4989
|
+
this.data = data;
|
|
4990
|
+
}
|
|
4991
|
+
async getMap(input, options, meshMaxError) {
|
|
4992
|
+
const mergedOptions = { ...DefaultGeoImageOptions, ...options };
|
|
4993
|
+
switch (mergedOptions.type) {
|
|
4994
|
+
case 'image':
|
|
4995
|
+
return this.getBitmap(input, mergedOptions);
|
|
4996
|
+
case 'terrain':
|
|
4997
|
+
return this.getHeightmap(input, mergedOptions, meshMaxError);
|
|
4998
|
+
default:
|
|
4999
|
+
return null;
|
|
5000
|
+
}
|
|
5030
5001
|
}
|
|
5031
5002
|
// GetHeightmap uses only "useChannel" and "multiplier" options
|
|
5032
|
-
getHeightmap(input, options, meshMaxError) {
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5003
|
+
async getHeightmap(input, options, meshMaxError) {
|
|
5004
|
+
let rasters = [];
|
|
5005
|
+
let width;
|
|
5006
|
+
let height;
|
|
5007
|
+
if (typeof (input) === 'string') {
|
|
5008
|
+
// TODO not tested
|
|
5009
|
+
// input is type of object
|
|
5010
|
+
await this.setUrl(input);
|
|
5011
|
+
rasters = (await this.data.readRasters());
|
|
5012
|
+
width = this.data.getWidth();
|
|
5013
|
+
height = this.data.getHeight();
|
|
5014
|
+
}
|
|
5015
|
+
else {
|
|
5016
|
+
rasters = input.rasters;
|
|
5017
|
+
width = input.width;
|
|
5018
|
+
height = input.height;
|
|
5019
|
+
}
|
|
5020
|
+
const optionsLocal = { ...options };
|
|
5021
|
+
let channel = rasters[0];
|
|
5022
|
+
optionsLocal.useChannelIndex ??= optionsLocal.useChannel == null ? null : optionsLocal.useChannel - 1;
|
|
5023
|
+
if (options.useChannelIndex != null) {
|
|
5024
|
+
if (rasters[optionsLocal.useChannelIndex]) {
|
|
5025
|
+
channel = rasters[optionsLocal.useChannelIndex];
|
|
5045
5026
|
}
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5027
|
+
}
|
|
5028
|
+
const terrain = new Float32Array((width + 1) * (height + 1));
|
|
5029
|
+
const numOfChannels = channel.length / (width * height);
|
|
5030
|
+
let pixel = options.useChannelIndex === null ? 0 : options.useChannelIndex;
|
|
5031
|
+
for (let i = 0, y = 0; y < height; y++) {
|
|
5032
|
+
for (let x = 0; x < width; x++, i++) {
|
|
5033
|
+
const elevationValue = (options.noDataValue && channel[pixel] === options.noDataValue) ? options.terrainMinValue : channel[pixel] * options.multiplier;
|
|
5034
|
+
terrain[i + y] = elevationValue;
|
|
5035
|
+
pixel += numOfChannels;
|
|
5050
5036
|
}
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
channel = rasters[optionsLocal.useChannelIndex];
|
|
5057
|
-
}
|
|
5037
|
+
}
|
|
5038
|
+
{
|
|
5039
|
+
// backfill bottom border
|
|
5040
|
+
for (let i = (width + 1) * width, x = 0; x < width; x++, i++) {
|
|
5041
|
+
terrain[i] = terrain[i - width - 1];
|
|
5058
5042
|
}
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
for (let i = 0, y = 0; y < height; y++) {
|
|
5063
|
-
for (let x = 0; x < width; x++, i++) {
|
|
5064
|
-
const elevationValue = (options.noDataValue && channel[pixel] === options.noDataValue) ? options.terrainMinValue : channel[pixel] * options.multiplier;
|
|
5065
|
-
terrain[i + y] = elevationValue;
|
|
5066
|
-
pixel += numOfChannels;
|
|
5067
|
-
}
|
|
5043
|
+
// backfill right border
|
|
5044
|
+
for (let i = height, y = 0; y < height + 1; y++, i += height + 1) {
|
|
5045
|
+
terrain[i] = terrain[i - 1];
|
|
5068
5046
|
}
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5047
|
+
}
|
|
5048
|
+
// getMesh
|
|
5049
|
+
const { terrainSkirtHeight } = options;
|
|
5050
|
+
let mesh;
|
|
5051
|
+
switch (tesselator) {
|
|
5052
|
+
case 'martini':
|
|
5053
|
+
mesh = getMartiniTileMesh(meshMaxError, width, terrain);
|
|
5054
|
+
break;
|
|
5055
|
+
case 'delatin':
|
|
5056
|
+
mesh = getDelatinTileMesh(meshMaxError, width, height, terrain);
|
|
5057
|
+
break;
|
|
5058
|
+
default:
|
|
5059
|
+
if (width === height && !(height && (width - 1))) {
|
|
5060
|
+
// fixme get terrain to separate method
|
|
5061
|
+
// terrain = getTerrain(data, width, height, elevationDecoder, 'martini');
|
|
5084
5062
|
mesh = getMartiniTileMesh(meshMaxError, width, terrain);
|
|
5085
|
-
|
|
5086
|
-
|
|
5063
|
+
}
|
|
5064
|
+
else {
|
|
5065
|
+
// fixme get terrain to separate method
|
|
5066
|
+
// terrain = getTerrain(data, width, height, elevationDecoder, 'delatin');
|
|
5087
5067
|
mesh = getDelatinTileMesh(meshMaxError, width, height, terrain);
|
|
5088
|
-
break;
|
|
5089
|
-
default:
|
|
5090
|
-
if (width === height && !(height && (width - 1))) {
|
|
5091
|
-
// fixme get terrain to separate method
|
|
5092
|
-
// terrain = getTerrain(data, width, height, elevationDecoder, 'martini');
|
|
5093
|
-
mesh = getMartiniTileMesh(meshMaxError, width, terrain);
|
|
5094
|
-
}
|
|
5095
|
-
else {
|
|
5096
|
-
// fixme get terrain to separate method
|
|
5097
|
-
// terrain = getTerrain(data, width, height, elevationDecoder, 'delatin');
|
|
5098
|
-
mesh = getDelatinTileMesh(meshMaxError, width, height, terrain);
|
|
5099
|
-
}
|
|
5100
|
-
break;
|
|
5101
|
-
}
|
|
5102
|
-
// Martini
|
|
5103
|
-
// Martini
|
|
5104
|
-
// Delatin
|
|
5105
|
-
// Delatin
|
|
5106
|
-
const { vertices } = mesh;
|
|
5107
|
-
let { triangles } = mesh;
|
|
5108
|
-
let attributes = getMeshAttributes(vertices, terrain, width, height, input.bounds);
|
|
5109
|
-
// Compute bounding box before adding skirt so that z values are not skewed
|
|
5110
|
-
const boundingBox = getMeshBoundingBox(attributes);
|
|
5111
|
-
if (terrainSkirtHeight) {
|
|
5112
|
-
const { attributes: newAttributes, triangles: newTriangles } = addSkirt(attributes, triangles, terrainSkirtHeight);
|
|
5113
|
-
attributes = newAttributes;
|
|
5114
|
-
triangles = newTriangles;
|
|
5115
|
-
}
|
|
5116
|
-
return {
|
|
5117
|
-
// Data return by this loader implementation
|
|
5118
|
-
loaderData: {
|
|
5119
|
-
header: {},
|
|
5120
|
-
},
|
|
5121
|
-
header: {
|
|
5122
|
-
vertexCount: triangles.length,
|
|
5123
|
-
boundingBox,
|
|
5124
|
-
},
|
|
5125
|
-
mode: 4,
|
|
5126
|
-
indices: { value: Uint32Array.from(triangles), size: 1 },
|
|
5127
|
-
attributes,
|
|
5128
|
-
};
|
|
5129
|
-
});
|
|
5130
|
-
}
|
|
5131
|
-
getBitmap(input, options) {
|
|
5132
|
-
var _a;
|
|
5133
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
5134
|
-
// console.time('bitmap-generated-in');
|
|
5135
|
-
// const optionsLocal = { ...options };
|
|
5136
|
-
const optionsLocal = Object.assign({}, options);
|
|
5137
|
-
let rasters = [];
|
|
5138
|
-
let channels;
|
|
5139
|
-
let width;
|
|
5140
|
-
let height;
|
|
5141
|
-
if (typeof (input) === 'string') {
|
|
5142
|
-
// TODO not tested
|
|
5143
|
-
// input is type of object
|
|
5144
|
-
yield this.setUrl(input);
|
|
5145
|
-
rasters = (yield this.data.readRasters());
|
|
5146
|
-
channels = rasters.length;
|
|
5147
|
-
width = this.data.getWidth();
|
|
5148
|
-
height = this.data.getHeight();
|
|
5149
|
-
}
|
|
5150
|
-
else {
|
|
5151
|
-
rasters = input.rasters;
|
|
5152
|
-
channels = rasters.length;
|
|
5153
|
-
width = input.width;
|
|
5154
|
-
height = input.height;
|
|
5155
|
-
}
|
|
5156
|
-
const canvas = document.createElement('canvas');
|
|
5157
|
-
canvas.width = width;
|
|
5158
|
-
canvas.height = height;
|
|
5159
|
-
const c = canvas.getContext('2d');
|
|
5160
|
-
const imageData = c.createImageData(width, height);
|
|
5161
|
-
let r;
|
|
5162
|
-
let g;
|
|
5163
|
-
let b;
|
|
5164
|
-
let a;
|
|
5165
|
-
const size = width * height * 4;
|
|
5166
|
-
// const size = width * height;
|
|
5167
|
-
// if (!options.noDataValue) {
|
|
5168
|
-
// console.log('Missing noData value. Raster might be displayed incorrectly.');
|
|
5169
|
-
// }
|
|
5170
|
-
optionsLocal.unidentifiedColor = this.getColorFromChromaType(optionsLocal.unidentifiedColor);
|
|
5171
|
-
optionsLocal.nullColor = this.getColorFromChromaType(optionsLocal.nullColor);
|
|
5172
|
-
optionsLocal.clippedColor = this.getColorFromChromaType(optionsLocal.clippedColor);
|
|
5173
|
-
optionsLocal.color = this.getColorFromChromaType(optionsLocal.color);
|
|
5174
|
-
(_a = optionsLocal.useChannelIndex) !== null && _a !== void 0 ? _a : (optionsLocal.useChannelIndex = options.useChannel === null ? null : options.useChannel - 1);
|
|
5175
|
-
// console.log(rasters[0])
|
|
5176
|
-
/* console.log("raster 0 length: " + rasters[0].length)
|
|
5177
|
-
console.log("image width: " + width)
|
|
5178
|
-
console.log("channels: " + channels)
|
|
5179
|
-
console.log("format: " + rasters[0].length / (width * height))
|
|
5180
|
-
*/
|
|
5181
|
-
if (optionsLocal.useChannelIndex == null) {
|
|
5182
|
-
if (channels === 1) {
|
|
5183
|
-
if (rasters[0].length / (width * height) === 1) {
|
|
5184
|
-
const channel = rasters[0];
|
|
5185
|
-
// AUTO RANGE
|
|
5186
|
-
if (optionsLocal.useAutoRange) {
|
|
5187
|
-
optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
|
|
5188
|
-
// console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
|
|
5189
|
-
}
|
|
5190
|
-
// SINGLE CHANNEL
|
|
5191
|
-
const colorData = this.getColorValue(channel, optionsLocal, size);
|
|
5192
|
-
colorData.forEach((value, index) => {
|
|
5193
|
-
imageData.data[index] = value;
|
|
5194
|
-
});
|
|
5195
|
-
}
|
|
5196
|
-
// RGB values in one channel
|
|
5197
|
-
if (rasters[0].length / (width * height) === 3) {
|
|
5198
|
-
// console.log("geoImage: " + "RGB 1 array of length: " + rasters[0].length);
|
|
5199
|
-
let pixel = 0;
|
|
5200
|
-
for (let idx = 0; idx < size; idx += 4) {
|
|
5201
|
-
const rgbColor = [rasters[0][pixel], rasters[0][pixel + 1], rasters[0][pixel + 2]];
|
|
5202
|
-
const rgbaColor = this.hasPixelsNoData(rgbColor, optionsLocal.noDataValue)
|
|
5203
|
-
? optionsLocal.nullColor
|
|
5204
|
-
: [...rgbColor, Math.floor(optionsLocal.alpha * 2.55)];
|
|
5205
|
-
// eslint-disable-next-line max-len
|
|
5206
|
-
[imageData.data[idx], imageData.data[idx + 1], imageData.data[idx + 2], imageData.data[idx + 3]] = rgbaColor;
|
|
5207
|
-
pixel += 3;
|
|
5208
|
-
}
|
|
5209
|
-
}
|
|
5210
|
-
if (rasters[0].length / (width * height) === 4) {
|
|
5211
|
-
// console.log("geoImage: " + "RGBA 1 array");
|
|
5212
|
-
rasters[0].forEach((value, index) => {
|
|
5213
|
-
imageData.data[index] = value;
|
|
5214
|
-
});
|
|
5215
|
-
}
|
|
5216
5068
|
}
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5069
|
+
break;
|
|
5070
|
+
}
|
|
5071
|
+
const { vertices } = mesh;
|
|
5072
|
+
let { triangles } = mesh;
|
|
5073
|
+
let attributes = getMeshAttributes(vertices, terrain, width, height, input.bounds);
|
|
5074
|
+
// Compute bounding box before adding skirt so that z values are not skewed
|
|
5075
|
+
const boundingBox = getMeshBoundingBox(attributes);
|
|
5076
|
+
if (terrainSkirtHeight) {
|
|
5077
|
+
const { attributes: newAttributes, triangles: newTriangles } = addSkirt(attributes, triangles, terrainSkirtHeight);
|
|
5078
|
+
attributes = newAttributes;
|
|
5079
|
+
triangles = newTriangles;
|
|
5080
|
+
}
|
|
5081
|
+
return {
|
|
5082
|
+
// Data return by this loader implementation
|
|
5083
|
+
loaderData: {
|
|
5084
|
+
header: {},
|
|
5085
|
+
},
|
|
5086
|
+
header: {
|
|
5087
|
+
vertexCount: triangles.length,
|
|
5088
|
+
boundingBox,
|
|
5089
|
+
},
|
|
5090
|
+
mode: 4, // TRIANGLES
|
|
5091
|
+
indices: { value: Uint32Array.from(triangles), size: 1 },
|
|
5092
|
+
attributes,
|
|
5093
|
+
};
|
|
5094
|
+
}
|
|
5095
|
+
async getBitmap(input, options) {
|
|
5096
|
+
// console.time('bitmap-generated-in');
|
|
5097
|
+
// const optionsLocal = { ...options };
|
|
5098
|
+
const optionsLocal = { ...options };
|
|
5099
|
+
let rasters = [];
|
|
5100
|
+
let channels;
|
|
5101
|
+
let width;
|
|
5102
|
+
let height;
|
|
5103
|
+
if (typeof (input) === 'string') {
|
|
5104
|
+
// TODO not tested
|
|
5105
|
+
// input is type of object
|
|
5106
|
+
await this.setUrl(input);
|
|
5107
|
+
rasters = (await this.data.readRasters());
|
|
5108
|
+
channels = rasters.length;
|
|
5109
|
+
width = this.data.getWidth();
|
|
5110
|
+
height = this.data.getHeight();
|
|
5111
|
+
}
|
|
5112
|
+
else {
|
|
5113
|
+
rasters = input.rasters;
|
|
5114
|
+
channels = rasters.length;
|
|
5115
|
+
width = input.width;
|
|
5116
|
+
height = input.height;
|
|
5117
|
+
}
|
|
5118
|
+
const canvas = document.createElement('canvas');
|
|
5119
|
+
canvas.width = width;
|
|
5120
|
+
canvas.height = height;
|
|
5121
|
+
const c = canvas.getContext('2d');
|
|
5122
|
+
const imageData = c.createImageData(width, height);
|
|
5123
|
+
let r;
|
|
5124
|
+
let g;
|
|
5125
|
+
let b;
|
|
5126
|
+
let a;
|
|
5127
|
+
const size = width * height * 4;
|
|
5128
|
+
// const size = width * height;
|
|
5129
|
+
// if (!options.noDataValue) {
|
|
5130
|
+
// console.log('Missing noData value. Raster might be displayed incorrectly.');
|
|
5131
|
+
// }
|
|
5132
|
+
optionsLocal.unidentifiedColor = this.getColorFromChromaType(optionsLocal.unidentifiedColor);
|
|
5133
|
+
optionsLocal.nullColor = this.getColorFromChromaType(optionsLocal.nullColor);
|
|
5134
|
+
optionsLocal.clippedColor = this.getColorFromChromaType(optionsLocal.clippedColor);
|
|
5135
|
+
optionsLocal.color = this.getColorFromChromaType(optionsLocal.color);
|
|
5136
|
+
optionsLocal.useChannelIndex ??= options.useChannel === null ? null : options.useChannel - 1;
|
|
5137
|
+
// console.log(rasters[0])
|
|
5138
|
+
/* console.log("raster 0 length: " + rasters[0].length)
|
|
5139
|
+
console.log("image width: " + width)
|
|
5140
|
+
console.log("channels: " + channels)
|
|
5141
|
+
console.log("format: " + rasters[0].length / (width * height))
|
|
5142
|
+
*/
|
|
5143
|
+
if (optionsLocal.useChannelIndex == null) {
|
|
5144
|
+
if (channels === 1) {
|
|
5145
|
+
if (rasters[0].length / (width * height) === 1) {
|
|
5146
|
+
const channel = rasters[0];
|
|
5147
|
+
// AUTO RANGE
|
|
5148
|
+
if (optionsLocal.useAutoRange) {
|
|
5149
|
+
optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
|
|
5150
|
+
// console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
|
|
5230
5151
|
}
|
|
5152
|
+
// SINGLE CHANNEL
|
|
5153
|
+
const colorData = this.getColorValue(channel, optionsLocal, size);
|
|
5154
|
+
colorData.forEach((value, index) => {
|
|
5155
|
+
imageData.data[index] = value;
|
|
5156
|
+
});
|
|
5231
5157
|
}
|
|
5232
|
-
|
|
5233
|
-
|
|
5158
|
+
// RGB values in one channel
|
|
5159
|
+
if (rasters[0].length / (width * height) === 3) {
|
|
5160
|
+
// console.log("geoImage: " + "RGB 1 array of length: " + rasters[0].length);
|
|
5234
5161
|
let pixel = 0;
|
|
5235
|
-
for (let
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
imageData.data[
|
|
5242
|
-
|
|
5243
|
-
imageData.data[i + 3] = a;
|
|
5244
|
-
pixel += 1;
|
|
5162
|
+
for (let idx = 0; idx < size; idx += 4) {
|
|
5163
|
+
const rgbColor = [rasters[0][pixel], rasters[0][pixel + 1], rasters[0][pixel + 2]];
|
|
5164
|
+
const rgbaColor = this.hasPixelsNoData(rgbColor, optionsLocal.noDataValue)
|
|
5165
|
+
? optionsLocal.nullColor
|
|
5166
|
+
: [...rgbColor, Math.floor(optionsLocal.alpha * 2.55)];
|
|
5167
|
+
// eslint-disable-next-line max-len
|
|
5168
|
+
[imageData.data[idx], imageData.data[idx + 1], imageData.data[idx + 2], imageData.data[idx + 3]] = rgbaColor;
|
|
5169
|
+
pixel += 3;
|
|
5245
5170
|
}
|
|
5246
5171
|
}
|
|
5172
|
+
if (rasters[0].length / (width * height) === 4) {
|
|
5173
|
+
// console.log("geoImage: " + "RGBA 1 array");
|
|
5174
|
+
rasters[0].forEach((value, index) => {
|
|
5175
|
+
imageData.data[index] = value;
|
|
5176
|
+
});
|
|
5177
|
+
}
|
|
5247
5178
|
}
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5179
|
+
if (channels === 3) {
|
|
5180
|
+
// RGB
|
|
5181
|
+
let pixel = 0;
|
|
5182
|
+
for (let i = 0; i < size; i += 4) {
|
|
5183
|
+
r = rasters[0][pixel];
|
|
5184
|
+
g = rasters[1][pixel];
|
|
5185
|
+
b = rasters[2][pixel];
|
|
5186
|
+
a = Math.floor(optionsLocal.alpha * 2.55);
|
|
5187
|
+
imageData.data[i] = r;
|
|
5188
|
+
imageData.data[i + 1] = g;
|
|
5189
|
+
imageData.data[i + 2] = b;
|
|
5190
|
+
imageData.data[i + 3] = a;
|
|
5191
|
+
pixel += 1;
|
|
5252
5192
|
}
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5193
|
+
}
|
|
5194
|
+
if (channels === 4) {
|
|
5195
|
+
// RGBA
|
|
5196
|
+
let pixel = 0;
|
|
5197
|
+
for (let i = 0; i < size; i += 4) {
|
|
5198
|
+
r = rasters[0][pixel];
|
|
5199
|
+
g = rasters[1][pixel];
|
|
5200
|
+
b = rasters[2][pixel];
|
|
5201
|
+
a = Math.floor(optionsLocal.alpha * 2.55);
|
|
5202
|
+
imageData.data[i] = r;
|
|
5203
|
+
imageData.data[i + 1] = g;
|
|
5204
|
+
imageData.data[i + 2] = b;
|
|
5205
|
+
imageData.data[i + 3] = a;
|
|
5206
|
+
pixel += 1;
|
|
5257
5207
|
}
|
|
5258
|
-
// const numOfChannels = channel.length / (width * height);
|
|
5259
|
-
const colorData = this.getColorValue(channel, optionsLocal, size, optionsLocal.numOfChannels);
|
|
5260
|
-
colorData.forEach((value, index) => {
|
|
5261
|
-
imageData.data[index] = value;
|
|
5262
|
-
});
|
|
5263
5208
|
}
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
imageData.data[index] = value;
|
|
5270
|
-
});
|
|
5209
|
+
}
|
|
5210
|
+
else if (optionsLocal.useChannelIndex < optionsLocal.numOfChannels && optionsLocal.useChannelIndex >= 0) {
|
|
5211
|
+
let channel = rasters[0];
|
|
5212
|
+
if (rasters[optionsLocal.useChannelIndex]) {
|
|
5213
|
+
channel = rasters[optionsLocal.useChannelIndex];
|
|
5271
5214
|
}
|
|
5272
|
-
//
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5215
|
+
// AUTO RANGE
|
|
5216
|
+
if (optionsLocal.useAutoRange) {
|
|
5217
|
+
optionsLocal.colorScaleValueRange = this.getMinMax(channel, optionsLocal);
|
|
5218
|
+
// console.log('data min: ' + optionsLocal.rangeMin + ', max: ' + optionsLocal.rangeMax);
|
|
5219
|
+
}
|
|
5220
|
+
// const numOfChannels = channel.length / (width * height);
|
|
5221
|
+
const colorData = this.getColorValue(channel, optionsLocal, size, optionsLocal.numOfChannels);
|
|
5222
|
+
colorData.forEach((value, index) => {
|
|
5223
|
+
imageData.data[index] = value;
|
|
5224
|
+
});
|
|
5225
|
+
}
|
|
5226
|
+
else {
|
|
5227
|
+
// if user defined channel does not exist
|
|
5228
|
+
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`);
|
|
5229
|
+
const defaultColorData = this.getDefaultColor(size, optionsLocal.nullColor);
|
|
5230
|
+
defaultColorData.forEach((value, index) => {
|
|
5231
|
+
imageData.data[index] = value;
|
|
5232
|
+
});
|
|
5233
|
+
}
|
|
5234
|
+
// console.timeEnd('bitmap-generated-in');
|
|
5235
|
+
c.putImageData(imageData, 0, 0);
|
|
5236
|
+
const imageUrl = canvas.toDataURL('image/png');
|
|
5237
|
+
// console.log('Bitmap generated.');
|
|
5238
|
+
return imageUrl;
|
|
5278
5239
|
}
|
|
5279
5240
|
getMinMax(array, options) {
|
|
5280
5241
|
let maxValue = options.maxValue ? options.maxValue : Number.MIN_VALUE;
|
|
@@ -5290,6 +5251,8 @@ class GeoImage {
|
|
|
5290
5251
|
return [minValue, maxValue];
|
|
5291
5252
|
}
|
|
5292
5253
|
getColorValue(dataArray, options, arrayLength, numOfChannels = 1) {
|
|
5254
|
+
// const rgb = chroma.random().rgb(); // [R, G, B]
|
|
5255
|
+
// const randomColor = [...rgb, 120];
|
|
5293
5256
|
const colorScale = chroma.scale(options.colorScale).domain(options.colorScaleValueRange);
|
|
5294
5257
|
// channel index is equal to channel number - 1
|
|
5295
5258
|
let pixel = options.useChannelIndex === null ? 0 : options.useChannelIndex;
|
|
@@ -5309,6 +5272,7 @@ class GeoImage {
|
|
|
5309
5272
|
}) : undefined;
|
|
5310
5273
|
for (let i = 0; i < arrayLength; i += 4) {
|
|
5311
5274
|
let pixelColor = options.nullColor;
|
|
5275
|
+
// let pixelColor = randomColor;
|
|
5312
5276
|
// FIXME
|
|
5313
5277
|
// eslint-disable-next-line max-len
|
|
5314
5278
|
if ((!Number.isNaN(dataArray[pixel])) && (options.noDataValue === undefined || dataArray[pixel] !== options.noDataValue)) {
|
|
@@ -5350,7 +5314,7 @@ class GeoImage {
|
|
|
5350
5314
|
}
|
|
5351
5315
|
// FIXME
|
|
5352
5316
|
// eslint-disable-next-line
|
|
5353
|
-
[colorsArray[i], colorsArray[i + 1], colorsArray[i + 2], colorsArray[i + 3]] = pixelColor;
|
|
5317
|
+
([colorsArray[i], colorsArray[i + 1], colorsArray[i + 2], colorsArray[i + 3]] = pixelColor);
|
|
5354
5318
|
pixel += numOfChannels;
|
|
5355
5319
|
}
|
|
5356
5320
|
return colorsArray;
|
|
@@ -5440,7 +5404,7 @@ function getMeshAttributes(vertices, terrain, width, height, bounds) {
|
|
|
5440
5404
|
function getDelatinTileMesh(meshMaxError, width, height, terrain) {
|
|
5441
5405
|
const tin = new Delatin(terrain, width + 1, height + 1);
|
|
5442
5406
|
tin.run(meshMaxError);
|
|
5443
|
-
// @ts-expect-error
|
|
5407
|
+
// @ts-expect-error: Delatin instance properties 'coords' and 'triangles' are not explicitly typed in the library port
|
|
5444
5408
|
const { coords, triangles } = tin;
|
|
5445
5409
|
const vertices = coords;
|
|
5446
5410
|
return { vertices, triangles };
|
|
@@ -5454,31 +5418,30 @@ const CogTilesGeoImageOptionsDefaults = {
|
|
|
5454
5418
|
blurredTexture: true,
|
|
5455
5419
|
};
|
|
5456
5420
|
class CogTiles {
|
|
5421
|
+
cog;
|
|
5422
|
+
cogZoomLookup = [0];
|
|
5423
|
+
cogResolutionLookup = [0];
|
|
5424
|
+
cogOrigin = [0, 0];
|
|
5425
|
+
zoomRange = [0, 0];
|
|
5426
|
+
tileSize;
|
|
5427
|
+
bounds;
|
|
5428
|
+
geo = new GeoImage();
|
|
5429
|
+
options;
|
|
5457
5430
|
constructor(options) {
|
|
5458
|
-
this.
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
this.
|
|
5462
|
-
this.
|
|
5463
|
-
this.
|
|
5464
|
-
this.options
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
this.cogOrigin = image.getOrigin();
|
|
5473
|
-
(_a = (_c = this.options).noDataValue) !== null && _a !== void 0 ? _a : (_c.noDataValue = this.getNoDataValue(image));
|
|
5474
|
-
(_b = (_d = this.options).format) !== null && _b !== void 0 ? _b : (_d.format = this.getDataTypeFromTags(image));
|
|
5475
|
-
this.options.numOfChannels = this.getNumberOfChannels(image);
|
|
5476
|
-
this.options.planarConfig = this.getPlanarConfiguration(image);
|
|
5477
|
-
[this.cogZoomLookup, this.cogResolutionLookup] = yield this.buildCogZoomResolutionLookup(this.cog);
|
|
5478
|
-
this.tileSize = image.getTileWidth();
|
|
5479
|
-
this.zoomRange = this.calculateZoomRange(image, yield this.cog.getImageCount());
|
|
5480
|
-
this.bounds = this.calculateBoundsAsLatLon(image);
|
|
5481
|
-
});
|
|
5431
|
+
this.options = { ...CogTilesGeoImageOptionsDefaults, ...options };
|
|
5432
|
+
}
|
|
5433
|
+
async initializeCog(url) {
|
|
5434
|
+
this.cog = await fromUrl(url);
|
|
5435
|
+
const image = await this.cog.getImage(); // by default, the first image is read.
|
|
5436
|
+
this.cogOrigin = image.getOrigin();
|
|
5437
|
+
this.options.noDataValue ??= this.getNoDataValue(image);
|
|
5438
|
+
this.options.format ??= this.getDataTypeFromTags(image);
|
|
5439
|
+
this.options.numOfChannels = this.getNumberOfChannels(image);
|
|
5440
|
+
this.options.planarConfig = this.getPlanarConfiguration(image);
|
|
5441
|
+
[this.cogZoomLookup, this.cogResolutionLookup] = await this.buildCogZoomResolutionLookup(this.cog);
|
|
5442
|
+
this.tileSize = image.getTileWidth();
|
|
5443
|
+
this.zoomRange = this.calculateZoomRange(image, await this.cog.getImageCount());
|
|
5444
|
+
this.bounds = this.calculateBoundsAsLatLon(image);
|
|
5482
5445
|
}
|
|
5483
5446
|
getZoomRange() {
|
|
5484
5447
|
return this.zoomRange;
|
|
@@ -5530,33 +5493,31 @@ class CogTiles {
|
|
|
5530
5493
|
* - The first array (`zoomLookup`) maps each image index to its computed zoom level.
|
|
5531
5494
|
* - The second array (`resolutionLookup`) maps each image index to its estimated resolution (m/pixel).
|
|
5532
5495
|
*/
|
|
5533
|
-
buildCogZoomResolutionLookup(cog) {
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
return [zoomLookup, resolutionLookup];
|
|
5559
|
-
});
|
|
5496
|
+
async buildCogZoomResolutionLookup(cog) {
|
|
5497
|
+
// Retrieve the total number of images (overviews) in the COG.
|
|
5498
|
+
const imageCount = await cog.getImageCount();
|
|
5499
|
+
// Use the first image as the base reference.
|
|
5500
|
+
const baseImage = await cog.getImage(0);
|
|
5501
|
+
const baseResolution = baseImage.getResolution()[0]; // Resolution (m/pixel) of the base image.
|
|
5502
|
+
const baseWidth = baseImage.getWidth();
|
|
5503
|
+
// Initialize arrays to store the zoom level and resolution for each image.
|
|
5504
|
+
const zoomLookup = [];
|
|
5505
|
+
const resolutionLookup = [];
|
|
5506
|
+
// Iterate over each image (overview) in the COG.
|
|
5507
|
+
for (let idx = 0; idx < imageCount; idx++) {
|
|
5508
|
+
const image = await cog.getImage(idx);
|
|
5509
|
+
const width = image.getWidth();
|
|
5510
|
+
// Calculate the scale factor relative to the base image.
|
|
5511
|
+
const scaleFactor = baseWidth / width;
|
|
5512
|
+
const estimatedResolution = baseResolution * scaleFactor;
|
|
5513
|
+
// Calculate the zoom level using the Web Mercator resolution standard:
|
|
5514
|
+
// webMercatorRes0 is the resolution at zoom level 0; each zoom level halves the resolution.
|
|
5515
|
+
const zoomLevel = Math.round(Math.log2(webMercatorRes0 / estimatedResolution));
|
|
5516
|
+
// console.log(`buildCogZoomResolutionLookup: Image index ${idx}: Estimated Resolution = ${estimatedResolution} m/pixel, Zoom Level = ${zoomLevel}`);
|
|
5517
|
+
zoomLookup[idx] = zoomLevel;
|
|
5518
|
+
resolutionLookup[idx] = estimatedResolution;
|
|
5519
|
+
}
|
|
5520
|
+
return [zoomLookup, resolutionLookup];
|
|
5560
5521
|
}
|
|
5561
5522
|
/**
|
|
5562
5523
|
* Determines the appropriate image index from the Cloud Optimized GeoTIFF (COG)
|
|
@@ -5585,99 +5546,138 @@ class CogTiles {
|
|
|
5585
5546
|
}
|
|
5586
5547
|
return exactMatchIndex;
|
|
5587
5548
|
}
|
|
5588
|
-
getTileFromImage(tileX, tileY, zoom) {
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5549
|
+
async getTileFromImage(tileX, tileY, zoom) {
|
|
5550
|
+
const imageIndex = this.getImageIndexForZoomLevel(zoom);
|
|
5551
|
+
const targetImage = await this.cog.getImage(imageIndex);
|
|
5552
|
+
// 1. Validation: Ensure the image is tiled
|
|
5553
|
+
const tileWidth = targetImage.getTileWidth();
|
|
5554
|
+
const tileHeight = targetImage.getTileHeight();
|
|
5555
|
+
if (!tileWidth || !tileHeight) {
|
|
5556
|
+
throw new Error('GeoTIFF Error: The provided image is not tiled. '
|
|
5557
|
+
+ 'Please use "rio cogeo create --web-optimized" to fix this.');
|
|
5558
|
+
}
|
|
5559
|
+
// --- STEP 1: CALCULATE BOUNDS IN METERS ---
|
|
5560
|
+
// 2. Get COG Metadata (image = COG)
|
|
5561
|
+
const imageResolution = this.cogResolutionLookup[imageIndex];
|
|
5562
|
+
const imageHeight = targetImage.getHeight();
|
|
5563
|
+
const imageWidth = targetImage.getWidth();
|
|
5564
|
+
const [imgOriginX, imgOriginY] = this.cogOrigin;
|
|
5565
|
+
// 3. Define Web Mercator Constants
|
|
5566
|
+
// We use the class property tileSize (usually 256) as the ground truth for grid calculations
|
|
5567
|
+
const TILE_SIZE = this.tileSize;
|
|
5568
|
+
const ORIGIN_X = webMercatorOrigin[0];
|
|
5569
|
+
const ORIGIN_Y = webMercatorOrigin[1];
|
|
5570
|
+
// 4. Calculate Tile BBox in World Meters
|
|
5571
|
+
// This defines where the map expects the tile to be physically located
|
|
5572
|
+
const tileGridResolution = (EARTH_CIRCUMFERENCE / TILE_SIZE) / (2 ** zoom);
|
|
5573
|
+
const tileMinXMeters = ORIGIN_X + (tileX * TILE_SIZE * tileGridResolution);
|
|
5574
|
+
const tileMaxYMeters = ORIGIN_Y - (tileY * TILE_SIZE * tileGridResolution);
|
|
5575
|
+
// Note: We don't strictly need MaxX/MinY meters for the start calculation,
|
|
5576
|
+
// but they are useful if debugging the full meter footprint.
|
|
5577
|
+
// --- STEP 2: CONVERT TO PIXEL COORDINATES ---
|
|
5578
|
+
// 5. Calculate precise floating-point start position relative to the image
|
|
5579
|
+
const windowMinX = (tileMinXMeters - imgOriginX) / imageResolution;
|
|
5580
|
+
const windowMinY = (imgOriginY - tileMaxYMeters) / imageResolution;
|
|
5581
|
+
// 6. Snap to Integer Grid (The "Force 256" Fix)
|
|
5582
|
+
// We round the start position to align with the nearest pixel.
|
|
5583
|
+
// Crucially, we calculate endX/endY by adding tileSize to startX/startY.
|
|
5584
|
+
// This guarantees the window is exactly 256x256, preventing "off-by-one" (257px) errors.
|
|
5585
|
+
const startX = Math.round(windowMinX);
|
|
5586
|
+
const startY = Math.round(windowMinY);
|
|
5587
|
+
const endX = startX + TILE_SIZE;
|
|
5588
|
+
const endY = startY + TILE_SIZE;
|
|
5589
|
+
// --- STEP 3: CALCULATE INTERSECTION ---
|
|
5590
|
+
// 7. Clamp the read window to the actual image dimensions
|
|
5591
|
+
// This defines the "Safe" area we can actually read from the file.
|
|
5592
|
+
const validReadX = Math.max(0, startX);
|
|
5593
|
+
const validReadY = Math.max(0, startY);
|
|
5594
|
+
const validReadMaxX = Math.min(imageWidth, endX);
|
|
5595
|
+
const validReadMaxY = Math.min(imageHeight, endY);
|
|
5596
|
+
const readWidth = validReadMaxX - validReadX;
|
|
5597
|
+
const readHeight = validReadMaxY - validReadY;
|
|
5598
|
+
// CHECK: If no overlap, return empty
|
|
5599
|
+
if (readWidth <= 0 || readHeight <= 0) {
|
|
5600
|
+
return [this.createEmptyTile()];
|
|
5601
|
+
}
|
|
5602
|
+
// 8. Calculate Offsets (Padding)
|
|
5603
|
+
// "missingLeft" is how many blank pixels we need to insert before the image data starts.
|
|
5604
|
+
// Logic: If we wanted to read from -50 (startX), but clamped to 0 (validReadX),
|
|
5605
|
+
// we are missing the first 50 pixels.
|
|
5606
|
+
const missingLeft = validReadX - startX;
|
|
5607
|
+
const missingTop = validReadY - startY;
|
|
5608
|
+
const window = [validReadX, validReadY, validReadMaxX, validReadMaxY];
|
|
5609
|
+
// --- STEP 4: READ AND COMPOSITE ---
|
|
5610
|
+
// Case A: Partial Overlap (Padding or Cropping required)
|
|
5611
|
+
// If the tile is hanging off the edge, we need to manually reconstruct it.
|
|
5612
|
+
if (missingLeft > 0 || missingTop > 0 || readWidth < tileWidth || readHeight < tileHeight) {
|
|
5613
|
+
/// Initialize a temporary buffer for a single band (filled with NoData)
|
|
5614
|
+
// We will reuse this buffer for each band to save memory allocations.
|
|
5615
|
+
const tileBuffer = this.createTileBuffer(this.options.format, tileWidth);
|
|
5616
|
+
tileBuffer.fill(this.options.noDataValue);
|
|
5617
|
+
// 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
|
|
5618
|
+
const validRasterData = await targetImage.readRasters({ window });
|
|
5619
|
+
// FOR MULTI-BAND - the result is one array with sequentially typed bands, firstly all data for the band 0, then for band 1
|
|
5620
|
+
// 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.
|
|
5621
|
+
const validImageData = Array(validRasterData.length * validRasterData[0].length);
|
|
5622
|
+
validImageData.fill(this.options.noDataValue);
|
|
5623
|
+
// Place the valid pixel data into the tile buffer.
|
|
5624
|
+
for (let band = 0; band < validRasterData.length; band += 1) {
|
|
5625
|
+
for (let row = 0; row < readHeight; row += 1) {
|
|
5626
|
+
const destRow = missingTop + row;
|
|
5627
|
+
const destRowOffset = destRow * TILE_SIZE;
|
|
5628
|
+
const srcRowOffset = row * validRasterData.width;
|
|
5629
|
+
for (let col = 0; col < readWidth; col += 1) {
|
|
5630
|
+
// Compute the destination position in the tile buffer.
|
|
5631
|
+
// We shift by the number of missing pixels (if any) at the top/left.
|
|
5632
|
+
const destCol = missingLeft + col;
|
|
5633
|
+
// Bounds Check: Ensure we don't write outside the 256x256 buffer
|
|
5634
|
+
if (destRow < tileWidth && destCol < tileHeight) {
|
|
5635
|
+
tileBuffer[destRowOffset + destCol] = validRasterData[band][srcRowOffset + col];
|
|
5636
|
+
}
|
|
5637
|
+
else {
|
|
5638
|
+
console.log('error in assigning data to tile buffer');
|
|
5657
5639
|
}
|
|
5658
5640
|
}
|
|
5659
|
-
tileBuffer.forEach((rasterValue, index) => {
|
|
5660
|
-
validImageData[index * this.options.numOfChannels + band] = rasterValue;
|
|
5661
|
-
});
|
|
5662
5641
|
}
|
|
5663
|
-
|
|
5642
|
+
for (let i = 0; i < tileBuffer.length; i += 1) {
|
|
5643
|
+
validImageData[i * this.options.numOfChannels + band] = tileBuffer[i];
|
|
5644
|
+
}
|
|
5664
5645
|
}
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5646
|
+
return [validImageData];
|
|
5647
|
+
}
|
|
5648
|
+
// Case B: Perfect Match (Optimization)
|
|
5649
|
+
// If the read window is exactly 256x256 and aligned, we can read directly interleaved.
|
|
5650
|
+
// console.log("Perfect aligned read");
|
|
5651
|
+
const tileData = await targetImage.readRasters({ window, interleave: true });
|
|
5652
|
+
// console.log(`data that starts at the left top corner of the tile ${tileX}, ${tileY}`);
|
|
5653
|
+
return [tileData];
|
|
5670
5654
|
}
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5655
|
+
/**
|
|
5656
|
+
* Creates a blank tile buffer filled with the "No Data" value.
|
|
5657
|
+
*/
|
|
5658
|
+
createEmptyTile() {
|
|
5659
|
+
// 1. Determine the size
|
|
5660
|
+
// Default to 1 channel (grayscale) if not specified
|
|
5661
|
+
const channels = this.options.numOfChannels || 1;
|
|
5662
|
+
const size = this.tileSize * this.tileSize * channels;
|
|
5663
|
+
// 2. Create the array
|
|
5664
|
+
// Float32 is standard for GeoTIFF data handling in browsers
|
|
5665
|
+
const tileData = new Float32Array(size);
|
|
5666
|
+
// 3. Fill with "No Data" value
|
|
5667
|
+
// If noDataValue is undefined, it defaults to 0
|
|
5668
|
+
if (this.options.noDataValue !== undefined) {
|
|
5669
|
+
tileData.fill(this.options.noDataValue);
|
|
5670
|
+
}
|
|
5671
|
+
return tileData;
|
|
5672
|
+
}
|
|
5673
|
+
async getTile(x, y, z, bounds, meshMaxError) {
|
|
5674
|
+
const tileData = await this.getTileFromImage(x, y, z);
|
|
5675
|
+
return this.geo.getMap({
|
|
5676
|
+
rasters: [tileData[0]],
|
|
5677
|
+
width: this.tileSize,
|
|
5678
|
+
height: this.tileSize,
|
|
5679
|
+
bounds,
|
|
5680
|
+
}, this.options, meshMaxError);
|
|
5681
5681
|
}
|
|
5682
5682
|
/**
|
|
5683
5683
|
* Determines the data type (e.g., "Int32", "Float64") of a GeoTIFF image
|
|
@@ -5723,24 +5723,33 @@ class CogTiles {
|
|
|
5723
5723
|
}
|
|
5724
5724
|
/**
|
|
5725
5725
|
* Extracts the noData value from a GeoTIFF.js image.
|
|
5726
|
-
* Returns the noData value as a number if available, otherwise undefined.
|
|
5726
|
+
* Returns the noData value as a number (including NaN) if available, otherwise undefined.
|
|
5727
5727
|
*
|
|
5728
5728
|
* @param {GeoTIFFImage} image - The GeoTIFF.js image.
|
|
5729
|
-
* @returns {number|undefined} The noData value
|
|
5729
|
+
* @returns {number|undefined} The noData value, possibly NaN, or undefined if not set or invalid.
|
|
5730
5730
|
*/
|
|
5731
5731
|
getNoDataValue(image) {
|
|
5732
|
-
// Attempt to retrieve the noData value via the GDAL method.
|
|
5733
5732
|
const noDataRaw = image.getGDALNoData();
|
|
5734
5733
|
if (noDataRaw === undefined || noDataRaw === null) {
|
|
5735
|
-
console.
|
|
5736
|
-
// No noData value is defined
|
|
5734
|
+
console.warn('No noData value defined — raster might be rendered incorrectly.');
|
|
5737
5735
|
return undefined;
|
|
5738
5736
|
}
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5737
|
+
const cleaned = String(noDataRaw).replace(/\0/g, '').trim();
|
|
5738
|
+
if (cleaned === '') {
|
|
5739
|
+
console.warn('noData value is an empty string after cleanup.');
|
|
5740
|
+
return undefined;
|
|
5741
|
+
}
|
|
5742
|
+
const parsed = Number(cleaned);
|
|
5743
|
+
// Allow NaN if explicitly declared
|
|
5744
|
+
if (cleaned.toLowerCase() === 'nan') {
|
|
5745
|
+
return NaN;
|
|
5746
|
+
}
|
|
5747
|
+
// If not declared as "nan" and still parsed to NaN, it's an error
|
|
5748
|
+
if (Number.isNaN(parsed)) {
|
|
5749
|
+
console.warn(`Failed to parse numeric noData value: '${cleaned}'`);
|
|
5750
|
+
return undefined;
|
|
5751
|
+
}
|
|
5752
|
+
return parsed;
|
|
5744
5753
|
}
|
|
5745
5754
|
/**
|
|
5746
5755
|
* Retrieves the number of channels (samples per pixel) in a GeoTIFF image.
|
|
@@ -5823,7 +5832,8 @@ const urlType$1 = {
|
|
|
5823
5832
|
return true;
|
|
5824
5833
|
},
|
|
5825
5834
|
};
|
|
5826
|
-
const defaultProps$1 =
|
|
5835
|
+
const defaultProps$1 = {
|
|
5836
|
+
...TileLayer.defaultProps,
|
|
5827
5837
|
// Image url that encodes height data
|
|
5828
5838
|
// elevationData: urlType,
|
|
5829
5839
|
// Image url to use as texture
|
|
@@ -5833,10 +5843,9 @@ const defaultProps$1 = Object.assign(Object.assign({}, TileLayer.defaultProps),
|
|
|
5833
5843
|
// Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
|
|
5834
5844
|
bounds: {
|
|
5835
5845
|
type: 'array', value: null, optional: true, compare: true,
|
|
5836
|
-
},
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
blurredTexture: true, opacity: 1, clampToTerrain: false,
|
|
5846
|
+
},
|
|
5847
|
+
rasterData: urlType$1,
|
|
5848
|
+
clampToTerrain: false,
|
|
5840
5849
|
// Object to decode height data, from (r, g, b) to height in meters
|
|
5841
5850
|
// elevationDecoder: {
|
|
5842
5851
|
// type: 'object',
|
|
@@ -5848,40 +5857,31 @@ const defaultProps$1 = Object.assign(Object.assign({}, TileLayer.defaultProps),
|
|
|
5848
5857
|
// },
|
|
5849
5858
|
// },
|
|
5850
5859
|
// Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
|
|
5851
|
-
workerUrl: ''
|
|
5860
|
+
workerUrl: '',
|
|
5861
|
+
// Same as SimpleMeshLayer wireframe
|
|
5862
|
+
// wireframe: false,
|
|
5863
|
+
// material: true,
|
|
5864
|
+
// loaders: [TerrainLoader],
|
|
5865
|
+
};
|
|
5852
5866
|
/** Render bitmap texture from cog raster images. */
|
|
5853
5867
|
class CogBitmapLayer extends CompositeLayer {
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
//
|
|
5862
|
-
initializeState(context) {
|
|
5863
|
-
const _super = Object.create(null, {
|
|
5864
|
-
initializeState: { get: () => super.initializeState }
|
|
5865
|
-
});
|
|
5866
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
5867
|
-
_super.initializeState.call(this, context);
|
|
5868
|
-
this.setState({
|
|
5869
|
-
bitmapCogTiles: new CogTiles(this.props.cogBitmapOptions),
|
|
5870
|
-
initialized: false,
|
|
5871
|
-
});
|
|
5872
|
-
yield this.init();
|
|
5868
|
+
static defaultProps = defaultProps$1;
|
|
5869
|
+
static layerName = 'CogBitmapLayer';
|
|
5870
|
+
async initializeState(context) {
|
|
5871
|
+
super.initializeState(context);
|
|
5872
|
+
this.setState({
|
|
5873
|
+
bitmapCogTiles: new CogTiles(this.props.cogBitmapOptions),
|
|
5874
|
+
initialized: false,
|
|
5873
5875
|
});
|
|
5876
|
+
await this.init();
|
|
5874
5877
|
}
|
|
5875
|
-
init() {
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
this.setState({ initialized: true, minZoom, maxZoom });
|
|
5881
|
-
});
|
|
5878
|
+
async init() {
|
|
5879
|
+
await this.state.bitmapCogTiles.initializeCog(this.props.rasterData);
|
|
5880
|
+
const zoomRange = this.state.bitmapCogTiles.getZoomRange();
|
|
5881
|
+
const [minZoom, maxZoom] = zoomRange;
|
|
5882
|
+
this.setState({ initialized: true, minZoom, maxZoom });
|
|
5882
5883
|
}
|
|
5883
5884
|
updateState({ props, oldProps }) {
|
|
5884
|
-
var _a, _b, _c;
|
|
5885
5885
|
const rasterDataChanged = props.rasterData !== oldProps.rasterData;
|
|
5886
5886
|
if (rasterDataChanged) {
|
|
5887
5887
|
const { rasterData } = props;
|
|
@@ -5901,45 +5901,47 @@ class CogBitmapLayer extends CompositeLayer {
|
|
|
5901
5901
|
// object in this way is not ideal and may need refactoring in the future to follow a more
|
|
5902
5902
|
// declarative state management approach. Consider revisiting this if additional properties
|
|
5903
5903
|
// need to be synchronized or if the state structure changes.
|
|
5904
|
-
if (
|
|
5904
|
+
if (props?.cogBitmapOptions?.useChannel && (props.cogBitmapOptions?.useChannel !== oldProps.cogBitmapOptions?.useChannel)) {
|
|
5905
5905
|
this.state.bitmapCogTiles.options.useChannel = props.cogBitmapOptions.useChannel;
|
|
5906
5906
|
}
|
|
5907
|
-
// TODO - remove in v9
|
|
5908
|
-
// @ts-ignore
|
|
5909
5907
|
if (props.workerUrl) {
|
|
5910
5908
|
log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
|
|
5911
5909
|
}
|
|
5912
5910
|
}
|
|
5913
|
-
getTiledBitmapData(tile) {
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
return tileData;
|
|
5919
|
-
});
|
|
5911
|
+
async getTiledBitmapData(tile) {
|
|
5912
|
+
// TODO - pass signal to getTile
|
|
5913
|
+
// abort request if signal is aborted
|
|
5914
|
+
const tileData = await this.state.bitmapCogTiles.getTile(tile.index.x, tile.index.y, tile.index.z);
|
|
5915
|
+
return tileData;
|
|
5920
5916
|
}
|
|
5921
5917
|
renderSubLayers(props) {
|
|
5922
5918
|
const SubLayerClass = this.getSubLayerClass('image', BitmapLayer);
|
|
5923
5919
|
const { blurredTexture } = this.state.bitmapCogTiles.options;
|
|
5924
|
-
const {
|
|
5920
|
+
const { clampToTerrain } = this.props;
|
|
5921
|
+
const hasDrawMode = typeof clampToTerrain === 'object' && clampToTerrain !== null && 'terrainDrawMode' in clampToTerrain;
|
|
5925
5922
|
const { data } = props;
|
|
5926
5923
|
if (!data) {
|
|
5927
5924
|
return null;
|
|
5928
5925
|
}
|
|
5929
5926
|
const { bbox: { west, south, east, north, }, } = props.tile;
|
|
5930
|
-
return new SubLayerClass(
|
|
5927
|
+
return new SubLayerClass({ ...props, tileSize: this.state.bitmapCogTiles.tileSize }, {
|
|
5928
|
+
data: null,
|
|
5929
|
+
image: data,
|
|
5930
|
+
_instanced: false,
|
|
5931
|
+
bounds: [west, south, east, north],
|
|
5932
|
+
textureParameters: {
|
|
5931
5933
|
minFilter: blurredTexture ? 'linear' : 'nearest',
|
|
5932
5934
|
magFilter: blurredTexture ? 'linear' : 'nearest',
|
|
5933
|
-
},
|
|
5935
|
+
},
|
|
5934
5936
|
// TODO check if works!!!
|
|
5935
|
-
extensions: clampToTerrain ? [new _TerrainExtension()] : []
|
|
5936
|
-
|
|
5937
|
-
|
|
5937
|
+
extensions: clampToTerrain ? [new _TerrainExtension()] : [],
|
|
5938
|
+
...(hasDrawMode
|
|
5939
|
+
? { terrainDrawMode: clampToTerrain.terrainDrawMode }
|
|
5940
|
+
: {}),
|
|
5941
|
+
});
|
|
5938
5942
|
}
|
|
5939
5943
|
renderLayers() {
|
|
5940
|
-
const {
|
|
5941
|
-
// tileSize,
|
|
5942
|
-
maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, cogBitmapOptions, } = this.props;
|
|
5944
|
+
const { clampToTerrain, maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, cogBitmapOptions, } = this.props;
|
|
5943
5945
|
if (this.state.isTiled && this.state.initialized) {
|
|
5944
5946
|
const { tileSize } = this.state.bitmapCogTiles;
|
|
5945
5947
|
return new TileLayer(this.getSubLayerProps({
|
|
@@ -5974,28 +5976,7 @@ class CogBitmapLayer extends CompositeLayer {
|
|
|
5974
5976
|
return null;
|
|
5975
5977
|
}
|
|
5976
5978
|
}
|
|
5977
|
-
CogBitmapLayer.defaultProps = defaultProps$1;
|
|
5978
|
-
CogBitmapLayer.layerName = 'CogBitmapLayer';
|
|
5979
5979
|
|
|
5980
|
-
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
|
|
5981
|
-
//
|
|
5982
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5983
|
-
// of this software and associated documentation files (the "Software"), to deal
|
|
5984
|
-
// in the Software without restriction, including without limitation the rights
|
|
5985
|
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
5986
|
-
// copies of the Software, and to permit persons to whom the Software is
|
|
5987
|
-
// furnished to do so, subject to the following conditions:
|
|
5988
|
-
//
|
|
5989
|
-
// The above copyright notice and this permission notice shall be included in
|
|
5990
|
-
// all copies or substantial portions of the Software.
|
|
5991
|
-
//
|
|
5992
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
5993
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
5994
|
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
5995
|
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
5996
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
5997
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
5998
|
-
// THE SOFTWARE.
|
|
5999
5980
|
const urlType = {
|
|
6000
5981
|
type: 'object',
|
|
6001
5982
|
value: null,
|
|
@@ -6022,19 +6003,20 @@ const urlType = {
|
|
|
6022
6003
|
},
|
|
6023
6004
|
};
|
|
6024
6005
|
const DUMMY_DATA = [1];
|
|
6025
|
-
const defaultProps =
|
|
6006
|
+
const defaultProps = {
|
|
6007
|
+
...TileLayer.defaultProps,
|
|
6026
6008
|
// Image url that encodes height data
|
|
6027
|
-
elevationData: urlType,
|
|
6009
|
+
elevationData: urlType,
|
|
6028
6010
|
// Image url to use as texture
|
|
6029
|
-
texture:
|
|
6011
|
+
texture: { ...urlType, optional: true },
|
|
6030
6012
|
// Martini error tolerance in meters, smaller number -> more detailed mesh
|
|
6031
|
-
meshMaxError: { type: 'number', value: 4.0 },
|
|
6013
|
+
meshMaxError: { type: 'number', value: 4.0 },
|
|
6032
6014
|
// Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
|
|
6033
6015
|
bounds: {
|
|
6034
6016
|
type: 'array', value: null, optional: true, compare: true,
|
|
6035
|
-
},
|
|
6017
|
+
},
|
|
6036
6018
|
// Color to use if texture is unavailable
|
|
6037
|
-
color: { type: 'color', value: [255, 255, 255] },
|
|
6019
|
+
color: { type: 'color', value: [255, 255, 255] },
|
|
6038
6020
|
// Object to decode height data, from (r, g, b) to height in meters
|
|
6039
6021
|
elevationDecoder: {
|
|
6040
6022
|
type: 'object',
|
|
@@ -6044,11 +6026,14 @@ const defaultProps = Object.assign(Object.assign({}, TileLayer.defaultProps), {
|
|
|
6044
6026
|
bScaler: 0,
|
|
6045
6027
|
offset: 0,
|
|
6046
6028
|
},
|
|
6047
|
-
},
|
|
6029
|
+
},
|
|
6048
6030
|
// Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
|
|
6049
|
-
workerUrl: '',
|
|
6031
|
+
workerUrl: '',
|
|
6050
6032
|
// Same as SimpleMeshLayer wireframe
|
|
6051
|
-
wireframe: false,
|
|
6033
|
+
wireframe: false,
|
|
6034
|
+
material: true,
|
|
6035
|
+
// loaders: [TerrainLoader],
|
|
6036
|
+
};
|
|
6052
6037
|
// Turns array of templates into a single string to work around shallow change
|
|
6053
6038
|
function urlTemplateToUpdateTrigger(template) {
|
|
6054
6039
|
if (Array.isArray(template)) {
|
|
@@ -6060,28 +6045,25 @@ function urlTemplateToUpdateTrigger(template) {
|
|
|
6060
6045
|
// TODO use meshMaxError
|
|
6061
6046
|
// TODO - pass signal to getTile
|
|
6062
6047
|
/** Render mesh surfaces from height map images. */
|
|
6063
|
-
class
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
});
|
|
6074
|
-
yield this.init(this.terrainUrl);
|
|
6048
|
+
class CogTerrainLayer extends CompositeLayer {
|
|
6049
|
+
static defaultProps = defaultProps;
|
|
6050
|
+
static layerName = 'CogTerrainLayer';
|
|
6051
|
+
// terrainCogTiles: CogTiles;
|
|
6052
|
+
terrainUrl;
|
|
6053
|
+
async initializeState(context) {
|
|
6054
|
+
super.initializeState(context);
|
|
6055
|
+
this.setState({
|
|
6056
|
+
terrainCogTiles: new CogTiles(this.props.terrainOptions),
|
|
6057
|
+
initialized: false,
|
|
6075
6058
|
});
|
|
6059
|
+
await this.init(this.terrainUrl);
|
|
6076
6060
|
}
|
|
6077
|
-
init(
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
this.setState({ initialized: true, minZoom, maxZoom });
|
|
6084
|
-
});
|
|
6061
|
+
async init() {
|
|
6062
|
+
await this.state.terrainCogTiles.initializeCog(this.props.elevationData);
|
|
6063
|
+
// this.tileSize = this.terrainCogTiles.getTileSize(cog);
|
|
6064
|
+
const zoomRange = this.state.terrainCogTiles.getZoomRange();
|
|
6065
|
+
const [minZoom, maxZoom] = zoomRange;
|
|
6066
|
+
this.setState({ initialized: true, minZoom, maxZoom });
|
|
6085
6067
|
}
|
|
6086
6068
|
updateState({ props, oldProps }) {
|
|
6087
6069
|
const elevationDataChanged = props.elevationData !== oldProps.elevationData;
|
|
@@ -6098,8 +6080,6 @@ class TerrainLayer extends CompositeLayer {
|
|
|
6098
6080
|
|| props.elevationDecoder !== oldProps.elevationDecoder
|
|
6099
6081
|
|| props.bounds !== oldProps.bounds;
|
|
6100
6082
|
if (!this.state.isTiled && shouldReload) ;
|
|
6101
|
-
// TODO - remove in v9
|
|
6102
|
-
// @ts-ignore
|
|
6103
6083
|
if (props.workerUrl) {
|
|
6104
6084
|
log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
|
|
6105
6085
|
}
|
|
@@ -6109,36 +6089,47 @@ class TerrainLayer extends CompositeLayer {
|
|
|
6109
6089
|
return null;
|
|
6110
6090
|
}
|
|
6111
6091
|
let loadOptions = this.getLoadOptions();
|
|
6112
|
-
loadOptions =
|
|
6092
|
+
loadOptions = {
|
|
6093
|
+
...loadOptions,
|
|
6094
|
+
_workerType: 'test',
|
|
6095
|
+
terrain: {
|
|
6096
|
+
skirtHeight: this.state.isTiled ? meshMaxError * 2 : 0,
|
|
6097
|
+
...loadOptions?.terrain,
|
|
6098
|
+
bounds,
|
|
6113
6099
|
meshMaxError,
|
|
6114
|
-
elevationDecoder
|
|
6100
|
+
elevationDecoder,
|
|
6101
|
+
},
|
|
6102
|
+
};
|
|
6115
6103
|
const { fetch } = this.props;
|
|
6116
6104
|
return fetch(elevationData, {
|
|
6117
6105
|
propName: 'elevationData', layer: this, loadOptions, signal, loaders: [],
|
|
6118
6106
|
});
|
|
6119
6107
|
}
|
|
6120
|
-
getTiledTerrainData(tile) {
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
const
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6108
|
+
async getTiledTerrainData(tile) {
|
|
6109
|
+
// const {
|
|
6110
|
+
// elevationData, fetch, texture, elevationDecoder, meshMaxError,
|
|
6111
|
+
// } = this.props;
|
|
6112
|
+
const { viewport } = this.context;
|
|
6113
|
+
// const dataUrl = getURLFromTemplate(elevationData, tile);
|
|
6114
|
+
// const textureUrl = texture && getURLFromTemplate(texture, tile);
|
|
6115
|
+
// const { signal } = tile;
|
|
6116
|
+
let bottomLeft = [0, 0];
|
|
6117
|
+
let topRight = [0, 0];
|
|
6118
|
+
if (viewport.isGeospatial) {
|
|
6119
|
+
const bbox = tile.bbox;
|
|
6120
|
+
bottomLeft = viewport.projectFlat([bbox.west, bbox.south]);
|
|
6121
|
+
topRight = viewport.projectFlat([bbox.east, bbox.north]);
|
|
6122
|
+
}
|
|
6123
|
+
else {
|
|
6124
|
+
const bbox = tile.bbox;
|
|
6125
|
+
bottomLeft = [bbox.left, bbox.bottom];
|
|
6126
|
+
topRight = [bbox.right, bbox.top];
|
|
6127
|
+
}
|
|
6128
|
+
const bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
|
|
6129
|
+
// TODO - pass signal to getTile
|
|
6130
|
+
// abort request if signal is aborted
|
|
6131
|
+
const terrain = await this.state.terrainCogTiles.getTile(tile.index.x, tile.index.y, tile.index.z, bounds, this.props.meshMaxError);
|
|
6132
|
+
return Promise.all([terrain, null]);
|
|
6142
6133
|
}
|
|
6143
6134
|
renderSubLayers(props) {
|
|
6144
6135
|
const SubLayerClass = this.getSubLayerClass('mesh', SimpleMeshLayer);
|
|
@@ -6149,13 +6140,13 @@ class TerrainLayer extends CompositeLayer {
|
|
|
6149
6140
|
}
|
|
6150
6141
|
// const [mesh, texture] = data;
|
|
6151
6142
|
const [mesh] = data;
|
|
6152
|
-
return new SubLayerClass(
|
|
6143
|
+
return new SubLayerClass({ ...props, tileSize: 256 }, {
|
|
6153
6144
|
data: DUMMY_DATA,
|
|
6154
6145
|
mesh,
|
|
6155
6146
|
// texture,
|
|
6156
6147
|
_instanced: false,
|
|
6157
6148
|
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
6158
|
-
getPosition: (d) => [0, 0, 0],
|
|
6149
|
+
// getPosition: (d) => [0, 0, 0],
|
|
6159
6150
|
getColor: color,
|
|
6160
6151
|
wireframe,
|
|
6161
6152
|
material,
|
|
@@ -6171,10 +6162,9 @@ class TerrainLayer extends CompositeLayer {
|
|
|
6171
6162
|
.map((tile) => tile.content)
|
|
6172
6163
|
.filter((x) => x && x[0])
|
|
6173
6164
|
.map((arr) => {
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
return bounds === null || bounds === void 0 ? void 0 : bounds.map((bound) => bound[2]);
|
|
6165
|
+
// @ts-expect-error: Tile content structure is not fully typed in the source layer
|
|
6166
|
+
const bounds = arr[0]?.header?.boundingBox;
|
|
6167
|
+
return bounds?.map((bound) => bound[2]);
|
|
6178
6168
|
});
|
|
6179
6169
|
if (ranges.length === 0) {
|
|
6180
6170
|
return;
|
|
@@ -6186,7 +6176,13 @@ class TerrainLayer extends CompositeLayer {
|
|
|
6186
6176
|
}
|
|
6187
6177
|
}
|
|
6188
6178
|
renderLayers() {
|
|
6189
|
-
const {
|
|
6179
|
+
const {
|
|
6180
|
+
// color,
|
|
6181
|
+
// material,
|
|
6182
|
+
elevationData,
|
|
6183
|
+
// texture,
|
|
6184
|
+
// wireframe,
|
|
6185
|
+
meshMaxError, elevationDecoder, tileSize, extent, maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, } = this.props;
|
|
6190
6186
|
if (this.state.isTiled && this.state.initialized) {
|
|
6191
6187
|
return new TileLayer(this.getSubLayerProps({
|
|
6192
6188
|
id: 'tiles',
|
|
@@ -6237,15 +6233,6 @@ class TerrainLayer extends CompositeLayer {
|
|
|
6237
6233
|
// );
|
|
6238
6234
|
}
|
|
6239
6235
|
}
|
|
6240
|
-
TerrainLayer.defaultProps = defaultProps;
|
|
6241
|
-
TerrainLayer.layerName = 'TerrainLayer';
|
|
6242
|
-
|
|
6243
|
-
var index = {
|
|
6244
|
-
CogBitmapLayer,
|
|
6245
|
-
CogTerrainLayer: TerrainLayer,
|
|
6246
|
-
cogtiles: CogTiles,
|
|
6247
|
-
GeoImage,
|
|
6248
|
-
};
|
|
6249
6236
|
|
|
6250
6237
|
class RawDecoder extends BaseDecoder {
|
|
6251
6238
|
decodeBlock(buffer) {
|
|
@@ -6254,8 +6241,8 @@ class RawDecoder extends BaseDecoder {
|
|
|
6254
6241
|
}
|
|
6255
6242
|
|
|
6256
6243
|
var raw = /*#__PURE__*/Object.freeze({
|
|
6257
|
-
|
|
6258
|
-
|
|
6244
|
+
__proto__: null,
|
|
6245
|
+
default: RawDecoder
|
|
6259
6246
|
});
|
|
6260
6247
|
|
|
6261
6248
|
const MIN_BITS = 9;
|
|
@@ -6389,8 +6376,8 @@ class LZWDecoder extends BaseDecoder {
|
|
|
6389
6376
|
}
|
|
6390
6377
|
|
|
6391
6378
|
var lzw = /*#__PURE__*/Object.freeze({
|
|
6392
|
-
|
|
6393
|
-
|
|
6379
|
+
__proto__: null,
|
|
6380
|
+
default: LZWDecoder
|
|
6394
6381
|
});
|
|
6395
6382
|
|
|
6396
6383
|
/* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
|
@@ -7288,8 +7275,8 @@ class JpegDecoder extends BaseDecoder {
|
|
|
7288
7275
|
}
|
|
7289
7276
|
|
|
7290
7277
|
var jpeg = /*#__PURE__*/Object.freeze({
|
|
7291
|
-
|
|
7292
|
-
|
|
7278
|
+
__proto__: null,
|
|
7279
|
+
default: JpegDecoder
|
|
7293
7280
|
});
|
|
7294
7281
|
|
|
7295
7282
|
/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */
|
|
@@ -14060,8 +14047,8 @@ class DeflateDecoder extends BaseDecoder {
|
|
|
14060
14047
|
}
|
|
14061
14048
|
|
|
14062
14049
|
var deflate = /*#__PURE__*/Object.freeze({
|
|
14063
|
-
|
|
14064
|
-
|
|
14050
|
+
__proto__: null,
|
|
14051
|
+
default: DeflateDecoder
|
|
14065
14052
|
});
|
|
14066
14053
|
|
|
14067
14054
|
class PackbitsDecoder extends BaseDecoder {
|
|
@@ -14090,8 +14077,8 @@ class PackbitsDecoder extends BaseDecoder {
|
|
|
14090
14077
|
}
|
|
14091
14078
|
|
|
14092
14079
|
var packbits = /*#__PURE__*/Object.freeze({
|
|
14093
|
-
|
|
14094
|
-
|
|
14080
|
+
__proto__: null,
|
|
14081
|
+
default: PackbitsDecoder
|
|
14095
14082
|
});
|
|
14096
14083
|
|
|
14097
14084
|
var LercDecode = {exports: {}};
|
|
@@ -16534,9 +16521,9 @@ class LercDecoder extends BaseDecoder {
|
|
|
16534
16521
|
}
|
|
16535
16522
|
|
|
16536
16523
|
var lerc = /*#__PURE__*/Object.freeze({
|
|
16537
|
-
|
|
16538
|
-
|
|
16539
|
-
|
|
16524
|
+
__proto__: null,
|
|
16525
|
+
default: LercDecoder,
|
|
16526
|
+
zstd: zstd
|
|
16540
16527
|
});
|
|
16541
16528
|
|
|
16542
16529
|
/**
|
|
@@ -16579,9 +16566,9 @@ class WebImageDecoder extends BaseDecoder {
|
|
|
16579
16566
|
}
|
|
16580
16567
|
|
|
16581
16568
|
var webimage = /*#__PURE__*/Object.freeze({
|
|
16582
|
-
|
|
16583
|
-
|
|
16569
|
+
__proto__: null,
|
|
16570
|
+
default: WebImageDecoder
|
|
16584
16571
|
});
|
|
16585
16572
|
|
|
16586
|
-
export {
|
|
16573
|
+
export { CogBitmapLayer, CogTerrainLayer, CogTiles, GeoImage };
|
|
16587
16574
|
//# sourceMappingURL=index.js.map
|