Skip to content
Draft
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
3 changes: 2 additions & 1 deletion examples/land-cover/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ export default function App() {
? [
new COGLayer({
id: "cog-layer",
geotiff,
data: COG_URL,
// geotiff,
maxError: 0.125,
debug,
debugOpacity,
Expand Down
2 changes: 2 additions & 0 deletions packages/deck.gl-geotiff/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
"url": "git+https://github.com/developmentseed/deck.gl-raster.git"
},
"devDependencies": {
"@loaders.gl/core": "^4.3.4",
"@loaders.gl/loader-utils": "^4.3.4",
"@types/node": "^25.0.1",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.16.0",
Expand Down
20 changes: 17 additions & 3 deletions packages/deck.gl-geotiff/src/cog-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { fromGeoTransform } from "./geotiff-reprojection.js";
import { defaultPool, loadRgbImage } from "./geotiff.js";
import type { GeoKeysParser } from "./proj.js";
import { epsgIoGeoKeyParser } from "./proj.js";
import { GeoTIFFLoader } from "./loader.js";

// Workaround until upstream exposes props
// https://github.com/visgl/deck.gl/pull/9917
Expand All @@ -29,7 +30,7 @@ type Tileset2DProps = any;
const DEFAULT_MAX_ERROR = 0.125;

export interface COGLayerProps extends CompositeLayerProps {
geotiff: GeoTIFF;
data: GeoTIFF | string;

/**
* A function callback for parsing GeoTIFF geo keys to a Proj4 compatible
Expand Down Expand Up @@ -97,6 +98,7 @@ const defaultProps: Partial<COGLayerProps> = {
maxError: DEFAULT_MAX_ERROR,
geoKeysParser: epsgIoGeoKeyParser,
loadTexture: loadRgbImage,
loaders: [GeoTIFFLoader],
};

/**
Expand All @@ -114,6 +116,7 @@ export class COGLayer extends CompositeLayer<COGLayerProps> {
};

override initializeState(): void {
console.log("initialize props", this.props);
this.setState({});
}

Expand All @@ -123,15 +126,25 @@ export class COGLayer extends CompositeLayer<COGLayerProps> {
const { props, oldProps, changeFlags } = params;

const needsUpdate =
Boolean(changeFlags.dataChanged) || props.geotiff !== oldProps.geotiff;
Boolean(changeFlags.dataChanged) || props.data !== oldProps.data;

if (needsUpdate) {
this._parseGeoTIFF();
}
}

async _parseGeoTIFF(): Promise<void> {
const { geotiff } = this.props;
let geotiff: GeoTIFF;

console.log(this.props.data, "data");

// If data is a string URL, create GeoTIFF from URL for lazy loading
if (typeof this.props.data === "string") {
const { fromUrl } = await import("geotiff");
geotiff = await fromUrl(this.props.data);
} else {
geotiff = this.props.data;
}

const geoKeysParser = this.props.geoKeysParser!;
const metadata = await parseCOGTileMatrixSet(geotiff, geoKeysParser);
Expand Down Expand Up @@ -170,6 +183,7 @@ export class COGLayer extends CompositeLayer<COGLayerProps> {
inverseReproject: ReprojectionFns["inverseReproject"],
images: GeoTIFFImage[],
): TileLayer {
console.log(this.props, "props");
const { maxError, debug = false, debugOpacity = 0.5 } = this.props;

// Create a factory class that wraps COGTileset2D with the metadata
Expand Down
71 changes: 71 additions & 0 deletions packages/deck.gl-geotiff/src/loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Simple shim that implements the loaders.gl interface so that the user can
* pass a string into the data prop.
*/
import type { Loader, LoaderWithParser } from "@loaders.gl/core";
import type { Source } from "@loaders.gl/loader-utils";
import type { GeoTIFF } from "geotiff";

/* ASCII I */
const I = 0x49;

/* ASCII M */
const M = 0x4d;

export const GeoTIFFLoader: LoaderWithParser<string> = {
id: "geotiff",
name: "GeoTIFF",
module: "geotiff",
version: "version",
worker: false,
extensions: ["tif", "tiff", "geotiff"],
mimeTypes: ["image/tiff", "image/geotiff"],
parse: async (arrayBuffer: ArrayBuffer): Promise<GeoTIFF> => {
console.log("parsing geotiff");
console.log(arrayBuffer);
},
// binary: false,
// text: true,
// tests: [testTIFFMagic],
// options: {
// fetch: (input, info) => input,
// geotiff: {
// fetch: (input, init) => {
// return input;
// },
// },
// },
// parseTextSync: (text: string) => text,
};

// function parseGeoTIFF(arrayBuffer: ArrayBuffer): Promise<GeoTIFF> {

// }

/**
* Test for TIFF magic bytes
*
* Magic bytes are either `II` or `MM` indicating little or big endian. Then the
* following bytes should be 42 for TIFF or 43 for BigTIFF.
*/
function testTIFFMagic(arrayBuffer: ArrayBuffer): boolean {
const byteArray = new Uint8Array(arrayBuffer);

const b0 = byteArray[0];
const b1 = byteArray[1];

// "II" = little endian, "MM" = big endian
const isLittleEndian = b0 === I && b1 === I;
const isBigEndian = b0 === M && b1 === M;

if (!isLittleEndian && !isBigEndian) {
return false;
}

const dataView = new DataView(arrayBuffer);

// 42 for classic TIFF, 43 for BigTIFF
const tiffVersion = dataView.getUint16(2, isLittleEndian);

return tiffVersion === 42 || tiffVersion === 43;
}
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading