[Git][debian-gis-team/rasterio][master] 4 commits: New upstream version 1.0.2
Bas Couwenberg
gitlab at salsa.debian.org
Sat Jul 28 09:11:03 BST 2018
Bas Couwenberg pushed to branch master at Debian GIS Project / rasterio
Commits:
3b435c7b by Bas Couwenberg at 2018-07-28T06:33:58Z
New upstream version 1.0.2
- - - - -
4cff5983 by Bas Couwenberg at 2018-07-28T06:34:04Z
Merge tag 'upstream/1.0.2'
Upstream version 1.0.2
- - - - -
c8508802 by Bas Couwenberg at 2018-07-28T06:35:25Z
New upstream release.
- - - - -
f4e4d1d6 by Bas Couwenberg at 2018-07-28T06:36:23Z
Set distribution to unstable.
- - - - -
12 changed files:
- CHANGES.txt
- debian/changelog
- rasterio/__init__.py
- rasterio/_base.pyx
- rasterio/_warp.pyx
- rasterio/rio/warp.py
- rasterio/warp.py
- + tests/data/rotated.tif
- tests/test_coords.py
- tests/test_rio_warp.py
- tests/test_warp.py
- tests/test_warp_transform.py
Changes:
=====================================
CHANGES.txt
=====================================
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,18 @@
Changes
=======
+1.0.2 (2018-07-27)
+------------------
+
+Bug fixes:
+
+- The output of calculate_default_transform() can be fixed to output dimensions
+ as well as to output resolution (#1409).
+- In using rio-warp, the --src-bounds option can now override the bounds of the
+ source dataset when --dimensions is used (#1419).
+- Bounds of rotated rasters are now calculated correctly (#1422).
+- A band indexing bug in reproject() (#1350) has been fixed (#1424).
+
1.0.1 (2018-07-23)
------------------
=====================================
debian/changelog
=====================================
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+rasterio (1.0.2-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+
+ -- Bas Couwenberg <sebastic at debian.org> Sat, 28 Jul 2018 08:36:14 +0200
+
rasterio (1.0.1-1) unstable; urgency=medium
* Team upload.
=====================================
rasterio/__init__.py
=====================================
--- a/rasterio/__init__.py
+++ b/rasterio/__init__.py
@@ -43,7 +43,7 @@ import rasterio.path
__all__ = ['band', 'open', 'pad', 'Env']
-__version__ = "1.0.1"
+__version__ = "1.0.2"
__gdal_version__ = gdal_version()
# Rasterio attaches NullHandler to the 'rasterio' logger and its
=====================================
rasterio/_base.pyx
=====================================
--- a/rasterio/_base.pyx
+++ b/rasterio/_base.pyx
@@ -788,7 +788,18 @@ cdef class DatasetBase(object):
"""
def __get__(self):
a, b, c, d, e, f, _, _, _ = self.transform
- return BoundingBox(c, f + e * self.height, c + a * self.width, f)
+ width = self.width
+ height = self.height
+ if b == d == 0:
+ return BoundingBox(c, f + e * height, c + a * width, f)
+ else:
+ c0x, c0y = c, f
+ c1x, c1y = self.transform * (0, height)
+ c2x, c2y = self.transform * (width, height)
+ c3x, c3y = self.transform * (width, 0)
+ xs = (c0x, c1x, c2x, c3x)
+ ys = (c0y, c1y, c2y, c3y)
+ return BoundingBox(min(xs), min(ys), max(xs), max(ys))
property res:
"""Returns the (width, height) of pixels in the units of its
=====================================
rasterio/_warp.pyx
=====================================
--- a/rasterio/_warp.pyx
+++ b/rasterio/_warp.pyx
@@ -433,8 +433,14 @@ def _reproject(
if dtypes.is_ndarray(destination):
if len(destination.shape) == 2:
destination = destination.reshape(1, *destination.shape)
- dst_bidx = [1]
+
+ if destination.shape[0] == src_count:
+ # Output shape matches number of bands being extracted
+ dst_bidx = [i + 1 for i in range(src_count)]
else:
+ # Assume src and dst are the same shape
+ if max(src_bidx) > destination.shape[0]:
+ raise ValueError("Invalid destination shape")
dst_bidx = src_bidx
try:
@@ -565,6 +571,11 @@ def _reproject(
psWOptions.hSrcDS = src_dataset
psWOptions.hDstDS = dst_dataset
+ for idx, (s, d) in enumerate(zip(src_bidx, dst_bidx)):
+ psWOptions.panSrcBands[idx] = s
+ psWOptions.panDstBands[idx] = d
+ log.debug('Configured to warp src band %d to destination band %d' % (s, d))
+
log.debug("Set transformer options")
# Now that the transformer and warp options are set up, we init
=====================================
rasterio/rio/warp.py
=====================================
--- a/rasterio/rio/warp.py
+++ b/rasterio/rio/warp.py
@@ -231,6 +231,7 @@ def warp(ctx, files, output, driver, like, dst_crs, dimensions, src_bounds,
# Same projection, different dimensions, calculate resolution.
dst_crs = src.crs
dst_width, dst_height = dimensions
+ l, b, r, t = src_bounds or (l, b, r, t)
dst_transform = Affine(
(r - l) / float(dst_width),
0, l, 0,
=====================================
rasterio/warp.py
=====================================
--- a/rasterio/warp.py
+++ b/rasterio/warp.py
@@ -342,7 +342,7 @@ def aligned_target(transform, width, height, resolution):
@ensure_env
def calculate_default_transform(
src_crs, dst_crs, width, height, left=None, bottom=None, right=None,
- top=None, gcps=None, resolution=None):
+ top=None, gcps=None, resolution=None, dst_width=None, dst_height=None):
"""Output dimensions and transform for a reprojection.
Source and destination coordinate reference systems and output
@@ -374,6 +374,9 @@ def calculate_default_transform(
resolution: tuple (x resolution, y resolution) or float, optional
Target resolution, in units of target coordinate reference
system.
+ dst_width, dst_height: int, optional
+ Output file size in pixels and lines. Cannot be used together
+ with resolution.
Returns
-------
@@ -398,6 +401,18 @@ def calculate_default_transform(
if any(x is None for x in (left, bottom, right, top)) and not gcps:
raise ValueError("Either four bounding values or ground control points"
"must be specified")
+
+ if (dst_width is None) != (dst_height is None):
+ raise ValueError("Either dst_width and dst_height must be specified "
+ "or none of them.")
+
+ if all(x is not None for x in (dst_width, dst_height)):
+ dimensions = (dst_width, dst_height)
+ else:
+ dimensions = None
+
+ if resolution and dimensions:
+ raise ValueError("Resolution cannot be used with dst_width and dst_height.")
dst_affine, dst_width, dst_height = _calculate_default_transform(
src_crs, dst_crs, width, height, left, bottom, right, top, gcps)
@@ -426,5 +441,15 @@ def calculate_default_transform(
dst_width = ceil(dst_width * xratio)
dst_height = ceil(dst_height * yratio)
+
+ if dimensions:
+ xratio = dst_width / dimensions[0]
+ yratio = dst_height / dimensions[1]
+
+ dst_width = dimensions[0]
+ dst_height = dimensions[1]
+
+ dst_affine = Affine(dst_affine.a * xratio, dst_affine.b, dst_affine.c,
+ dst_affine.d, dst_affine.e * yratio, dst_affine.f)
return dst_affine, dst_width, dst_height
=====================================
tests/data/rotated.tif
=====================================
Binary files /dev/null and b/tests/data/rotated.tif differ
=====================================
tests/test_coords.py
=====================================
--- a/tests/test_coords.py
+++ b/tests/test_coords.py
@@ -1,4 +1,5 @@
import rasterio
+import numpy as np
def test_bounds():
with rasterio.open('tests/data/RGB.byte.tif') as src:
@@ -13,3 +14,10 @@ def test_ul():
def test_res():
with rasterio.open('tests/data/RGB.byte.tif') as src:
assert tuple(round(v, 6) for v in src.res) == (300.037927, 300.041783)
+
+def test_rotated_bounds():
+ with rasterio.open('tests/data/rotated.tif') as src:
+ assert src.res == (20.0, 10.0)
+ np.testing.assert_almost_equal(
+ src.bounds,
+ (100.0, 70.0961894323342, 348.20508075688775, 300.0))
=====================================
tests/test_rio_warp.py
=====================================
--- a/tests/test_rio_warp.py
+++ b/tests/test_rio_warp.py
@@ -212,6 +212,28 @@ def test_warp_no_reproject_bounds_res(runner, tmpdir):
assert np.allclose(output.bounds, out_bounds)
+def test_warp_no_reproject_src_bounds_dimensions(runner, tmpdir):
+ """--src-bounds option works with dimensions"""
+ srcname = 'tests/data/shade.tif'
+ outputname = str(tmpdir.join('test.tif'))
+ out_bounds = [-11850000, 4810000, -11849000, 4812000]
+ result = runner.invoke(
+ main_group, [
+ 'warp', srcname, outputname, '--dimensions', 9, 14,
+ '--src-bounds'] + out_bounds)
+ assert result.exit_code == 0
+ assert os.path.exists(outputname)
+
+ with rasterio.open(srcname) as src:
+ with rasterio.open(outputname) as output:
+ assert output.crs == src.crs
+ assert np.allclose(output.bounds, out_bounds)
+ assert np.allclose([111.111111, 142.857142],
+ [output.transform.a, -output.transform.e])
+ assert output.width == 9
+ assert output.height == 14
+
+
def test_warp_reproject_dst_crs(runner, tmpdir):
srcname = 'tests/data/RGB.byte.tif'
outputname = str(tmpdir.join('test.tif'))
=====================================
tests/test_warp.py
=====================================
--- a/tests/test_warp.py
+++ b/tests/test_warp.py
@@ -253,6 +253,24 @@ def test_calculate_default_transform_multiple_resolutions():
assert height == 20
+def test_calculate_default_transform_dimensions():
+ with rasterio.open('tests/data/RGB.byte.tif') as src:
+ dst_width, dst_height = (113, 103)
+ target_transform = Affine(
+ 0.02108612597535966, 0.0, -78.95864996545055,
+ 0.0, -0.0192823863230055, 25.550873767433984
+ )
+
+ dst_transform, width, height = calculate_default_transform(
+ src.crs, {'init': 'EPSG:4326'}, src.width, src.height,
+ *src.bounds, dst_width=dst_width, dst_height=dst_height
+ )
+
+ assert dst_transform.almost_equals(target_transform)
+ assert width == dst_width
+ assert height == dst_height
+
+
def test_reproject_ndarray():
with rasterio.open('tests/data/RGB.byte.tif') as src:
source = src.read(1)
@@ -1268,3 +1286,31 @@ def test_reproject_dst_alpha(path_rgb_msk_byte_tif):
dst_alpha=4)
assert dst_arr[3].any()
+
+
+ at pytest.mark.xfail(
+ rasterio.__gdal_version__ in ['2.2.0', '2.2.1', '2.2.2', '2.2.3'],
+ reason=("GDAL had regression in 2.2.X series, fixed in 2.2.4,"
+ " reproject used dst index instead of src index when destination was single band"))
+def test_issue1350():
+ """Warp bands other than 1 or All"""
+
+ with rasterio.open('tests/data/RGB.byte.tif') as src:
+ dst_crs = {'init': 'EPSG:3857'}
+
+ reprojected = []
+
+ for dtype, idx in zip(src.dtypes, src.indexes):
+ out = np.zeros((1,) + src.shape, dtype=dtype)
+
+ reproject(
+ rasterio.band(src, idx),
+ out,
+ resampling=Resampling.nearest,
+ dst_transform=DST_TRANSFORM,
+ dst_crs=dst_crs)
+
+ reprojected.append(out)
+
+ for i in range(1, len(reprojected)):
+ assert not (reprojected[0] == reprojected[i]).all()
=====================================
tests/test_warp_transform.py
=====================================
--- a/tests/test_warp_transform.py
+++ b/tests/test_warp_transform.py
@@ -16,6 +16,27 @@ def test_gcps_bounds_exclusivity():
'epsg:4326', 'epsg:3857', width=1, height=1, left=1.0, gcps=[1])
+def test_resolution_dimensions_exclusivity():
+ """resolution and dimensions parameters are mutually exclusive"""
+ with pytest.raises(ValueError):
+ calculate_default_transform(
+ 'epsg:4326', 'epsg:3857', width=1, height=1, gcps=[1],
+ resolution=1, dst_width=1, dst_height=1)
+
+
+def test_dimensions_missing_params():
+ """dst_width and dst_height must be specified together"""
+ with pytest.raises(ValueError):
+ calculate_default_transform(
+ 'epsg:4326', 'epsg:3857', width=1, height=1, gcps=[1],
+ resolution=1, dst_width=1, dst_height=None)
+
+ with pytest.raises(ValueError):
+ calculate_default_transform(
+ 'epsg:4326', 'epsg:3857', width=1, height=1, gcps=[1],
+ resolution=1, dst_width=None, dst_height=1)
+
+
def test_one_of_gcps_bounds():
"""at least one of gcps or bounds parameters must be provided"""
with pytest.raises(ValueError):
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/compare/d2379ce40bbc10a06b38cecbfaa5cdd96f5f5225...f4e4d1d61f3651be9c53cad0da9dc5f3f158017c
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/compare/d2379ce40bbc10a06b38cecbfaa5cdd96f5f5225...f4e4d1d61f3651be9c53cad0da9dc5f3f158017c
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/20180728/bc0a5456/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list