Mapbox-gl-js: Image layer disappears while zooming

Created on 16 Aug 2016  路  5Comments  路  Source: mapbox/mapbox-gl-js

mapbox-gl-js version: v0.22.0

Steps to Trigger Behavior

  1. open "Add an image" example
  2. zoom in and out arround the raster overlay

    Expected Behavior

the raster overlay is visibile at all zoom levels

Actual Behavior

the raster overlay disappears at certain zoom levels

v.0.21.0 works as expected.

bug release blocker

Most helpful comment

I think ImageSource and VideoSource are fundamentally not tile-based sources and it's awkward to treat them as such (was before #2667, even more so now). I'm most interested in solutions that take "tiles" out of the equation for these source types.

All 5 comments

This is a regression from #2667. @anandthakker, can you please take a look?

Took an initial look. The problem was introduced because of the inversion of TilePyramid (now SourceCache) and Sources. Here's what I think is happening:

ImageSource (and VideoSource) both work by yielding a _single_ valid tile, using that to hold the image/video data. This was true before #2667 as well. However, when inverting the SourceCache/Source dependency, I moved the responsibility for listing the currently-visible tile coordinates (getVisibleCoordinates) from Source to SourceCache. (Before this, it was the responsibility of each Source, but pyramid-based sources delegated to TilePyramid#getRenderableIds.)

What's happening now is that the SourceCache is deciding which tiles are renderable and asking the ImageSource for them. Because some (or even most) of the image is currently getting rendered outside of the (non-clipped) tile, when the map is zoomed in, the single tile responsible for holding the image may end up outside of the view, so that SourceCache no longer includes it in the list of renderable tiles.

Possible ways to solve:

  1. Modify the Source interface to enable sources to provide a getVisibleCoordinates: Transform => Array<TileCoordinate> method. I don't love this: it feels like a hack, and it really seems like transform => visible tiles ought to be a straightforward geometry calculation.
  2. Choose the "one tile" that houses the image/video data more carefully, using a tile that fully contains the image. This way, if the image's coordinates are in the view, the the "one tile" should be included as a renderable ID. This is pretty clean, but it doesn't solve the problem of zooming _out_: if the map's zoom level goes below that of the "one tile", then SourceCache won't request the tile, because there's no concept of "underzooming" (true?).
  3. Change ImageSource/VideoSource to actually chop up the image into multiple, clipped tiles, so that it can just populate the ones that are being requested, as needed. I'm not familiar enough with the GL buffer stuff that's happening here to judge whether this is a reasonable thing to do or not. It does seem like it might get tricky for the video source...

@jfirebaugh @lucaswoj thoughts?

I think ImageSource and VideoSource are fundamentally not tile-based sources and it's awkward to treat them as such (was before #2667, even more so now). I'm most interested in solutions that take "tiles" out of the equation for these source types.

I certainly agree in principle / in the long run, but it does seem like this would require some pretty invasive changes in painter / rendering code. Admittedly, I'm very unfamiliar with that part of the codebase, so perhaps this is just my ignorance talking.

I captured some thoughts about refactoring per @jfirebaugh's comment above in #3186

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aaronlidman picture aaronlidman  路  3Comments

foundryspatial-duncan picture foundryspatial-duncan  路  3Comments

aendrew picture aendrew  路  3Comments

jfirebaugh picture jfirebaugh  路  3Comments

stevage picture stevage  路  3Comments