@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/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
|
|
276
|
-
const shiftTable = new
|
|
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 < -
|
|
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;
|
|
324
|
-
let e = 0;
|
|
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;
|
|
302
|
+
e -= 0x00800000; // decrement exponent
|
|
330
303
|
}
|
|
331
304
|
|
|
332
|
-
m &= ~0x00800000;
|
|
333
|
-
e += 0x38800000;
|
|
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
|
|
365
|
-
uint32View[0] = mantissaTable[offsetTable[
|
|
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] ===
|
|
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
|
-
|
|
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
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
}
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
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
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
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];
|
|
5047
5028
|
}
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
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;
|
|
5052
5038
|
}
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
channel = rasters[optionsLocal.useChannelIndex];
|
|
5059
|
-
}
|
|
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];
|
|
5060
5044
|
}
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
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
|
-
}
|
|
5045
|
+
// backfill right border
|
|
5046
|
+
for (let i = height, y = 0; y < height + 1; y++, i += height + 1) {
|
|
5047
|
+
terrain[i] = terrain[i - 1];
|
|
5070
5048
|
}
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
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
|
-
|
|
5088
|
-
|
|
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
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
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
|
-
|
|
5235
|
-
|
|
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
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
imageData.data[
|
|
5244
|
-
|
|
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
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
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
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
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
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
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
|
-
//
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
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;
|
|
@@ -5292,6 +5253,8 @@ class GeoImage {
|
|
|
5292
5253
|
return [minValue, maxValue];
|
|
5293
5254
|
}
|
|
5294
5255
|
getColorValue(dataArray, options, arrayLength, numOfChannels = 1) {
|
|
5256
|
+
// const rgb = chroma.random().rgb(); // [R, G, B]
|
|
5257
|
+
// const randomColor = [...rgb, 120];
|
|
5295
5258
|
const colorScale = chroma.scale(options.colorScale).domain(options.colorScaleValueRange);
|
|
5296
5259
|
// channel index is equal to channel number - 1
|
|
5297
5260
|
let pixel = options.useChannelIndex === null ? 0 : options.useChannelIndex;
|
|
@@ -5311,6 +5274,7 @@ class GeoImage {
|
|
|
5311
5274
|
}) : undefined;
|
|
5312
5275
|
for (let i = 0; i < arrayLength; i += 4) {
|
|
5313
5276
|
let pixelColor = options.nullColor;
|
|
5277
|
+
// let pixelColor = randomColor;
|
|
5314
5278
|
// FIXME
|
|
5315
5279
|
// eslint-disable-next-line max-len
|
|
5316
5280
|
if ((!Number.isNaN(dataArray[pixel])) && (options.noDataValue === undefined || dataArray[pixel] !== options.noDataValue)) {
|
|
@@ -5352,7 +5316,7 @@ class GeoImage {
|
|
|
5352
5316
|
}
|
|
5353
5317
|
// FIXME
|
|
5354
5318
|
// eslint-disable-next-line
|
|
5355
|
-
[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);
|
|
5356
5320
|
pixel += numOfChannels;
|
|
5357
5321
|
}
|
|
5358
5322
|
return colorsArray;
|
|
@@ -5442,7 +5406,7 @@ function getMeshAttributes(vertices, terrain, width, height, bounds) {
|
|
|
5442
5406
|
function getDelatinTileMesh(meshMaxError, width, height, terrain) {
|
|
5443
5407
|
const tin = new Delatin(terrain, width + 1, height + 1);
|
|
5444
5408
|
tin.run(meshMaxError);
|
|
5445
|
-
// @ts-expect-error
|
|
5409
|
+
// @ts-expect-error: Delatin instance properties 'coords' and 'triangles' are not explicitly typed in the library port
|
|
5446
5410
|
const { coords, triangles } = tin;
|
|
5447
5411
|
const vertices = coords;
|
|
5448
5412
|
return { vertices, triangles };
|
|
@@ -5456,31 +5420,30 @@ const CogTilesGeoImageOptionsDefaults = {
|
|
|
5456
5420
|
blurredTexture: true,
|
|
5457
5421
|
};
|
|
5458
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;
|
|
5459
5432
|
constructor(options) {
|
|
5460
|
-
this.
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
this.
|
|
5464
|
-
this.
|
|
5465
|
-
this.
|
|
5466
|
-
this.options
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
this.cogOrigin = image.getOrigin();
|
|
5475
|
-
(_a = (_c = this.options).noDataValue) !== null && _a !== void 0 ? _a : (_c.noDataValue = this.getNoDataValue(image));
|
|
5476
|
-
(_b = (_d = this.options).format) !== null && _b !== void 0 ? _b : (_d.format = this.getDataTypeFromTags(image));
|
|
5477
|
-
this.options.numOfChannels = this.getNumberOfChannels(image);
|
|
5478
|
-
this.options.planarConfig = this.getPlanarConfiguration(image);
|
|
5479
|
-
[this.cogZoomLookup, this.cogResolutionLookup] = yield this.buildCogZoomResolutionLookup(this.cog);
|
|
5480
|
-
this.tileSize = image.getTileWidth();
|
|
5481
|
-
this.zoomRange = this.calculateZoomRange(image, yield this.cog.getImageCount());
|
|
5482
|
-
this.bounds = this.calculateBoundsAsLatLon(image);
|
|
5483
|
-
});
|
|
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);
|
|
5484
5447
|
}
|
|
5485
5448
|
getZoomRange() {
|
|
5486
5449
|
return this.zoomRange;
|
|
@@ -5532,33 +5495,31 @@ class CogTiles {
|
|
|
5532
5495
|
* - The first array (`zoomLookup`) maps each image index to its computed zoom level.
|
|
5533
5496
|
* - The second array (`resolutionLookup`) maps each image index to its estimated resolution (m/pixel).
|
|
5534
5497
|
*/
|
|
5535
|
-
buildCogZoomResolutionLookup(cog) {
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
return [zoomLookup, resolutionLookup];
|
|
5561
|
-
});
|
|
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];
|
|
5562
5523
|
}
|
|
5563
5524
|
/**
|
|
5564
5525
|
* Determines the appropriate image index from the Cloud Optimized GeoTIFF (COG)
|
|
@@ -5587,99 +5548,138 @@ class CogTiles {
|
|
|
5587
5548
|
}
|
|
5588
5549
|
return exactMatchIndex;
|
|
5589
5550
|
}
|
|
5590
|
-
getTileFromImage(tileX, tileY, zoom) {
|
|
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
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
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');
|
|
5659
5641
|
}
|
|
5660
5642
|
}
|
|
5661
|
-
tileBuffer.forEach((rasterValue, index) => {
|
|
5662
|
-
validImageData[index * this.options.numOfChannels + band] = rasterValue;
|
|
5663
|
-
});
|
|
5664
5643
|
}
|
|
5665
|
-
|
|
5644
|
+
for (let i = 0; i < tileBuffer.length; i += 1) {
|
|
5645
|
+
validImageData[i * this.options.numOfChannels + band] = tileBuffer[i];
|
|
5646
|
+
}
|
|
5666
5647
|
}
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
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];
|
|
5672
5656
|
}
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
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);
|
|
5683
5683
|
}
|
|
5684
5684
|
/**
|
|
5685
5685
|
* Determines the data type (e.g., "Int32", "Float64") of a GeoTIFF image
|
|
@@ -5725,24 +5725,33 @@ class CogTiles {
|
|
|
5725
5725
|
}
|
|
5726
5726
|
/**
|
|
5727
5727
|
* Extracts the noData value from a GeoTIFF.js image.
|
|
5728
|
-
* Returns the noData value as a number if available, otherwise undefined.
|
|
5728
|
+
* Returns the noData value as a number (including NaN) if available, otherwise undefined.
|
|
5729
5729
|
*
|
|
5730
5730
|
* @param {GeoTIFFImage} image - The GeoTIFF.js image.
|
|
5731
|
-
* @returns {number|undefined} The noData value
|
|
5731
|
+
* @returns {number|undefined} The noData value, possibly NaN, or undefined if not set or invalid.
|
|
5732
5732
|
*/
|
|
5733
5733
|
getNoDataValue(image) {
|
|
5734
|
-
// Attempt to retrieve the noData value via the GDAL method.
|
|
5735
5734
|
const noDataRaw = image.getGDALNoData();
|
|
5736
5735
|
if (noDataRaw === undefined || noDataRaw === null) {
|
|
5737
|
-
console.
|
|
5738
|
-
// No noData value is defined
|
|
5736
|
+
console.warn('No noData value defined — raster might be rendered incorrectly.');
|
|
5739
5737
|
return undefined;
|
|
5740
5738
|
}
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5739
|
+
const cleaned = String(noDataRaw).replace(/\0/g, '').trim();
|
|
5740
|
+
if (cleaned === '') {
|
|
5741
|
+
console.warn('noData value is an empty string after cleanup.');
|
|
5742
|
+
return undefined;
|
|
5743
|
+
}
|
|
5744
|
+
const parsed = Number(cleaned);
|
|
5745
|
+
// Allow NaN if explicitly declared
|
|
5746
|
+
if (cleaned.toLowerCase() === 'nan') {
|
|
5747
|
+
return NaN;
|
|
5748
|
+
}
|
|
5749
|
+
// If not declared as "nan" and still parsed to NaN, it's an error
|
|
5750
|
+
if (Number.isNaN(parsed)) {
|
|
5751
|
+
console.warn(`Failed to parse numeric noData value: '${cleaned}'`);
|
|
5752
|
+
return undefined;
|
|
5753
|
+
}
|
|
5754
|
+
return parsed;
|
|
5746
5755
|
}
|
|
5747
5756
|
/**
|
|
5748
5757
|
* Retrieves the number of channels (samples per pixel) in a GeoTIFF image.
|
|
@@ -5825,7 +5834,8 @@ const urlType$1 = {
|
|
|
5825
5834
|
return true;
|
|
5826
5835
|
},
|
|
5827
5836
|
};
|
|
5828
|
-
const defaultProps$1 =
|
|
5837
|
+
const defaultProps$1 = {
|
|
5838
|
+
...geoLayers.TileLayer.defaultProps,
|
|
5829
5839
|
// Image url that encodes height data
|
|
5830
5840
|
// elevationData: urlType,
|
|
5831
5841
|
// Image url to use as texture
|
|
@@ -5835,10 +5845,9 @@ const defaultProps$1 = Object.assign(Object.assign({}, geoLayers.TileLayer.defau
|
|
|
5835
5845
|
// Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
|
|
5836
5846
|
bounds: {
|
|
5837
5847
|
type: 'array', value: null, optional: true, compare: true,
|
|
5838
|
-
},
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
blurredTexture: true, opacity: 1, clampToTerrain: false,
|
|
5848
|
+
},
|
|
5849
|
+
rasterData: urlType$1,
|
|
5850
|
+
clampToTerrain: false,
|
|
5842
5851
|
// Object to decode height data, from (r, g, b) to height in meters
|
|
5843
5852
|
// elevationDecoder: {
|
|
5844
5853
|
// type: 'object',
|
|
@@ -5850,40 +5859,31 @@ const defaultProps$1 = Object.assign(Object.assign({}, geoLayers.TileLayer.defau
|
|
|
5850
5859
|
// },
|
|
5851
5860
|
// },
|
|
5852
5861
|
// Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
|
|
5853
|
-
workerUrl: ''
|
|
5862
|
+
workerUrl: '',
|
|
5863
|
+
// Same as SimpleMeshLayer wireframe
|
|
5864
|
+
// wireframe: false,
|
|
5865
|
+
// material: true,
|
|
5866
|
+
// loaders: [TerrainLoader],
|
|
5867
|
+
};
|
|
5854
5868
|
/** Render bitmap texture from cog raster images. */
|
|
5855
5869
|
class CogBitmapLayer extends core.CompositeLayer {
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
//
|
|
5864
|
-
initializeState(context) {
|
|
5865
|
-
const _super = Object.create(null, {
|
|
5866
|
-
initializeState: { get: () => super.initializeState }
|
|
5867
|
-
});
|
|
5868
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
5869
|
-
_super.initializeState.call(this, context);
|
|
5870
|
-
this.setState({
|
|
5871
|
-
bitmapCogTiles: new CogTiles(this.props.cogBitmapOptions),
|
|
5872
|
-
initialized: false,
|
|
5873
|
-
});
|
|
5874
|
-
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,
|
|
5875
5877
|
});
|
|
5878
|
+
await this.init();
|
|
5876
5879
|
}
|
|
5877
|
-
init() {
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
this.setState({ initialized: true, minZoom, maxZoom });
|
|
5883
|
-
});
|
|
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 });
|
|
5884
5885
|
}
|
|
5885
5886
|
updateState({ props, oldProps }) {
|
|
5886
|
-
var _a, _b, _c;
|
|
5887
5887
|
const rasterDataChanged = props.rasterData !== oldProps.rasterData;
|
|
5888
5888
|
if (rasterDataChanged) {
|
|
5889
5889
|
const { rasterData } = props;
|
|
@@ -5903,45 +5903,47 @@ class CogBitmapLayer extends core.CompositeLayer {
|
|
|
5903
5903
|
// object in this way is not ideal and may need refactoring in the future to follow a more
|
|
5904
5904
|
// declarative state management approach. Consider revisiting this if additional properties
|
|
5905
5905
|
// need to be synchronized or if the state structure changes.
|
|
5906
|
-
if (
|
|
5906
|
+
if (props?.cogBitmapOptions?.useChannel && (props.cogBitmapOptions?.useChannel !== oldProps.cogBitmapOptions?.useChannel)) {
|
|
5907
5907
|
this.state.bitmapCogTiles.options.useChannel = props.cogBitmapOptions.useChannel;
|
|
5908
5908
|
}
|
|
5909
|
-
// TODO - remove in v9
|
|
5910
|
-
// @ts-ignore
|
|
5911
5909
|
if (props.workerUrl) {
|
|
5912
5910
|
core.log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
|
|
5913
5911
|
}
|
|
5914
5912
|
}
|
|
5915
|
-
getTiledBitmapData(tile) {
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
return tileData;
|
|
5921
|
-
});
|
|
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;
|
|
5922
5918
|
}
|
|
5923
5919
|
renderSubLayers(props) {
|
|
5924
5920
|
const SubLayerClass = this.getSubLayerClass('image', layers.BitmapLayer);
|
|
5925
5921
|
const { blurredTexture } = this.state.bitmapCogTiles.options;
|
|
5926
|
-
const {
|
|
5922
|
+
const { clampToTerrain } = this.props;
|
|
5923
|
+
const hasDrawMode = typeof clampToTerrain === 'object' && clampToTerrain !== null && 'terrainDrawMode' in clampToTerrain;
|
|
5927
5924
|
const { data } = props;
|
|
5928
5925
|
if (!data) {
|
|
5929
5926
|
return null;
|
|
5930
5927
|
}
|
|
5931
5928
|
const { bbox: { west, south, east, north, }, } = props.tile;
|
|
5932
|
-
return new SubLayerClass(
|
|
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: {
|
|
5933
5935
|
minFilter: blurredTexture ? 'linear' : 'nearest',
|
|
5934
5936
|
magFilter: blurredTexture ? 'linear' : 'nearest',
|
|
5935
|
-
},
|
|
5937
|
+
},
|
|
5936
5938
|
// TODO check if works!!!
|
|
5937
|
-
extensions: clampToTerrain ? [new extensions._TerrainExtension()] : []
|
|
5938
|
-
|
|
5939
|
-
|
|
5939
|
+
extensions: clampToTerrain ? [new extensions._TerrainExtension()] : [],
|
|
5940
|
+
...(hasDrawMode
|
|
5941
|
+
? { terrainDrawMode: clampToTerrain.terrainDrawMode }
|
|
5942
|
+
: {}),
|
|
5943
|
+
});
|
|
5940
5944
|
}
|
|
5941
5945
|
renderLayers() {
|
|
5942
|
-
const {
|
|
5943
|
-
// tileSize,
|
|
5944
|
-
maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, cogBitmapOptions, } = this.props;
|
|
5946
|
+
const { clampToTerrain, maxRequests, onTileLoad, onTileUnload, onTileError, maxCacheSize, maxCacheByteSize, refinementStrategy, cogBitmapOptions, } = this.props;
|
|
5945
5947
|
if (this.state.isTiled && this.state.initialized) {
|
|
5946
5948
|
const { tileSize } = this.state.bitmapCogTiles;
|
|
5947
5949
|
return new geoLayers.TileLayer(this.getSubLayerProps({
|
|
@@ -5976,28 +5978,7 @@ class CogBitmapLayer extends core.CompositeLayer {
|
|
|
5976
5978
|
return null;
|
|
5977
5979
|
}
|
|
5978
5980
|
}
|
|
5979
|
-
CogBitmapLayer.defaultProps = defaultProps$1;
|
|
5980
|
-
CogBitmapLayer.layerName = 'CogBitmapLayer';
|
|
5981
5981
|
|
|
5982
|
-
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
|
|
5983
|
-
//
|
|
5984
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5985
|
-
// of this software and associated documentation files (the "Software"), to deal
|
|
5986
|
-
// in the Software without restriction, including without limitation the rights
|
|
5987
|
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
5988
|
-
// copies of the Software, and to permit persons to whom the Software is
|
|
5989
|
-
// furnished to do so, subject to the following conditions:
|
|
5990
|
-
//
|
|
5991
|
-
// The above copyright notice and this permission notice shall be included in
|
|
5992
|
-
// all copies or substantial portions of the Software.
|
|
5993
|
-
//
|
|
5994
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
5995
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
5996
|
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
5997
|
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
5998
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
5999
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
6000
|
-
// THE SOFTWARE.
|
|
6001
5982
|
const urlType = {
|
|
6002
5983
|
type: 'object',
|
|
6003
5984
|
value: null,
|
|
@@ -6024,19 +6005,20 @@ const urlType = {
|
|
|
6024
6005
|
},
|
|
6025
6006
|
};
|
|
6026
6007
|
const DUMMY_DATA = [1];
|
|
6027
|
-
const defaultProps =
|
|
6008
|
+
const defaultProps = {
|
|
6009
|
+
...geoLayers.TileLayer.defaultProps,
|
|
6028
6010
|
// Image url that encodes height data
|
|
6029
|
-
elevationData: urlType,
|
|
6011
|
+
elevationData: urlType,
|
|
6030
6012
|
// Image url to use as texture
|
|
6031
|
-
texture:
|
|
6013
|
+
texture: { ...urlType, optional: true },
|
|
6032
6014
|
// Martini error tolerance in meters, smaller number -> more detailed mesh
|
|
6033
|
-
meshMaxError: { type: 'number', value: 4.0 },
|
|
6015
|
+
meshMaxError: { type: 'number', value: 4.0 },
|
|
6034
6016
|
// Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates
|
|
6035
6017
|
bounds: {
|
|
6036
6018
|
type: 'array', value: null, optional: true, compare: true,
|
|
6037
|
-
},
|
|
6019
|
+
},
|
|
6038
6020
|
// Color to use if texture is unavailable
|
|
6039
|
-
color: { type: 'color', value: [255, 255, 255] },
|
|
6021
|
+
color: { type: 'color', value: [255, 255, 255] },
|
|
6040
6022
|
// Object to decode height data, from (r, g, b) to height in meters
|
|
6041
6023
|
elevationDecoder: {
|
|
6042
6024
|
type: 'object',
|
|
@@ -6046,11 +6028,14 @@ const defaultProps = Object.assign(Object.assign({}, geoLayers.TileLayer.default
|
|
|
6046
6028
|
bScaler: 0,
|
|
6047
6029
|
offset: 0,
|
|
6048
6030
|
},
|
|
6049
|
-
},
|
|
6031
|
+
},
|
|
6050
6032
|
// Supply url to local terrain worker bundle. Only required if running offline and cannot access CDN.
|
|
6051
|
-
workerUrl: '',
|
|
6033
|
+
workerUrl: '',
|
|
6052
6034
|
// Same as SimpleMeshLayer wireframe
|
|
6053
|
-
wireframe: false,
|
|
6035
|
+
wireframe: false,
|
|
6036
|
+
material: true,
|
|
6037
|
+
// loaders: [TerrainLoader],
|
|
6038
|
+
};
|
|
6054
6039
|
// Turns array of templates into a single string to work around shallow change
|
|
6055
6040
|
function urlTemplateToUpdateTrigger(template) {
|
|
6056
6041
|
if (Array.isArray(template)) {
|
|
@@ -6062,28 +6047,25 @@ function urlTemplateToUpdateTrigger(template) {
|
|
|
6062
6047
|
// TODO use meshMaxError
|
|
6063
6048
|
// TODO - pass signal to getTile
|
|
6064
6049
|
/** Render mesh surfaces from height map images. */
|
|
6065
|
-
class
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
});
|
|
6076
|
-
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,
|
|
6077
6060
|
});
|
|
6061
|
+
await this.init(this.terrainUrl);
|
|
6078
6062
|
}
|
|
6079
|
-
init(
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
this.setState({ initialized: true, minZoom, maxZoom });
|
|
6086
|
-
});
|
|
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 });
|
|
6087
6069
|
}
|
|
6088
6070
|
updateState({ props, oldProps }) {
|
|
6089
6071
|
const elevationDataChanged = props.elevationData !== oldProps.elevationData;
|
|
@@ -6100,8 +6082,6 @@ class TerrainLayer extends core.CompositeLayer {
|
|
|
6100
6082
|
|| props.elevationDecoder !== oldProps.elevationDecoder
|
|
6101
6083
|
|| props.bounds !== oldProps.bounds;
|
|
6102
6084
|
if (!this.state.isTiled && shouldReload) ;
|
|
6103
|
-
// TODO - remove in v9
|
|
6104
|
-
// @ts-ignore
|
|
6105
6085
|
if (props.workerUrl) {
|
|
6106
6086
|
core.log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
|
|
6107
6087
|
}
|
|
@@ -6111,36 +6091,47 @@ class TerrainLayer extends core.CompositeLayer {
|
|
|
6111
6091
|
return null;
|
|
6112
6092
|
}
|
|
6113
6093
|
let loadOptions = this.getLoadOptions();
|
|
6114
|
-
loadOptions =
|
|
6094
|
+
loadOptions = {
|
|
6095
|
+
...loadOptions,
|
|
6096
|
+
_workerType: 'test',
|
|
6097
|
+
terrain: {
|
|
6098
|
+
skirtHeight: this.state.isTiled ? meshMaxError * 2 : 0,
|
|
6099
|
+
...loadOptions?.terrain,
|
|
6100
|
+
bounds,
|
|
6115
6101
|
meshMaxError,
|
|
6116
|
-
elevationDecoder
|
|
6102
|
+
elevationDecoder,
|
|
6103
|
+
},
|
|
6104
|
+
};
|
|
6117
6105
|
const { fetch } = this.props;
|
|
6118
6106
|
return fetch(elevationData, {
|
|
6119
6107
|
propName: 'elevationData', layer: this, loadOptions, signal, loaders: [],
|
|
6120
6108
|
});
|
|
6121
6109
|
}
|
|
6122
|
-
getTiledTerrainData(tile) {
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
const
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
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]);
|
|
6144
6135
|
}
|
|
6145
6136
|
renderSubLayers(props) {
|
|
6146
6137
|
const SubLayerClass = this.getSubLayerClass('mesh', meshLayers.SimpleMeshLayer);
|
|
@@ -6151,13 +6142,13 @@ class TerrainLayer extends core.CompositeLayer {
|
|
|
6151
6142
|
}
|
|
6152
6143
|
// const [mesh, texture] = data;
|
|
6153
6144
|
const [mesh] = data;
|
|
6154
|
-
return new SubLayerClass(
|
|
6145
|
+
return new SubLayerClass({ ...props, tileSize: 256 }, {
|
|
6155
6146
|
data: DUMMY_DATA,
|
|
6156
6147
|
mesh,
|
|
6157
6148
|
// texture,
|
|
6158
6149
|
_instanced: false,
|
|
6159
6150
|
coordinateSystem: core.COORDINATE_SYSTEM.CARTESIAN,
|
|
6160
|
-
getPosition: (d) => [0, 0, 0],
|
|
6151
|
+
// getPosition: (d) => [0, 0, 0],
|
|
6161
6152
|
getColor: color,
|
|
6162
6153
|
wireframe,
|
|
6163
6154
|
material,
|
|
@@ -6173,10 +6164,9 @@ class TerrainLayer extends core.CompositeLayer {
|
|
|
6173
6164
|
.map((tile) => tile.content)
|
|
6174
6165
|
.filter((x) => x && x[0])
|
|
6175
6166
|
.map((arr) => {
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
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]);
|
|
6180
6170
|
});
|
|
6181
6171
|
if (ranges.length === 0) {
|
|
6182
6172
|
return;
|
|
@@ -6188,7 +6178,13 @@ class TerrainLayer extends core.CompositeLayer {
|
|
|
6188
6178
|
}
|
|
6189
6179
|
}
|
|
6190
6180
|
renderLayers() {
|
|
6191
|
-
const {
|
|
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;
|
|
6192
6188
|
if (this.state.isTiled && this.state.initialized) {
|
|
6193
6189
|
return new geoLayers.TileLayer(this.getSubLayerProps({
|
|
6194
6190
|
id: 'tiles',
|
|
@@ -6239,15 +6235,6 @@ class TerrainLayer extends core.CompositeLayer {
|
|
|
6239
6235
|
// );
|
|
6240
6236
|
}
|
|
6241
6237
|
}
|
|
6242
|
-
TerrainLayer.defaultProps = defaultProps;
|
|
6243
|
-
TerrainLayer.layerName = 'TerrainLayer';
|
|
6244
|
-
|
|
6245
|
-
var index = {
|
|
6246
|
-
CogBitmapLayer,
|
|
6247
|
-
CogTerrainLayer: TerrainLayer,
|
|
6248
|
-
cogtiles: CogTiles,
|
|
6249
|
-
GeoImage,
|
|
6250
|
-
};
|
|
6251
6238
|
|
|
6252
6239
|
class RawDecoder extends BaseDecoder {
|
|
6253
6240
|
decodeBlock(buffer) {
|
|
@@ -6256,8 +6243,8 @@ class RawDecoder extends BaseDecoder {
|
|
|
6256
6243
|
}
|
|
6257
6244
|
|
|
6258
6245
|
var raw = /*#__PURE__*/Object.freeze({
|
|
6259
|
-
|
|
6260
|
-
|
|
6246
|
+
__proto__: null,
|
|
6247
|
+
default: RawDecoder
|
|
6261
6248
|
});
|
|
6262
6249
|
|
|
6263
6250
|
const MIN_BITS = 9;
|
|
@@ -6391,8 +6378,8 @@ class LZWDecoder extends BaseDecoder {
|
|
|
6391
6378
|
}
|
|
6392
6379
|
|
|
6393
6380
|
var lzw = /*#__PURE__*/Object.freeze({
|
|
6394
|
-
|
|
6395
|
-
|
|
6381
|
+
__proto__: null,
|
|
6382
|
+
default: LZWDecoder
|
|
6396
6383
|
});
|
|
6397
6384
|
|
|
6398
6385
|
/* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
|
@@ -7290,8 +7277,8 @@ class JpegDecoder extends BaseDecoder {
|
|
|
7290
7277
|
}
|
|
7291
7278
|
|
|
7292
7279
|
var jpeg = /*#__PURE__*/Object.freeze({
|
|
7293
|
-
|
|
7294
|
-
|
|
7280
|
+
__proto__: null,
|
|
7281
|
+
default: JpegDecoder
|
|
7295
7282
|
});
|
|
7296
7283
|
|
|
7297
7284
|
/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */
|
|
@@ -14062,8 +14049,8 @@ class DeflateDecoder extends BaseDecoder {
|
|
|
14062
14049
|
}
|
|
14063
14050
|
|
|
14064
14051
|
var deflate = /*#__PURE__*/Object.freeze({
|
|
14065
|
-
|
|
14066
|
-
|
|
14052
|
+
__proto__: null,
|
|
14053
|
+
default: DeflateDecoder
|
|
14067
14054
|
});
|
|
14068
14055
|
|
|
14069
14056
|
class PackbitsDecoder extends BaseDecoder {
|
|
@@ -14092,8 +14079,8 @@ class PackbitsDecoder extends BaseDecoder {
|
|
|
14092
14079
|
}
|
|
14093
14080
|
|
|
14094
14081
|
var packbits = /*#__PURE__*/Object.freeze({
|
|
14095
|
-
|
|
14096
|
-
|
|
14082
|
+
__proto__: null,
|
|
14083
|
+
default: PackbitsDecoder
|
|
14097
14084
|
});
|
|
14098
14085
|
|
|
14099
14086
|
var LercDecode = {exports: {}};
|
|
@@ -16536,9 +16523,9 @@ class LercDecoder extends BaseDecoder {
|
|
|
16536
16523
|
}
|
|
16537
16524
|
|
|
16538
16525
|
var lerc = /*#__PURE__*/Object.freeze({
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16526
|
+
__proto__: null,
|
|
16527
|
+
default: LercDecoder,
|
|
16528
|
+
zstd: zstd
|
|
16542
16529
|
});
|
|
16543
16530
|
|
|
16544
16531
|
/**
|
|
@@ -16581,9 +16568,12 @@ class WebImageDecoder extends BaseDecoder {
|
|
|
16581
16568
|
}
|
|
16582
16569
|
|
|
16583
16570
|
var webimage = /*#__PURE__*/Object.freeze({
|
|
16584
|
-
|
|
16585
|
-
|
|
16571
|
+
__proto__: null,
|
|
16572
|
+
default: WebImageDecoder
|
|
16586
16573
|
});
|
|
16587
16574
|
|
|
16588
|
-
|
|
16575
|
+
exports.CogBitmapLayer = CogBitmapLayer;
|
|
16576
|
+
exports.CogTerrainLayer = CogTerrainLayer;
|
|
16577
|
+
exports.CogTiles = CogTiles;
|
|
16578
|
+
exports.GeoImage = GeoImage;
|
|
16589
16579
|
//# sourceMappingURL=index.js.map
|