Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • debian-gis-team/rasterio
1 result
Show changes
Commits on Source (4)
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 (1.0.26-1) unstable; urgency=medium
* Team upload.
* New upstream release.
-- Bas Couwenberg <sebastic@debian.org> Tue, 27 Aug 2019 05:53:36 +0200
rasterio (1.0.25-1) unstable; urgency=medium
* Team upload.
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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'):
......
......@@ -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
......@@ -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):
......
......@@ -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))
......
......@@ -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,
......
......@@ -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
......@@ -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
......@@ -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
@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
......@@ -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)
@pytest.mark.parametrize("dtype", ["float64", "float32"])
def test_can_cast_dtype_nan(dtype):
assert can_cast_dtype([np.nan], dtype)
@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):
......
......@@ -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)
......@@ -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:
......
......@@ -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.")
@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.")