@developmentseed/geotiff 0.3.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/dist/api.d.ts +34 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +84 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/array.d.ts +75 -0
  8. package/dist/array.d.ts.map +1 -0
  9. package/dist/array.js +141 -0
  10. package/dist/array.js.map +1 -0
  11. package/dist/codecs/canvas.d.ts +3 -0
  12. package/dist/codecs/canvas.d.ts.map +1 -0
  13. package/dist/codecs/canvas.js +32 -0
  14. package/dist/codecs/canvas.js.map +1 -0
  15. package/dist/codecs/decompression-stream.d.ts +6 -0
  16. package/dist/codecs/decompression-stream.d.ts.map +1 -0
  17. package/dist/codecs/decompression-stream.js +19 -0
  18. package/dist/codecs/decompression-stream.js.map +1 -0
  19. package/dist/codecs/deflate.d.ts +2 -0
  20. package/dist/codecs/deflate.d.ts.map +1 -0
  21. package/dist/codecs/deflate.js +5 -0
  22. package/dist/codecs/deflate.js.map +1 -0
  23. package/dist/codecs/lerc.d.ts +3 -0
  24. package/dist/codecs/lerc.d.ts.map +1 -0
  25. package/dist/codecs/lerc.js +16 -0
  26. package/dist/codecs/lerc.js.map +1 -0
  27. package/dist/codecs/lzw.d.ts +3 -0
  28. package/dist/codecs/lzw.d.ts.map +1 -0
  29. package/dist/codecs/lzw.js +8 -0
  30. package/dist/codecs/lzw.js.map +1 -0
  31. package/dist/codecs/predictor.d.ts +15 -0
  32. package/dist/codecs/predictor.d.ts.map +1 -0
  33. package/dist/codecs/predictor.js +88 -0
  34. package/dist/codecs/predictor.js.map +1 -0
  35. package/dist/colormap.d.ts +10 -0
  36. package/dist/colormap.d.ts.map +1 -0
  37. package/dist/colormap.js +31 -0
  38. package/dist/colormap.js.map +1 -0
  39. package/dist/crs.d.ts +86 -0
  40. package/dist/crs.d.ts.map +1 -0
  41. package/dist/crs.js +462 -0
  42. package/dist/crs.js.map +1 -0
  43. package/dist/decode/api.d.ts +28 -0
  44. package/dist/decode/api.d.ts.map +1 -0
  45. package/dist/decode/api.js +80 -0
  46. package/dist/decode/api.js.map +1 -0
  47. package/dist/decode.d.ts +34 -0
  48. package/dist/decode.d.ts.map +1 -0
  49. package/dist/decode.js +84 -0
  50. package/dist/decode.js.map +1 -0
  51. package/dist/fetch.d.ts +27 -0
  52. package/dist/fetch.d.ts.map +1 -0
  53. package/dist/fetch.js +116 -0
  54. package/dist/fetch.js.map +1 -0
  55. package/dist/geotiff.d.ts +116 -0
  56. package/dist/geotiff.d.ts.map +1 -0
  57. package/dist/geotiff.js +239 -0
  58. package/dist/geotiff.js.map +1 -0
  59. package/dist/ifd.d.ts +84 -0
  60. package/dist/ifd.d.ts.map +1 -0
  61. package/dist/ifd.js +113 -0
  62. package/dist/ifd.js.map +1 -0
  63. package/dist/index.d.ts +10 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +6 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/overview.d.ts +55 -0
  68. package/dist/overview.d.ts.map +1 -0
  69. package/dist/overview.js +78 -0
  70. package/dist/overview.js.map +1 -0
  71. package/dist/tile-matrix-set.d.ts +36 -0
  72. package/dist/tile-matrix-set.d.ts.map +1 -0
  73. package/dist/tile-matrix-set.js +87 -0
  74. package/dist/tile-matrix-set.js.map +1 -0
  75. package/dist/tile.d.ts +11 -0
  76. package/dist/tile.d.ts.map +1 -0
  77. package/dist/tile.js +2 -0
  78. package/dist/tile.js.map +1 -0
  79. package/dist/transform.d.ts +28 -0
  80. package/dist/transform.d.ts.map +1 -0
  81. package/dist/transform.js +51 -0
  82. package/dist/transform.js.map +1 -0
  83. package/dist/tsconfig.tsbuildinfo +1 -0
  84. package/package.json +59 -0
package/dist/decode.js ADDED
@@ -0,0 +1,84 @@
1
+ import { Compression, SampleFormat } from "@cogeotiff/core";
2
+ import { decode as decodeViaCanvas } from "./codecs/canvas.js";
3
+ import { applyPredictor } from "./codecs/predictor.js";
4
+ async function decodeUncompressed(bytes) {
5
+ return bytes;
6
+ }
7
+ export const registry = new Map();
8
+ registry.set(Compression.None, () => Promise.resolve(decodeUncompressed));
9
+ registry.set(Compression.Deflate, () => import("./codecs/deflate.js").then((m) => m.decode));
10
+ registry.set(Compression.DeflateOther, () => import("./codecs/deflate.js").then((m) => m.decode));
11
+ registry.set(Compression.Lzw, () => import("./codecs/lzw.js").then((m) => m.decode));
12
+ // registry.set(Compression.Zstd, () =>
13
+ // import("../codecs/zstd.js").then((m) => m.decode),
14
+ // );
15
+ // registry.set(Compression.Lzma, () =>
16
+ // import("../codecs/lzma.js").then((m) => m.decode),
17
+ // );
18
+ // registry.set(Compression.Jp2000, () =>
19
+ // import("../codecs/jp2000.js").then((m) => m.decode),
20
+ // );
21
+ registry.set(Compression.Jpeg, () => Promise.resolve(decodeViaCanvas));
22
+ registry.set(Compression.Jpeg6, () => Promise.resolve(decodeViaCanvas));
23
+ registry.set(Compression.Webp, () => Promise.resolve(decodeViaCanvas));
24
+ registry.set(Compression.Lerc, () => import("./codecs/lerc.js").then((m) => m.decode));
25
+ /**
26
+ * Decode a tile's bytes according to its compression and image metadata.
27
+ */
28
+ export async function decode(bytes, compression, metadata) {
29
+ const loader = registry.get(compression);
30
+ if (!loader) {
31
+ throw new Error(`Unsupported compression: ${compression}`);
32
+ }
33
+ const decoder = await loader();
34
+ const result = await decoder(bytes, metadata);
35
+ if (result instanceof ArrayBuffer) {
36
+ const { predictor, width, height, bitsPerSample, samplesPerPixel, planarConfiguration, } = metadata;
37
+ const predicted = applyPredictor(result, predictor, width, height, bitsPerSample, samplesPerPixel, planarConfiguration);
38
+ return {
39
+ layout: "pixel-interleaved",
40
+ data: toTypedArray(predicted, metadata),
41
+ };
42
+ }
43
+ return result;
44
+ }
45
+ /**
46
+ * Convert a raw ArrayBuffer of pixel data into a typed array based on the
47
+ * sample format and bits per sample. This is used for codecs that return raw
48
+ * bytes.
49
+ */
50
+ function toTypedArray(buffer, metadata) {
51
+ const { sampleFormat, bitsPerSample } = metadata;
52
+ switch (sampleFormat) {
53
+ case SampleFormat.Uint:
54
+ switch (bitsPerSample) {
55
+ case 8:
56
+ return new Uint8Array(buffer);
57
+ case 16:
58
+ return new Uint16Array(buffer);
59
+ case 32:
60
+ return new Uint32Array(buffer);
61
+ }
62
+ break;
63
+ case SampleFormat.Int:
64
+ switch (bitsPerSample) {
65
+ case 8:
66
+ return new Int8Array(buffer);
67
+ case 16:
68
+ return new Int16Array(buffer);
69
+ case 32:
70
+ return new Int32Array(buffer);
71
+ }
72
+ break;
73
+ case SampleFormat.Float:
74
+ switch (bitsPerSample) {
75
+ case 32:
76
+ return new Float32Array(buffer);
77
+ case 64:
78
+ return new Float64Array(buffer);
79
+ }
80
+ break;
81
+ }
82
+ throw new Error(`Unsupported sample format/depth: SampleFormat=${sampleFormat}, BitsPerSample=${bitsPerSample}`);
83
+ }
84
+ //# sourceMappingURL=decode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../src/decode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { TiffImage } from "@cogeotiff/core";
2
+ import type { ProjJson } from "./crs.js";
3
+ import type { CachedTags } from "./ifd.js";
4
+ import type { Tile } from "./tile";
5
+ import type { HasTransform } from "./transform";
6
+ /** Protocol for objects that hold a TIFF reference and can request tiles. */
7
+ interface HasTiffReference extends HasTransform {
8
+ readonly cachedTags: CachedTags;
9
+ /** The data Image File Directory (IFD) */
10
+ readonly image: TiffImage;
11
+ /** The mask Image File Directory (IFD), if any. */
12
+ readonly maskImage: TiffImage | null;
13
+ /** The coordinate reference system. */
14
+ readonly crs: number | ProjJson;
15
+ /** The height of tiles in pixels. */
16
+ readonly tileHeight: number;
17
+ /** The width of tiles in pixels. */
18
+ readonly tileWidth: number;
19
+ /** The nodata value for the image, if any. */
20
+ readonly nodata: number | null;
21
+ }
22
+ export declare function fetchTile(self: HasTiffReference, x: number, y: number, options?: {
23
+ boundless?: boolean;
24
+ signal?: AbortSignal;
25
+ }): Promise<Tile>;
26
+ export {};
27
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,6EAA6E;AAC7E,UAAU,gBAAiB,SAAQ,YAAY;IAC7C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAEhC,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAE1B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAErC,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC;IAEhC,qCAAqC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,oCAAoC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,gBAAgB,EACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAC1D,OAAO,CAAC,IAAI,CAAC,CA0Df"}
package/dist/fetch.js ADDED
@@ -0,0 +1,116 @@
1
+ import { TiffTag } from "@cogeotiff/core";
2
+ import { compose, translation } from "@developmentseed/affine";
3
+ import { decode } from "./decode.js";
4
+ export async function fetchTile(self, x, y, options = {}) {
5
+ if (self.maskImage != null) {
6
+ throw new Error("Mask fetching not implemented yet");
7
+ }
8
+ const tile = await self.image.getTile(x, y, options);
9
+ if (tile === null) {
10
+ throw new Error("Tile not found");
11
+ }
12
+ const { bitsPerSample: bitsPerSamples, predictor, planarConfiguration, sampleFormat: sampleFormats, } = self.cachedTags;
13
+ const { bytes, compression } = tile;
14
+ const { sampleFormat, bitsPerSample } = getUniqueSampleFormat(sampleFormats, bitsPerSamples);
15
+ const tileTransform = compose(self.transform, translation(x * self.tileWidth, y * self.tileHeight));
16
+ const samplesPerPixel = self.image.value(TiffTag.SamplesPerPixel) ?? 1;
17
+ const decodedPixels = await decode(bytes, compression, {
18
+ sampleFormat,
19
+ bitsPerSample,
20
+ samplesPerPixel,
21
+ width: self.tileWidth,
22
+ height: self.tileHeight,
23
+ predictor,
24
+ planarConfiguration,
25
+ });
26
+ const array = {
27
+ ...decodedPixels,
28
+ count: samplesPerPixel,
29
+ height: self.tileHeight,
30
+ width: self.tileWidth,
31
+ mask: null,
32
+ transform: tileTransform,
33
+ crs: self.crs,
34
+ nodata: self.nodata,
35
+ };
36
+ return {
37
+ x,
38
+ y,
39
+ array: options.boundless === false
40
+ ? clipToImageBounds(self, x, y, array)
41
+ : array,
42
+ };
43
+ }
44
+ /**
45
+ * Clip a decoded tile array to the valid image bounds.
46
+ *
47
+ * Edge tiles in a COG are always encoded at the full tile size, with the
48
+ * out-of-bounds region zero-padded. When `boundless=false` is requested, this
49
+ * function copies only the valid pixel sub-rectangle into a new typed array,
50
+ * returning a `RasterArray` whose `width`/`height` match the actual image
51
+ * content rather than the tile dimensions.
52
+ *
53
+ * Interior tiles (where the tile fits entirely within the image) are returned
54
+ * unchanged.
55
+ */
56
+ function clipToImageBounds(self, x, y, array) {
57
+ const { width: clippedWidth, height: clippedHeight } = self.image.getTileBounds(x, y);
58
+ // Interior tile — nothing to clip.
59
+ if (clippedWidth === self.tileWidth && clippedHeight === self.tileHeight) {
60
+ return array;
61
+ }
62
+ if (array.layout === "pixel-interleaved") {
63
+ const { count, data } = array;
64
+ const Ctor = data.constructor;
65
+ const clipped = new Ctor(clippedWidth * clippedHeight * count);
66
+ for (let r = 0; r < clippedHeight; r++) {
67
+ const srcOffset = r * self.tileWidth * count;
68
+ const dstOffset = r * clippedWidth * count;
69
+ clipped.set(data.subarray(srcOffset, srcOffset + clippedWidth * count), dstOffset);
70
+ }
71
+ return {
72
+ ...array,
73
+ width: clippedWidth,
74
+ height: clippedHeight,
75
+ data: clipped,
76
+ };
77
+ }
78
+ // band-separate
79
+ const { bands } = array;
80
+ const Ctor = bands[0].constructor;
81
+ const clippedBands = bands.map((band) => {
82
+ const clipped = new Ctor(clippedWidth * clippedHeight);
83
+ for (let r = 0; r < clippedHeight; r++) {
84
+ const srcOffset = r * self.tileWidth;
85
+ const dstOffset = r * clippedWidth;
86
+ clipped.set(band.subarray(srcOffset, srcOffset + clippedWidth), dstOffset);
87
+ }
88
+ return clipped;
89
+ });
90
+ return {
91
+ ...array,
92
+ width: clippedWidth,
93
+ height: clippedHeight,
94
+ bands: clippedBands,
95
+ };
96
+ }
97
+ function getUniqueSampleFormat(sampleFormats, bitsPerSamples) {
98
+ const uniqueSampleFormats = new Set(sampleFormats);
99
+ const uniqueBitsPerSample = new Set(bitsPerSamples);
100
+ if (uniqueSampleFormats.size > 1) {
101
+ throw new Error("Multiple sample formats are not supported.");
102
+ }
103
+ if (uniqueBitsPerSample.size > 1) {
104
+ throw new Error("Multiple bits per sample values are not supported.");
105
+ }
106
+ const sampleFormat = sampleFormats[0];
107
+ const bitsPerSample = bitsPerSamples[0];
108
+ if (sampleFormat === undefined || bitsPerSample === undefined) {
109
+ throw new Error("SampleFormat and BitsPerSample arrays cannot be empty.");
110
+ }
111
+ return {
112
+ sampleFormat,
113
+ bitsPerSample,
114
+ };
115
+ }
116
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import type { Source, TiffImage } from "@cogeotiff/core";
2
+ import { Tiff } from "@cogeotiff/core";
3
+ import type { Affine } from "@developmentseed/affine";
4
+ import type { ProjJson } from "./crs.js";
5
+ import type { CachedTags, GeoKeyDirectory } from "./ifd.js";
6
+ import { Overview } from "./overview.js";
7
+ import type { Tile } from "./tile.js";
8
+ /**
9
+ * A higher-level GeoTIFF abstraction built on @cogeotiff/core.
10
+ *
11
+ * Separates data IFDs from mask IFDs, pairs them by resolution level,
12
+ * and exposes sorted overviews. Mirrors the Python async-geotiff API.
13
+ *
14
+ * Construct via `GeoTIFF.open(source)` or `GeoTIFF.fromTiff(tiff)`.
15
+ */
16
+ export declare class GeoTIFF {
17
+ /**
18
+ * Reduced-resolution overview levels, sorted finest-to-coarsest.
19
+ *
20
+ * Does not include the full-resolution image — use `fetchTile` / methods
21
+ * on the GeoTIFF instance itself for that.
22
+ */
23
+ readonly overviews: Overview[];
24
+ /** A cached CRS value. */
25
+ private _crs?;
26
+ /** Cached TIFF tags that are pre-fetched when opening the GeoTIFF. */
27
+ readonly cachedTags: CachedTags;
28
+ /** The underlying Tiff instance. */
29
+ readonly tiff: Tiff;
30
+ /** The primary (full-resolution) TiffImage. */
31
+ readonly image: TiffImage;
32
+ /** The mask IFD of the full-resolution GeoTIFF, if any. */
33
+ readonly maskImage: TiffImage | null;
34
+ /** The GeoKeyDirectory of the primary IFD. */
35
+ readonly gkd: GeoKeyDirectory;
36
+ private constructor();
37
+ /**
38
+ * Open a GeoTIFF from a @cogeotiff/core Source.
39
+ *
40
+ * This creates and initialises the underlying Tiff, then classifies IFDs.
41
+ */
42
+ static open(source: Source): Promise<GeoTIFF>;
43
+ /**
44
+ * Create a GeoTIFF from an already-initialised Tiff instance.
45
+ *
46
+ * All IFDs are walked; mask IFDs are matched to data IFDs by matching
47
+ * (width, height). Overviews are sorted from finest to coarsest resolution.
48
+ */
49
+ static fromTiff(tiff: Tiff): Promise<GeoTIFF>;
50
+ static fromArrayBuffer(input: ArrayBuffer): Promise<GeoTIFF>;
51
+ static fromUrl(url: string | URL, { chunkSize, cacheSize, }?: {
52
+ chunkSize?: number;
53
+ cacheSize?: number;
54
+ }): Promise<GeoTIFF>;
55
+ /**
56
+ * The CRS parsed from the GeoKeyDirectory.
57
+ *
58
+ * Returns an EPSG code (number) for EPSG-coded CRSes, or a PROJJSON object
59
+ * for user-defined CRSes. The result is cached after the first access.
60
+ *
61
+ * See also {@link GeoTIFF.epsg} for the EPSG code directly from the TIFF tags.
62
+ */
63
+ get crs(): number | ProjJson;
64
+ /** Image width in pixels. */
65
+ get width(): number;
66
+ /** Image height in pixels. */
67
+ get height(): number;
68
+ /** Tile width in pixels. */
69
+ get tileWidth(): number;
70
+ /** Tile height in pixels. */
71
+ get tileHeight(): number;
72
+ /** The NoData value, or null if not set. */
73
+ get nodata(): number | null;
74
+ /** Whether the primary image is tiled. */
75
+ get isTiled(): boolean;
76
+ /** Number of bands (samples per pixel). */
77
+ get count(): number;
78
+ /** Bounding box [minX, minY, maxX, maxY] in the CRS. */
79
+ get bbox(): [number, number, number, number];
80
+ /**
81
+ * Return the dataset's georeferencing transformation matrix.
82
+ */
83
+ get transform(): Affine;
84
+ /** Fetch a single tile from the full-resolution image. */
85
+ fetchTile(x: number, y: number, options?: {
86
+ boundless?: boolean;
87
+ signal?: AbortSignal;
88
+ }): Promise<Tile>;
89
+ /**
90
+ * Get the (row, col) pixel index containing the geographic coordinate (x, y).
91
+ *
92
+ * @param x x coordinate in the CRS.
93
+ * @param y y coordinate in the CRS.
94
+ * @param op Rounding function applied to fractional pixel indices.
95
+ * Defaults to Math.floor.
96
+ * @returns [row, col] pixel indices.
97
+ */
98
+ index(x: number, y: number, op?: (n: number) => number): [number, number];
99
+ /**
100
+ * Get the geographic (x, y) coordinate of the pixel at (row, col).
101
+ *
102
+ * @param row Pixel row.
103
+ * @param col Pixel column.
104
+ * @param offset Which part of the pixel to return. Defaults to "center".
105
+ * @returns [x, y] in the CRS.
106
+ */
107
+ xy(row: number, col: number, offset?: "center" | "ul" | "ur" | "ll" | "lr"): [number, number];
108
+ }
109
+ /**
110
+ * Determine whether a TiffImage is a mask IFD.
111
+ *
112
+ * A mask IFD has SubFileType with the Mask bit set (value 4) AND
113
+ * PhotometricInterpretation === Mask (4).
114
+ */
115
+ export declare function isMaskIfd(image: TiffImage): boolean;
116
+ //# sourceMappingURL=geotiff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geotiff.d.ts","sourceRoot":"","sources":["../src/geotiff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,239 @@
1
+ import { SourceCache } from "@chunkd/middleware";
2
+ import { SourceChunk } from "@chunkd/middleware/build/src/middleware/chunk.js";
3
+ import { SourceView } from "@chunkd/source";
4
+ import { SourceHttp } from "@chunkd/source-http";
5
+ import { SourceMemory } from "@chunkd/source-memory";
6
+ import { Photometric, SubFileType, Tiff, TiffTag } from "@cogeotiff/core";
7
+ import { crsFromGeoKeys } from "./crs.js";
8
+ import { fetchTile } from "./fetch.js";
9
+ import { extractGeoKeyDirectory, prefetchTags } from "./ifd.js";
10
+ import { Overview } from "./overview.js";
11
+ import { index, xy } from "./transform.js";
12
+ /**
13
+ * A higher-level GeoTIFF abstraction built on @cogeotiff/core.
14
+ *
15
+ * Separates data IFDs from mask IFDs, pairs them by resolution level,
16
+ * and exposes sorted overviews. Mirrors the Python async-geotiff API.
17
+ *
18
+ * Construct via `GeoTIFF.open(source)` or `GeoTIFF.fromTiff(tiff)`.
19
+ */
20
+ export class GeoTIFF {
21
+ /**
22
+ * Reduced-resolution overview levels, sorted finest-to-coarsest.
23
+ *
24
+ * Does not include the full-resolution image — use `fetchTile` / methods
25
+ * on the GeoTIFF instance itself for that.
26
+ */
27
+ overviews;
28
+ /** A cached CRS value. */
29
+ _crs;
30
+ /** Cached TIFF tags that are pre-fetched when opening the GeoTIFF. */
31
+ cachedTags;
32
+ /** The underlying Tiff instance. */
33
+ tiff;
34
+ /** The primary (full-resolution) TiffImage. */
35
+ image;
36
+ /** The mask IFD of the full-resolution GeoTIFF, if any. */
37
+ maskImage;
38
+ /** The GeoKeyDirectory of the primary IFD. */
39
+ gkd;
40
+ constructor(tiff, image, maskImage, gkd, overviews, cachedTags) {
41
+ this.tiff = tiff;
42
+ this.image = image;
43
+ this.maskImage = maskImage;
44
+ this.gkd = gkd;
45
+ this.overviews = overviews;
46
+ this.cachedTags = cachedTags;
47
+ }
48
+ /**
49
+ * Open a GeoTIFF from a @cogeotiff/core Source.
50
+ *
51
+ * This creates and initialises the underlying Tiff, then classifies IFDs.
52
+ */
53
+ static async open(source) {
54
+ const tiff = await Tiff.create(source);
55
+ return GeoTIFF.fromTiff(tiff);
56
+ }
57
+ /**
58
+ * Create a GeoTIFF from an already-initialised Tiff instance.
59
+ *
60
+ * All IFDs are walked; mask IFDs are matched to data IFDs by matching
61
+ * (width, height). Overviews are sorted from finest to coarsest resolution.
62
+ */
63
+ static async fromTiff(tiff) {
64
+ const images = tiff.images;
65
+ if (images.length === 0) {
66
+ throw new Error("TIFF does not contain any IFDs");
67
+ }
68
+ // Force loading of important tags in sub-images
69
+ // https://github.com/blacha/cogeotiff/blob/4781a6375adf419da9f0319d15c8a67284dfb0c4/packages/core/src/tiff.image.ts#L72-L88
70
+ await Promise.all(images.map((image) => image.init(true)));
71
+ const primaryImage = images[0];
72
+ const gkd = extractGeoKeyDirectory(primaryImage);
73
+ // Classify IFDs (skipping index 0) into data and mask buckets
74
+ // keyed by "width,height".
75
+ const dataIFDs = new Map();
76
+ const maskIFDs = new Map();
77
+ for (let i = 1; i < images.length; i++) {
78
+ const image = images[i];
79
+ const size = image.size;
80
+ const key = `${size.width},${size.height}`;
81
+ if (isMaskIfd(image)) {
82
+ maskIFDs.set(key, image);
83
+ }
84
+ else {
85
+ dataIFDs.set(key, image);
86
+ }
87
+ }
88
+ // Find the primary mask, if any.
89
+ const primaryKey = `${primaryImage.size.width},${primaryImage.size.height}`;
90
+ const primaryMask = maskIFDs.get(primaryKey) ?? null;
91
+ // Build reduced-resolution Overview instances, sorted by pixel count
92
+ // descending (finest first).
93
+ const dataEntries = Array.from(dataIFDs.entries());
94
+ dataEntries.sort((a, b) => {
95
+ const sa = a[1].size;
96
+ const sb = b[1].size;
97
+ return sb.width * sb.height - sa.width * sa.height;
98
+ });
99
+ const cachedTags = await prefetchTags(primaryImage);
100
+ // Two-phase construction: create the GeoTIFF first (with empty overviews),
101
+ // then build Overviews that reference back to it.
102
+ const geotiff = new GeoTIFF(tiff, primaryImage, primaryMask, gkd, [], cachedTags);
103
+ const overviews = dataEntries.map(([key, dataImage]) => {
104
+ const maskImage = maskIFDs.get(key) ?? null;
105
+ return new Overview(geotiff, gkd, dataImage, maskImage, cachedTags);
106
+ });
107
+ // Mutate the readonly field — safe here because we're still in the factory.
108
+ geotiff.overviews = overviews;
109
+ return geotiff;
110
+ }
111
+ static async fromArrayBuffer(input) {
112
+ const source = new SourceMemory("memory://input.tif", input);
113
+ return await GeoTIFF.open(source);
114
+ }
115
+ static async fromUrl(url, { chunkSize = 32 * 1024, cacheSize = 1024 * 1024 * 1024, } = {}) {
116
+ // read files in chunks
117
+ const chunk = new SourceChunk({ size: chunkSize });
118
+ // 1MB cache for recently accessed chunks
119
+ const cache = new SourceCache({ size: cacheSize });
120
+ const source = new SourceHttp(url);
121
+ const view = new SourceView(source, [chunk, cache]);
122
+ return await GeoTIFF.open(view);
123
+ }
124
+ // ── Properties from the primary image ─────────────────────────────────
125
+ /**
126
+ * The CRS parsed from the GeoKeyDirectory.
127
+ *
128
+ * Returns an EPSG code (number) for EPSG-coded CRSes, or a PROJJSON object
129
+ * for user-defined CRSes. The result is cached after the first access.
130
+ *
131
+ * See also {@link GeoTIFF.epsg} for the EPSG code directly from the TIFF tags.
132
+ */
133
+ get crs() {
134
+ if (this._crs === undefined) {
135
+ this._crs = crsFromGeoKeys(this.gkd);
136
+ }
137
+ return this._crs;
138
+ }
139
+ /** Image width in pixels. */
140
+ get width() {
141
+ return this.image.size.width;
142
+ }
143
+ /** Image height in pixels. */
144
+ get height() {
145
+ return this.image.size.height;
146
+ }
147
+ /** Tile width in pixels. */
148
+ get tileWidth() {
149
+ return this.image.tileSize.width;
150
+ }
151
+ /** Tile height in pixels. */
152
+ get tileHeight() {
153
+ return this.image.tileSize.height;
154
+ }
155
+ /** The NoData value, or null if not set. */
156
+ get nodata() {
157
+ return this.image.noData;
158
+ }
159
+ /** Whether the primary image is tiled. */
160
+ get isTiled() {
161
+ return this.image.isTiled();
162
+ }
163
+ /** Number of bands (samples per pixel). */
164
+ get count() {
165
+ return this.image.value(TiffTag.SamplesPerPixel) ?? 1;
166
+ }
167
+ /** Bounding box [minX, minY, maxX, maxY] in the CRS. */
168
+ get bbox() {
169
+ return this.image.bbox;
170
+ }
171
+ /**
172
+ * Return the dataset's georeferencing transformation matrix.
173
+ */
174
+ get transform() {
175
+ const origin = this.image.origin;
176
+ const resolution = this.image.resolution;
177
+ // Check for rotation via ModelTransformation.
178
+ // This tag is pre-fetched by @cogeotiff/core during initialization,
179
+ // so value() is safe to call synchronously.
180
+ const modelTransformation = this.image.value(TiffTag.ModelTransformation);
181
+ let b = 0; // row rotation
182
+ let d = 0; // column rotation
183
+ if (modelTransformation != null && modelTransformation.length >= 16) {
184
+ b = modelTransformation[1];
185
+ d = modelTransformation[4];
186
+ }
187
+ return [
188
+ resolution[0], // a: pixel width (x per col)
189
+ b, // b: row rotation
190
+ origin[0], // c: x origin
191
+ d, // d: column rotation
192
+ resolution[1], // e: pixel height (negative = north-up)
193
+ origin[1], // f: y origin
194
+ ];
195
+ }
196
+ // Mixins
197
+ /** Fetch a single tile from the full-resolution image. */
198
+ async fetchTile(x, y, options = {}) {
199
+ return await fetchTile(this, x, y, options);
200
+ }
201
+ // Transform mixin
202
+ /**
203
+ * Get the (row, col) pixel index containing the geographic coordinate (x, y).
204
+ *
205
+ * @param x x coordinate in the CRS.
206
+ * @param y y coordinate in the CRS.
207
+ * @param op Rounding function applied to fractional pixel indices.
208
+ * Defaults to Math.floor.
209
+ * @returns [row, col] pixel indices.
210
+ */
211
+ index(x, y, op = Math.floor) {
212
+ return index(this, x, y, op);
213
+ }
214
+ /**
215
+ * Get the geographic (x, y) coordinate of the pixel at (row, col).
216
+ *
217
+ * @param row Pixel row.
218
+ * @param col Pixel column.
219
+ * @param offset Which part of the pixel to return. Defaults to "center".
220
+ * @returns [x, y] in the CRS.
221
+ */
222
+ xy(row, col, offset = "center") {
223
+ return xy(this, row, col, offset);
224
+ }
225
+ }
226
+ /**
227
+ * Determine whether a TiffImage is a mask IFD.
228
+ *
229
+ * A mask IFD has SubFileType with the Mask bit set (value 4) AND
230
+ * PhotometricInterpretation === Mask (4).
231
+ */
232
+ export function isMaskIfd(image) {
233
+ const subFileType = image.value(TiffTag.SubFileType);
234
+ const photometric = image.value(TiffTag.Photometric);
235
+ return (subFileType !== null &&
236
+ (subFileType & SubFileType.Mask) !== 0 &&
237
+ photometric === Photometric.Mask);
238
+ }
239
+ //# sourceMappingURL=geotiff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geotiff.js","sourceRoot":"","sources":["../src/geotiff.ts"],"names":[],"mappings":"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"}