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

Fix invalid tile key issues when swapping rasters when region picker active #105

Merged
merged 9 commits into from
Feb 15, 2024

Conversation

Shane98c
Copy link
Member

@Shane98c Shane98c commented Feb 14, 2024

Adds a couple checks to make sure we're not accessing the tile before it has been initialized. This solves errors when swapping raster properties (like variable) while a region picker is active.

Fixes zoom/center state initialization and makes sure dataset level is correctly calculated before querying.

Copy link

vercel bot commented Feb 14, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Ignored Deployments
Name Status Preview Comments Updated (UTC)
maps-demo ⬜️ Ignored (Inspect) Visit Preview Feb 15, 2024 3:30pm
maps-docs ⬜️ Ignored (Inspect) Visit Preview Feb 15, 2024 3:30pm

src/tiles.js Outdated Show resolved Hide resolved
@Shane98c
Copy link
Member Author

Ok new direction here. Traced this back to the camera center/zoom properties being undefined. This was due to the way useControls was set up.

Since the map was already loaded, map.on('load', ... was never (or at least not consistently) fired, so those values remained undefined until the map was moved. This change makes the the state initialization ask the map right away for the current values, removes the 'load' event listener, and also cleans up the listener on dismount.

I'm slightly worried that map.getZoom() and map.getCenter() could be undefined if useControls is raced against map initialization, but I don't think that's likely with its current usage.

I'm now seeing key issues (they look totally legit, but don't exist on this.tiles) only in cases where I zoom in somewhat far, which could be an unrelated to maps and instead have something to do with the zarr metadata for OAE not setting maxzoom correctly?

@Shane98c
Copy link
Member Author

Shane98c commented Feb 15, 2024

Ok I think I have a good solution to the timing thing we were diving into yesterday - we just need to update this.level during initialization since maxZoom is fine in there. We don't actually have to run the entire updateCamera function and worry about timing if we take this route. We also don't need to be in the updateCamera function for access to zoom because this.zoom is correct and accessible in the initialization function.

@Shane98c Shane98c changed the title check if the tile exists before accessing Fix invalid tile key issues when swapping rasters when region picker active Feb 15, 2024
@@ -120,6 +120,7 @@ export const createTiles = (regl, opts) => {
}) => {
if (setMetadata) setMetadata(metadata)
this.maxZoom = maxZoom
this.level = zoomToLevel(this.zoom, maxZoom)
Copy link
Member

Choose a reason for hiding this comment

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

This is sooo much cleaner than the callback!!

Question: in the case that triggered the race condition where queryRegion runs before updateCamera (rendering a new Raster in an existing Map with an already active region), will the tiles from the max zoom level always be fetched and queried regardless of what level the tiles actually end up rendering at?

For example, if the map is at zoom ~0 but maxZoom === 1, will the 1-level tiles be fetched by queryRegion while the 0-level tile is fetched for updateCamera? While not a huge deal in this example, this could potentially be quite costly for pyramids with high maxZooms.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm if i'm following correctly I think the zoomToLevel function returns the lesser of zoom vs maxzoom, which is what's used by queryRegion, so my understanding is that it should fetch the data for the relevant current zoom of the map, not the maxZoom. This works because this.zoom has been set by updateCamera previously. There might be a possible edge case where if you're swapping out rasters while actively zooming something could get funky - but I don't think this fix makes that situation worse than it would be normally. If zoom is for some reason undefined, I think zoomToLevels will return zero, so I don't see a way that we'd be fetching data for higher levels than needed.

Copy link
Member

Choose a reason for hiding this comment

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

This works because this.zoom has been set by updateCamera previously.

Ah! I thought that we were hitting this case because updateCamera hadn't finished by the time queryRegion ran but it's actually because updateCamera can run before initialized resolves, right? And because of this we saw the real value of this.zoom but an unexpected value for this.level in queryRegion?

Then this all feels great, especially with the assurance that

If zoom is for some reason undefined, I think zoomToLevels will return zero

Copy link
Member Author

Choose a reason for hiding this comment

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

yes I think that's right! we had a real zoom but maxZoom was undefined because we hadn't finished initializing yet so we were getting a level set based on zoom, with no consideration for maxZoom

So another potential spot issues could arise is if there are places in updateCamera where level not respecting maxZoom could cause issues. It looks like level is used a few times throughout. and some bad tile keys are created, but I think the check for this.loaders[level] prevents anything from going further than that.

@Shane98c Shane98c merged commit 8601213 into main Feb 15, 2024
10 checks passed
@Shane98c Shane98c deleted the check-tiles branch February 15, 2024 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants