From 35c5afbc46a84c1e12031e2cc9a21445a7bab9a5 Mon Sep 17 00:00:00 2001 From: Scott Henderson Date: Mon, 3 Dec 2018 20:14:15 -0800 Subject: [PATCH 1/5] added some logic to deal with rasterio objects in addition to filepath strings --- xarray/backends/rasterio_.py | 67 +++++++++++++++++++++++++++++++---- xarray/tests/test_backends.py | 36 +++++++++++++++++++ 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/xarray/backends/rasterio_.py b/xarray/backends/rasterio_.py index 7a343a6529e..c4f2330382c 100644 --- a/xarray/backends/rasterio_.py +++ b/xarray/backends/rasterio_.py @@ -2,7 +2,8 @@ import warnings from collections import OrderedDict from distutils.version import LooseVersion - +import rasterio +from rasterio.vrt import WarpedVRT import numpy as np from .. import DataArray @@ -24,11 +25,13 @@ class RasterioArrayWrapper(BackendArray): """A wrapper around rasterio dataset objects""" - def __init__(self, manager): + def __init__(self, manager, vrt=None): self.manager = manager # cannot save riods as an attribute: this would break pickleability riods = manager.acquire() + if vrt: + riods = vrt self._shape = (riods.count, riods.height, riods.width) @@ -123,6 +126,39 @@ def __getitem__(self, key): key, self.shape, indexing.IndexingSupport.OUTER, self._getitem) +class RasterioVRTWrapper(RasterioArrayWrapper): + """A wrapper around rasterio WarpedVRT objects""" + def __init__(self, manager, vrt_params): + #print('Using VRT Wrapper') + self.manager = manager + self.vrt_params = vrt_params + # cannot save riods as an attribute: this would break pickleability + riods = manager.acquire() + vrt = WarpedVRT(riods, **vrt_params) + self._shape = (vrt.count, vrt.height, vrt.width) + + dtypes = vrt.dtypes + if not np.all(np.asarray(dtypes) == dtypes[0]): + raise ValueError('All bands should have the same dtype') + self._dtype = np.dtype(dtypes[0]) + + def _getitem(self, key): + band_key, window, squeeze_axis, np_inds = self._get_indexer(key) + + if not band_key or any(start == stop for (start, stop) in window): + # no need to do IO + shape = (len(band_key),) + tuple( + stop - start for (start, stop) in window) + out = np.zeros(shape, dtype=self.dtype) + else: + riods = self.manager.acquire() + vrt = WarpedVRT(riods, **self.vrt_params) + out = vrt.read(band_key, window=window) + + if squeeze_axis: + out = np.squeeze(out, axis=squeeze_axis) + return out[np_inds] + def _parse_envi(meta): """Parse ENVI metadata into Python data structures. @@ -176,8 +212,8 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, Parameters ---------- - filename : str - Path to the file to open. + filename : str, rasterio.DatasetReader, or rasterio.WarpedVRT + Path to the file to open. Or already open rasterio dataset. parse_coordinates : bool, optional Whether to parse the x and y coordinates out of the file's ``transform`` attribute or not. The default is to automatically @@ -204,12 +240,26 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, data : DataArray The newly created DataArray. """ - - import rasterio + vrt_params = None + if isinstance(filename, rasterio.io.DatasetReader): + filename = filename.name + elif isinstance(filename, rasterio.vrt.WarpedVRT): + vrt = filename + filename = vrt.src_dataset.name + #crs = vrt.crs.to_string() + vrt_params = dict(crs=vrt.crs.to_string(), + resampling=vrt.resampling, + src_nodata=vrt.src_nodata, + dst_nodata=vrt.dst_nodata, + tolerance=vrt.tolerance, + warp_extras=vrt.warp_extras) manager = CachingFileManager(rasterio.open, filename, mode='r') riods = manager.acquire() + if vrt_params: + riods = WarpedVRT(riods, **vrt_params) + if cache is None: cache = chunks is None @@ -288,7 +338,10 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, else: attrs[k] = v - data = indexing.LazilyOuterIndexedArray(RasterioArrayWrapper(manager)) + if vrt_params: + data = indexing.LazilyOuterIndexedArray(RasterioVRTWrapper(manager, vrt_params)) + else: + data = indexing.LazilyOuterIndexedArray(RasterioArrayWrapper(manager)) # this lets you write arrays loaded with rasterio data = indexing.CopyOnWriteArray(data) diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index fb9c43c0165..839359fb820 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -3057,6 +3057,42 @@ def test_http_url(self): import dask.array as da assert isinstance(actual.data, da.Array) + def test_rasterio_environment(self): + with create_tmp_geotiff() as (tmp_file, expected): + # Should fail with error since suffix not allowed + with pytest.raises(Exception): + with rasterio.Env(CPL_VSIL_CURL_ALLOWED_EXTENSIONS='H5'): + with xr.open_rasterio(tmp_file) as actual: + assert_allclose(actual, expected) + + def test_rasterio_vrt(self): + url = 'https://storage.googleapis.com/\ + gcp-public-data-landsat/LC08/01/047/027/\ + LC08_L1TP_047027_20130421_20170310_01_T1/\ + LC08_L1TP_047027_20130421_20170310_01_T1_B4.TIF' + env = rasterio.Env(GDAL_DISABLE_READDIR_ON_OPEN='EMPTY_DIR', + CPL_VSIL_CURL_USE_HEAD=False, + CPL_VSIL_CURL_ALLOWED_EXTENSIONS='TIF') + with env: + with rasterio.open(url) as src: + with WarpedVRT(src, crs='epsg:4326') as vrt: + expected_shape = (vrt.width, vrt.height) + expected_crs = vrt.crs + expected_res = vrt.res + # Value of single pixel in center of image + lon,lat = vrt.xy(vrt.width // 2, vrt.height // 2) + expected_val = next(vrt.sample([(lon, lat)])) + with xr.open_rasterio(vrt) as da: + actual_shape = (da.sizes['x'], da.sizes['y']) + actual_crs = da.crs + actual_res = da.res + actual_val = da.sel(dict(x=lon, y=lat), + method='nearest').data + + assert_equal(actual_shape, expected_shape) + assert_equal(actual_crs, expected_crs) + assert_equal(actual_res, expected_res) + assert_equal(expected_val, actual_val) class TestEncodingInvalid(object): From 35f99478a02eeccbf7f29024f1beb3395521b3ac Mon Sep 17 00:00:00 2001 From: Scott Henderson Date: Tue, 18 Dec 2018 15:51:32 -0800 Subject: [PATCH 2/5] added no network test, pep8 compliance, whatsnew.rst --- doc/whats-new.rst | 16 ++++--- xarray/backends/rasterio_.py | 19 ++++---- xarray/tests/test_backends.py | 89 +++++++++++++++++++++++------------ 3 files changed, 81 insertions(+), 43 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index b1d5b92da4d..be4b697ae73 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -39,6 +39,10 @@ Enhancements - :py:class:`CFTimeIndex` uses slicing for string indexing when possible (like :py:class:`pandas.DatetimeIndex`), which avoids unnecessary copies. By `Stephan Hoyer `_ +- Enable passing ``rasterio.io.DatasetReader`` or ``rasterio.vrt.WarpedVRT`` to + ``open_rasterio`` instead of file path string. Allows for in-memory + reprojection, see (:issue:`2588`). + By `Scott Henderson `_. Bug fixes ~~~~~~~~~ @@ -56,15 +60,15 @@ Breaking changes - ``Dataset.T`` has been removed as a shortcut for :py:meth:`Dataset.transpose`. Call :py:meth:`Dataset.transpose` directly instead. - Iterating over a ``Dataset`` now includes only data variables, not coordinates. - Similarily, calling ``len`` and ``bool`` on a ``Dataset`` now + Similarily, calling ``len`` and ``bool`` on a ``Dataset`` now includes only data variables. - ``DataArray.__contains__`` (used by Python's ``in`` operator) now checks - array data, not coordinates. + array data, not coordinates. - The old resample syntax from before xarray 0.10, e.g., ``data.resample('1D', dim='time', how='mean')``, is no longer supported will raise an error in most cases. You need to use the new resample syntax instead, e.g., ``data.resample(time='1D').mean()`` or - ``data.resample({'time': '1D'}).mean()``. + ``data.resample({'time': '1D'}).mean()``. - New deprecations (behavior will be changed in xarray 0.12): @@ -101,13 +105,13 @@ Breaking changes than by default trying to coerce them into ``np.datetime64[ns]`` objects. A :py:class:`~xarray.CFTimeIndex` will be used for indexing along time coordinates in these cases. - - A new method :py:meth:`~xarray.CFTimeIndex.to_datetimeindex` has been added + - A new method :py:meth:`~xarray.CFTimeIndex.to_datetimeindex` has been added to aid in converting from a :py:class:`~xarray.CFTimeIndex` to a :py:class:`pandas.DatetimeIndex` for the remaining use-cases where using a :py:class:`~xarray.CFTimeIndex` is still a limitation (e.g. for resample or plotting). - Setting the ``enable_cftimeindex`` option is now a no-op and emits a - ``FutureWarning``. + ``FutureWarning``. Enhancements ~~~~~~~~~~~~ @@ -194,7 +198,7 @@ Bug fixes the dates must be encoded using cftime rather than NumPy (:issue:`2272`). By `Spencer Clark `_. -- Chunked datasets can now roundtrip to Zarr storage continually +- Chunked datasets can now roundtrip to Zarr storage continually with `to_zarr` and ``open_zarr`` (:issue:`2300`). By `Lily Wang `_. diff --git a/xarray/backends/rasterio_.py b/xarray/backends/rasterio_.py index c4f2330382c..2c0a24a2a08 100644 --- a/xarray/backends/rasterio_.py +++ b/xarray/backends/rasterio_.py @@ -2,8 +2,6 @@ import warnings from collections import OrderedDict from distutils.version import LooseVersion -import rasterio -from rasterio.vrt import WarpedVRT import numpy as np from .. import DataArray @@ -128,8 +126,9 @@ def __getitem__(self, key): class RasterioVRTWrapper(RasterioArrayWrapper): """A wrapper around rasterio WarpedVRT objects""" + def __init__(self, manager, vrt_params): - #print('Using VRT Wrapper') + from rasterio.vrt import WarpedVRT self.manager = manager self.vrt_params = vrt_params # cannot save riods as an attribute: this would break pickleability @@ -143,6 +142,7 @@ def __init__(self, manager, vrt_params): self._dtype = np.dtype(dtypes[0]) def _getitem(self, key): + from rasterio.vrt import WarpedVRT band_key, window, squeeze_axis, np_inds = self._get_indexer(key) if not band_key or any(start == stop for (start, stop) in window): @@ -159,6 +159,7 @@ def _getitem(self, key): out = np.squeeze(out, axis=squeeze_axis) return out[np_inds] + def _parse_envi(meta): """Parse ENVI metadata into Python data structures. @@ -240,13 +241,14 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, data : DataArray The newly created DataArray. """ + import rasterio + vrt_params = None if isinstance(filename, rasterio.io.DatasetReader): filename = filename.name elif isinstance(filename, rasterio.vrt.WarpedVRT): vrt = filename filename = vrt.src_dataset.name - #crs = vrt.crs.to_string() vrt_params = dict(crs=vrt.crs.to_string(), resampling=vrt.resampling, src_nodata=vrt.src_nodata, @@ -258,7 +260,7 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, riods = manager.acquire() if vrt_params: - riods = WarpedVRT(riods, **vrt_params) + riods = rasterio.vrt.WarpedVRT(riods, **vrt_params) if cache is None: cache = chunks is None @@ -332,14 +334,15 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, for k, v in meta.items(): # Add values as coordinates if they match the band count, # as attributes otherwise - if (isinstance(v, (list, np.ndarray)) and - len(v) == riods.count): + if (isinstance(v, (list, np.ndarray)) + and len(v) == riods.count): coords[k] = ('band', np.asarray(v)) else: attrs[k] = v if vrt_params: - data = indexing.LazilyOuterIndexedArray(RasterioVRTWrapper(manager, vrt_params)) + data = indexing.LazilyOuterIndexedArray(RasterioVRTWrapper(manager, + vrt_params)) else: data = indexing.LazilyOuterIndexedArray(RasterioArrayWrapper(manager)) diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 839359fb820..565285b9b27 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -199,9 +199,9 @@ def check_dtypes_roundtripped(self, expected, actual): actual_dtype = actual.variables[k].dtype # TODO: check expected behavior for string dtypes more carefully string_kinds = {'O', 'S', 'U'} - assert (expected_dtype == actual_dtype or - (expected_dtype.kind in string_kinds and - actual_dtype.kind in string_kinds)) + assert (expected_dtype == actual_dtype + or (expected_dtype.kind in string_kinds and + actual_dtype.kind in string_kinds)) def test_roundtrip_test_data(self): expected = create_test_data() @@ -376,17 +376,17 @@ def test_roundtrip_cftime_datetime_data(self): with self.roundtrip(expected, save_kwargs=kwds) as actual: abs_diff = abs(actual.t.values - expected_decoded_t) assert (abs_diff <= np.timedelta64(1, 's')).all() - assert (actual.t.encoding['units'] == - 'days since 0001-01-01 00:00:00.000000') - assert (actual.t.encoding['calendar'] == - expected_calendar) + assert (actual.t.encoding['units'] + == 'days since 0001-01-01 00:00:00.000000') + assert (actual.t.encoding['calendar'] + == expected_calendar) abs_diff = abs(actual.t0.values - expected_decoded_t0) assert (abs_diff <= np.timedelta64(1, 's')).all() - assert (actual.t0.encoding['units'] == - 'days since 0001-01-01') - assert (actual.t.encoding['calendar'] == - expected_calendar) + assert (actual.t0.encoding['units'] + == 'days since 0001-01-01') + assert (actual.t.encoding['calendar'] + == expected_calendar) def test_roundtrip_timedelta_data(self): time_deltas = pd.to_timedelta(['1h', '2h', 'NaT']) @@ -622,20 +622,20 @@ def test_unsigned_roundtrip_mask_and_scale(self): encoded = create_encoded_unsigned_masked_scaled_data() with self.roundtrip(decoded) as actual: for k in decoded.variables: - assert (decoded.variables[k].dtype == - actual.variables[k].dtype) + assert (decoded.variables[k].dtype + == actual.variables[k].dtype) assert_allclose(decoded, actual, decode_bytes=False) with self.roundtrip(decoded, open_kwargs=dict(decode_cf=False)) as actual: for k in encoded.variables: - assert (encoded.variables[k].dtype == - actual.variables[k].dtype) + assert (encoded.variables[k].dtype + == actual.variables[k].dtype) assert_allclose(encoded, actual, decode_bytes=False) with self.roundtrip(encoded, open_kwargs=dict(decode_cf=False)) as actual: for k in encoded.variables: - assert (encoded.variables[k].dtype == - actual.variables[k].dtype) + assert (encoded.variables[k].dtype + == actual.variables[k].dtype) assert_allclose(encoded, actual, decode_bytes=False) # make sure roundtrip encoding didn't change the # original dataset. @@ -2520,8 +2520,8 @@ def myatts(**attrs): 'ULOD_FLAG': '-7777', 'ULOD_VALUE': 'N/A', 'LLOD_FLAG': '-8888', 'LLOD_VALUE': ('N/A, N/A, N/A, N/A, 0.025'), - 'OTHER_COMMENTS': ('www-air.larc.nasa.gov/missions/etc/' + - 'IcarttDataFormat.htm'), + 'OTHER_COMMENTS': ('www-air.larc.nasa.gov/missions/etc/' + + 'IcarttDataFormat.htm'), 'REVISION': 'R0', 'R0': 'No comments for this revision.', 'TFLAG': 'Start_UTC' @@ -2610,8 +2610,8 @@ def test_uamiv_format_read(self): expected = xr.Variable(('TSTEP',), data, dict(bounds='time_bounds', long_name=('synthesized time coordinate ' + - 'from SDATE, STIME, STEP ' + - 'global attributes'))) + 'from SDATE, STIME, STEP ' + + 'global attributes'))) actual = camxfile.variables['time'] assert_allclose(expected, actual) camxfile.close() @@ -2640,8 +2640,8 @@ def test_uamiv_format_mfread(self): data = np.concatenate([data1] * 2, axis=0) attrs = dict(bounds='time_bounds', long_name=('synthesized time coordinate ' + - 'from SDATE, STIME, STEP ' + - 'global attributes')) + 'from SDATE, STIME, STEP ' + + 'global attributes')) expected = xr.Variable(('TSTEP',), data, attrs) actual = camxfile.variables['time'] assert_allclose(expected, actual) @@ -3058,42 +3058,73 @@ def test_http_url(self): assert isinstance(actual.data, da.Array) def test_rasterio_environment(self): + import rasterio with create_tmp_geotiff() as (tmp_file, expected): # Should fail with error since suffix not allowed with pytest.raises(Exception): - with rasterio.Env(CPL_VSIL_CURL_ALLOWED_EXTENSIONS='H5'): + with rasterio.Env(GDAL_SKIP='GTiff'): with xr.open_rasterio(tmp_file) as actual: assert_allclose(actual, expected) def test_rasterio_vrt(self): + import rasterio + # tmp_file default crs is UTM: CRS({'init': 'epsg:32618'} + with create_tmp_geotiff() as (tmp_file, expected): + with rasterio.open(tmp_file) as src: + with rasterio.vrt.WarpedVRT(src, crs='epsg:4326') as vrt: + expected_shape = (vrt.width, vrt.height) + expected_crs = vrt.crs + print(expected_crs) + expected_res = vrt.res + # Value of single pixel in center of image + lon, lat = vrt.xy(vrt.width // 2, vrt.height // 2) + expected_val = next(vrt.sample([(lon, lat)])) + with xr.open_rasterio(vrt) as da: + actual_shape = (da.sizes['x'], da.sizes['y']) + actual_crs = da.crs + print(actual_crs) + actual_res = da.res + actual_val = da.sel(dict(x=lon, y=lat), + method='nearest').data + + assert actual_crs == expected_crs + assert actual_res == expected_res + assert actual_shape == expected_shape + assert expected_val.all() == actual_val.all() + + @network + def test_rasterio_vrt_network(self): + import rasterio + url = 'https://storage.googleapis.com/\ gcp-public-data-landsat/LC08/01/047/027/\ LC08_L1TP_047027_20130421_20170310_01_T1/\ LC08_L1TP_047027_20130421_20170310_01_T1_B4.TIF' env = rasterio.Env(GDAL_DISABLE_READDIR_ON_OPEN='EMPTY_DIR', - CPL_VSIL_CURL_USE_HEAD=False, - CPL_VSIL_CURL_ALLOWED_EXTENSIONS='TIF') + CPL_VSIL_CURL_USE_HEAD=False, + CPL_VSIL_CURL_ALLOWED_EXTENSIONS='TIF') with env: with rasterio.open(url) as src: - with WarpedVRT(src, crs='epsg:4326') as vrt: + with rasterio.vrt.WarpedVRT(src, crs='epsg:4326') as vrt: expected_shape = (vrt.width, vrt.height) expected_crs = vrt.crs expected_res = vrt.res # Value of single pixel in center of image - lon,lat = vrt.xy(vrt.width // 2, vrt.height // 2) + lon, lat = vrt.xy(vrt.width // 2, vrt.height // 2) expected_val = next(vrt.sample([(lon, lat)])) with xr.open_rasterio(vrt) as da: actual_shape = (da.sizes['x'], da.sizes['y']) actual_crs = da.crs actual_res = da.res actual_val = da.sel(dict(x=lon, y=lat), - method='nearest').data + method='nearest').data assert_equal(actual_shape, expected_shape) assert_equal(actual_crs, expected_crs) assert_equal(actual_res, expected_res) assert_equal(expected_val, actual_val) + class TestEncodingInvalid(object): def test_extract_nc4_variable_encoding(self): From ce56d35ab04ee5aa291e5f58c3d445c57ac2070b Mon Sep 17 00:00:00 2001 From: Scott Henderson Date: Tue, 18 Dec 2018 19:46:22 -0800 Subject: [PATCH 3/5] removed subclass, added to base RasterioArrayWrapper --- xarray/backends/rasterio_.py | 59 ++++++------------------------------ 1 file changed, 9 insertions(+), 50 deletions(-) diff --git a/xarray/backends/rasterio_.py b/xarray/backends/rasterio_.py index 2c0a24a2a08..27655438cc3 100644 --- a/xarray/backends/rasterio_.py +++ b/xarray/backends/rasterio_.py @@ -22,15 +22,14 @@ class RasterioArrayWrapper(BackendArray): """A wrapper around rasterio dataset objects""" - - def __init__(self, manager, vrt=None): + def __init__(self, manager, vrt_params=None): + from rasterio.vrt import WarpedVRT self.manager = manager # cannot save riods as an attribute: this would break pickleability riods = manager.acquire() - if vrt: - riods = vrt - + riods = riods if vrt_params is None else WarpedVRT(riods, **vrt_params) + self.vrt_params = vrt_params self._shape = (riods.count, riods.height, riods.width) dtypes = riods.dtypes @@ -104,6 +103,7 @@ def _get_indexer(self, key): return band_key, tuple(window), tuple(squeeze_axis), tuple(np_inds) def _getitem(self, key): + from rasterio.vrt import WarpedVRT band_key, window, squeeze_axis, np_inds = self._get_indexer(key) if not band_key or any(start == stop for (start, stop) in window): @@ -113,6 +113,7 @@ def _getitem(self, key): out = np.zeros(shape, dtype=self.dtype) else: riods = self.manager.acquire() + riods = riods if self.vrt_params is None else WarpedVRT(riods,**self.vrt_params) out = riods.read(band_key, window=window) if squeeze_axis: @@ -124,42 +125,6 @@ def __getitem__(self, key): key, self.shape, indexing.IndexingSupport.OUTER, self._getitem) -class RasterioVRTWrapper(RasterioArrayWrapper): - """A wrapper around rasterio WarpedVRT objects""" - - def __init__(self, manager, vrt_params): - from rasterio.vrt import WarpedVRT - self.manager = manager - self.vrt_params = vrt_params - # cannot save riods as an attribute: this would break pickleability - riods = manager.acquire() - vrt = WarpedVRT(riods, **vrt_params) - self._shape = (vrt.count, vrt.height, vrt.width) - - dtypes = vrt.dtypes - if not np.all(np.asarray(dtypes) == dtypes[0]): - raise ValueError('All bands should have the same dtype') - self._dtype = np.dtype(dtypes[0]) - - def _getitem(self, key): - from rasterio.vrt import WarpedVRT - band_key, window, squeeze_axis, np_inds = self._get_indexer(key) - - if not band_key or any(start == stop for (start, stop) in window): - # no need to do IO - shape = (len(band_key),) + tuple( - stop - start for (start, stop) in window) - out = np.zeros(shape, dtype=self.dtype) - else: - riods = self.manager.acquire() - vrt = WarpedVRT(riods, **self.vrt_params) - out = vrt.read(band_key, window=window) - - if squeeze_axis: - out = np.squeeze(out, axis=squeeze_axis) - return out[np_inds] - - def _parse_envi(meta): """Parse ENVI metadata into Python data structures. @@ -242,7 +207,7 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, The newly created DataArray. """ import rasterio - + from rasterio.vrt import WarpedVRT vrt_params = None if isinstance(filename, rasterio.io.DatasetReader): filename = filename.name @@ -258,9 +223,7 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, manager = CachingFileManager(rasterio.open, filename, mode='r') riods = manager.acquire() - - if vrt_params: - riods = rasterio.vrt.WarpedVRT(riods, **vrt_params) + riods = riods if vrt_params is None else WarpedVRT(riods, **vrt_params) if cache is None: cache = chunks is None @@ -340,11 +303,7 @@ def open_rasterio(filename, parse_coordinates=None, chunks=None, cache=None, else: attrs[k] = v - if vrt_params: - data = indexing.LazilyOuterIndexedArray(RasterioVRTWrapper(manager, - vrt_params)) - else: - data = indexing.LazilyOuterIndexedArray(RasterioArrayWrapper(manager)) + data = indexing.LazilyOuterIndexedArray(RasterioArrayWrapper(manager, vrt_params)) # this lets you write arrays loaded with rasterio data = indexing.CopyOnWriteArray(data) From a113b50f014f8ec0dcb878fdd37560ba22c7f226 Mon Sep 17 00:00:00 2001 From: Scott Henderson Date: Wed, 19 Dec 2018 09:48:50 -0800 Subject: [PATCH 4/5] upped rasterio test version to > 1 --- .travis.yml | 2 +- ...ts-py36-rasterio-0.36.yml => requirements-py36-rasterio.yml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename ci/{requirements-py36-rasterio-0.36.yml => requirements-py36-rasterio.yml} (93%) diff --git a/.travis.yml b/.travis.yml index defb37ec8aa..881d293263b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ matrix: - env: CONDA_ENV=py36-bottleneck-dev - env: CONDA_ENV=py36-condaforge-rc - env: CONDA_ENV=py36-pynio-dev - - env: CONDA_ENV=py36-rasterio-0.36 + - env: CONDA_ENV=py36-rasterio - env: CONDA_ENV=py36-zarr-dev - env: CONDA_ENV=docs - env: CONDA_ENV=py36-hypothesis diff --git a/ci/requirements-py36-rasterio-0.36.yml b/ci/requirements-py36-rasterio.yml similarity index 93% rename from ci/requirements-py36-rasterio-0.36.yml rename to ci/requirements-py36-rasterio.yml index 5c724e1b981..2ec75f5d8b2 100644 --- a/ci/requirements-py36-rasterio-0.36.yml +++ b/ci/requirements-py36-rasterio.yml @@ -16,7 +16,7 @@ dependencies: - scipy - seaborn - toolz - - rasterio=0.36.0 + - rasterio>=1.0 - bottleneck - pip: - coveralls From dde9428fec1ec6ebabd016955feb82569abcf389 Mon Sep 17 00:00:00 2001 From: Scott Henderson Date: Wed, 19 Dec 2018 10:46:04 -0800 Subject: [PATCH 5/5] specified rasterio version should be greater than 1 --- doc/installing.rst | 2 +- doc/whats-new.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/installing.rst b/doc/installing.rst index 64751eea637..fbe6a316936 100644 --- a/doc/installing.rst +++ b/doc/installing.rst @@ -32,7 +32,7 @@ For netCDF and IO for accessing CAMx, GEOS-Chem (bpch), NOAA ARL files, ICARTT files (ffi1001) and many other. - `rasterio `__: for reading GeoTiffs and - other gridded raster datasets. + other gridded raster datasets. (version 1.0 or later) - `iris `__: for conversion to and from iris' Cube objects - `cfgrib `__: for reading GRIB files via the diff --git a/doc/whats-new.rst b/doc/whats-new.rst index ae0772dbb9d..549ab1a533a 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -33,6 +33,8 @@ v0.11.1 (unreleased) Breaking changes ~~~~~~~~~~~~~~~~ +- Minimum rasterio version increased from 0.36 to 1.0 (for ``open_rasterio``) + Enhancements ~~~~~~~~~~~~