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

Bas Couwenberg gitlab at salsa.debian.org
Tue Aug 27 05:07:41 BST 2019



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


Commits:
63539a28 by Bas Couwenberg at 2019-08-27T03:50:54Z
New upstream version 1.0.26
- - - - -


16 changed files:

- CHANGES.txt
- rasterio/__init__.py
- rasterio/_base.pyx
- rasterio/_io.pyx
- rasterio/_warp.pyx
- rasterio/compat.py
- rasterio/crs.py
- rasterio/dtypes.py
- rasterio/rio/clip.py
- setup.cfg
- tests/test_complex_dtypes.py
- tests/test_crs.py
- tests/test_dtypes.py
- tests/test_memoryfile.py
- tests/test_warpedvrt.py
- tests/test_write.py


Changes:

=====================================
CHANGES.txt
=====================================
@@ -1,12 +1,29 @@
 Changes
 =======
 
+1.0.26 (2019-08-26)
+-------------------
+
+- Allow `nan` to be used as fill for float32 datasets in ``rasterize`` (#1761).
+- A WarpedVRTs destination crs now will default to ``src_crs`` if given, else
+  to the crs of the source dataset (#1755).
+- Prevent open's ``sharing`` keyword argument from being pass on to GDAL as a
+  dataset opening option for create-copy formats like JPEG and PNG (#1758).
+- Allow complex datasets to be created with a specified nodata value (#1747).
+- Several Python deprecation warnings have been eliminated (#1742).
+- When a MemoryFile is opened in write mode, a TypeError will be raised if
+  integer width and height are not given, fixing #1748.
+- Return False when checking equality with objects incompatible with
+  ``CRS.from_user_input()`` (#1719)
+- Support CRS.from_user_input with other CRS object with ``to_wkt()`` method
+  (#1718)
+
 1.0.25 (2019-08-06)
 -------------------
 
-- In `features.rasterize()`, a shape with an associated value of `None` is now
-  burned in using the function's `fill` value and no longer triggers a
-  `TypeError` (#1738).
+- In ``features.rasterize()``, a shape with an associated value of ``None`` is
+  now burned in using the function's ``fill`` value and no longer triggers a
+  TypeError (#1738).
 - Instances of pytest's tmp_path fixture in tests/test_dataset.py have been
   replaced by instances of the older style tmpdir fixture (#1697).
 - Add support for using GDAL 3.x and PROJ 6 libraries (#1700, #1729). Please
@@ -732,6 +749,7 @@ Packaging:
 
 1.0a5 (2016-12-23)
 ------------------
+
 - New binary wheels using version 1.2.0 of sgillies/frs-wheel-builds. See
   https://github.com/sgillies/frs-wheel-builds/blob/master/CHANGES.txt.
 


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


=====================================
rasterio/_base.pyx
=====================================
@@ -420,6 +420,13 @@ cdef class DatasetBase(object):
             for i in range(self._count):
                 band = self.band(i + 1)
                 dtype = _band_dtype(band)
+
+                # To address the issue in #1747.
+                if dtype == "complex128":
+                    dtype = "float64"
+                elif dtype == "complex64":
+                    dtype = "float32"
+
                 nodataval = GDALGetRasterNoDataValue(band, &success)
                 val = nodataval
                 # GDALGetRasterNoDataValue() has two ways of telling you that


=====================================
rasterio/_io.pyx
=====================================
@@ -620,7 +620,7 @@ cdef class DatasetReaderBase(DatasetBase):
                     # 255 and log that we have done so.
 
                     out = np.where(out != 0, 255, 0)
-                    log.warn("Nonzero values in mask have been converted to 255, see note in rasterio/_io.pyx, read_masks()")
+                    log.warning("Nonzero values in mask have been converted to 255, see note in rasterio/_io.pyx, read_masks()")
 
         if return2d:
             out.shape = out.shape[1:]
@@ -1048,7 +1048,7 @@ cdef class DatasetWriterBase(DatasetReaderBase):
 
         # Validate write mode arguments.
         log.debug("Path: %s, mode: %s, driver: %s", path, mode, driver)
-        if mode == 'w':
+        if mode in ('w', 'w+'):
             if not isinstance(driver, string_types):
                 raise TypeError("A driver name string is required.")
             try:
@@ -1442,7 +1442,7 @@ cdef class DatasetWriterBase(DatasetReaderBase):
             CSLDestroy(papszStrList)
 
         if retval == 2:
-            log.warn("Tags accepted but may not be persisted.")
+            log.warning("Tags accepted but may not be persisted.")
         elif retval == 3:
             raise RuntimeError("Tag update failed.")
 
@@ -1514,7 +1514,7 @@ cdef class DatasetWriterBase(DatasetReaderBase):
                 rgba = tuple(rgba) + (255,)
 
             if i not in vals:
-                log.warn("Invalid colormap key %d", i)
+                log.warning("Invalid colormap key %d", i)
                 continue
 
             color.c1, color.c2, color.c3, color.c4 = rgba
@@ -1848,7 +1848,7 @@ cdef class BufferedDatasetWriterBase(DatasetWriterBase):
 
     def __init__(self, path, mode='r', driver=None, width=None, height=None,
                  count=None, crs=None, transform=None, dtype=None, nodata=None,
-                 gcps=None, **kwargs):
+                 gcps=None, sharing=True, **kwargs):
         """Construct a new dataset
 
         Parameters


=====================================
rasterio/_warp.pyx
=====================================
@@ -718,8 +718,9 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
             warnings.warn(
                 "dst_crs will be removed in 1.1, use crs",
                 RasterioDeprecationWarning)
+
         if crs is None:
-            crs = dst_crs if dst_crs is not None else src_dataset.crs
+            crs = dst_crs if dst_crs is not None else (src_crs or src_dataset.crs)
         # End of `dst_parameter` deprecation and aliasing.
 
         if add_alpha and gdal_version().startswith('1'):


=====================================
rasterio/compat.py
=====================================
@@ -12,6 +12,7 @@ if sys.version_info[0] >= 3:   # pragma: no cover
     import configparser
     from urllib.parse import urlparse
     from collections import UserDict
+    from collections.abc import Mapping
     from inspect import getfullargspec as getargspec
 else:  # pragma: no cover
     string_types = basestring,
@@ -22,3 +23,4 @@ else:  # pragma: no cover
     from urlparse import urlparse
     from UserDict import UserDict
     from inspect import getargspec
+    from collections import Mapping


=====================================
rasterio/crs.py
=====================================
@@ -15,11 +15,11 @@ import json
 import pickle
 
 from rasterio._crs import _CRS, all_proj_keys
-from rasterio.compat import string_types
+from rasterio.compat import Mapping, string_types
 from rasterio.errors import CRSError
 
 
-class CRS(collections.Mapping):
+class CRS(Mapping):
     """A geographic or projected coordinate reference system
 
     CRS objects may be created by passing PROJ parameters as keyword
@@ -86,7 +86,10 @@ class CRS(collections.Mapping):
     __nonzero__ = __bool__
 
     def __eq__(self, other):
-        other = CRS.from_user_input(other)
+        try:
+            other = CRS.from_user_input(other)
+        except CRSError:
+            return False
         return (self._crs == other._crs)
 
     def __getstate__(self):
@@ -427,6 +430,11 @@ class CRS(collections.Mapping):
         """
         if isinstance(value, cls):
             return value
+        elif hasattr(value, "to_wkt") and callable(value.to_wkt):
+            return cls.from_wkt(
+                value.to_wkt(),
+                morph_from_esri_dialect=morph_from_esri_dialect,
+            )
         elif isinstance(value, int):
             return cls.from_epsg(value)
         elif isinstance(value, dict):


=====================================
rasterio/dtypes.py
=====================================
@@ -158,7 +158,7 @@ def can_cast_dtype(values, dtype):
         return True
 
     elif values.dtype.kind == 'f':
-        return np.allclose(values, values.astype(dtype))
+        return np.allclose(values, values.astype(dtype), equal_nan=True)
 
     else:
         return np.array_equal(values, values.astype(dtype))


=====================================
rasterio/rio/clip.py
=====================================
@@ -127,10 +127,10 @@ def clip(ctx, files, output, bounds, like, driver, projection,
 
             if 'blockxsize' in out_kwargs and out_kwargs['blockxsize'] > width:
                 del out_kwargs['blockxsize']
-                logger.warn("Blockxsize removed from creation options to accomodate small output width")
+                logger.warning("Blockxsize removed from creation options to accomodate small output width")
             if 'blockysize' in out_kwargs and out_kwargs['blockysize'] > height:
                 del out_kwargs['blockysize']
-                logger.warn("Blockysize removed from creation options to accomodate small output height")
+                logger.warning("Blockysize removed from creation options to accomodate small output height")
 
             with rasterio.open(output, 'w', **out_kwargs) as out:
                 out.write(src.read(window=out_window,


=====================================
setup.cfg
=====================================
@@ -4,3 +4,7 @@ filterwarnings =
     ignore::rasterio.errors.NotGeoreferencedWarning
     ignore::rasterio.errors.RasterioDeprecationWarning
     ignore:numpy.ufunc size changed
+markers =
+    wheel: tests of modules installed from a wheel
+    gdalbin: tests that require GDAL programs
+    network: tests that require a network connection


=====================================
tests/test_complex_dtypes.py
=====================================
@@ -36,3 +36,25 @@ def test_read_array(tempfile, dtype, height, width):
         dataset.write(in_img, 1)
         out_img = dataset.read(1)
     assert (in_img == out_img).all()
+
+
+def test_complex_nodata(tmpdir):
+    """A complex dataset can be created with a real nodata value"""
+    import numpy as np
+    import rasterio
+    from rasterio.transform import Affine
+
+    x = np.linspace(-4.0, 4.0, 240)
+    y = np.linspace(-3.0, 3.0, 180)
+    X, Y = np.meshgrid(x, y)
+    Z1 = np.ones_like(X) + 1j
+
+    res = (x[-1] - x[0]) / 240.0
+    transform1 = Affine.translation(x[0] - res / 2, y[-1] - res / 2) * Affine.scale(res, -res)
+
+    tempfile = str(tmpdir.join("test.tif"))
+    with rasterio.open(tempfile, 'w', driver='GTiff', height=Z1.shape[0], width=Z1.shape[1], nodata=0, count=1, dtype=Z1.dtype, crs='+proj=latlong', transform=transform1) as dst:
+        dst.write(Z1, 1)
+
+    with rasterio.open(tempfile) as dst:
+        assert dst.nodata == 0


=====================================
tests/test_crs.py
=====================================
@@ -40,6 +40,11 @@ ESRI_PROJECTION_STRING = (
     'PARAMETER["Direction",1.0],UNIT["Centimeter",0.01]]]')
 
 
+class CustomCRS(object):
+    def to_wkt(self):
+        return CRS.from_epsg(4326).to_wkt()
+
+
 def test_crs_constructor_dict():
     """Can create a CRS from a dict"""
     crs = CRS({'init': 'epsg:3857'})
@@ -471,3 +476,14 @@ def test_crs_hash_unequal():
 def test_crs84():
     """Create CRS from OGC code"""
     assert "WGS 84" in CRS.from_user_input("urn:ogc:def:crs:OGC::CRS84").wkt
+
+
+ at pytest.mark.parametrize("other", ["", 4.2, 0])
+def test_equals_different_type(other):
+    """Comparison to non-CRS objects is False"""
+    assert CRS.from_epsg(4326) != other
+
+
+def test_from_user_input_custom_crs_class():
+    """Support comparison to foreign objects that provide to_wkt()"""
+    assert CRS.from_user_input(CustomCRS()) == CRS.from_epsg(4326)
\ No newline at end of file


=====================================
tests/test_dtypes.py
=====================================
@@ -12,8 +12,8 @@ from rasterio.dtypes import (
 
 def test_is_ndarray():
     assert is_ndarray(np.zeros((1,)))
-    assert is_ndarray([0]) == False
-    assert is_ndarray((0,)) == False
+    assert not is_ndarray([0])
+    assert not is_ndarray((0,))
 
 
 def test_np_dt_uint8():
@@ -25,7 +25,7 @@ def test_dt_ubyte():
 
 
 def test_check_dtype_invalid():
-    assert check_dtype('foo') == False
+    assert not check_dtype('foo')
 
 
 def test_gdal_name():
@@ -52,19 +52,29 @@ def test_get_minimum_dtype():
 
 
 def test_can_cast_dtype():
-    assert can_cast_dtype((1, 2, 3), np.uint8) == True
-    assert can_cast_dtype(np.array([1, 2, 3]), np.uint8) == True
-    assert can_cast_dtype(np.array([1, 2, 3], dtype=np.uint8), np.uint8) == True
-    assert can_cast_dtype(np.array([1, 2, 3]), np.float32) == True
-    assert can_cast_dtype(np.array([1.4, 2.1, 3.65]), np.float32) == True
-    assert can_cast_dtype(np.array([1.4, 2.1, 3.65]), np.uint8) == False
+    assert can_cast_dtype((1, 2, 3), np.uint8)
+    assert can_cast_dtype(np.array([1, 2, 3]), np.uint8)
+    assert can_cast_dtype(np.array([1, 2, 3], dtype=np.uint8), np.uint8)
+    assert can_cast_dtype(np.array([1, 2, 3]), np.float32)
+    assert can_cast_dtype(np.array([1.4, 2.1, 3.65]), np.float32)
+    assert not can_cast_dtype(np.array([1.4, 2.1, 3.65]), np.uint8)
+
+
+ at pytest.mark.parametrize("dtype", ["float64", "float32"])
+def test_can_cast_dtype_nan(dtype):
+    assert can_cast_dtype([np.nan], dtype)
+
+
+ at pytest.mark.parametrize("dtype", ["uint8", "uint16", "uint32", "int32"])
+def test_cant_cast_dtype_nan(dtype):
+    assert not can_cast_dtype([np.nan], dtype)
 
 
 def test_validate_dtype():
-    assert validate_dtype([1, 2, 3], ('uint8', 'uint16')) == True
-    assert validate_dtype(np.array([1, 2, 3]), ('uint8', 'uint16')) == True
-    assert validate_dtype(np.array([1.4, 2.1, 3.65]), ('float32',)) == True
-    assert validate_dtype(np.array([1.4, 2.1, 3.65]), ('uint8',)) == False
+    assert validate_dtype([1, 2, 3], ('uint8', 'uint16'))
+    assert validate_dtype(np.array([1, 2, 3]), ('uint8', 'uint16'))
+    assert validate_dtype(np.array([1.4, 2.1, 3.65]), ('float32',))
+    assert not validate_dtype(np.array([1.4, 2.1, 3.65]), ('uint8',))
 
 
 def test_complex(tmpdir):


=====================================
tests/test_memoryfile.py
=====================================
@@ -297,3 +297,17 @@ def test_memory_file_gdal_error_message(capsys):
     captured = capsys.readouterr()
     assert "ERROR 4" not in captured.err
     assert "ERROR 4" not in captured.out
+
+
+def test_write_plus_mode_requires_width():
+    """Width is required"""
+    with MemoryFile() as memfile:
+        with pytest.raises(TypeError):
+            memfile.open(driver='GTiff', dtype='uint8', count=3, height=32, crs='epsg:3226', transform=Affine.identity() * Affine.scale(0.5, -0.5))
+
+
+def test_write_plus_mode_blockxsize_requires_width():
+    """Width is required"""
+    with MemoryFile() as memfile:
+        with pytest.raises(TypeError):
+            memfile.open(driver='GTiff', dtype='uint8', count=3, height=32, crs='epsg:3226', transform=Affine.identity() * Affine.scale(0.5, -0.5), blockxsize=128)


=====================================
tests/test_warpedvrt.py
=====================================
@@ -157,6 +157,18 @@ def test_warped_vrt_set_src_crs(path_rgb_byte_tif, tmpdir):
             assert vrt.src_crs == original_crs
 
 
+def test_warped_vrt_set_src_crs_default(path_rgb_byte_tif, tmpdir):
+    """A warped VRT's dst_src defaults to the given src_crs"""
+    path_crs_unset = str(tmpdir.join("rgb_byte_crs_unset.tif"))
+    _copy_update_profile(path_rgb_byte_tif, path_crs_unset, crs=None)
+    with rasterio.open(path_rgb_byte_tif) as src:
+        original_crs = src.crs
+    with rasterio.open(path_crs_unset) as src:
+        with WarpedVRT(src, src_crs=original_crs) as vrt:
+            assert vrt.src_crs == original_crs
+            assert vrt.dst_crs == original_crs
+
+
 def test_wrap_file(path_rgb_byte_tif):
     """A VirtualVRT has the expected dataset properties."""
     with rasterio.open(path_rgb_byte_tif) as src:


=====================================
tests/test_write.py
=====================================
@@ -356,3 +356,12 @@ def test_write_no_driver__issue_1203(tmpdir):
     name = str(tmpdir.join("test.tif"))
     with pytest.raises(ValueError), rasterio.open(name, 'w', height=1, width=1, count=1, dtype='uint8'):
         print("TEST FAILED IF THIS IS REACHED.")
+
+
+ at pytest.mark.parametrize("mode", ["w", "w+"])
+def test_require_width(tmpdir, mode):
+    """width and height are required for w and w+ mode"""
+    name = str(tmpdir.join("test.tif"))
+    with pytest.raises(TypeError):
+        with rasterio.open(name, mode, driver="GTiff", height=1, count=1, dtype='uint8'):
+            print("TEST FAILED IF THIS IS REACHED.")



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

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/commit/63539a28567c6a97e3a7208d6b9fbc837a42db04
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/20190827/a3a080e4/attachment-0001.html>


More information about the Pkg-grass-devel mailing list