Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/geotiff/src/geotiff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { SourceHttp } from "@chunkd/source-http";
import { SourceMemory } from "@chunkd/source-memory";
import type { Source, TiffImage } from "@cogeotiff/core";
import { Photometric, SubFileType, Tiff, TiffTag } from "@cogeotiff/core";
// https://github.com/blacha/cogeotiff/issues/1417
import type { TiffImageTileCount } from "@cogeotiff/core/build/tiff.image.js";
import type { Affine } from "@developmentseed/affine";
import type { ProjJson } from "./crs.js";
import { crsFromGeoKeys } from "./crs.js";
Expand Down Expand Up @@ -199,6 +201,11 @@ export class GeoTIFF {
return this.image.size.height;
}

/** The number of tiles in the x and y directions */
get tileCount(): TiffImageTileCount {
return this.image.tileCount;
}

/** Tile width in pixels. */
get tileWidth(): number {
return this.image.tileSize.width;
Expand Down
10 changes: 10 additions & 0 deletions packages/geotiff/src/overview.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { TiffImage } from "@cogeotiff/core";
import type { TiffImageTileCount } from "@cogeotiff/core/build/tiff.image.js";
import type { Affine } from "@developmentseed/affine";
import { compose, scale } from "@developmentseed/affine";
import type { ProjJson } from "./crs.js";
Expand Down Expand Up @@ -54,6 +55,11 @@ export class Overview {
return this.geotiff.nodata;
}

/** The number of tiles in the x and y directions */
get tileCount(): TiffImageTileCount {
return this.image.tileCount;
}

get tileHeight(): number {
return this.image.tileSize.height;
}
Expand Down Expand Up @@ -82,6 +88,10 @@ export class Overview {
return await fetchTile(this, x, y, options);
}

// TiledMixin

// Transform mixin

/**
* Get the (row, col) pixel index containing the geographic coordinate (x, y).
*
Expand Down
43 changes: 20 additions & 23 deletions packages/geotiff/src/tile-matrix-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,21 @@ function buildTileMatrix(
id: string,
transform: Affine,
mpu: number,
cornerOfOrigin: "bottomLeft" | "topLeft",
tileWidth: number,
tileHeight: number,
width: number,
height: number,
matrixWidth: number,
matrixHeight: number,
): TileMatrix {
return {
id,
scaleDenominator: (affine.a(transform) * mpu) / SCREEN_PIXEL_SIZE,
cellSize: affine.a(transform),
cornerOfOrigin,
cornerOfOrigin: affine.e(transform) > 0 ? "bottomLeft" : "topLeft",
pointOfOrigin: [affine.c(transform), affine.f(transform)],
tileWidth,
tileHeight,
matrixWidth: Math.ceil(width / tileWidth),
matrixHeight: Math.ceil(height / tileHeight),
matrixWidth,
matrixHeight,
};
}

Expand All @@ -88,20 +87,12 @@ export function generateTileMatrixSet(
{ id = uuidv4() }: { id?: string } = {},
): TileMatrixSet {
const bbox = geotiff.bbox;
const tr = geotiff.transform;

// Full-resolution level is appended last.
if (!geotiff.isTiled) {
throw new Error("GeoTIFF must be tiled to generate a TMS.");
}

if (tr[1] !== 0 || tr[3] !== 0) {
// TileMatrixSet assumes orthogonal axes
throw new Error(
"COG TileMatrixSet with rotation/skewed geotransform is not supported",
);
}

// Perhaps we should allow metersPerUnit to take any string
const crsUnit = crs.units as
| "m"
Expand All @@ -119,8 +110,6 @@ export function generateTileMatrixSet(

const semiMajorAxis = crs.a || crs.datum?.a;
const mpu = metersPerUnit(crsUnit, { semiMajorAxis });
const cornerOfOrigin: "bottomLeft" | "topLeft" =
affine.e(tr) > 0 ? "bottomLeft" : "topLeft";

const tileMatrices: TileMatrix[] = [];

Expand All @@ -129,30 +118,38 @@ export function generateTileMatrixSet(

for (let idx = 0; idx < overviewsCoarseFirst.length; idx++) {
const overview = overviewsCoarseFirst[idx]!;
const { x: matrixWidth, y: matrixHeight } = overview.tileCount;
tileMatrices.push(
buildTileMatrix(
String(idx),
overview.transform,
mpu,
cornerOfOrigin,
overview.tileWidth,
overview.tileHeight,
overview.width,
overview.height,
matrixWidth,
matrixHeight,
),
);
}

if (geotiff.transform[1] !== 0 || geotiff.transform[3] !== 0) {
// TileMatrixSet assumes orthogonal axes
throw new Error(
"COG TileMatrixSet with rotation/skewed geotransform is not supported",
);
}

const { x: matrixWidth, y: matrixHeight } = geotiff.tileCount;

tileMatrices.push(
buildTileMatrix(
String(geotiff.overviews.length),
tr,
geotiff.transform,
mpu,
cornerOfOrigin,
geotiff.tileWidth,
geotiff.tileHeight,
geotiff.width,
geotiff.height,
matrixWidth,
matrixHeight,
),
);

Expand Down