Skip to content

deck.gl-geotiff: Use boundless: true when fetching COG tiles in COGLayer? #412

@kylebarron

Description

@kylebarron

Currently we use boundless: false when fetching COG tiles:

const tile = await image.fetchTile(x, y, {
boundless: false,
pool,
signal,
});

and then we use clipToImageBounds to clip on CPU to the valid region of the image

/**
* Clip a decoded tile array to the valid image bounds.
*
* Edge tiles in a COG are always encoded at the full tile size, with the
* out-of-bounds region zero-padded. When `boundless=false` is requested, this
* function copies only the valid pixel sub-rectangle into a new typed array,
* returning a `RasterArray` whose `width`/`height` match the actual image
* content rather than the tile dimensions.
*
* Interior tiles (where the tile fits entirely within the image) are returned
* unchanged.
*/
function clipToImageBounds(
self: HasTiffReference,
x: number,
y: number,
array: RasterArray,
): RasterArray {
const { width: clippedWidth, height: clippedHeight } =
self.image.getTileBounds(x, y);
// Interior tile — nothing to clip.
if (clippedWidth === self.tileWidth && clippedHeight === self.tileHeight) {
return array;
}
const clippedMask = array.mask
? clipRows(array.mask, self.tileWidth, clippedWidth, clippedHeight, 1)
: array.mask;
if (array.layout === "pixel-interleaved") {
const { count, data } = array;
const clipped = clipRows(
data,
self.tileWidth,
clippedWidth,
clippedHeight,
count,
);
return {
...array,
width: clippedWidth,
height: clippedHeight,
data: clipped as typeof data,
mask: clippedMask,
};
}
// band-separate
const { bands } = array;
const clippedBands = bands.map(
(band) =>
clipRows(
band,
self.tileWidth,
clippedWidth,
clippedHeight,
1,
) as typeof band,
);
return {
...array,
width: clippedWidth,
height: clippedHeight,
bands: clippedBands,
mask: clippedMask,
};
}

I think we should probably (? maybe?) avoid image clipping on CPU and upload the raw tiles as-is. Then we can use existing nodata-masking or mask-array masking to discard these pixels from rendering.

The tradeoff is that using boundless: true and removing CPU clipping:

  • Should be faster by having less CPU overhead
  • Should use slightly more GPU memory for the regions of the texture that are known to be nodata

In the MultiCOGLayer we always use boundless: true because we need the uvTransform to be consistent across all tiles. This is what produced the warped screenshots in #410, which was fixed in #411

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions