diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-12-13 12:52:23 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-13 12:52:23 -0800 |
commit | f545d21df0d9a5b29b902bacee8dadf48ab11493 (patch) | |
tree | ddeb1c28b1cbdcaab724cb687660ef27c2add2a1 /src/mbgl/renderer/sources | |
parent | 88cafa8e32bcaf5b81765c3b47e45ab9d0b37fe1 (diff) | |
download | qtlocation-mapboxgl-f545d21df0d9a5b29b902bacee8dadf48ab11493.tar.gz |
[core] Overzoomed image sources vanish (#10677)
Use z0 tile coordinates instead of screen coordinates to compute ideal zoom for image sources
Diffstat (limited to 'src/mbgl/renderer/sources')
-rw-r--r-- | src/mbgl/renderer/sources/render_image_source.cpp | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index b5c42584e0..d215dc8d13 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -114,44 +114,43 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_, return; } - auto size = transformState.getSize(); - const double viewportHeight = size.height; - - // Compute the screen coordinates at wrap=0 for the given LatLng - ScreenCoordinate nePixel = { -INFINITY, -INFINITY }; - ScreenCoordinate swPixel = { INFINITY, INFINITY }; - + // Compute the z0 tile coordinates for the given LatLngs + TileCoordinatePoint nePoint = { -INFINITY, -INFINITY }; + TileCoordinatePoint swPoint = { INFINITY, INFINITY }; + std::vector<TileCoordinatePoint> tileCoordinates; for (LatLng latLng : coords) { - ScreenCoordinate pixel = transformState.latLngToScreenCoordinate(latLng); - swPixel.x = std::min(swPixel.x, pixel.x); - nePixel.x = std::max(nePixel.x, pixel.x); - swPixel.y = std::min(swPixel.y, viewportHeight - pixel.y); - nePixel.y = std::max(nePixel.y, viewportHeight - pixel.y); - } - const double width = nePixel.x - swPixel.x; - const double height = nePixel.y - swPixel.y; + auto point = TileCoordinate::fromLatLng(0, latLng).p; + tileCoordinates.push_back(point); + swPoint.x = std::min(swPoint.x, point.x); + nePoint.x = std::max(nePoint.x, point.x); + swPoint.y = std::min(swPoint.y, point.y); + nePoint.y = std::max(nePoint.y, point.y); + } - // Don't bother drawing the ImageSource unless it occupies >4 screen pixels - enabled = (width * height > 4); + // Calculate the optimum zoom level to determine the tile ids to use for transforms + auto dx = nePoint.x - swPoint.x; + auto dy = nePoint.y - swPoint.y; + auto dMax = std::max(dx, dy); + double zoom = std::max(0.0, std::floor(-util::log2(dMax))); + + // Only enable if the long side of the image is > 2 pixels. Resulting in a + // display of at least 2 x 1 px image + // A tile coordinate unit represents the length of one tile (tileSize) at a given zoom. + // To convert a tile coordinate to pixels, multiply by tileSize. + // Here dMax is in z0 tile units, so we also scale by 2^z to match current zoom. + enabled = dMax * std::pow(2.0, transformState.getZoom()) * util::tileSize > 2.0; if (!enabled) { return; } - // Calculate the optimum zoom level to determine the tile ids to use for transforms - double minScale = INFINITY; - double scaleX = double(size.width) / width; - double scaleY = double(size.height) / height; - minScale = util::min(scaleX, scaleY); - double zoom = transformState.getZoom() + util::log2(minScale); - zoom = std::floor(util::clamp(zoom, transformState.getMinZoom(), transformState.getMaxZoom())); auto imageBounds = LatLngBounds::hull(coords[0], coords[1]); imageBounds.extend(coords[2]); imageBounds.extend(coords[3]); auto tileCover = util::tileCover(imageBounds, zoom); tileIds.clear(); tileIds.push_back(tileCover[0]); - bool hasVisibleTile = false; + bool hasVisibleTile = false; // Add additional wrapped tile ids if neccessary auto idealTiles = util::tileCover(transformState, transformState.getZoom()); for (auto tile : idealTiles) { @@ -177,9 +176,8 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_, // Calculate Geometry Coordinates based on tile cover at ideal zoom GeometryCoordinates geomCoords; - for (auto latLng : coords) { - auto tc = TileCoordinate::fromLatLng(0, latLng); - auto gc = TileCoordinate::toGeometryCoordinate(tileIds[0], tc.p); + for (auto tileCoords : tileCoordinates) { + auto gc = TileCoordinate::toGeometryCoordinate(tileIds[0], tileCoords); geomCoords.push_back(gc); } if (!bucket) { |