[Git][debian-gis-team/rasterio][master] 4 commits: New upstream version 1.0.9
Bas Couwenberg
gitlab at salsa.debian.org
Fri Oct 26 06:34:37 BST 2018
Bas Couwenberg pushed to branch master at Debian GIS Project / rasterio
Commits:
6a96aed5 by Bas Couwenberg at 2018-10-26T05:05:14Z
New upstream version 1.0.9
- - - - -
338fc7de by Bas Couwenberg at 2018-10-26T05:05:25Z
Merge tag 'upstream/1.0.9'
Upstream version 1.0.9
- - - - -
5622e0a2 by Bas Couwenberg at 2018-10-26T05:05:44Z
New upstream release.
- - - - -
cfc76c7c by Bas Couwenberg at 2018-10-26T05:07:13Z
Set distribution to unstable.
- - - - -
21 changed files:
- CHANGES.txt
- README.rst
- debian/changelog
- docs/cli.rst
- rasterio/__init__.py
- rasterio/_base.pyx
- rasterio/_crs.pyx
- rasterio/_env.pyx
- rasterio/_err.pyx
- rasterio/_warp.pyx
- rasterio/enums.py
- rasterio/env.py
- rasterio/features.py
- rasterio/session.py
- rasterio/shutil.pyx
- tests/test_driver_management.py
- tests/test_env.py
- tests/test_features.py
- tests/test_read_resample.py
- tests/test_tag_item.py
- tests/test_warpedvrt.py
Changes:
=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,35 @@
Changes
=======
+1.0.9 (2019-10-25)
+------------------
+
+Bug fixes:
+
+- Delegate test of the environment for existing session credentials to the
+ session class to generalize credentialization of GDAL to cloud providers
+ other than AWS (#1520). The env.hascreds function is no longer used in
+ Rasterio and has been marked as deprecated.
+- Switch to use of botocore Credentials.get_frozen_credentials (#1521).
+- Numpy masked arrays with the normal Numpy mask sense (True == invalid) are
+ now supported as input for feature.shapes(). The mask keyword argument of the
+ function keeps to the GDAL sense of masks (nonzero == invalid) and the
+ documentation has been improved to communicate this (#1517).
+- The defaults for WarpedVRT's `src_nodata` and `nodata` keyword arguments are
+ no longer None, but are markers for the default behavior: inheritance of
+ nodata values from the VRT's source dataset. Values of `None` for these
+ keyword arguments means that the VRT does not inherit from the source and has
+ no nodata value at all (#1503).
+- WEBP has been added to the Compression enum. Exploitation of this new
+ compression mode will require GDAL 2.4.
+- Rasterio now check for two AWS environment variables before creating a
+ session (#1494).
+- The ensure_env_with_credentials decorator which wraps rasterio.open will no
+ longer clobber the credentials in a surrounding environment or seek
+ credentials when they already exist (#1507).
+- The comparison of CRS objects to dicts and strs that we pledged to remove at
+ 1.0 has at last been removed (#1492).
+
1.0.8 (2018-10-02)
------------------
@@ -81,10 +110,12 @@ This version corrects errors made in building binary wheels for 1.0.3. There
are no bug fixes or new features in this version.
1.0.3 (2018-08-01)
-------------------
Bug fixes:
+- A regression in GeoJSON source handling in rio-rasterize (#1425) has been
+ fixed.
+- Rasterization of linear rings (#1431) is now supported.
- The input file handler of rio-rasterize has been changed so that it does not
reject GeoJSON files (#1425).
- Linear rings have been added as acceptable input for rio-rasterize and other
=====================================
README.rst
=====================================
@@ -230,6 +230,13 @@ this from the downloads folder:
$ pip install GDAL-2.0.2-cp27-none-win32.whl
$ pip install rasterio-0.34.0-cp27-cp27m-win32.whl
+You can also install rasterio with conda using Anaconda's conda-forge channel.
+
+.. code-block:: console
+
+ $ conda install -c conda-forge rasterio
+
+
Source Distributions
--------------------
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+rasterio (1.0.9-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+
+ -- Bas Couwenberg <sebastic at debian.org> Fri, 26 Oct 2018 07:07:04 +0200
+
rasterio (1.0.8-1) unstable; urgency=medium
* Team upload.
=====================================
docs/cli.rst
=====================================
@@ -452,6 +452,15 @@ Information about existing overviews can be printed using the --ls option.
$ rio overview --ls
+The block size (tile width and height) used for overviews (internal
+or external) can be specified by setting the ``GDAL_TIFF_OVR_BLOCKSIZE``
+environment variable to a power-of-two value between 64 and 4096. The
+default value is 128.
+
+.. code-block:: console
+
+ $ GDAL_TIFF_OVR_BLOCKSIZE=256 rio overview --build 2^1..4
+
rasterize
---------
=====================================
rasterio/__init__.py
=====================================
@@ -25,7 +25,7 @@ from rasterio.drivers import is_blacklisted
from rasterio.dtypes import (
bool_, ubyte, uint8, uint16, int16, uint32, int32, float32, float64,
complex_, check_dtype)
-from rasterio.env import ensure_env_credentialled, Env
+from rasterio.env import ensure_env_with_credentials, Env
from rasterio.errors import RasterioIOError
from rasterio.compat import string_types
from rasterio.io import (
@@ -43,7 +43,7 @@ import rasterio.path
__all__ = ['band', 'open', 'pad', 'Env']
-__version__ = "1.0.8"
+__version__ = "1.0.9"
__gdal_version__ = gdal_version()
# Rasterio attaches NullHandler to the 'rasterio' logger and its
@@ -55,7 +55,7 @@ log = logging.getLogger(__name__)
log.addHandler(NullHandler())
- at ensure_env_credentialled
+ at ensure_env_with_credentials
def open(fp, mode='r', driver=None, width=None, height=None, count=None,
crs=None, transform=None, dtype=None, nodata=None, sharing=True,
**kwargs):
@@ -119,7 +119,7 @@ def open(fp, mode='r', driver=None, width=None, height=None, count=None,
Returns
-------
- A ``DatasetReader`` or ``DatasetUpdater`` object.
+ A ``DatasetReader`` or ``DatasetWriter`` object.
Examples
--------
=====================================
rasterio/_base.pyx
=====================================
@@ -197,7 +197,7 @@ cdef class DatasetBase(object):
try:
self._hds = open_dataset(filename, flags, driver, kwargs, None)
- except CPLE_OpenFailedError as err:
+ except CPLE_BaseError as err:
raise RasterioIOError(str(err))
self.name = path.name
@@ -993,7 +993,7 @@ cdef class DatasetBase(object):
else:
band = self._hds
- if ovr:
+ if ovr is not None:
obj = GDALGetOverview(band, ovr)
if obj == NULL:
raise BandOverviewError(
=====================================
rasterio/_crs.pyx
=====================================
@@ -5,12 +5,11 @@ include "gdal.pxi"
import json
import logging
-import warnings
from rasterio._err import CPLE_BaseError
from rasterio.compat import UserDict
from rasterio.compat import string_types
-from rasterio.errors import CRSError, RasterioDeprecationWarning
+from rasterio.errors import CRSError
from rasterio._base cimport _osr_from_crs as osr_from_crs
from rasterio._base cimport _safe_osr_release
@@ -74,25 +73,10 @@ class _CRS(UserDict):
if not self or not other:
return not self and not other
- # use dictionary equality rules first
- elif isinstance(other, dict):
- warnings.warn(
- "Comparison to dict will be removed in 1.0",
- RasterioDeprecationWarning
- )
- if UserDict(self.data) == UserDict(other):
- return True
-
- else:
- if isinstance(other, str):
- warnings.warn(
- "Comparison to str will be removed in 1.0",
- RasterioDeprecationWarning
- )
- osr_crs1 = osr_from_crs(self)
- osr_crs2 = osr_from_crs(other)
- retval = OSRIsSame(osr_crs1, osr_crs2)
- return bool(retval == 1)
+ osr_crs1 = osr_from_crs(self)
+ osr_crs2 = osr_from_crs(other)
+ retval = OSRIsSame(osr_crs1, osr_crs2)
+ return bool(retval == 1)
finally:
_safe_osr_release(osr_crs1)
=====================================
rasterio/_env.pyx
=====================================
@@ -55,7 +55,7 @@ cdef bint is_64bit = sys.maxsize > 2 ** 32
cdef void log_error(CPLErr err_class, int err_no, const char* msg) with gil:
"""Send CPL debug messages and warnings to Python's logger."""
- log = logging.getLogger('rasterio._gdal')
+ log = logging.getLogger(__name__)
if err_class < 3:
if err_no in code_map:
log.log(level_map[err_class], "%s in %s", code_map[err_no], msg)
=====================================
rasterio/_err.pyx
=====================================
@@ -99,6 +99,10 @@ class CPLE_AWSSignatureDoesNotMatchError(CPLE_BaseError):
pass
+class CPLE_AWSError(CPLE_BaseError):
+ pass
+
+
# Map of GDAL error numbers to the Python exceptions.
exception_map = {
1: CPLE_AppDefinedError,
@@ -119,7 +123,9 @@ exception_map = {
13: CPLE_AWSObjectNotFoundError,
14: CPLE_AWSAccessDeniedError,
15: CPLE_AWSInvalidCredentialsError,
- 16: CPLE_AWSSignatureDoesNotMatchError}
+ 16: CPLE_AWSSignatureDoesNotMatchError,
+ 17: CPLE_AWSError
+}
# CPL Error types as an enum.
=====================================
rasterio/_warp.pyx
=====================================
@@ -592,11 +592,14 @@ def _calculate_default_transform(src_crs, dst_crs, width, height,
return dst_affine, dst_width, dst_height
+DEFAULT_NODATA_FLAG = object()
+
+
cdef class WarpedVRTReaderBase(DatasetReaderBase):
def __init__(self, src_dataset, src_crs=None, dst_crs=None, crs=None,
resampling=Resampling.nearest, tolerance=0.125,
- src_nodata=None, dst_nodata=None, nodata=None,
+ src_nodata=DEFAULT_NODATA_FLAG, dst_nodata=None, nodata=DEFAULT_NODATA_FLAG,
dst_width=None, width=None, dst_height=None, height=None,
src_transform=None, dst_transform=None, transform=None,
init_dest_nodata=True, src_alpha=0, add_alpha=False,
@@ -612,7 +615,8 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
src_transfrom : Affine, optional
Overrides the transform of `src_dataset`.
src_nodata : float, optional
- Overrides the nodata value of `src_dataset`.
+ Overrides the nodata value of `src_dataset`, which is the
+ default.
crs : CRS or str, optional
The coordinate reference system at the end of the warp
operation. Default: the crs of `src_dataset`. dst_crs is
@@ -727,8 +731,8 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
self.resampling = resampling
self.tolerance = tolerance
- self.src_nodata = self.src_dataset.nodata if src_nodata is None else src_nodata
- self.dst_nodata = self.src_nodata if nodata is None else nodata
+ self.src_nodata = self.src_dataset.nodata if src_nodata is DEFAULT_NODATA_FLAG else src_nodata
+ self.dst_nodata = self.src_nodata if nodata is DEFAULT_NODATA_FLAG else nodata
self.dst_width = width
self.dst_height = height
self.dst_transform = transform
=====================================
rasterio/enums.py
=====================================
@@ -28,13 +28,14 @@ class ColorInterp(IntEnum):
class Resampling(IntEnum):
"""Available warp resampling algorithms.
- The subset of 'nearest', 'cubic', 'average', 'mode', and 'gauss'
- are available in making dataset overviews.
+ The first 8, 'nearest', 'bilinear', 'cubic', 'cubic_spline',
+ 'lanczos', 'average', 'mode', and 'gauss', are available for making
+ dataset overviews.
'max', 'min', 'med', 'q1', 'q3' are only supported in GDAL >= 2.0.0.
- 'nearest', 'bilinear', 'cubic', 'cubic_spline', 'lanczos', 'average', 'mode'
- are always available (GDAL >= 1.10).
+ 'nearest', 'bilinear', 'cubic', 'cubic_spline', 'lanczos',
+ 'average', 'mode' are always available (GDAL >= 1.10).
Note: 'gauss' is not available to the functions in rio.warp.
"""
@@ -66,6 +67,7 @@ class Compression(Enum):
none = 'NONE'
zstd = 'ZSTD'
lerc = 'LERC'
+ webp = 'WEBP'
class Interleaving(Enum):
=====================================
rasterio/env.py
=====================================
@@ -8,16 +8,11 @@ import re
import threading
import warnings
-import rasterio
-from rasterio._env import (
- GDALEnv, del_gdal_config, get_gdal_config, set_gdal_config)
+from rasterio._env import GDALEnv, get_gdal_config, set_gdal_config
from rasterio.compat import string_types, getargspec
-from rasterio.dtypes import check_dtype
from rasterio.errors import (
EnvError, GDALVersionError, RasterioDeprecationWarning)
-from rasterio.path import parse_path, UnparsedPath, ParsedPath
from rasterio.session import Session, AWSSession, DummySession
-from rasterio.transform import guard_transform
class ThreadEnv(threading.local):
@@ -194,7 +189,7 @@ class Env(object):
region_name=region_name,
profile_name=profile_name,
aws_unsigned=aws_unsigned)
- elif 'AWS_ACCESS_KEY_ID' in os.environ:
+ elif 'AWS_ACCESS_KEY_ID' in os.environ and 'AWS_SECRET_ACCESS_KEY' in os.environ:
self.session = AWSSession()
else:
self.session = DummySession()
@@ -226,16 +221,6 @@ class Env(object):
options.update(**kwargs)
return Env(*args, **options)
- @property
- def is_credentialized(self):
- """Test for existence of cloud credentials
-
- Returns
- -------
- bool
- """
- return hascreds() # bool(self.session)
-
def credentialize(self):
"""Get credentials and configure GDAL
@@ -247,7 +232,7 @@ class Env(object):
None
"""
- if hascreds():
+ if self.session.hascreds(getenv()):
pass
else:
cred_opts = self.session.get_credential_options()
@@ -338,9 +323,8 @@ def setenv(**options):
def hascreds():
- gdal_config = local._env.get_config_options()
- return bool('AWS_ACCESS_KEY_ID' in gdal_config and
- 'AWS_SECRET_ACCESS_KEY' in gdal_config)
+ warnings.warn("Please use Env.session.hascreds() instead", RasterioDeprecationWarning)
+ return local._env is not None and all(key in local._env.get_config_options() for key in ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'])
def delenv():
@@ -368,6 +352,12 @@ def ensure_env(f):
def ensure_env_credentialled(f):
+ """DEPRECATED alias for ensure_env_with_credentials"""
+ warnings.warn("Please use ensure_env_with_credentials instead", RasterioDeprecationWarning)
+ return ensure_env_with_credentials(f)
+
+
+def ensure_env_with_credentials(f):
"""Ensures a config environment exists and is credentialized
Parameters
@@ -394,9 +384,15 @@ def ensure_env_credentialled(f):
env_ctor = Env.from_defaults
if isinstance(args[0], str):
- session = Session.from_path(args[0])
+ session_cls = Session.cls_from_path(args[0])
+
+ if local._env and session_cls.hascreds(getenv()):
+ session_cls = DummySession
+
+ session = session_cls()
+
else:
- session = Session.from_path(None)
+ session = DummySession()
with env_ctor(session=session):
return f(*args, **kwds)
@@ -449,7 +445,7 @@ class GDALVersion(object):
elif isinstance(input, string_types):
# Extract major and minor version components.
# alpha, beta, rc suffixes ignored
- match = re.search('^\d+\.\d+', input)
+ match = re.search(r'^\d+\.\d+', input)
if not match:
raise ValueError(
"value does not appear to be a valid GDAL version "
=====================================
rasterio/features.py
=====================================
@@ -78,8 +78,12 @@ def shapes(source, mask=None, connectivity=4, transform=IDENTITY):
Data type must be one of rasterio.int16, rasterio.int32,
rasterio.uint8, rasterio.uint16, or rasterio.float32.
mask : numpy ndarray or rasterio Band object, optional
- Values of False or 0 will be excluded from feature generation
- Must evaluate to bool (rasterio.bool_ or rasterio.uint8)
+ Must evaluate to bool (rasterio.bool_ or rasterio.uint8). Values
+ of False or 0 will be excluded from feature generation. Note
+ well that this is the inverse sense from Numpy's, where a mask
+ value of True indicates invalid data in an array. If `source` is
+ a Numpy masked array and `mask` is None, the source's mask will
+ be inverted and used in place of `mask`.
connectivity : int, optional
Use 4 or 8 pixel connectivity for grouping pixels into features
transform : Affine transformation, optional
@@ -104,6 +108,10 @@ def shapes(source, mask=None, connectivity=4, transform=IDENTITY):
memory.
"""
+ if hasattr(source, 'mask') and mask is None:
+ mask = ~source.mask
+ source = source.data
+
transform = guard_transform(transform)
for s, v in _shapes(source, mask, connectivity, transform):
yield s, v
=====================================
rasterio/session.py
=====================================
@@ -1,7 +1,7 @@
"""Abstraction for sessions in various clouds."""
-from rasterio.path import parse_path, UnparsedPath, ParsedPath
+from rasterio.path import parse_path, UnparsedPath
class Session(object):
@@ -18,6 +18,24 @@ class Session(object):
"""
+ @classmethod
+ def hascreds(cls, config):
+ """Determine if the given configuration has proper credentials
+
+ Parameters
+ ----------
+ cls : class
+ A Session class.
+ config : dict
+ GDAL configuration as a dict.
+
+ Returns
+ -------
+ bool
+
+ """
+ return NotImplementedError
+
def get_credential_options(self):
"""Get credentials as GDAL configuration options
@@ -50,40 +68,56 @@ class Session(object):
return cls(session)
@staticmethod
- def from_path(path, *args, **kwargs):
- """Create a session object suited to the data at `path`.
+ def cls_from_path(path):
+ """Find the session class suited to the data at `path`.
Parameters
----------
path : str
A dataset path or identifier.
- args : sequence
- Positional arguments for the foreign session constructor.
- kwargs : dict
- Keyword arguments for the foreign session constructor.
Returns
-------
- Session
+ class
"""
if not path:
- return DummySession()
+ return DummySession
path = parse_path(path)
if isinstance(path, UnparsedPath) or path.is_local:
- return DummySession()
+ return DummySession
elif path.scheme == "s3" or "amazonaws.com" in path.path:
- return AWSSession(*args, **kwargs)
+ return AWSSession
# This factory can be extended to other cloud providers here.
# elif path.scheme == "cumulonimbus": # for example.
# return CumulonimbusSession(*args, **kwargs)
else:
- return DummySession()
+ return DummySession
+
+ @staticmethod
+ def from_path(path, *args, **kwargs):
+ """Create a session object suited to the data at `path`.
+
+ Parameters
+ ----------
+ path : str
+ A dataset path or identifier.
+ args : sequence
+ Positional arguments for the foreign session constructor.
+ kwargs : dict
+ Keyword arguments for the foreign session constructor.
+
+ Returns
+ -------
+ Session
+
+ """
+ return Session.cls_from_path(path)(*args, **kwargs)
class DummySession(Session):
@@ -100,6 +134,24 @@ class DummySession(Session):
self._session = None
self.credentials = {}
+ @classmethod
+ def hascreds(cls, config):
+ """Determine if the given configuration has proper credentials
+
+ Parameters
+ ----------
+ cls : class
+ A Session class.
+ config : dict
+ GDAL configuration as a dict.
+
+ Returns
+ -------
+ bool
+
+ """
+ return True
+
def get_credential_options(self):
"""Get credentials as GDAL configuration options
@@ -157,22 +209,41 @@ class AWSSession(Session):
self.unsigned = aws_unsigned
self._creds = self._session._session.get_credentials()
+ @classmethod
+ def hascreds(cls, config):
+ """Determine if the given configuration has proper credentials
+
+ Parameters
+ ----------
+ cls : class
+ A Session class.
+ config : dict
+ GDAL configuration as a dict.
+
+ Returns
+ -------
+ bool
+
+ """
+ return 'AWS_ACCESS_KEY_ID' in config and 'AWS_SECRET_ACCESS_KEY' in config
+
@property
def credentials(self):
"""The session credentials as a dict"""
- creds = {}
+ res = {}
if self._creds:
- if self._creds.access_key: # pragma: no branch
- creds['aws_access_key_id'] = self._creds.access_key
- if self._creds.secret_key: # pragma: no branch
- creds['aws_secret_access_key'] = self._creds.secret_key
- if self._creds.token:
- creds['aws_session_token'] = self._creds.token
+ frozen_creds = self._creds.get_frozen_credentials()
+ if frozen_creds.access_key: # pragma: no branch
+ res['aws_access_key_id'] = frozen_creds.access_key
+ if frozen_creds.secret_key: # pragma: no branch
+ res['aws_secret_access_key'] = frozen_creds.secret_key
+ if frozen_creds.token:
+ res['aws_session_token'] = frozen_creds.token
if self._session.region_name:
- creds['aws_region'] = self._session.region_name
+ res['aws_region'] = self._session.region_name
if self.requester_pays:
- creds['aws_request_payer'] = 'requester'
- return creds
+ res['aws_request_payer'] = 'requester'
+ return res
def get_credential_options(self):
"""Get credentials as GDAL configuration options
=====================================
rasterio/shutil.pyx
=====================================
@@ -7,7 +7,7 @@ import logging
from rasterio._io cimport DatasetReaderBase
from rasterio._err cimport exc_wrap_int, exc_wrap_pointer
-from rasterio.env import ensure_env_credentialled
+from rasterio.env import ensure_env_with_credentials
from rasterio._err import CPLE_OpenFailedError
from rasterio.errors import DriverRegistrationError, RasterioIOError
from rasterio.path import parse_path, vsi_path
@@ -16,7 +16,7 @@ from rasterio.path import parse_path, vsi_path
log = logging.getLogger(__name__)
- at ensure_env_credentialled
+ at ensure_env_with_credentials
def exists(path):
"""Determine if a dataset exists by attempting to open it.
@@ -47,7 +47,7 @@ def exists(path):
GDALClose(h_dataset)
- at ensure_env_credentialled
+ at ensure_env_with_credentials
def copy(src, dst, driver='GTiff', strict=True, **creation_options):
"""Copy a raster from a path or open dataset handle to a new destination
@@ -120,7 +120,7 @@ def copy(src, dst, driver='GTiff', strict=True, **creation_options):
GDALClose(src_dataset)
- at ensure_env_credentialled
+ at ensure_env_with_credentials
def copyfiles(src, dst):
"""Copy files associated with a dataset from one location to another.
@@ -162,7 +162,7 @@ def copyfiles(src, dst):
GDALClose(h_dataset)
- at ensure_env_credentialled
+ at ensure_env_with_credentials
def delete(path, driver=None):
"""Delete a GDAL dataset
=====================================
tests/test_driver_management.py
=====================================
@@ -20,7 +20,7 @@ def test_drivers_bwd_compat():
def test_cpl_debug_true(tmpdir):
"""Setting CPL_DEBUG=True results in GDAL debug messages."""
- log = logging.getLogger('rasterio._gdal')
+ log = logging.getLogger('rasterio._env')
log.setLevel(logging.DEBUG)
logfile = str(tmpdir.join('test.log'))
fh = logging.FileHandler(logfile)
=====================================
tests/test_env.py
=====================================
@@ -13,6 +13,7 @@ from rasterio.env import Env, defenv, delenv, getenv, setenv, ensure_env, ensure
from rasterio.env import GDALVersion, require_gdal_version
from rasterio.errors import EnvError, RasterioIOError, GDALVersionError
from rasterio.rio.main import main_group
+from rasterio.session import AWSSession
from .conftest import requires_gdal21
@@ -23,8 +24,6 @@ credentials = pytest.mark.skipif(
reason="S3 raster access requires credentials")
-logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
-
L8TIF = "s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF"
L8TIFB2 = "s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B2.TIF"
httpstif = "https://landsat-pds.s3.amazonaws.com/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF"
@@ -167,9 +166,9 @@ def test_aws_session(gdalenv):
aws_access_key_id='id', aws_secret_access_key='key',
aws_session_token='token', region_name='null-island-1')
with rasterio.env.Env(session=aws_session) as s:
- assert s.session._creds.access_key == 'id'
- assert s.session._creds.secret_key == 'key'
- assert s.session._creds.token == 'token'
+ assert s.session._session.get_credentials().get_frozen_credentials().access_key == 'id'
+ assert s.session._session.get_credentials().get_frozen_credentials().secret_key == 'key'
+ assert s.session._session.get_credentials().get_frozen_credentials().token == 'token'
assert s.session._session.region_name == 'null-island-1'
@@ -739,3 +738,22 @@ def test_rio_env_no_credentials(tmpdir, monkeypatch, runner):
with rasterio.Env() as env:
assert env.drivers()
+
+
+def test_nested_credentials(monkeypatch):
+ """Check that rasterio.open() doesn't wipe out surrounding credentials"""
+
+ @ensure_env_credentialled
+ def fake_opener(path):
+ return getenv()
+
+ with rasterio.Env(session=AWSSession(aws_access_key_id='foo', aws_secret_access_key='bar')):
+ assert getenv()['AWS_ACCESS_KEY_ID'] == 'foo'
+ assert getenv()['AWS_SECRET_ACCESS_KEY'] == 'bar'
+
+ monkeypatch.setenv('AWS_ACCESS_KEY_ID', 'lol')
+ monkeypatch.setenv('AWS_SECRET_ACCESS_KEY', 'wut')
+
+ gdalenv = fake_opener('s3://foo/bar')
+ assert gdalenv['AWS_ACCESS_KEY_ID'] == 'foo'
+ assert gdalenv['AWS_SECRET_ACCESS_KEY'] == 'bar'
=====================================
tests/test_features.py
=====================================
@@ -845,6 +845,25 @@ def test_shapes_mask(basic_image):
assert value == 1
+def test_shapes_masked_array(basic_image):
+ """Only pixels not masked out should be converted to features."""
+ mask = np.full(basic_image.shape, False, dtype=rasterio.bool_)
+ mask[4:5, 4:5] = True
+
+ results = list(shapes(np.ma.masked_array(basic_image, mask=mask)))
+
+ assert len(results) == 2
+
+ shape, value = results[0]
+ assert shape == {
+ 'coordinates': [
+ [(2, 2), (2, 5), (4, 5), (4, 4), (5, 4), (5, 2), (2, 2)]
+ ],
+ 'type': 'Polygon'
+ }
+ assert value == 1
+
+
def test_shapes_blank_mask(basic_image):
"""Mask is blank so results should mask shapes without mask."""
assert np.array_equal(
=====================================
tests/test_read_resample.py
=====================================
@@ -1,3 +1,8 @@
+"""
+Rasterio exposes GDAL's resampling/decimation on I/O. These are the tests
+that it does this correctly.
+"""
+
import numpy as np
import rasterio
@@ -7,9 +12,6 @@ from rasterio.windows import Window
from .conftest import requires_gdal2
-# Rasterio exposes GDAL's resampling/decimation on I/O. These are the tests
-# that it does this correctly.
-#
# Rasterio's test dataset is 718 rows by 791 columns.
def test_read_out_shape_resample_down():
@@ -38,6 +40,7 @@ def test_read_out_shape_resample_up():
assert data.mean() == s.read(1, masked=True).mean()
+# TODO: justify or remove this test.
def test_read_downsample_alpha():
with rasterio.Env(GTIFF_IMPLICIT_JPEG_OVR=False):
with rasterio.open('tests/data/alpha.tif') as src:
@@ -51,15 +54,31 @@ def test_read_downsample_alpha():
@requires_gdal2
-def test_resample_alg():
+def test_resample_alg_effect_1():
"""default (nearest) and cubic produce different results"""
with rasterio.open('tests/data/RGB.byte.tif') as s:
+ # Existence of overviews can upset our expectations, so we
+ # guard against that here.
+ assert not any([s.overviews(bidx) for bidx in s.indexes])
out_shape = (s.height // 2, s.width // 2)
nearest = s.read(1, out_shape=out_shape)
cubic = s.read(1, out_shape=out_shape, resampling=Resampling.cubic)
assert np.any(nearest != cubic)
+ at requires_gdal2
+def test_resample_alg_effect_2():
+ """Average and bilinear produce different results"""
+ with rasterio.open('tests/data/RGB.byte.tif') as s:
+ # Existence of overviews can upset our expectations, so we
+ # guard against that here.
+ assert not any([s.overviews(bidx) for bidx in s.indexes])
+ out_shape = (s.height // 2, s.width // 2)
+ avg = s.read(1, out_shape=out_shape, resampling=Resampling.average)
+ bilin = s.read(1, out_shape=out_shape, resampling=Resampling.bilinear)
+ assert np.any(avg != bilin)
+
+
@requires_gdal2
def test_float_window():
"""floating point windows work"""
=====================================
tests/test_tag_item.py
=====================================
@@ -21,6 +21,7 @@ def test_get_tag_item():
def test_get_tag_item_Tiff():
with rasterio.open('tests/data/cogeo.tif') as src:
assert src.get_tag_item('IFD_OFFSET', 'TIFF', bidx=1) == '8'
+ assert src.get_tag_item('IFD_OFFSET', 'TIFF', bidx=1, ovr=0) == '1104'
assert src.get_tag_item('IFD_OFFSET', 'TIFF', bidx=1, ovr=1) == '1504'
assert not src.get_tag_item('IF', 'TIFF', bidx=1)
with pytest.raises(Exception):
=====================================
tests/test_warpedvrt.py
=====================================
@@ -60,6 +60,20 @@ def test_warped_vrt(path_rgb_byte_tif):
assert vrt.mask_flag_enums == ([MaskFlags.nodata],) * 3
+ at requires_gdal21
+def test_warped_vrt_nondefault_nodata(path_rgb_byte_tif):
+ """A VirtualVRT has expected nondefault nodata values."""
+ with rasterio.open(path_rgb_byte_tif) as src:
+ vrt = WarpedVRT(src, crs=DST_CRS, src_nodata=None, nodata=None)
+ assert vrt.dst_crs == CRS.from_string(DST_CRS)
+ assert vrt.src_nodata is None
+ assert vrt.dst_nodata is None
+ assert vrt.tolerance == 0.125
+ assert vrt.resampling == Resampling.nearest
+ assert vrt.warp_extras == {"init_dest": "NO_DATA"}
+ assert vrt.mask_flag_enums == ([MaskFlags.all_valid],) * 3
+
+
@requires_gdal21(reason="Nodata deletion requires GDAL 2.1+")
def test_warped_vrt_add_alpha(path_rgb_byte_tif):
"""A VirtualVRT has the expected VRT properties."""
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/compare/78e0f2c10437a711c7185e3e0cf8a30641a9e480...cfc76c7c02e7ca1478fa232ed381e2149c3cf944
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/compare/78e0f2c10437a711c7185e3e0cf8a30641a9e480...cfc76c7c02e7ca1478fa232ed381e2149c3cf944
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20181026/4acaccd4/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list