@cogeotiff/core 7.2.0 → 8.0.1
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/CHANGELOG.md +3 -500
- package/README.md +28 -10
- package/build/__benchmark__/cog.read.benchmark.d.ts +0 -1
- package/build/__benchmark__/cog.read.benchmark.js +6 -4
- package/build/__benchmark__/cog.read.benchmark.js.map +1 -0
- package/build/__benchmark__/source.file.d.ts +9 -0
- package/build/__benchmark__/source.file.js +29 -0
- package/build/__benchmark__/source.file.js.map +1 -0
- package/build/__benchmark__/source.memory.d.ts +9 -0
- package/build/__benchmark__/source.memory.js +32 -0
- package/build/__benchmark__/source.memory.js.map +1 -0
- package/build/__test__/cog.image.test.d.ts +1 -2
- package/build/__test__/cog.image.test.js +82 -90
- package/build/__test__/cog.image.test.js.map +1 -0
- package/build/__test__/cog.read.test.d.ts +1 -2
- package/build/__test__/cog.read.test.js +37 -55
- package/build/__test__/cog.read.test.js.map +1 -0
- package/build/__test__/example.d.ts +1 -0
- package/build/__test__/example.js +27 -0
- package/build/__test__/example.js.map +1 -0
- package/build/cog.tiff.d.ts +22 -28
- package/build/cog.tiff.image.d.ts +16 -28
- package/build/cog.tiff.image.js +147 -101
- package/build/cog.tiff.image.js.map +1 -0
- package/build/cog.tiff.js +141 -97
- package/build/cog.tiff.js.map +1 -0
- package/build/const/index.d.ts +1 -2
- package/build/const/index.js +2 -2
- package/build/const/index.js.map +1 -0
- package/build/const/tiff.endian.d.ts +0 -1
- package/build/const/tiff.endian.js +1 -1
- package/build/const/tiff.endian.js.map +1 -0
- package/build/const/tiff.mime.d.ts +10 -11
- package/build/const/tiff.mime.js +22 -22
- package/build/const/tiff.mime.js.map +1 -0
- package/build/const/tiff.tag.id.d.ts +5 -5
- package/build/const/tiff.tag.id.js +155 -154
- package/build/const/tiff.tag.id.js.map +1 -0
- package/build/const/tiff.tag.value.d.ts +15 -16
- package/build/const/tiff.tag.value.js +16 -16
- package/build/const/tiff.tag.value.js.map +1 -0
- package/build/const/tiff.version.d.ts +0 -1
- package/build/const/tiff.version.js +1 -1
- package/build/const/tiff.version.js.map +1 -0
- package/build/index.d.ts +11 -6
- package/build/index.js +9 -5
- package/build/index.js.map +1 -0
- package/build/read/data.view.offset.d.ts +15 -0
- package/build/read/data.view.offset.js +19 -0
- package/build/read/data.view.offset.js.map +1 -0
- package/build/read/tiff.gdal.d.ts +9 -12
- package/build/read/tiff.gdal.js +22 -17
- package/build/read/tiff.gdal.js.map +1 -0
- package/build/read/tiff.ifd.config.d.ts +6 -4
- package/build/read/tiff.ifd.config.js +2 -2
- package/build/read/tiff.ifd.config.js.map +1 -0
- package/build/read/tiff.tag.d.ts +37 -20
- package/build/read/tiff.tag.factory.d.ts +16 -0
- package/build/read/tiff.tag.factory.js +130 -0
- package/build/read/tiff.tag.factory.js.map +1 -0
- package/build/read/tiff.tag.js +2 -37
- package/build/read/tiff.tag.js.map +1 -0
- package/build/read/tiff.value.reader.d.ts +2 -6
- package/build/read/tiff.value.reader.js +16 -54
- package/build/read/tiff.value.reader.js.map +1 -0
- package/build/source.d.ts +5 -0
- package/build/source.js +2 -0
- package/build/source.js.map +1 -0
- package/build/util/bytes.d.ts +17 -0
- package/build/util/bytes.js +42 -0
- package/build/util/bytes.js.map +1 -0
- package/build/util/util.hex.d.ts +2 -3
- package/build/util/util.hex.js +4 -5
- package/build/util/util.hex.js.map +1 -0
- package/build/vector.d.ts +0 -1
- package/build/vector.js +1 -1
- package/build/vector.js.map +1 -0
- package/package.json +25 -30
- package/src/__benchmark__/cog.read.benchmark.ts +12 -10
- package/src/__benchmark__/source.file.ts +23 -0
- package/src/__benchmark__/source.memory.ts +23 -0
- package/src/__test__/cog.image.test.ts +188 -197
- package/src/__test__/cog.read.test.ts +50 -72
- package/src/__test__/example.ts +31 -0
- package/src/cog.tiff.image.ts +456 -448
- package/src/cog.tiff.ts +143 -146
- package/src/const/index.ts +1 -1
- package/src/const/tiff.endian.ts +2 -2
- package/src/const/tiff.mime.ts +21 -21
- package/src/const/tiff.tag.id.ts +159 -158
- package/src/const/tiff.tag.value.ts +16 -16
- package/src/const/tiff.version.ts +11 -11
- package/src/index.ts +11 -5
- package/src/read/data.view.offset.ts +23 -0
- package/src/read/tiff.gdal.ts +61 -63
- package/src/read/tiff.ifd.config.ts +35 -31
- package/src/read/tiff.tag.factory.ts +163 -0
- package/src/read/tiff.tag.ts +38 -39
- package/src/read/tiff.value.reader.ts +25 -73
- package/src/source.ts +5 -0
- package/src/util/bytes.ts +44 -0
- package/src/util/util.hex.ts +5 -7
- package/src/vector.ts +5 -5
- package/tsconfig.json +8 -10
- package/build/__benchmark__/cog.read.benchmark.d.ts.map +0 -1
- package/build/__test__/cog.image.test.d.ts.map +0 -1
- package/build/__test__/cog.read.test.d.ts.map +0 -1
- package/build/cog.tiff.d.ts.map +0 -1
- package/build/cog.tiff.image.d.ts.map +0 -1
- package/build/const/index.d.ts.map +0 -1
- package/build/const/tiff.endian.d.ts.map +0 -1
- package/build/const/tiff.mime.d.ts.map +0 -1
- package/build/const/tiff.tag.id.d.ts.map +0 -1
- package/build/const/tiff.tag.value.d.ts.map +0 -1
- package/build/const/tiff.version.d.ts.map +0 -1
- package/build/index.d.ts.map +0 -1
- package/build/read/tag/__test__/tag.test.d.ts +0 -2
- package/build/read/tag/__test__/tag.test.d.ts.map +0 -1
- package/build/read/tag/__test__/tag.test.js +0 -23
- package/build/read/tag/tiff.tag.base.d.ts +0 -55
- package/build/read/tag/tiff.tag.base.d.ts.map +0 -1
- package/build/read/tag/tiff.tag.base.js +0 -79
- package/build/read/tag/tiff.tag.lazy.d.ts +0 -7
- package/build/read/tag/tiff.tag.lazy.d.ts.map +0 -1
- package/build/read/tag/tiff.tag.lazy.js +0 -18
- package/build/read/tag/tiff.tag.offset.d.ts +0 -21
- package/build/read/tag/tiff.tag.offset.d.ts.map +0 -1
- package/build/read/tag/tiff.tag.offset.js +0 -54
- package/build/read/tag/tiff.tag.static.d.ts +0 -8
- package/build/read/tag/tiff.tag.static.d.ts.map +0 -1
- package/build/read/tag/tiff.tag.static.js +0 -17
- package/build/read/tiff.gdal.d.ts.map +0 -1
- package/build/read/tiff.ifd.config.d.ts.map +0 -1
- package/build/read/tiff.tag.d.ts.map +0 -1
- package/build/read/tiff.value.reader.d.ts.map +0 -1
- package/build/source/cog.source.view.d.ts +0 -33
- package/build/source/cog.source.view.d.ts.map +0 -1
- package/build/source/cog.source.view.js +0 -65
- package/build/util/util.hex.d.ts.map +0 -1
- package/build/vector.d.ts.map +0 -1
- package/src/@types/ieee754.d.ts +0 -18
- package/src/read/tag/__test__/tag.test.ts +0 -27
- package/src/read/tag/tiff.tag.base.ts +0 -126
- package/src/read/tag/tiff.tag.lazy.ts +0 -17
- package/src/read/tag/tiff.tag.offset.ts +0 -61
- package/src/read/tag/tiff.tag.static.ts +0 -15
- package/src/source/cog.source.view.ts +0 -77
package/build/util/util.hex.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Convert a number to a
|
|
2
|
+
* Convert a number to a formatted hex string
|
|
3
3
|
*
|
|
4
4
|
* @param num number to convert
|
|
5
5
|
* @param padding number of 0's to pad the digit with
|
|
@@ -7,11 +7,10 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @returns hex string eg 0x0015
|
|
9
9
|
**/
|
|
10
|
-
export function
|
|
10
|
+
export function toHex(num, padding = 4, prefix = true) {
|
|
11
11
|
const hex = num.toString(16).padStart(padding, '0');
|
|
12
|
-
if (prefix)
|
|
12
|
+
if (prefix)
|
|
13
13
|
return '0x' + hex;
|
|
14
|
-
}
|
|
15
14
|
return hex;
|
|
16
15
|
}
|
|
17
|
-
//# sourceMappingURL=
|
|
16
|
+
//# sourceMappingURL=util.hex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.hex.js","sourceRoot":"","sources":["../../src/util/util.hex.ts"],"names":[],"mappings":"AAAA;;;;;;;;IAQI;AACJ,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,OAAO,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,MAAM;QAAE,OAAO,IAAI,GAAG,GAAG,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/build/vector.d.ts
CHANGED
package/build/vector.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
//# sourceMappingURL=
|
|
2
|
+
//# sourceMappingURL=vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../src/vector.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
"publishConfig": {
|
|
29
|
-
"access": "public"
|
|
30
|
-
},
|
|
31
|
-
"gitHead": "64a437a3590a1fc8395d1f4294a5fc74cbbe6127"
|
|
2
|
+
"name": "@cogeotiff/core",
|
|
3
|
+
"version": "8.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/blacha/cogeotiff.git",
|
|
7
|
+
"directory": "packages/core"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
|
12
|
+
},
|
|
13
|
+
"main": "./build/index.js",
|
|
14
|
+
"types": "./build/index.d.ts",
|
|
15
|
+
"author": "Blayne Chard",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "node --test"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^20.0.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"gitHead": "6e7b4f6250189ce8a3fa88641eaf35538b104ddd"
|
|
32
27
|
}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import { SourceMemory } from '@chunkd/core';
|
|
2
1
|
import { readFile } from 'fs/promises';
|
|
3
2
|
import { CogTiff } from '../cog.tiff.js';
|
|
3
|
+
import { SourceMemory } from './source.memory.js';
|
|
4
4
|
|
|
5
|
+
// console.log = console.trace;
|
|
5
6
|
/** Read a tile from every image inside of a tiff 300 tiles read */
|
|
6
7
|
async function main(): Promise<void> {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const buf = await readFile(process.argv[process.argv.length - 1]);
|
|
9
|
+
const source = new SourceMemory(buf);
|
|
10
|
+
for (let i = 0; i < 5_000; i++) {
|
|
11
|
+
performance.mark('cog:init');
|
|
12
|
+
const tiff = new CogTiff(source);
|
|
13
|
+
await tiff.init();
|
|
14
|
+
performance.mark('cog:init:done');
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
16
|
+
// 6 images
|
|
17
|
+
for (const img of tiff.images) await img.getTile(0, 0);
|
|
18
|
+
}
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
main();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFile, stat } from 'fs/promises';
|
|
2
|
+
import { Source } from '../source.js';
|
|
3
|
+
|
|
4
|
+
export class TestFileSource implements Source {
|
|
5
|
+
url: URL;
|
|
6
|
+
data: Promise<Buffer>;
|
|
7
|
+
|
|
8
|
+
constructor(fileName: URL) {
|
|
9
|
+
this.url = fileName;
|
|
10
|
+
this.data = readFile(this.url);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async fetch(offset: number, length: number): Promise<ArrayBuffer> {
|
|
14
|
+
const fileData = await this.data;
|
|
15
|
+
return fileData.buffer.slice(fileData.byteOffset + offset, fileData.byteOffset + offset + length);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get size(): Promise<number> {
|
|
19
|
+
return Promise.resolve()
|
|
20
|
+
.then(() => stat(this.url))
|
|
21
|
+
.then((f) => f.size);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Source } from '../source.js';
|
|
2
|
+
|
|
3
|
+
export class SourceMemory implements Source {
|
|
4
|
+
url: URL;
|
|
5
|
+
data: ArrayBuffer;
|
|
6
|
+
|
|
7
|
+
static toArrayBuffer(buf: Buffer | Uint8Array | ArrayBuffer): ArrayBuffer {
|
|
8
|
+
if (buf instanceof ArrayBuffer) return buf;
|
|
9
|
+
if (buf.byteLength === buf.buffer.byteLength) return buf.buffer;
|
|
10
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
constructor(bytes: Buffer | Uint8Array | ArrayBuffer) {
|
|
14
|
+
this.url = new URL('memory://fake-file');
|
|
15
|
+
this.data = SourceMemory.toArrayBuffer(bytes);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async fetch(offset: number, length?: number): Promise<ArrayBuffer> {
|
|
19
|
+
// console.log('Fetch', offset, length);
|
|
20
|
+
if (offset < 0) offset = this.data.byteLength + offset;
|
|
21
|
+
return this.data.slice(offset, length == null ? undefined : offset + length);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,214 +1,205 @@
|
|
|
1
|
-
import o from 'ospec';
|
|
2
|
-
import * as path from 'path';
|
|
3
1
|
import { promises as fs } from 'fs';
|
|
4
|
-
|
|
5
|
-
import '
|
|
6
|
-
|
|
7
|
-
import {
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { beforeEach, describe, it } from 'node:test';
|
|
4
|
+
import { TestFileSource } from '../__benchmark__/source.file.js';
|
|
5
|
+
import { SourceMemory } from '../__benchmark__/source.memory.js';
|
|
6
|
+
import { ByteSize } from '../util/bytes.js';
|
|
8
7
|
import { CogTiff } from '../cog.tiff.js';
|
|
9
|
-
import { TiffMimeType } from '../const/
|
|
10
|
-
import { ByteSize, SourceMemory } from '@chunkd/core';
|
|
11
|
-
import { fileURLToPath } from 'url';
|
|
8
|
+
import { TiffMimeType } from '../const/tiff.mime.js';
|
|
12
9
|
|
|
13
|
-
const __dirname = fileURLToPath(import.meta.url);
|
|
14
10
|
// 900913 properties.
|
|
15
11
|
const A = 6378137.0;
|
|
16
12
|
const InitialResolution = (2 * Math.PI * A) / 256;
|
|
17
13
|
|
|
18
14
|
function getResolution(zoom: number): number {
|
|
19
|
-
|
|
15
|
+
return InitialResolution / 2 ** zoom;
|
|
20
16
|
}
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
18
|
+
describe('CogTiled', () => {
|
|
19
|
+
const cogSourceFile = new TestFileSource(new URL('../../data/rgba8_tiled.tiff', import.meta.url));
|
|
20
|
+
const cog = new CogTiff(cogSourceFile);
|
|
21
|
+
|
|
22
|
+
beforeEach(() => cog.init());
|
|
23
|
+
|
|
24
|
+
it('should match resolutions to web mercator zoom levels', () => {
|
|
25
|
+
for (let i = 0; i < 14; i++) {
|
|
26
|
+
assert.equal(cog.getImageByResolution(getResolution(i)).id, 4);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
assert.equal(cog.getImageByResolution(getResolution(14)).id, 3);
|
|
30
|
+
assert.equal(cog.getImageByResolution(getResolution(15)).id, 2);
|
|
31
|
+
assert.equal(cog.getImageByResolution(getResolution(16)).id, 1);
|
|
32
|
+
assert.equal(cog.getImageByResolution(getResolution(17)).id, 0);
|
|
33
|
+
assert.equal(cog.getImageByResolution(getResolution(18)).id, 0);
|
|
34
|
+
|
|
35
|
+
for (let i = 19; i < 32; i++) {
|
|
36
|
+
assert.equal(cog.getImageByResolution(getResolution(i)).id, 0);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should get origin from all images', () => {
|
|
41
|
+
const baseOrigin = cog.images[0].origin;
|
|
42
|
+
for (const img of cog.images) {
|
|
43
|
+
assert.deepEqual(img.origin, baseOrigin);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should get bounding box from all images', () => {
|
|
48
|
+
const baseOrigin = cog.images[0].bbox;
|
|
49
|
+
for (const img of cog.images) {
|
|
50
|
+
assert.deepEqual(img.bbox, baseOrigin);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should be geolocated', () => {
|
|
55
|
+
for (const img of cog.images) assert.equal(img.isGeoLocated, true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should scale image resolution for all images', () => {
|
|
59
|
+
const [resX, resY, resZ] = cog.images[0].resolution;
|
|
60
|
+
for (let i = 0; i < cog.images.length; i++) {
|
|
61
|
+
const img = cog.images[i];
|
|
62
|
+
const scale = 2 ** i; // This tiff is scaled at a factor of two per zoom level
|
|
63
|
+
assert.deepEqual(img.resolution, [resX * scale, resY * scale, resZ]);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should have tile information', () => {
|
|
68
|
+
const [firstImage] = cog.images;
|
|
69
|
+
assert.equal(firstImage.stripCount, 0);
|
|
70
|
+
assert.equal(firstImage.isTiled(), true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should hasTile for every tile', async () => {
|
|
74
|
+
const [firstImage] = cog.images;
|
|
75
|
+
|
|
76
|
+
for (let x = 0; x < firstImage.tileCount.x; x++) {
|
|
77
|
+
for (let y = 0; y < firstImage.tileCount.y; y++) {
|
|
78
|
+
assert.equal(await firstImage.hasTile(x, y), true);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
86
82
|
});
|
|
87
83
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
o(firstImage.isTiled()).equals(true);
|
|
117
|
-
|
|
118
|
-
const img = cog.getImage(4);
|
|
119
|
-
o(img.tileCount).deepEquals({ x: 2, y: 2 });
|
|
120
|
-
});
|
|
84
|
+
describe('Cog.Big', () => {
|
|
85
|
+
it('should support reading from memory', async () => {
|
|
86
|
+
const fullSource = new TestFileSource(new URL('../../data/sparse.tiff', import.meta.url));
|
|
87
|
+
|
|
88
|
+
const cog = new CogTiff(fullSource);
|
|
89
|
+
await cog.init();
|
|
90
|
+
|
|
91
|
+
const [firstImage] = cog.images;
|
|
92
|
+
assert.equal(firstImage.stripCount, 0);
|
|
93
|
+
assert.equal(firstImage.isTiled(), true);
|
|
94
|
+
|
|
95
|
+
const img = cog.images[4];
|
|
96
|
+
assert.deepEqual(img.tileCount, { x: 2, y: 2 });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should read using a memory source', async () => {
|
|
100
|
+
const bytes = await fs.readFile(new URL('../../data/sparse.tiff', import.meta.url));
|
|
101
|
+
const source = new SourceMemory(bytes.buffer);
|
|
102
|
+
const cog = new CogTiff(source);
|
|
103
|
+
await cog.init();
|
|
104
|
+
|
|
105
|
+
const [firstImage] = cog.images;
|
|
106
|
+
assert.equal(firstImage.stripCount, 0);
|
|
107
|
+
assert.equal(firstImage.isTiled(), true);
|
|
108
|
+
|
|
109
|
+
const img = cog.images[4];
|
|
110
|
+
assert.deepEqual(img.tileCount, { x: 2, y: 2 });
|
|
111
|
+
});
|
|
121
112
|
});
|
|
122
113
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
114
|
+
describe('Cog.Sparse', () => {
|
|
115
|
+
const cogSourceFile = new TestFileSource(new URL('../../data/sparse.tiff', import.meta.url));
|
|
116
|
+
const cog = new CogTiff(cogSourceFile);
|
|
117
|
+
|
|
118
|
+
it('should read metadata', async () => {
|
|
119
|
+
await cog.init();
|
|
120
|
+
assert.equal(cog.images[0].epsg, 2193);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should be geolocated', () => {
|
|
124
|
+
for (const img of cog.images) assert.equal(img.isGeoLocated, true);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should support sparse cogs', async () => {
|
|
128
|
+
const z = 4;
|
|
129
|
+
const img = cog.images[z];
|
|
130
|
+
|
|
131
|
+
const { tileCount } = img;
|
|
132
|
+
assert.deepEqual(tileCount, { x: 2, y: 2 });
|
|
133
|
+
|
|
134
|
+
for (let x = 0; x < tileCount.x; x++) {
|
|
135
|
+
for (let y = 0; y < tileCount.y; y++) {
|
|
136
|
+
const hasTile = await img.hasTile(x, y);
|
|
137
|
+
assert.equal(hasTile, false);
|
|
138
|
+
const tileXy = await img.getTile(x, y);
|
|
139
|
+
const tileXyz = await cog.images[z].getTile(x, y);
|
|
140
|
+
assert.equal(tileXy, null, `Tile x:${x} y:${y} should be empty`);
|
|
141
|
+
assert.equal(tileXyz, null, `Tile x:${x} y:${y} z: ${z} should be empty`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should have ghost options', () => {
|
|
147
|
+
assert.equal(cog.options?.options.size, 6);
|
|
148
|
+
assert.equal(cog.options?.tileLeaderByteSize, ByteSize.UInt32);
|
|
149
|
+
assert.equal(cog.options?.isCogOptimized, true);
|
|
150
|
+
|
|
151
|
+
const entries = [...(cog.options?.options.entries() ?? [])];
|
|
152
|
+
assert.deepEqual(entries, [
|
|
153
|
+
['GDAL_STRUCTURAL_METADATA_SIZE', '000140 bytes'],
|
|
154
|
+
['LAYOUT', 'IFDS_BEFORE_DATA'],
|
|
155
|
+
['BLOCK_ORDER', 'ROW_MAJOR'],
|
|
156
|
+
['BLOCK_LEADER', 'SIZE_AS_UINT4'],
|
|
157
|
+
['BLOCK_TRAILER', 'LAST_4_BYTES_REPEATED'],
|
|
158
|
+
['KNOWN_INCOMPATIBLE_EDITION', 'NO'],
|
|
159
|
+
]);
|
|
160
|
+
});
|
|
170
161
|
});
|
|
171
162
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
163
|
+
describe('CogStrip', () => {
|
|
164
|
+
const cogSourceFile = new TestFileSource(new URL('../../data/rgba8_strip.tiff', import.meta.url));
|
|
165
|
+
const cog = new CogTiff(cogSourceFile);
|
|
166
|
+
|
|
167
|
+
beforeEach(() => cog.init());
|
|
168
|
+
|
|
169
|
+
it('should get origin from all images', () => {
|
|
170
|
+
const baseOrigin = cog.images[0].origin;
|
|
171
|
+
for (const img of cog.images) {
|
|
172
|
+
assert.deepEqual(img.origin, baseOrigin);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should get bounding box from all images', () => {
|
|
177
|
+
const baseOrigin = cog.images[0].bbox;
|
|
178
|
+
for (const img of cog.images) {
|
|
179
|
+
assert.deepEqual(img.bbox, baseOrigin);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should scale image resolution for all images', () => {
|
|
184
|
+
const [resX, resY, resZ] = cog.images[0].resolution;
|
|
185
|
+
for (let i = 0; i < cog.images.length; i++) {
|
|
186
|
+
const img = cog.images[i];
|
|
187
|
+
const scale = 2 ** i; // This tiff is scaled at a factor of two per zoom level
|
|
188
|
+
assert.deepEqual(img.resolution, [resX * scale, resY * scale, resZ]);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should have strip information', async () => {
|
|
193
|
+
const [firstImage] = cog.images;
|
|
194
|
+
assert.equal(firstImage.isTiled(), false);
|
|
195
|
+
assert.equal(firstImage.stripCount, 2);
|
|
196
|
+
|
|
197
|
+
const stripA = await firstImage.getStrip(0);
|
|
198
|
+
assert.equal(stripA?.mimeType, TiffMimeType.Webp);
|
|
199
|
+
assert.equal(stripA?.bytes.byteLength, 152);
|
|
200
|
+
|
|
201
|
+
const stripB = await firstImage.getStrip(1);
|
|
202
|
+
assert.equal(stripB?.mimeType, TiffMimeType.Webp);
|
|
203
|
+
assert.equal(stripB?.bytes.byteLength, 152);
|
|
204
|
+
});
|
|
214
205
|
});
|