[Git][debian-gis-team/rasterio][upstream] New upstream version 1.2.7

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Wed Sep 8 06:19:46 BST 2021



Bas Couwenberg pushed to branch upstream at Debian GIS Project / rasterio


Commits:
b5d9e460 by Bas Couwenberg at 2021-09-08T06:59:06+02:00
New upstream version 1.2.7
- - - - -


19 changed files:

- CHANGES.txt
- README.rst
- rasterio/__init__.py
- rasterio/_crs.pyx
- rasterio/env.py
- rasterio/features.py
- rasterio/session.py
- rasterio/transform.py
- rasterio/windows.py
- requirements.txt
- tests/test_env.py
- tests/test_merge.py
- tests/test_rio_info.py
- tests/test_rpcs.py
- tests/test_transform.py
- tests/test_warp.py
- tests/test_warpedvrt.py
- tests/test_windows.py
- tests/test_write.py


Changes:

=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,21 @@
 Changes
 =======
 
+1.2.7 (2021-09-07)
+------------------
+
+- CRS objects are now compared to the EPSG authority using OSRFindMatches for
+  compatibility with GDAL 3.3.2 (#2279).
+- Allow open's fp keyword argument to pass the credential decorator (#2267).
+- Fix a copy-paste bug in features.geometry_window() affecting Y-axis padding
+  (#2266).
+- Note upcoming deprecation of the height and width parameters of
+  rasterio.windows.from_bounds() and stop using these parameters in project
+  code and tests.
+- The transform.xy and transform.rowcol functions now return a pair of
+  single-element lists if passed a pair of single-element lists. This was the
+  original behavior, but was broken in version 1.2.1 (#2242).
+
 1.2.6 (2021-06-22)
 ------------------
 


=====================================
README.rst
=====================================
@@ -183,9 +183,58 @@ other libraries provided by most major operating systems and also depends on
 the non standard GEOS and PROJ4 libraries. How to meet these requirement will
 be explained below.
 
-Rasterio's Python dependencies are listed in its requirements.txt file.
-
-Development also requires (see requirements-dev.txt) Cython and other packages.
+Rasterio's Python dependencies are (see the package metadata file):
+
+.. code-block::
+
+    affine
+    attrs
+    certifi
+    click>=4.0
+    cligj>=0.5
+    numpy
+    snuggs>=1.4.1
+    click-plugins
+    setuptools
+
+    [all]
+    hypothesis
+    pytest-cov>=2.2.0
+    matplotlib
+    boto3>=1.3.1
+    numpydoc
+    pytest>=2.8.2
+    shapely
+    ipython>=2.0
+    sphinx
+    packaging
+    ghp-import
+    sphinx-rtd-theme
+
+    [docs]
+    ghp-import
+    numpydoc
+    sphinx
+    sphinx-rtd-theme
+
+    [ipython]
+    ipython>=2.0
+
+    [plot]
+    matplotlib
+
+    [s3]
+    boto3>=1.3.1
+
+    [test]
+    boto3>=1.3.1
+    hypothesis
+    packaging
+    pytest-cov>=2.2.0
+    pytest>=2.8.2
+    shapely
+
+Development requires Cython and other packages.
 
 Binary Distributions
 --------------------


=====================================
rasterio/__init__.py
=====================================
@@ -40,7 +40,7 @@ import rasterio.enums
 import rasterio.path
 
 __all__ = ['band', 'open', 'pad', 'Env']
-__version__ = "1.2.6"
+__version__ = "1.2.7"
 __gdal_version__ = gdal_version()
 
 # Rasterio attaches NullHandler to the 'rasterio' logger and its


=====================================
rasterio/_crs.pyx
=====================================
@@ -3,6 +3,7 @@
 """Coordinate reference systems, class and functions.
 """
 
+from collections import defaultdict
 import logging
 
 import rasterio._env
@@ -215,14 +216,13 @@ cdef class _CRS(object):
         """
         if self._epsg is not None:
             return self._epsg
-
-        auth = self.to_authority()
-        if auth is None:
-            return None
-        name, code = auth
-        if name.upper() == "EPSG":
-            self._epsg = int(code)
-        return self._epsg
+        else:
+            matches = self._matches()
+            if "EPSG" in matches:
+                self._epsg = int(matches["EPSG"][0])
+                return self._epsg
+            else:
+                return None
 
     def to_authority(self):
         """The authority name and code of the CRS
@@ -231,30 +231,67 @@ cdef class _CRS(object):
         -------
         (str, str) or None
 
+        """
+        matches = self._matches()
+        # Note: before version 1.2.7 this function only paid attention
+        # to EPSG as an authority, which is why it takes priority over
+        # others even if they were a better match.
+        if "EPSG" in matches:
+            return "EPSG", matches["EPSG"][0]
+        elif "OGC" in matches:
+            return "OGC", matches["OGC"][0]
+        elif "ESRI" in matches:
+            return "ESRI", matches["ESRI"][0]
+        else:
+            return None
+
+    def _matches(self):
+        """Find matches in authority files.
+
+        Returns
+        -------
+        dict : {name: [codes]}
+            A dictionary in which capitalized authority names are the
+            keys and lists of codes ordered by match confidence,
+            descending, are the values.
+
         """
         cdef OGRSpatialReferenceH osr = NULL
+        cdef OGRSpatialReferenceH *matches = NULL
+        cdef int num_matches = 0
+        cdef int i = 0
 
-        code = None
-        name = None
+        results = defaultdict(list)
 
         try:
             osr = exc_wrap_pointer(OSRClone(self._osr))
-            exc_wrap_ogrerr(OSRMorphFromESRI(osr))
 
-            if OSRAutoIdentifyEPSG(osr) == 0:
-                c_code = OSRGetAuthorityCode(osr, NULL)
-                c_name = OSRGetAuthorityName(osr, NULL)
-                if c_code != NULL and c_name != NULL:
-                    code = c_code.decode('utf-8')
-                    name = c_name.decode('utf-8')
+            if gdal_version().startswith("3"):
+                matches = OSRFindMatches(osr, NULL, &num_matches, NULL)
 
-        finally:
-            _safe_osr_release(osr)
+                for i in range(num_matches):
+                    c_code = OSRGetAuthorityCode(matches[i], NULL)
+                    c_name = OSRGetAuthorityName(matches[i], NULL)
+                    if c_code != NULL and c_name != NULL:
+                        code = c_code.decode('utf-8')
+                        name = c_name.decode('utf-8')
+                        results[name].append(code)
 
-        if None not in (name, code):
-            return (name, code)
+            else:
+                exc_wrap_ogrerr(OSRMorphFromESRI(osr))
+                if OSRAutoIdentifyEPSG(osr) == 0:
+                    c_code = OSRGetAuthorityCode(osr, NULL)
+                    c_name = OSRGetAuthorityName(osr, NULL)
+                    if c_code != NULL and c_name != NULL:
+                        code = c_code.decode('utf-8')
+                        name = c_name.decode('utf-8')
+                        results[name].append(code)
+
+            return results
 
-        return None
+        finally:
+            _safe_osr_release(osr)
+            OSRFreeSRSArray(matches)
 
     @staticmethod
     def from_epsg(code):


=====================================
rasterio/env.py
=====================================
@@ -420,8 +420,10 @@ def ensure_env_with_credentials(f):
         else:
             env_ctor = Env.from_defaults
 
-        if isinstance(args[0], str):
-            session_cls = Session.cls_from_path(args[0])
+        fp_arg = kwds.get("fp", None) or args[0]
+
+        if isinstance(fp_arg, str):
+            session_cls = Session.cls_from_path(fp_arg)
 
             if local._env and session_cls.hascreds(getenv()):
                 session_cls = DummySession


=====================================
rasterio/features.py
=====================================
@@ -454,7 +454,7 @@ def geometry_window(
     ys = [
         y
         for (left, bottom, right, top) in all_bounds
-        for y in (top + pad_y, top + pad_y, bottom - pad_x, bottom - pad_x)
+        for y in (top + pad_y, top + pad_y, bottom - pad_y, bottom - pad_y)
     ]
 
     rows1, cols1 = rowcol(


=====================================
rasterio/session.py
=====================================
@@ -285,7 +285,7 @@ class AWSSession(Session):
         self.unsigned = bool(os.getenv("AWS_NO_SIGN_REQUEST", aws_unsigned))
         self.endpoint_url = endpoint_url
         self._creds = (
-            self._session._session.get_credentials()
+            self._session.get_credentials()
             if not self.unsigned and self._session
             else None
         )


=====================================
rasterio/transform.py
=====================================
@@ -6,6 +6,7 @@ import sys
 
 from affine import Affine
 
+from rasterio.errors import TransformError
 from rasterio._transform import _transform_from_gcps
 
 IDENTITY = Affine.identity()
@@ -127,7 +128,8 @@ def array_bounds(height, width, transform):
 
 
 def xy(transform, rows, cols, offset='center'):
-    """Returns the x and y coordinates of pixels at `rows` and `cols`.
+    """Get the x and y coordinates of pixels at `rows` and `cols`.
+
     The pixel's center is returned by default, but a corner can be returned
     by setting `offset` to one of `ul, ur, ll, lr`.
 
@@ -135,9 +137,9 @@ def xy(transform, rows, cols, offset='center'):
     ----------
     transform : affine.Affine
         Transformation from pixel coordinates to coordinate reference system.
-    rows : list or int
+    rows : int or sequence of ints
         Pixel rows.
-    cols : list or int
+    cols : int or sequence of ints
         Pixel columns.
     offset : str, optional
         Determines if the returned coordinates are for the center of the
@@ -145,16 +147,12 @@ def xy(transform, rows, cols, offset='center'):
 
     Returns
     -------
-    xs : list
+    xs : float or list of floats
         x coordinates in coordinate reference system
-    ys : list
+    ys : float or list of floats
         y coordinates in coordinate reference system
-    """
-    if not isinstance(cols, Iterable):
-        cols = [cols]
-    if not isinstance(rows, Iterable):
-        rows = [rows]
 
+    """
     if offset == 'center':
         coff, roff = (0.5, 0.5)
     elif offset == 'ul':
@@ -166,26 +164,21 @@ def xy(transform, rows, cols, offset='center'):
     elif offset == 'lr':
         coff, roff = (1, 1)
     else:
-        raise ValueError("Invalid offset")
+        raise TransformError("Invalid offset")
 
-    xs = []
-    ys = []
-    T = transform * transform.translation(coff, roff)
-    for pt in zip(cols, rows):
-        x, y = T * pt
-        xs.append(x)
-        ys.append(y)
+    adjusted_transform = transform * Affine.translation(coff, roff)
 
-    if len(xs) == 1:
-        # xs and ys will always have the same length
-        return xs[0], ys[0]
-    return xs, ys
+    if isinstance(rows, (int, float)) and isinstance(cols, (int, float)):
+        return adjusted_transform * (cols, rows)
+    elif isinstance(rows, Iterable) and isinstance(cols, Iterable):
+        xs, ys = zip(*(adjusted_transform * (col, row) for col, row in zip(cols, rows)))
+        return list(xs), list(ys)
+    else:
+        raise TransformError("Invalid inputs")
 
 
 def rowcol(transform, xs, ys, op=math.floor, precision=None):
-    """
-    Returns the rows and cols of the pixels containing (x, y) given a
-    coordinate reference system.
+    """The rows and cols of the pixels containing (x, y).
 
     Use an epsilon, magnitude determined by the precision parameter
     and sign determined by the op function:
@@ -208,17 +201,12 @@ def rowcol(transform, xs, ys, op=math.floor, precision=None):
 
     Returns
     -------
-    rows : list of ints
-        list of row indices
-    cols : list of ints
-        list of column indices
-    """
-
-    if not isinstance(xs, Iterable):
-        xs = [xs]
-    if not isinstance(ys, Iterable):
-        ys = [ys]
+    rows : list or int
+        Row indices.
+    cols : list or int
+        Column indices.
 
+    """
     if precision is None:
         eps = sys.float_info.epsilon
     elif isinstance(precision, int):
@@ -232,17 +220,14 @@ def rowcol(transform, xs, ys, op=math.floor, precision=None):
 
     invtransform = ~transform
 
-    rows = []
-    cols = []
-    for x, y in zip(xs, ys):
-        fcol, frow = invtransform * (x + eps, y + eps)
-        cols.append(op(fcol))
-        rows.append(op(frow))
-
-    if len(cols) == 1:
-        # rows and cols will always have the same length
-        return rows[0], cols[0]
-    return rows, cols
+    if isinstance(xs, (int, float)) and isinstance(ys, (int, float)):
+        fcol, frow = invtransform * (xs + eps, ys + eps)
+        return op(frow), op(fcol)
+    elif isinstance(xs, Iterable) and isinstance(ys, Iterable):
+        fcols, frows = zip(*(invtransform * (x + eps, y + eps) for x, y in zip(xs, ys)))
+        return [op(row) for row in frows], [op(col) for col in fcols]
+    else:
+        raise TransformError("Invalid inputs")
 
 
 def from_gcps(gcps):


=====================================
rasterio/windows.py
=====================================
@@ -273,13 +273,11 @@ def from_bounds(
         Top (north) bounding coordinates
     transform: Affine, required
         Affine transform matrix.
-    height: int, required
-        Number of rows of the window.
-    width: int, required
-        Number of columns of the window.
     precision: int or float, optional
         An integer number of decimal points of precision when computing
         inverse transform, or an absolute float precision.
+    height, width: int, optional
+        These parameters are unused and will be deprecated.
 
     Returns
     -------
@@ -301,6 +299,10 @@ def from_bounds(
     if (bottom - top) / transform.e < 0:
         raise WindowError("Bounds and transform are inconsistent")
 
+    if height is None or width is not None:
+        # TODO: raise a deprecation warning in version 1.3.0.
+        pass
+
     rows, cols = rowcol(
         transform,
         [left, right, right, left],


=====================================
requirements.txt
=====================================
@@ -1,10 +1,9 @@
 affine~=2.3.0
 attrs>=19.2.0
-boto3>=1.2.4
-click~=7.1.0
+boto3>=1.3.1
+click~=8.0
 click-plugins
 cligj>=0.5
-enum34; python_version < "3.4"
 matplotlib
 numpy>=1.10
 snuggs~=1.4.0


=====================================
tests/test_env.py
=====================================
@@ -26,7 +26,7 @@ from .conftest import requires_gdal21
 
 # Custom markers.
 credentials = pytest.mark.skipif(
-    not(boto3.Session()._session.get_credentials()),
+    not(boto3.Session().get_credentials()),
     reason="S3 raster access requires credentials")
 
 
@@ -168,17 +168,33 @@ def test_ensure_env_credentialled_decorator(monkeypatch, gdalenv):
     monkeypatch.setenv('AWS_SESSION_TOKEN', 'token')
 
     @ensure_env_credentialled
-    def f(path):
+    def f(fp):
         return getenv()
 
-    config = f('s3://foo/bar')
-    assert config['AWS_ACCESS_KEY_ID'] == 'id'
-    assert config['AWS_SECRET_ACCESS_KEY'] == 'key'
-    assert config['AWS_SESSION_TOKEN'] == 'token'
+    config = f("s3://foo/bar")
+    assert config["AWS_ACCESS_KEY_ID"] == "id"
+    assert config["AWS_SECRET_ACCESS_KEY"] == "key"
+    assert config["AWS_SESSION_TOKEN"] == "token"
 
     monkeypatch.undo()
 
 
+def test_ensure_env_credentialled_decorator_fp_kwarg(monkeypatch, gdalenv):
+    """Demonstrate resolution of #2267"""
+    monkeypatch.setenv('AWS_ACCESS_KEY_ID', 'id')
+    monkeypatch.setenv('AWS_SECRET_ACCESS_KEY', 'key')
+    monkeypatch.setenv('AWS_SESSION_TOKEN', 'token')
+
+    @ensure_env_credentialled
+    def f(fp):
+        return getenv()
+
+    config = f(fp="s3://foo/bar")
+    assert config["AWS_ACCESS_KEY_ID"] == "id"
+    assert config["AWS_SECRET_ACCESS_KEY"] == "key"
+    assert config["AWS_SESSION_TOKEN"] == "token"
+
+    monkeypatch.undo()
 def test_no_aws_gdal_config(gdalenv):
     """Trying to set AWS-specific GDAL config options fails."""
     with pytest.raises(EnvError):


=====================================
tests/test_merge.py
=====================================
@@ -72,7 +72,7 @@ def test_unsafe_casting():
 
 
 @pytest.mark.skipif(
-    not (boto3.Session()._session.get_credentials()),
+    not (boto3.Session().get_credentials()),
     reason="S3 raster access requires credentials",
 )
 @pytest.mark.network


=====================================
tests/test_rio_info.py
=====================================
@@ -417,7 +417,7 @@ def test_info_no_credentials(tmpdir, monkeypatch, runner):
         ['info', 'tests/data/RGB.byte.tif'])
     assert result.exit_code == 0
 
- at pytest.mark.skipif(not(boto3.Session()._session.get_credentials()), reason="S3 raster access requires credentials")
+ at pytest.mark.skipif(not(boto3.Session().get_credentials()), reason="S3 raster access requires credentials")
 @requires_gdal23(reason="Unsigned S3 requests require GDAL ~= 2.3")
 @pytest.mark.network
 def test_info_aws_unsigned(runner):


=====================================
tests/test_rpcs.py
=====================================
@@ -3,118 +3,127 @@ import rasterio
 from rasterio.rpc import RPC
 
 TEST_RPCS_NATIVE_PYTHON = {
-    'err_bias': 0.5,
-    'err_rand': 0.5,
-    'height_off': 89.0,
-    'height_scale': 701.0,
-    'lat_off': 49.2199,
-    'lat_scale': 0.3093,
-    'line_den_coeff': [1.0,
-    0.0009222511757408093,
-    0.0009437608823165506,
-    0.0,
-    3.227813186168402e-07,
-    0.0,
-    -1.209023819818124e-08,
-    1.847595567040099e-06,
-    5.799102000140301e-07,
-    -4.460833665210641e-07,
-    0.0,
-    0.0,
-    -6.034797295293836e-08,
-    0.0,
-    1.667569505660956e-07,
-    -2.974442475526043e-08,
-    0.0,
-    0.0,
-    0.0,
-    0.0],
-    'line_num_coeff': [0.002001303029283497,
-    -0.1860717345625879,
-    -1.127856422682348,
-    -4.632230551975493e-05,
-    0.001019881908582774,
-    5.673855447822687e-08,
-    -8.698433522294479e-08,
-    -0.00322675985508854,
-    -0.001332756784778704,
-    0.0,
-    1.215249975522747e-08,
-    -7.132377372126199e-07,
-    2.017197679474549e-06,
-    8.275158167048898e-08,
-    -1.210585983708413e-06,
-    -1.07835388717073e-06,
-    5.032973521799926e-07,
-    0.0,
-    1.716128319528072e-08,
-    0.0],
-    'line_off': 5760.0,
-    'line_scale': 5761.0,
-    'long_off': -123.176,
-    'long_scale': 0.4534,
-    'samp_den_coeff': [1.0,
-    9.278262976396983e-05,
-    0.001781926782031641,
-    -0.0006510570023623242,
-    -0.0002216055849873611,
-    9.161290674286373e-07,
-    3.126587074446549e-06,
-    0.0003565361629769621,
-    -2.582447705973245e-05,
-    -9.228544337667984e-05,
-    5.29808516621947e-07,
-    1.025006482963347e-05,
-    7.478466127324454e-07,
-    -1.692384939549647e-06,
-    -1.124443674146492e-05,
-    -1.793628425616464e-07,
-    -2.791740249303018e-07,
-    -2.820306656137878e-07,
-    4.593502012060843e-08,
-    1.035174961061441e-07],
-    'samp_num_coeff': [0.02202618393703774,
-    1.185886131197477,
-    -0.2151710781539888,
-    0.03045218075295352,
-    0.002420581655336635,
-    -4.398438360671764e-06,
-    5.871407208028941e-05,
-    -0.02166676957828599,
-    -0.0004180699044156175,
-    -2.753492566174621e-05,
-    -7.124639699900795e-06,
-    -1.101195320211651e-05,
-    -0.0001119110912711932,
-    -0.000109618465373252,
-    0.0001183590823839227,
-    1.382552349641905e-05,
-    1.997075688106731e-05,
-    2.673528192748438e-05,
-    -1.230207121465409e-06,
-    -2.830467933081173e-06],
-    'samp_off': 3724.0,
-    'samp_scale': 3725.0
-    }
+    "err_bias": 0.5,
+    "err_rand": 0.5,
+    "height_off": 89.0,
+    "height_scale": 701.0,
+    "lat_off": 49.2199,
+    "lat_scale": 0.3093,
+    "line_den_coeff": [
+        1.0,
+        0.0009222511757408093,
+        0.0009437608823165506,
+        0.0,
+        3.227813186168402e-07,
+        0.0,
+        -1.209023819818124e-08,
+        1.847595567040099e-06,
+        5.799102000140301e-07,
+        -4.460833665210641e-07,
+        0.0,
+        0.0,
+        -6.034797295293836e-08,
+        0.0,
+        1.667569505660956e-07,
+        -2.974442475526043e-08,
+        0.0,
+        0.0,
+        0.0,
+        0.0,
+    ],
+    "line_num_coeff": [
+        0.002001303029283497,
+        -0.1860717345625879,
+        -1.127856422682348,
+        -4.632230551975493e-05,
+        0.001019881908582774,
+        5.673855447822687e-08,
+        -8.698433522294479e-08,
+        -0.00322675985508854,
+        -0.001332756784778704,
+        0.0,
+        1.215249975522747e-08,
+        -7.132377372126199e-07,
+        2.017197679474549e-06,
+        8.275158167048898e-08,
+        -1.210585983708413e-06,
+        -1.07835388717073e-06,
+        5.032973521799926e-07,
+        0.0,
+        1.716128319528072e-08,
+        0.0,
+    ],
+    "line_off": 5760.0,
+    "line_scale": 5761.0,
+    "long_off": -123.176,
+    "long_scale": 0.4534,
+    "samp_den_coeff": [
+        1.0,
+        9.278262976396983e-05,
+        0.001781926782031641,
+        -0.0006510570023623242,
+        -0.0002216055849873611,
+        9.161290674286373e-07,
+        3.126587074446549e-06,
+        0.0003565361629769621,
+        -2.582447705973245e-05,
+        -9.228544337667984e-05,
+        5.29808516621947e-07,
+        1.025006482963347e-05,
+        7.478466127324454e-07,
+        -1.692384939549647e-06,
+        -1.124443674146492e-05,
+        -1.793628425616464e-07,
+        -2.791740249303018e-07,
+        -2.820306656137878e-07,
+        4.593502012060843e-08,
+        1.035174961061441e-07,
+    ],
+    "samp_num_coeff": [
+        0.02202618393703774,
+        1.185886131197477,
+        -0.2151710781539888,
+        0.03045218075295352,
+        0.002420581655336635,
+        -4.398438360671764e-06,
+        5.871407208028941e-05,
+        -0.02166676957828599,
+        -0.0004180699044156175,
+        -2.753492566174621e-05,
+        -7.124639699900795e-06,
+        -1.101195320211651e-05,
+        -0.0001119110912711932,
+        -0.000109618465373252,
+        0.0001183590823839227,
+        1.382552349641905e-05,
+        1.997075688106731e-05,
+        2.673528192748438e-05,
+        -1.230207121465409e-06,
+        -2.830467933081173e-06,
+    ],
+    "samp_off": 3724.0,
+    "samp_scale": 3725.0,
+}
 
 TEST_RPCS_FROM_GDAL = {
-    'ERR_BIAS': '5.000000000000000e-01',
-    'ERR_RAND': '5.000000000000000e-01',
-    'HEIGHT_OFF': '8.900000000000000e+01',
-    'HEIGHT_SCALE': '7.010000000000000e+02',
-    'LAT_OFF': '4.921990000000000e+01',
-    'LAT_SCALE': '3.093000000000000e-01',
-    'LINE_DEN_COEFF': '1.000000000000000e+00 9.222511757408093e-04 9.437608823165506e-04 0.000000000000000e+00 3.227813186168402e-07 0.000000000000000e+00 -1.209023819818124e-08 1.847595567040099e-06 5.799102000140301e-07 -4.460833665210641e-07 0.000000000000000e+00 0.000000000000000e+00 -6.034797295293836e-08 0.000000000000000e+00 1.667569505660956e-07 -2.974442475526043e-08 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00',
-    'LINE_NUM_COEFF': '2.001303029283497e-03 -1.860717345625879e-01 -1.127856422682348e+00 -4.632230551975493e-05 1.019881908582774e-03 5.673855447822687e-08 -8.698433522294479e-08 -3.226759855088540e-03 -1.332756784778704e-03 0.000000000000000e+00 1.215249975522747e-08 -7.132377372126199e-07 2.017197679474549e-06 8.275158167048898e-08 -1.210585983708413e-06 -1.078353887170730e-06 5.032973521799926e-07 0.000000000000000e+00 1.716128319528072e-08 0.000000000000000e+00',
-    'LINE_OFF': '5760',
-    'LINE_SCALE': '5761',
-    'LONG_OFF': '-1.231760000000000e+02',
-    'LONG_SCALE': '4.534000000000000e-01',
-    'SAMP_DEN_COEFF': '1.000000000000000e+00 9.278262976396983e-05 1.781926782031641e-03 -6.510570023623242e-04 -2.216055849873611e-04 9.161290674286373e-07 3.126587074446549e-06 3.565361629769621e-04 -2.582447705973245e-05 -9.228544337667984e-05 5.298085166219470e-07 1.025006482963347e-05 7.478466127324454e-07 -1.692384939549647e-06 -1.124443674146492e-05 -1.793628425616464e-07 -2.791740249303018e-07 -2.820306656137878e-07 4.593502012060843e-08 1.035174961061441e-07',
-    'SAMP_NUM_COEFF': '2.202618393703774e-02 1.185886131197477e+00 -2.151710781539888e-01 3.045218075295352e-02 2.420581655336635e-03 -4.398438360671764e-06 5.871407208028941e-05 -2.166676957828599e-02 -4.180699044156175e-04 -2.753492566174621e-05 -7.124639699900795e-06 -1.101195320211651e-05 -1.119110912711932e-04 -1.096184653732520e-04 1.183590823839227e-04 1.382552349641905e-05 1.997075688106731e-05 2.673528192748438e-05 -1.230207121465409e-06 -2.830467933081173e-06',
-    'SAMP_OFF': '3724',
-    'SAMP_SCALE': '3725'
-    }
+    "ERR_BIAS": "5.000000000000000e-01",
+    "ERR_RAND": "5.000000000000000e-01",
+    "HEIGHT_OFF": "8.900000000000000e+01",
+    "HEIGHT_SCALE": "7.010000000000000e+02",
+    "LAT_OFF": "4.921990000000000e+01",
+    "LAT_SCALE": "3.093000000000000e-01",
+    "LINE_DEN_COEFF": "1.000000000000000e+00 9.222511757408093e-04 9.437608823165506e-04 0.000000000000000e+00 3.227813186168402e-07 0.000000000000000e+00 -1.209023819818124e-08 1.847595567040099e-06 5.799102000140301e-07 -4.460833665210641e-07 0.000000000000000e+00 0.000000000000000e+00 -6.034797295293836e-08 0.000000000000000e+00 1.667569505660956e-07 -2.974442475526043e-08 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00",
+    "LINE_NUM_COEFF": "2.001303029283497e-03 -1.860717345625879e-01 -1.127856422682348e+00 -4.632230551975493e-05 1.019881908582774e-03 5.673855447822687e-08 -8.698433522294479e-08 -3.226759855088540e-03 -1.332756784778704e-03 0.000000000000000e+00 1.215249975522747e-08 -7.132377372126199e-07 2.017197679474549e-06 8.275158167048898e-08 -1.210585983708413e-06 -1.078353887170730e-06 5.032973521799926e-07 0.000000000000000e+00 1.716128319528072e-08 0.000000000000000e+00",
+    "LINE_OFF": "5760",
+    "LINE_SCALE": "5761",
+    "LONG_OFF": "-1.231760000000000e+02",
+    "LONG_SCALE": "4.534000000000000e-01",
+    "SAMP_DEN_COEFF": "1.000000000000000e+00 9.278262976396983e-05 1.781926782031641e-03 -6.510570023623242e-04 -2.216055849873611e-04 9.161290674286373e-07 3.126587074446549e-06 3.565361629769621e-04 -2.582447705973245e-05 -9.228544337667984e-05 5.298085166219470e-07 1.025006482963347e-05 7.478466127324454e-07 -1.692384939549647e-06 -1.124443674146492e-05 -1.793628425616464e-07 -2.791740249303018e-07 -2.820306656137878e-07 4.593502012060843e-08 1.035174961061441e-07",
+    "SAMP_NUM_COEFF": "2.202618393703774e-02 1.185886131197477e+00 -2.151710781539888e-01 3.045218075295352e-02 2.420581655336635e-03 -4.398438360671764e-06 5.871407208028941e-05 -2.166676957828599e-02 -4.180699044156175e-04 -2.753492566174621e-05 -7.124639699900795e-06 -1.101195320211651e-05 -1.119110912711932e-04 -1.096184653732520e-04 1.183590823839227e-04 1.382552349641905e-05 1.997075688106731e-05 2.673528192748438e-05 -1.230207121465409e-06 -2.830467933081173e-06",
+    "SAMP_OFF": "3724",
+    "SAMP_SCALE": "3725",
+}
+
 
 def test_rpcs():
     rpcs = RPC(**TEST_RPCS_NATIVE_PYTHON)
@@ -126,12 +135,14 @@ def test_rpcs():
             assert len(value) == 20
             assert isinstance(value[0], float)
 
+
 def test_rpcs_to_gdal():
     rpcs = RPC(**TEST_RPCS_NATIVE_PYTHON)
     for key, value in rpcs.to_gdal().items():
         assert key in TEST_RPCS_FROM_GDAL.keys()
         assert isinstance(value, str)
 
+
 def test_rpcs_from_gdal():
     rpcs = RPC.from_gdal(TEST_RPCS_FROM_GDAL)
     for key, value in rpcs.to_dict().items():
@@ -142,45 +153,56 @@ def test_rpcs_from_gdal():
             assert len(value) == 20
             assert isinstance(value[0], float)
 
+
 def test_rpcs_write_read_rpcs(tmpdir):
-    tiffname = str(tmpdir.join('test.tif'))
+    tiffname = str(tmpdir.join("test.tif"))
     rpcs = RPC.from_gdal(TEST_RPCS_FROM_GDAL)
-    
-    with rasterio.open(tiffname, 'w', driver='GTiff', dtype='uint8', count=1,
-                       width=7449, height=11522, rpcs=rpcs) as dst:
+
+    with rasterio.open(
+        tiffname,
+        "w",
+        driver="GTiff",
+        dtype="uint8",
+        count=1,
+        width=7449,
+        height=11522,
+        rpcs=rpcs,
+    ) as dst:
         pass
-        
-    with rasterio.open(tiffname, 'r+') as dst:
+
+    with rasterio.open(tiffname, "r+") as dst:
         rpcs = dst.rpcs
         assert rpcs
         assert isinstance(rpcs, RPC)
-        expected = TEST_RPCS_FROM_GDAL
+        expected = TEST_RPCS_FROM_GDAL.copy()
 
         # GDAL < 3.3 does not ensure ERR_BIAS and ERR_RAND are written out
         # so we wont either
-        expected.pop('ERR_BIAS')
-        expected.pop('ERR_RAND')
+        expected.pop("ERR_BIAS")
+        expected.pop("ERR_RAND")
         rpcs.err_bias = None
         rpcs.err_rand = None
-        
+
         assert sorted(rpcs.to_gdal().keys()) == sorted(expected.keys())
-        
-        rpcs.lat_off=48
-        rpcs.long_off=-123
+
+        rpcs.lat_off = 48
+        rpcs.long_off = -123
         dst.rpcs = rpcs
         assert dst.rpcs
         assert dst.rpcs.lat_off == 48
         assert dst.rpcs.long_off == -123
-    
+
     # check changes were written to dataset.
-    with rasterio.open(tiffname, 'r') as dst:
+    with rasterio.open(tiffname, "r") as dst:
         assert dst.rpcs
         assert dst.rpcs.lat_off == 48
         assert dst.rpcs.long_off == -123
-        
+
+
 def test_read_vrt_rpcs(tmpdir):
-    vrtfile = tmpdir.join('test.vrt')
-    vrtfile.write("""
+    vrtfile = tmpdir.join("test.vrt")
+    vrtfile.write(
+        """
 <VRTDataset rasterXSize="512" rasterYSize="512">
 <Metadata domain="RPC">
     <MDI key="ERR_BIAS">5.000000000000000e-01</MDI>
@@ -210,16 +232,19 @@ def test_read_vrt_rpcs(tmpdir):
     </SimpleSource>
 </VRTRasterBand>
 </VRTDataset>
-    """)
+    """
+    )
 
     with rasterio.open(str(vrtfile)) as src:
         rpcs = src.rpcs
         assert rpcs
-    
+
+
 def test_rpcs_attribute_none_if_no_rpcs(tmpdir):
-    tiffname = str(tmpdir.join('test.tif'))
-    with rasterio.open(tiffname, 'w', driver='GTiff', dtype='uint8', count=1,
-                       width=10, height=10):
+    tiffname = str(tmpdir.join("test.tif"))
+    with rasterio.open(
+        tiffname, "w", driver="GTiff", dtype="uint8", count=1, width=10, height=10
+    ):
         pass
     with rasterio.open(tiffname) as src:
         assert src.rpcs is None


=====================================
tests/test_transform.py
=====================================
@@ -3,6 +3,7 @@ import pytest
 import rasterio
 from rasterio import transform
 from rasterio.env import GDALVersion
+from rasterio.errors import TransformError
 from rasterio.transform import xy, rowcol
 from rasterio.windows import Window
 
@@ -132,12 +133,12 @@ def test_from_bounds_two():
 
 
 def test_xy():
+    # TODO: use pytest's parametrize to make separate tests.
     aff = Affine(300.0379266750948, 0.0, 101985.0,
                  0.0, -300.041782729805, 2826915.0)
     ul_x, ul_y = aff * (0, 0)
     xoff = aff.a
     yoff = aff.e
-    assert xy(aff, 0, 0, offset='ul') == (ul_x, ul_y)
     assert xy(aff, 0, 0, offset='ur') == (ul_x + xoff, ul_y)
     assert xy(aff, 0, 0, offset='ll') == (ul_x, ul_y + yoff)
     expected = (ul_x + xoff, ul_y + yoff)
@@ -149,9 +150,12 @@ def test_xy():
         xy(aff, 1, 1, offset='ul') == \
         xy(aff, 1, 0, offset='ur')
 
+    # Check list inputs.
+    assert xy(aff, [0], [0], offset='ul') == ([ul_x], [ul_y])
+
 
 def test_bogus_offset():
-    with pytest.raises(ValueError):
+    with pytest.raises(TransformError):
         xy(None, 1, 0, offset='bogus')
 
 
@@ -181,7 +185,9 @@ def test_rowcol():
         assert rowcol(aff, right, bottom) == (src.height, src.width)
         assert rowcol(aff, left, bottom) == (src.height, 0)
         assert rowcol(aff, 101985.0, 2826915.0) == (0, 0)
-        assert rowcol(aff, 101985.0 + 400.0, 2826915.0) == (0, 1)
+
+        # Check list inputs.
+        assert rowcol(aff, [101985.0 + 400.0], [2826915.0]) == ([0], [1])
 
 
 def test_xy_rowcol_inverse():


=====================================
tests/test_warp.py
=====================================
@@ -233,13 +233,12 @@ def test_transform_bounds_densify(density, expected):
     # This transform is non-linear along the edges, so densification produces
     # a different result than otherwise
     src_crs = CRS.from_epsg(4326)
-    dst_crs = CRS.from_proj4(
-        "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs"
-    )
-    assert np.allclose(
-        expected,
-        transform_bounds(src_crs, dst_crs, -120, 40, -80, 64, densify_pts=density),
-    )
+    dst_crs = CRS.from_epsg(2163)
+    with rasterio.Env(OSR_USE_NON_DEPRECATED="NO"):
+        assert np.allclose(
+            expected,
+            transform_bounds(src_crs, dst_crs, -120, 40, -80, 64, densify_pts=density),
+        )
 
 
 def test_transform_bounds_no_change():


=====================================
tests/test_warpedvrt.py
=====================================
@@ -24,7 +24,7 @@ log = logging.getLogger(__name__)
 
 # Custom markers.
 credentials = pytest.mark.skipif(
-    not (boto3.Session()._session.get_credentials()),
+    not (boto3.Session().get_credentials()),
     reason="S3 raster access requires credentials",
 )
 


=====================================
tests/test_windows.py
=====================================
@@ -311,21 +311,29 @@ def test_window_from_bounds(path_rgb_byte_tif):
         height = src.height
         width = src.width
 
-        assert_window_almost_equals(from_bounds(
-            left + EPS, bottom + EPS, right - EPS, top - EPS, src.transform,
-            height, width), Window.from_slices((0, height), (0, width)))
+        assert_window_almost_equals(
+            from_bounds(
+                left + EPS, bottom + EPS, right - EPS, top - EPS, src.transform
+            ),
+            Window.from_slices((0, height), (0, width)),
+        )
 
-        assert_window_almost_equals(from_bounds(
-            left, top - 2 * dy - EPS, left + 2 * dx - EPS, top, src.transform,
-            height, width), Window.from_slices((0, 2), (0, 2)))
+        assert_window_almost_equals(
+            from_bounds(
+                left, top - 2 * dy - EPS, left + 2 * dx - EPS, top, src.transform
+            ),
+            Window.from_slices((0, 2), (0, 2)),
+        )
 
         # boundless
         assert_window_almost_equals(
-            from_bounds(left - 2 * dx, top - 2 * dy, left + 2 * dx,
-                        top + 2 * dy, src.transform, height=height,
-                        width=width),
-            Window.from_slices((-2, 2), (-2, 2), boundless=True, height=height,
-                               width=width))
+            from_bounds(
+                left - 2 * dx, top - 2 * dy, left + 2 * dx, top + 2 * dy, src.transform
+            ),
+            Window.from_slices(
+                (-2, 2), (-2, 2), boundless=True, height=height, width=width
+            ),
+        )
 
 
 def test_window_float(path_rgb_byte_tif):
@@ -333,26 +341,25 @@ def test_window_float(path_rgb_byte_tif):
     with rasterio.open(path_rgb_byte_tif) as src:
         left, bottom, right, top = src.bounds
         dx, dy = src.res
-        height = src.height
-        width = src.width
 
-        assert_window_almost_equals(from_bounds(
-            left, top - 400, left + 400, top, src.transform,
-            height, width), Window.from_slices((0, 400 / src.res[1]), (0, 400 / src.res[0])))
+        assert_window_almost_equals(
+            from_bounds(left, top - 400, left + 400, top, src.transform),
+            Window.from_slices((0, 400 / src.res[1]), (0, 400 / src.res[0])),
+        )
 
 
 def test_window_bounds_south_up():
     identity = Affine.identity()
     assert_window_almost_equals(
-        from_bounds(0, 10, 10, 0, identity, 10, 10),
-        Window(0, 0, 10, 10))
+        from_bounds(0, 10, 10, 0, identity), Window(0, 0, 10, 10)
+    )
 
 
 def test_window_bounds_north_up():
     transform = Affine.translation(0.0, 10.0) * Affine.scale(1.0, -1.0) * Affine.identity()
     assert_window_almost_equals(
-        from_bounds(0, 0, 10, 10, transform, 10, 10),
-        Window(0, 0, 10, 10))
+        from_bounds(0, 0, 10, 10, transform), Window(0, 0, 10, 10)
+    )
 
 
 def test_window_transform_function(path_rgb_byte_tif):
@@ -584,7 +591,7 @@ def test_window_hashable():
 def test_from_bounds_requires_transform():
     """Test fix for issue 1857"""
     with pytest.raises(WindowError):
-        from_bounds(-105, 40, -100, 45, height=100, width=100)
+        from_bounds(-105, 40, -100, 45)
 
 
 def test_from_bounds_rotation():
@@ -598,9 +605,7 @@ def test_from_bounds_rotation():
         * Affine.translation(-sqrt2, sqrt2)
         * Affine.scale(sqrt2 / 2.0, -sqrt2 / 2.0)
     )
-    win = from_bounds(
-        -2.0, -2.0, 2.0, 2.0, transform=transform, height=height, width=width,
-    )
+    win = from_bounds(-2.0, -2.0, 2.0, 2.0, transform=transform)
     assert win.col_off == pytest.approx(-2.0)
     assert win.row_off == pytest.approx(-2.0)
     assert win.width == pytest.approx(2.0 * width)


=====================================
tests/test_write.py
=====================================
@@ -180,12 +180,22 @@ def test_write_crs_transform(tmpdir):
                               0.0, -300.041782729805, 2826915.0)
 
     with rasterio.open(
-            name, 'w',
-            driver='GTiff', width=100, height=100, count=1,
-            crs={'units': 'm', 'no_defs': True, 'ellps': 'WGS84',
-                 'proj': 'utm', 'zone': 18},
-            transform=transform,
-            dtype=rasterio.ubyte) as s:
+        name,
+        "w",
+        driver="GTiff",
+        width=100,
+        height=100,
+        count=1,
+        crs={
+            "units": "m",
+            "no_defs": True,
+            "datum": "WGS84",
+            "proj": "utm",
+            "zone": 18,
+        },
+        transform=transform,
+        dtype=rasterio.ubyte,
+    ) as s:
         s.write(a, indexes=1)
     assert s.crs.to_epsg() == 32618
     info = subprocess.check_output(["gdalinfo", name]).decode('utf-8')
@@ -201,12 +211,22 @@ def test_write_crs_transform_affine(tmpdir):
     transform = affine.Affine(300.0379266750948, 0.0, 101985.0,
                               0.0, -300.041782729805, 2826915.0)
     with rasterio.open(
-            name, 'w',
-            driver='GTiff', width=100, height=100, count=1,
-            crs={'units': 'm', 'no_defs': True, 'ellps': 'WGS84',
-                 'proj': 'utm', 'zone': 18},
-            transform=transform,
-            dtype=rasterio.ubyte) as s:
+        name,
+        "w",
+        driver="GTiff",
+        width=100,
+        height=100,
+        count=1,
+        crs={
+            "units": "m",
+            "no_defs": True,
+            "datum": "WGS84",
+            "proj": "utm",
+            "zone": 18,
+        },
+        transform=transform,
+        dtype=rasterio.ubyte,
+    ) as s:
         s.write(a, indexes=1)
 
     assert s.crs.to_epsg() == 32618
@@ -247,7 +267,8 @@ def test_write_crs_transform_3(tmpdir):
     a = np.ones((100, 100), dtype=rasterio.ubyte) * 127
     transform = affine.Affine(300.0379266750948, 0.0, 101985.0,
                               0.0, -300.041782729805, 2826915.0)
-    wkt = 'PROJCS["UTM Zone 18, Northern Hemisphere",GEOGCS["WGS 84",DATUM["unknown",SPHEROID["WGS84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-75],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]'
+    wkt = 'PROJCS["WGS 84 / UTM zone 18N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-75],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32618"]]'
+
     with rasterio.open(
             name, 'w',
             driver='GTiff', width=100, height=100, count=1,
@@ -257,7 +278,7 @@ def test_write_crs_transform_3(tmpdir):
         s.write(a, indexes=1)
     assert s.crs.to_epsg() == 32618
     info = subprocess.check_output(["gdalinfo", name]).decode('utf-8')
-    assert '"UTM Zone 18, Northern Hemisphere",' in info
+    assert 'UTM zone 18N' in info
     # make sure that pixel size is nearly the same as transform
     # (precision varies slightly by platform)
     assert re.search(r'Pixel Size = \(300.03792\d+,-300.04178\d+\)', info)



View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/-/commit/b5d9e46027e945321fa32ed30801672fa3ee95a2

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/-/commit/b5d9e46027e945321fa32ed30801672fa3ee95a2
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/20210908/f929e3f5/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list