[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