Skip to content

Bug in WarpedVRT support of open_rasterio() #2864

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

Closed
jmichel-otb opened this issue Apr 2, 2019 · 3 comments
Closed

Bug in WarpedVRT support of open_rasterio() #2864

jmichel-otb opened this issue Apr 2, 2019 · 3 comments

Comments

@jmichel-otb
Copy link
Contributor

jmichel-otb commented Apr 2, 2019

Code Sample, a copy-pastable example if possible

Using the following data:

https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/blob/develop/Data/Input/QB_Toulouse_Ortho_XS.tif

import rasterio as rio
from rasterio.crs import CRS
from rasterio.warp import calculate_default_transform,aligned_target
from rasterio.enums import Resampling
from rasterio.vrt import WarpedVRT

import xarray as xr

path = 'QB_Toulouse_Ortho_XS.tif'

# Read input metadata with rasterio                                                                                                                                                                                                           
with rio.open(path) as src:
    print('Input file CRS is {}'.format(src.crs))
    print('Input file shape is {}'.format(src.shape))
    print('Input file transform is {}'.format(src.transform))
    # Create a different CRS                                                                                                                                                                                                                  
    dst_crs = CRS.from_epsg(2154)
    # Compute a transform that will resample to dst_crs and change resolution to dst_crs                                                                                                                                                      
    transform, width, height = calculate_default_transform(
        src.crs, dst_crs, src.width, src.height,resolution=20, *src.bounds)
    # Fill vrt options as shown in https://rasterio.readthedocs.io/en/stable/topics/virtual-warping.html                                                                                                                                      
    vrt_options = {
    'resampling': Resampling.cubic,
    'crs': dst_crs,
    'transform': transform,
    'height': height,
    'width': width
    }
    # Create a WarpedVRT using the vrt_options                                                                                                                                                                                                
    with WarpedVRT(src,**vrt_options) as vrt:
        print('VRT shape is {}'.format(vrt.shape))
        # Open VRT with xarray                                                                                                                                                                                                                
        ds = xr.open_rasterio(vrt)
        # Shape does not match vrt shape:                                                                                                                                                                                                     
        print(ds)

Output:

$ python test_rio_vrt.py
Input file CRS is EPSG:32631
Input file shape is (500, 500)
Input file transform is | 0.60, 0.00, 374149.98|
| 0.00,-0.60, 4829183.99|
| 0.00, 0.00, 1.00|
VRT shape is (16, 16)
<xarray.DataArray (band: 4, y: 500, x: 500)>
[1000000 values with dtype=int16]
Coordinates:
  * band     (band) int64 1 2 3 4
  * y        (y) float64 6.28e+06 6.28e+06 6.28e+06 ... 6.279e+06 6.279e+06
  * x        (x) float64 5.741e+05 5.741e+05 5.741e+05 ... 5.744e+05 5.744e+05
Attributes:
    transform:   (0.6003151072155879, 0.0, 574068.2261249251, 0.0, -0.6003151...
    crs:         EPSG:2154
    res:         (0.6003151072155879, 0.6003151072155879)
    is_tiled:    0
    nodatavals:  (nan, nan, nan, nan)

Problem description

In the above example, xarray.open_rasterio() is asked to read a WarpedVRT created with rasterio. This WarpedVRT has custom transform, width and height, which is a very common use case of WarpedVRT where you upsample or downsample your data on the fly during read. Las, open_rasterio() ignores those custom attributes, which result in a wrong DataArray shape:

VRT shape is (16, 16)
<xarray.DataArray (band: 4, y: 500, x: 500)>

Expected Output

Correct output should be:

VRT shape is (16, 16)
<xarray.DataArray (band: 4, y: 16, x: 16)>

Which is fairly easy to obtain by modifying the following lines in open_rasterio():

vrt_params = dict(crs=vrt.crs.to_string(),

With the following:

      vrt_params = dict(crs=vrt.crs.to_string(),
                          resampling=vrt.resampling,
                          src_nodata=vrt.src_nodata,
                          dst_nodata=vrt.dst_nodata,
                          tolerance=vrt.tolerance,
                          # Edit                                                                                                                                                                                                              
                          transform=vrt.transform,
                          width=vrt.width,
                          height=vrt.height,
                          # End edit                                                                                                                                                                                                          
                          warp_extras=vrt.warp_extras)

I can provide this patch in a pull request if needed.

Output of xr.show_versions()

>>> xr.show_versions()

INSTALLED VERSIONS

commit: None
python: 3.6.7 | packaged by conda-forge | (default, Nov 21 2018, 03:09:43)
[GCC 7.3.0]
python-bits: 64
OS: Linux
OS-release: 3.10.0-862.2.3.el7.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: fr_FR.utf8
LOCALE: fr_FR.UTF-8
libhdf5: 1.10.4
libnetcdf: 4.6.2

xarray: 0.11.3
pandas: 0.24.1
numpy: 1.16.1
scipy: 1.2.0
netCDF4: 1.4.2
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: None
cftime: 1.0.3.4
PseudonetCDF: None
rasterio: 1.0.17
cfgrib: None
iris: None
bottleneck: None
cyordereddict: None
dask: 1.1.1
distributed: 1.25.3
matplotlib: 3.0.2
cartopy: 0.17.0
seaborn: 0.9.0
setuptools: 40.7.3
pip: 19.0.1
conda: None
pytest: 4.2.0
IPython: 7.1.1
sphinx: None

@fmaussion
Copy link
Member

Thanks for the great report!

I can provide this patch in a pull request if needed.

Please, do ;-)

@jhamman
Copy link
Member

jhamman commented Apr 2, 2019

cc @scottyhq

@jmichel-otb jmichel-otb changed the title Bug in WarpedVRTSupport of open_rasterio() Bug in WarpedVRT Support of open_rasterio() Apr 2, 2019
@jmichel-otb jmichel-otb changed the title Bug in WarpedVRT Support of open_rasterio() Bug in WarpedVRT support of open_rasterio() Apr 2, 2019
jmichel-otb added a commit to jmichel-otb/xarray that referenced this issue Apr 2, 2019
@jmichel-otb
Copy link
Contributor Author

@fmaussion done.

jmichel-otb added a commit to jmichel-otb/xarray that referenced this issue Apr 4, 2019
dcherian pushed a commit that referenced this issue Apr 11, 2019
* BUG: Fix #2864 by adding the missing vrt parameters (transform, width, height)

* TEST: Add a test to demonstrate that #2864 is actually fixed by patch

* DOC: Add an entry corresponding to the patch in whats-new.rst

* STY: Conform to PEP 8

* TEST: Fix test imports and assert for the affine transform check
dcherian added a commit to yohai/xarray that referenced this issue Apr 19, 2019
* master: (29 commits)
  Handle the character array dim name  (pydata#2896)
  Partial fix for pydata#2841 to improve formatting. (pydata#2906)
  docs: Move quick overview one level up (pydata#2890)
  Manually specify chunks in open_zarr (pydata#2530)
  Minor improvement of docstring for Dataset (pydata#2904)
  Fix minor typos in docstrings (pydata#2903)
  Added docs example for `xarray.Dataset.get()` (pydata#2894)
  Bugfix for docs build instructions (pydata#2897)
  Return correct count for scalar datetime64 arrays (pydata#2892)
  Indexing with an empty array (pydata#2883)
  BUG: Fix pydata#2864 by adding the missing vrt parameters (pydata#2865)
  Reduce length of cftime resample tests (pydata#2879)
  WIP: type annotations (pydata#2877)
  decreased pytest verbosity (pydata#2881)
  Fix mypy typing error in cftime_offsets.py (pydata#2878)
  update links to https (pydata#2872)
  revert to 0.12.2 dev
  0.12.1 release
  Various fixes for explicit Dataset.indexes (pydata#2858)
  Fix minor typo in docstring (pydata#2860)
  ...
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

No branches or pull requests

3 participants