@cogeotiff/cli 9.0.7 → 9.1.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/CHANGELOG.md +14 -0
- package/build/commands/fetch-tile.d.ts +20 -0
- package/build/commands/fetch-tile.d.ts.map +1 -0
- package/build/commands/fetch-tile.js +85 -0
- package/build/fs.js +1 -1
- package/build/index.d.ts +26 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/package.json +3 -3
- package/src/commands/fetch-tile.ts +95 -0
- package/src/fs.ts +1 -1
- package/src/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -24,6 +24,20 @@
|
|
|
24
24
|
* dependencies
|
|
25
25
|
* @cogeotiff/core bumped from ^9.1.1 to ^9.1.2
|
|
26
26
|
|
|
27
|
+
## [9.1.0](https://github.com/blacha/cogeotiff/compare/cli-v9.0.7...cli-v9.1.0) (2026-02-20)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* **cli:** trace how a tiff is loaded with fetch-tile ([#1414](https://github.com/blacha/cogeotiff/issues/1414)) ([8a69302](https://github.com/blacha/cogeotiff/commit/8a693021e2c07fd08c6e2470d00106126e5b9f70))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Dependencies
|
|
36
|
+
|
|
37
|
+
* The following workspace dependencies were updated
|
|
38
|
+
* dependencies
|
|
39
|
+
* @cogeotiff/core bumped from ^9.2.0 to ^9.3.0
|
|
40
|
+
|
|
27
41
|
## [9.0.7](https://github.com/blacha/cogeotiff/compare/cli-v9.0.6...cli-v9.0.7) (2026-02-18)
|
|
28
42
|
|
|
29
43
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const commandFetchTile: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
|
|
2
|
+
parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<{
|
|
3
|
+
tile: string;
|
|
4
|
+
output: URL | undefined;
|
|
5
|
+
readSize: number;
|
|
6
|
+
path: URL;
|
|
7
|
+
verbose: boolean;
|
|
8
|
+
extraVerbose: boolean;
|
|
9
|
+
}>>;
|
|
10
|
+
} & import("cmd-ts/dist/cjs/helpdoc.js").PrintHelp & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & import("cmd-ts/dist/cjs/helpdoc.js").Named & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Versioned> & import("cmd-ts/dist/cjs/argparser.js").Register & import("cmd-ts/dist/cjs/runner.js").Handling<{
|
|
11
|
+
tile: string;
|
|
12
|
+
output: URL | undefined;
|
|
13
|
+
readSize: number;
|
|
14
|
+
path: URL;
|
|
15
|
+
verbose: boolean;
|
|
16
|
+
extraVerbose: boolean;
|
|
17
|
+
}, Promise<void>> & {
|
|
18
|
+
run(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<Promise<void>>>;
|
|
19
|
+
} & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Versioned & import("cmd-ts/dist/cjs/helpdoc.js").Descriptive & import("cmd-ts/dist/cjs/helpdoc.js").Aliased>;
|
|
20
|
+
//# sourceMappingURL=fetch-tile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-tile.d.ts","sourceRoot":"","sources":["../../src/commands/fetch-tile.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;6JAsF3B,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { fsa } from '@chunkd/fs';
|
|
2
|
+
import { Tiff, TiffTag } from '@cogeotiff/core';
|
|
3
|
+
import { command, number, option, optional, positional, string } from 'cmd-ts';
|
|
4
|
+
import { DefaultArgs, Url } from '../common.js';
|
|
5
|
+
import { FetchLog } from '../fs.js';
|
|
6
|
+
import { setupLogger } from '../log.js';
|
|
7
|
+
export const commandFetchTile = command({
|
|
8
|
+
name: 'fetch-tile',
|
|
9
|
+
args: {
|
|
10
|
+
...DefaultArgs,
|
|
11
|
+
tile: option({
|
|
12
|
+
short: 't',
|
|
13
|
+
long: 'tile',
|
|
14
|
+
description: 'tile to process "z-x-y" multiple tiles can be fetched by comma separating them "z-x-y,z-x-y"',
|
|
15
|
+
type: string,
|
|
16
|
+
defaultValue: () => '0-0-0',
|
|
17
|
+
}),
|
|
18
|
+
output: option({ short: 'o', long: 'output', type: optional(Url) }),
|
|
19
|
+
readSize: option({
|
|
20
|
+
long: 'read-size',
|
|
21
|
+
description: 'Size of bytes to read for the tile, default is to read the whole tile in KB',
|
|
22
|
+
type: number,
|
|
23
|
+
defaultValue: () => 16,
|
|
24
|
+
}),
|
|
25
|
+
path: positional({ type: Url, description: 'File to process' }),
|
|
26
|
+
},
|
|
27
|
+
async handler(args) {
|
|
28
|
+
const logger = setupLogger(args);
|
|
29
|
+
if (logger.level === 'warn')
|
|
30
|
+
logger.level = 'info';
|
|
31
|
+
fsa.middleware = [FetchLog]; // reset middleware so we don't cache or chunk requests
|
|
32
|
+
const tiles = args.tile.split(',').map((t) => t.split('-').map((s) => parseInt(s, 10)));
|
|
33
|
+
for (const t of tiles) {
|
|
34
|
+
if (isNaN(t[0]) || isNaN(t[1]) || isNaN(t[2])) {
|
|
35
|
+
logger.error('Invalid tile format, expected {z-x-y}', { tile: args.tile });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const tiff = new Tiff(fsa.source(args.path));
|
|
40
|
+
tiff.defaultReadSize = args.readSize * 1024;
|
|
41
|
+
logger.debug('Tiff:load', { path: args.path.href });
|
|
42
|
+
const loadStart = performance.now();
|
|
43
|
+
await tiff.init();
|
|
44
|
+
const loadEnd = performance.now();
|
|
45
|
+
logger.info('Tiff:loaded', {
|
|
46
|
+
path: args.path.href,
|
|
47
|
+
fetches: FetchLog.fetches.length,
|
|
48
|
+
bytesRead: FetchLog.bytesRead,
|
|
49
|
+
duration: loadEnd - loadStart,
|
|
50
|
+
});
|
|
51
|
+
for (const i of tiff.images) {
|
|
52
|
+
const byteCount = i.tags.get(TiffTag.TileByteCounts);
|
|
53
|
+
const tileOffsets = i.tags.get(TiffTag.TileOffsets);
|
|
54
|
+
logger.debug('Image:TileInfo', {
|
|
55
|
+
image: i.id,
|
|
56
|
+
toLoaded: tileOffsets?.isLoaded,
|
|
57
|
+
bcLoaded: byteCount?.isLoaded,
|
|
58
|
+
bcOffset: byteCount?.dataOffset,
|
|
59
|
+
toOffset: tileOffsets?.dataOffset,
|
|
60
|
+
count: byteCount?.count,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
for (const t of tiles) {
|
|
64
|
+
const [z, x, y] = t;
|
|
65
|
+
if (tiff.images.length < z || z < 0) {
|
|
66
|
+
logger.error('Invalid tile z level', { z, max: tiff.images.length });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const image = tiff.images[z];
|
|
70
|
+
const tile = await image.getTile(x, y);
|
|
71
|
+
if (tile == null) {
|
|
72
|
+
logger.error('Failed to fetch tile', { z, x, y });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
logger.info('Tile:fetched', {
|
|
76
|
+
z,
|
|
77
|
+
x,
|
|
78
|
+
y,
|
|
79
|
+
bytes: tile.bytes.byteLength,
|
|
80
|
+
fetches: FetchLog.fetches.length,
|
|
81
|
+
bytesRead: FetchLog.bytesRead,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
});
|
package/build/fs.js
CHANGED
|
@@ -4,7 +4,7 @@ export const FetchLog = {
|
|
|
4
4
|
fetch(req, next) {
|
|
5
5
|
this.fetches.push(req);
|
|
6
6
|
this.bytesRead += req.length ?? 0;
|
|
7
|
-
logger.
|
|
7
|
+
logger.debug('Tiff:fetch', { href: req.source.url.href, offset: req.offset, length: req.length });
|
|
8
8
|
return next(req);
|
|
9
9
|
},
|
|
10
10
|
reset() {
|
package/build/index.d.ts
CHANGED
|
@@ -9,6 +9,16 @@ export declare const cmd: Partial<import("cmd-ts/dist/cjs/argparser.js").Registe
|
|
|
9
9
|
verbose: boolean;
|
|
10
10
|
extraVerbose: boolean;
|
|
11
11
|
};
|
|
12
|
+
} | {
|
|
13
|
+
command: "fetch-tile";
|
|
14
|
+
args: {
|
|
15
|
+
tile: string;
|
|
16
|
+
output: URL | undefined;
|
|
17
|
+
readSize: number;
|
|
18
|
+
path: URL;
|
|
19
|
+
verbose: boolean;
|
|
20
|
+
extraVerbose: boolean;
|
|
21
|
+
};
|
|
12
22
|
} | {
|
|
13
23
|
command: "info";
|
|
14
24
|
args: {
|
|
@@ -31,6 +41,16 @@ export declare const cmd: Partial<import("cmd-ts/dist/cjs/argparser.js").Registe
|
|
|
31
41
|
verbose: boolean;
|
|
32
42
|
extraVerbose: boolean;
|
|
33
43
|
};
|
|
44
|
+
} | {
|
|
45
|
+
command: "fetch-tile";
|
|
46
|
+
args: {
|
|
47
|
+
tile: string;
|
|
48
|
+
output: URL | undefined;
|
|
49
|
+
readSize: number;
|
|
50
|
+
path: URL;
|
|
51
|
+
verbose: boolean;
|
|
52
|
+
extraVerbose: boolean;
|
|
53
|
+
};
|
|
34
54
|
} | {
|
|
35
55
|
command: "info";
|
|
36
56
|
args: {
|
|
@@ -45,6 +65,9 @@ export declare const cmd: Partial<import("cmd-ts/dist/cjs/argparser.js").Registe
|
|
|
45
65
|
}, {
|
|
46
66
|
command: "dump";
|
|
47
67
|
value: Promise<void>;
|
|
68
|
+
} | {
|
|
69
|
+
command: "fetch-tile";
|
|
70
|
+
value: Promise<void>;
|
|
48
71
|
} | {
|
|
49
72
|
command: "info";
|
|
50
73
|
value: Promise<void>;
|
|
@@ -52,6 +75,9 @@ export declare const cmd: Partial<import("cmd-ts/dist/cjs/argparser.js").Registe
|
|
|
52
75
|
run(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<{
|
|
53
76
|
command: "dump";
|
|
54
77
|
value: Promise<void>;
|
|
78
|
+
} | {
|
|
79
|
+
command: "fetch-tile";
|
|
80
|
+
value: Promise<void>;
|
|
55
81
|
} | {
|
|
56
82
|
command: "info";
|
|
57
83
|
value: Promise<void>;
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQd,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { subcommands } from 'cmd-ts';
|
|
2
2
|
import { commandDump } from './commands/dump.js';
|
|
3
|
+
import { commandFetchTile } from './commands/fetch-tile.js';
|
|
3
4
|
import { commandInfo } from './commands/info.js';
|
|
4
5
|
export const cmd = subcommands({
|
|
5
6
|
name: 'cogeotiff',
|
|
@@ -7,5 +8,6 @@ export const cmd = subcommands({
|
|
|
7
8
|
cmds: {
|
|
8
9
|
info: commandInfo,
|
|
9
10
|
dump: commandDump,
|
|
11
|
+
'fetch-tile': commandFetchTile,
|
|
10
12
|
},
|
|
11
13
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogeotiff/cli",
|
|
3
|
-
"version": "9.0
|
|
3
|
+
"version": "9.1.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/blacha/cogeotiff.git",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@chunkd/fs-aws": "^11.0.2",
|
|
22
22
|
"@chunkd/middleware": "^11.0.0",
|
|
23
23
|
"@chunkd/source": "^11.0.0",
|
|
24
|
-
"@cogeotiff/core": "^9.
|
|
24
|
+
"@cogeotiff/core": "^9.3.0",
|
|
25
25
|
"@linzjs/tracing": "^1.1.1",
|
|
26
26
|
"ansi-colors": "^4.1.1",
|
|
27
27
|
"cmd-ts": "^0.14.3",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "82b82e9d9f8996dfb0cb48827c143e134acc9865"
|
|
39
39
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { fsa } from '@chunkd/fs';
|
|
2
|
+
import { TagOffset, Tiff, TiffTag } from '@cogeotiff/core';
|
|
3
|
+
import { command, number, option, optional, positional, string } from 'cmd-ts';
|
|
4
|
+
|
|
5
|
+
import { DefaultArgs, Url } from '../common.js';
|
|
6
|
+
import { FetchLog } from '../fs.js';
|
|
7
|
+
import { setupLogger } from '../log.js';
|
|
8
|
+
|
|
9
|
+
export const commandFetchTile = command({
|
|
10
|
+
name: 'fetch-tile',
|
|
11
|
+
args: {
|
|
12
|
+
...DefaultArgs,
|
|
13
|
+
tile: option({
|
|
14
|
+
short: 't',
|
|
15
|
+
long: 'tile',
|
|
16
|
+
description: 'tile to process "z-x-y" multiple tiles can be fetched by comma separating them "z-x-y,z-x-y"',
|
|
17
|
+
type: string,
|
|
18
|
+
defaultValue: () => '0-0-0',
|
|
19
|
+
}),
|
|
20
|
+
output: option({ short: 'o', long: 'output', type: optional(Url) }),
|
|
21
|
+
readSize: option({
|
|
22
|
+
long: 'read-size',
|
|
23
|
+
description: 'Size of bytes to read for the tile, default is to read the whole tile in KB',
|
|
24
|
+
type: number,
|
|
25
|
+
defaultValue: () => 16,
|
|
26
|
+
}),
|
|
27
|
+
path: positional({ type: Url, description: 'File to process' }),
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
async handler(args) {
|
|
31
|
+
const logger = setupLogger(args);
|
|
32
|
+
if (logger.level === 'warn') logger.level = 'info';
|
|
33
|
+
fsa.middleware = [FetchLog]; // reset middleware so we don't cache or chunk requests
|
|
34
|
+
|
|
35
|
+
const tiles = args.tile.split(',').map((t) => t.split('-').map((s) => parseInt(s, 10)));
|
|
36
|
+
for (const t of tiles) {
|
|
37
|
+
if (isNaN(t[0]) || isNaN(t[1]) || isNaN(t[2])) {
|
|
38
|
+
logger.error('Invalid tile format, expected {z-x-y}', { tile: args.tile });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const tiff = new Tiff(fsa.source(args.path));
|
|
44
|
+
tiff.defaultReadSize = args.readSize * 1024;
|
|
45
|
+
|
|
46
|
+
logger.debug('Tiff:load', { path: args.path.href });
|
|
47
|
+
const loadStart = performance.now();
|
|
48
|
+
await tiff.init();
|
|
49
|
+
const loadEnd = performance.now();
|
|
50
|
+
logger.info('Tiff:loaded', {
|
|
51
|
+
path: args.path.href,
|
|
52
|
+
fetches: FetchLog.fetches.length,
|
|
53
|
+
bytesRead: FetchLog.bytesRead,
|
|
54
|
+
duration: loadEnd - loadStart,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
for (const i of tiff.images) {
|
|
58
|
+
const byteCount = i.tags.get(TiffTag.TileByteCounts) as TagOffset | undefined;
|
|
59
|
+
const tileOffsets = i.tags.get(TiffTag.TileOffsets) as TagOffset | undefined;
|
|
60
|
+
logger.debug('Image:TileInfo', {
|
|
61
|
+
image: i.id,
|
|
62
|
+
toLoaded: tileOffsets?.isLoaded,
|
|
63
|
+
bcLoaded: byteCount?.isLoaded,
|
|
64
|
+
bcOffset: byteCount?.dataOffset,
|
|
65
|
+
toOffset: tileOffsets?.dataOffset,
|
|
66
|
+
count: byteCount?.count,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const t of tiles) {
|
|
71
|
+
const [z, x, y] = t;
|
|
72
|
+
|
|
73
|
+
if (tiff.images.length < z || z < 0) {
|
|
74
|
+
logger.error('Invalid tile z level', { z, max: tiff.images.length });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const image = tiff.images[z];
|
|
79
|
+
const tile = await image.getTile(x, y);
|
|
80
|
+
if (tile == null) {
|
|
81
|
+
logger.error('Failed to fetch tile', { z, x, y });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
logger.info('Tile:fetched', {
|
|
86
|
+
z,
|
|
87
|
+
x,
|
|
88
|
+
y,
|
|
89
|
+
bytes: tile.bytes.byteLength,
|
|
90
|
+
fetches: FetchLog.fetches.length,
|
|
91
|
+
bytesRead: FetchLog.bytesRead,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
});
|
package/src/fs.ts
CHANGED
|
@@ -7,7 +7,7 @@ export const FetchLog: SourceMiddleware & { reset(): void; fetches: SourceReques
|
|
|
7
7
|
fetch(req: SourceRequest, next: SourceCallback) {
|
|
8
8
|
this.fetches.push(req);
|
|
9
9
|
this.bytesRead += req.length ?? 0;
|
|
10
|
-
logger.
|
|
10
|
+
logger.debug('Tiff:fetch', { href: req.source.url.href, offset: req.offset, length: req.length });
|
|
11
11
|
return next(req);
|
|
12
12
|
},
|
|
13
13
|
reset() {
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { subcommands } from 'cmd-ts';
|
|
2
2
|
|
|
3
3
|
import { commandDump } from './commands/dump.js';
|
|
4
|
+
import { commandFetchTile } from './commands/fetch-tile.js';
|
|
4
5
|
import { commandInfo } from './commands/info.js';
|
|
5
6
|
|
|
6
7
|
export const cmd = subcommands({
|
|
@@ -9,5 +10,6 @@ export const cmd = subcommands({
|
|
|
9
10
|
cmds: {
|
|
10
11
|
info: commandInfo,
|
|
11
12
|
dump: commandDump,
|
|
13
|
+
'fetch-tile': commandFetchTile,
|
|
12
14
|
},
|
|
13
15
|
});
|