qgis / QGIS

QGIS is a free, open source, cross platform (lin/win/mac) geographical information system (GIS)
https://qgis.org
GNU General Public License v2.0
10.63k stars 3.01k forks source link

Raster Layers misaligned when resampled and uses an overview #36820

Closed palmerj closed 4 years ago

palmerj commented 4 years ago

Describe the bug Is some cases resampled Geotiff images with added overviews are misaligned in the QGIS canvas by a very small amount (maybe one pixel). Changing the layer symbology resampling settings for zoomed in/out, or increasing the oversampling parameter makes no difference.

How to Reproduce

  1. Take a Geotiff then run the following process on it with GDAL:
gdal_translate source.tif out_half.tif -r cubic -outsize 50% 50%

cp source.tif out_with_ovr.tif
gdaladdo -r cubic out_with_ovr.tif 2
  1. Now add both files to a QGIS project
  2. Zoom to native resolution for out_half.tif
  3. Toogle top layer on and off to see misaligment.

See GIF below. You might want to open the image in a new tab to see the shift as it's only a pixel or so.

Note I've tested the output from GDAL converting the two images to a GIF with imagemagick convert and then displaying in multiple image viewers. The GDAL output looks good.

compare

QGIS and OS versions

QGIS master Test on Ubuntu 18.04 and MacOS

Additional context

gioman commented 4 years ago

@palmerj is the misalignment not visible on other GIS software? Try to understand if is an issue of QGIS or if it is a result of the gdal_translate operation.

rouault commented 4 years ago

Procedure to reproduce 1) Download a BMNG tile

wget http://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73751/world.topo.bathy.200407.3x21600x21600.C1.jpg

2) Create the associated worldfile

echo '0.004166666666666
0.0
0.0
-0.004166666666666
0.002083333
89.997916667
' > world.topo.bathy.200407.3x21600x21600.C1.jgw

3) Convert to GeoTIFF

gdal_translate world.topo.bathy.200407.3x21600x21600.C1.jpg world.topo.bathy.200407.3x21600x21600.C1.tif -co tiled=yes -co compress=lzw

4) Downsample full resolution image by a factor of 2, using cubic resampling

gdal_translate world.topo.bathy.200407.3x21600x21600.C1.tif half.tif  -r cubic -outsize 50% 50% -co tiled=yes -co compress=lzw

5) Create a version of the full resolution image with an overview of factor 2, using cubic resampling

cp world.topo.bathy.200407.3x21600x21600.C1.tif withovr.tif
gdaladdo -r cubic withovr.tif 2 

6) Extract that overview generated at previous ste in a standalone file (no resampling involved here)

gdal_translate withovr.tif withovr_ovr_extracted.tif -oo OVERVIEW_LEVEL=0 -co tiled=yes -co compress=lzw

==> withovr_ovr_extracted.tif and half.tif are binary identical

7) In QGIS, open half.tif and withovr.tif. Center for example on Caspian sea (lat = 44.5, lon = 50.2) and zoom on native resolution on half.tif. You can notice a shift between the 2 images when toggling the layers on/off (might be horizontal and/or vertical. depends on the size of the canvas). While this isn't a completely full proof (we have only proven that gdal_translate -outsize 50% 50% and gdaladdo 2 are consistant), this tends to demonstrate that the issue is on QGIS visualization side, when it displays a dataset with overviews.

But more convincgly, a preliminary analysis shows that the root cause is likely the QGIS GDAL provider which at https://github.com/qgis/QGIS/blob/81abbbb74f4e56cd8f9ae73c34bacb34735764de/src/core/providers/gdal/qgsgdalprovider.cpp#L909 issues a pixel request to GDAL without specifying a resampling method. Consequently GDAL uses the default nearest resampling mode, which is known to cause such ~ 1 pixel shift, instead of more precise resampling kernel such as cubic that avoid them.

(In the above experiment, though, this shouldn't matter as we in principle display exactly at the resolution of the overview. I suspect some "margins" are taken in the raster queries which make that the request is at a slightly different resolution, and thus not at exactly the resolution of the overview, which underlines the lack of precise resampling)

palmerj commented 4 years ago

Thanks @gioman and @rouault. I have also checked this by outputting the two images to a GIF with imagemagick (convert) and then displaying in multiple image viewers. The GDAL output is good.