Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(layers): Trim Top of Pyramids #633

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ const MultiscaleImageLayer = class extends CompositeLayer {
} = this.props;
// Get properties from highest resolution
const { tileSize, dtype } = loader[0];

// This is basically to invert:
// https://github.com/visgl/deck.gl/pull/4616/files#diff-4d6a2e500c0e79e12e562c4f1217dc80R128
// The z level can be wrong for showing the correct scales because of the calculation deck.gl does
// so we need to invert it for fetching tiles and minZoom/maxZoom.
const getTileData = async ({ x, y, z, signal }) => {
const getTileData = async ({ index: { x, y, z }, signal }) => {
// Early return if no selections
if (!selections || selections.length === 0) {
return null;
Expand All @@ -84,10 +83,40 @@ const MultiscaleImageLayer = class extends CompositeLayer {
// The image-tile example works without, this but I have a feeling there is something
// going on with our pyramids and/or rendering that is different.
const resolution = Math.round(-z);

// Here we set up variables for checking whether or not we should cip the black border of incoming tiles
// at low resolutions i.e for zarr tiles. We need to check a few things before trimming:
// 1. The height/width of the full image at the current resolution
// produces an image smaller than the current tileSize
// 2. The incoming image is indeed padded out to the tile size
// in some dimension i.e it should be clipped down to the smaller size
// Once these have been confirmed, we trim the tile by going over it in row major order,
// keeping only the data that is not out of the clipped bounds.
const planarSize = loader[0].shape.slice(-2);
ilan-gold marked this conversation as resolved.
Show resolved Hide resolved
const [clippedHeight, clippedWidth] = planarSize.map(size =>
Math.floor(size / 2 ** resolution)
);
const isHeightUnderTileSize = clippedHeight < tileSize;
const isWidthUnderTileSize = clippedWidth < tileSize;
const getTile = selection => {
const config = { x, y, selection, signal };
return loader[resolution].getTile(config);
};
const clip = ({ data, height, width }) => {
if (
(isHeightUnderTileSize && height === tileSize) ||
(width === tileSize && isWidthUnderTileSize)
) {
return data.filter((d, ind) => {
return !(
(ind % tileSize >= clippedWidth && isWidthUnderTileSize) ||
(isHeightUnderTileSize &&
Math.floor(ind / tileSize) >= clippedHeight)
);
});
}
return data;
};
ilan-gold marked this conversation as resolved.
Show resolved Hide resolved

try {
/*
Expand All @@ -99,11 +128,22 @@ const MultiscaleImageLayer = class extends CompositeLayer {
* return type, and optional throw for performance.
*/
const tiles = await Promise.all(selections.map(getTile));

const tile = {
data: tiles.map(d => d.data),
width: tiles[0].width,
height: tiles[0].height
data: tiles.map(d =>
clip({
data: d.data,
width: tiles[0].width,
height: tiles[0].height
})
),
width:
isWidthUnderTileSize && tiles[0].height === tileSize
? clippedWidth
: tiles[0].width,
height:
isHeightUnderTileSize && tiles[0].height === tileSize
? clippedHeight
: tiles[0].height
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, I seem to remember adding padding to tiles from the loaders. It seems like we are just reversing that here? Perhaps this warrants a change to the loaders?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this was also my first instinct but I don't think we do anymore after you found that specific WebGL setting for controlling of what number the textures should be a multiple, which we set to 1.

};

if (isInterleaved(loader[resolution].shape)) {
Expand Down