[Git][debian-gis-team/rasterio][experimental] 4 commits: New upstream version 1.2.3
Bas Couwenberg
gitlab at salsa.debian.org
Tue Apr 27 05:05:58 BST 2021
Bas Couwenberg pushed to branch experimental at Debian GIS Project / rasterio
Commits:
369df47b by Bas Couwenberg at 2021-04-27T05:49:05+02:00
New upstream version 1.2.3
- - - - -
d230a341 by Bas Couwenberg at 2021-04-27T05:49:39+02:00
Update upstream source from tag 'upstream/1.2.3'
Update to upstream version '1.2.3'
with Debian dir 39387efee7c7a4e4258497c9cb3fc46cdf92d237
- - - - -
9cdd1a0f by Bas Couwenberg at 2021-04-27T05:51:51+02:00
New upstream release.
- - - - -
a5ad29ea by Bas Couwenberg at 2021-04-27T05:52:52+02:00
Set distribution to experimental.
- - - - -
21 changed files:
- .travis.yml
- CHANGES.txt
- debian/changelog
- rasterio/__init__.py
- rasterio/_env.pyx
- rasterio/_io.pyx
- rasterio/_warp.pyx
- rasterio/enums.py
- rasterio/env.py
- rasterio/errors.py
- rasterio/io.py
- rasterio/merge.py
- rasterio/rio/overview.py
- rasterio/windows.py
- + tests/data/float_raster_with_nodata.tif
- tests/test__env.py
- tests/test_enums.py
- tests/test_merge.py
- tests/test_overviews.py
- tests/test_rpcs.py
- tests/test_windows.py
Changes:
=====================================
.travis.yml
=====================================
@@ -43,7 +43,7 @@ jobs:
PROJVERSION="6.2.1"
- python: "3.8"
env:
- GDALVERSION="3.2.1"
+ GDALVERSION="3.2.2"
PROJVERSION="7.2.1"
- python: "3.8"
env:
=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,20 @@
Changes
=======
+1.2.3 (2021-04-26)
+------------------
+
+- Change usage of super() to be Python 3 compatible only.
+- Use numpy.isclose instead of equals when merging float data (fixes #2163).
+- The restriction on resampling methods available to overviews has been made
+ more clear with the addition of a not-yet-public _OverviewResampling enum
+ (#2157).
+- Fix a regression introduced in 1.2.2: from_bounds() can again return Windows
+ of zero height or width.
+- Search for GDAL data in installed packages is done before searching in
+ built-in locations when entering an Env, as is already done when importing
+ rasterio.env.
+
1.2.2 (2021-04-06)
------------------
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+rasterio (1.2.3-1~exp1) experimental; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+
+ -- Bas Couwenberg <sebastic at debian.org> Tue, 27 Apr 2021 05:52:39 +0200
+
rasterio (1.2.2-1~exp1) experimental; urgency=medium
* Team upload.
=====================================
rasterio/__init__.py
=====================================
@@ -27,7 +27,7 @@ import rasterio.enums
import rasterio.path
__all__ = ['band', 'open', 'pad', 'Env']
-__version__ = "1.2.2"
+__version__ = "1.2.3"
__gdal_version__ = gdal_version()
# Rasterio attaches NullHandler to the 'rasterio' logger and its
=====================================
rasterio/_env.pyx
=====================================
@@ -333,7 +333,7 @@ cdef class GDALEnv(ConfigEnv):
"""Configuration and driver management"""
def __init__(self, **options):
- super(GDALEnv, self).__init__(**options)
+ super().__init__(**options)
self._have_registered_drivers = False
def start(self):
@@ -350,40 +350,49 @@ cdef class GDALEnv(ConfigEnv):
OGRRegisterAll()
if 'GDAL_DATA' in os.environ:
+ log.debug("GDAL_DATA found in environment.")
self.update_config_options(GDAL_DATA=os.environ['GDAL_DATA'])
- log.debug("GDAL_DATA found in environment: %r.", os.environ['GDAL_DATA'])
-
- # See https://github.com/mapbox/rasterio/issues/1631.
- elif GDALDataFinder().find_file("header.dxf"):
- log.debug("GDAL data files are available at built-in paths")
else:
- path = GDALDataFinder().search()
+ path = GDALDataFinder().search_wheel()
if path:
+ log.debug("GDAL data found in package: path=%r.", path)
self.update_config_options(GDAL_DATA=path)
- log.debug("GDAL_DATA not found in environment, set to %r.", path)
+
+ # See https://github.com/mapbox/rasterio/issues/1631.
+ elif GDALDataFinder().find_file("header.dxf"):
+ log.debug("GDAL data files are available at built-in paths.")
+
+ else:
+ path = GDALDataFinder().search()
+
+ if path:
+ log.debug("GDAL data found in other locations: path=%r.", path)
+ self.update_config_options(GDAL_DATA=path)
if 'PROJ_LIB' in os.environ:
- log.debug("PROJ_LIB found in environment: %r.", os.environ['PROJ_LIB'])
+ log.debug("PROJ_LIB found in environment.")
path = os.environ["PROJ_LIB"]
set_proj_data_search_path(path)
- elif PROJDataFinder().search_wheel():
- path = PROJDataFinder().search_wheel()
- log.debug("PROJ data found in wheel, setting to %r.", path)
- set_proj_data_search_path(path)
-
- elif PROJDataFinder().has_data():
- log.debug("PROJ data files are available at built-in paths")
-
else:
- path = PROJDataFinder().search()
+ path = PROJDataFinder().search_wheel()
if path:
- log.debug("PROJ data not found in environment, setting to %r.", path)
+ log.debug("PROJ data found in package: path=%r.", path)
set_proj_data_search_path(path)
+ elif PROJDataFinder().has_data():
+ log.debug("PROJ data files are available at built-in paths.")
+
+ else:
+ path = PROJDataFinder().search()
+
+ if path:
+ log.debug("PROJ data found in other locations: path=%r.", path)
+ set_proj_data_search_path(path)
+
if driver_count() == 0:
CPLPopErrorHandler()
raise ValueError("Drivers not registered.")
@@ -394,7 +403,7 @@ cdef class GDALEnv(ConfigEnv):
# actually makes it this far.
self._have_registered_drivers = True
- log.debug("Started GDALEnv %r.", self)
+ log.debug("Started GDALEnv: self=%r.", self)
def stop(self):
# NB: do not restore the CPL error handler to its default
=====================================
rasterio/_io.pyx
=====================================
@@ -1602,7 +1602,9 @@ cdef class DatasetWriterBase(DatasetReaderBase):
4: 'LANCZOS',
5: 'AVERAGE',
6: 'MODE',
- 7: 'GAUSS'}
+ 7: 'GAUSS',
+ 14: 'RMS',
+ }
resampling_alg = resampling_map[Resampling(resampling.value)]
except (KeyError, ValueError):
=====================================
rasterio/_warp.pyx
=====================================
@@ -1153,14 +1153,14 @@ cdef class WarpedVRTReaderBase(DatasetReaderBase):
if kwargs.get("boundless", False):
raise ValueError("WarpedVRT does not permit boundless reads")
else:
- return super(WarpedVRTReaderBase, self).read(indexes=indexes, out=out, window=window, masked=masked, out_shape=out_shape, resampling=resampling, fill_value=fill_value, out_dtype=out_dtype)
+ return super().read(indexes=indexes, out=out, window=window, masked=masked, out_shape=out_shape, resampling=resampling, fill_value=fill_value, out_dtype=out_dtype)
def read_masks(self, indexes=None, out=None, out_shape=None, window=None, resampling=Resampling.nearest, **kwargs):
"""Read raster band masks as a multidimensional array"""
if kwargs.get("boundless", False):
raise ValueError("WarpedVRT does not permit boundless reads")
else:
- return super(WarpedVRTReaderBase, self).read_masks(indexes=indexes, out=out, window=window, out_shape=out_shape, resampling=resampling)
+ return super().read_masks(indexes=indexes, out=out, window=window, out_shape=out_shape, resampling=resampling)
def _suggested_proxy_vrt_doc(width, height, transform=None, crs=None, gcps=None):
=====================================
rasterio/enums.py
=====================================
@@ -60,6 +60,30 @@ class Resampling(IntEnum):
rms = 14
+class _OverviewResampling(IntEnum):
+ """Available Overview resampling algorithms.
+
+ The first 8, 'nearest', 'bilinear', 'cubic', 'cubic_spline',
+ 'lanczos', 'average', 'mode', and 'gauss', are available for making
+ dataset overviews.
+
+ 'nearest', 'bilinear', 'cubic', 'cubic_spline', 'lanczos',
+ 'average', 'mode' are always available (GDAL >= 1.10).
+
+ 'rms' is only supported in GDAL >= 3.3.
+
+ """
+ nearest = 0
+ bilinear = 1
+ cubic = 2
+ cubic_spline = 3
+ lanczos = 4
+ average = 5
+ mode = 6
+ gauss = 7
+ rms = 14
+
+
class Compression(Enum):
"""Available compression algorithms."""
jpeg = 'JPEG'
@@ -100,6 +124,7 @@ class PhotometricInterp(Enum):
icclab = 'ICCLAB'
itulab = 'ITULAB'
+
class MergeAlg(Enum):
"""Available rasterization algorithms"""
replace = 'REPLACE'
=====================================
rasterio/env.py
=====================================
@@ -621,19 +621,19 @@ if 'GDAL_DATA' not in os.environ:
path = GDALDataFinder().search_wheel()
if path:
+ log.debug("GDAL data found in package: path=%r.", path)
set_gdal_config("GDAL_DATA", path)
- log.debug("GDAL data found in package, GDAL_DATA set to %r.", path)
# See https://github.com/mapbox/rasterio/issues/1631.
elif GDALDataFinder().find_file("header.dxf"):
- log.debug("GDAL data files are available at built-in paths")
+ log.debug("GDAL data files are available at built-in paths.")
else:
path = GDALDataFinder().search()
if path:
set_gdal_config("GDAL_DATA", path)
- log.debug("GDAL_DATA not found in environment, set to %r.", path)
+ log.debug("GDAL data found in other locations: path=%r.", path)
if "PROJ_LIB" in os.environ:
path = os.environ["PROJ_LIB"]
@@ -641,16 +641,16 @@ if "PROJ_LIB" in os.environ:
elif PROJDataFinder().search_wheel():
path = PROJDataFinder().search_wheel()
- log.debug("PROJ data found in wheel, setting to %r.", path)
+ log.debug("PROJ data found in package: path=%r.", path)
set_proj_data_search_path(path)
# See https://github.com/mapbox/rasterio/issues/1631.
elif PROJDataFinder().has_data():
- log.debug("PROJ data files are available at built-in paths")
+ log.debug("PROJ data files are available at built-in paths.")
else:
path = PROJDataFinder().search()
if path:
- log.debug("PROJ data not found in environment, setting to %r.", path)
+ log.debug("PROJ data found in other locations: path=%r.", path)
set_proj_data_search_path(path)
=====================================
rasterio/errors.py
=====================================
@@ -38,7 +38,7 @@ class FileOverwriteError(FileError):
def __init__(self, message):
"""Raise FileOverwriteError with message as hint."""
- super(FileOverwriteError, self).__init__('', hint=message)
+ super().__init__('', hint=message)
class RasterioIOError(IOError):
=====================================
rasterio/io.py
=====================================
@@ -101,8 +101,9 @@ class MemoryFile(MemoryFileBase):
-------
MemoryFile
"""
- super(MemoryFile, self).__init__(
- file_or_bytes=file_or_bytes, dirname=dirname, filename=filename, ext=ext)
+ super().__init__(
+ file_or_bytes=file_or_bytes, dirname=dirname, filename=filename, ext=ext
+ )
@ensure_env
def open(self, driver=None, width=None, height=None, count=None, crs=None,
@@ -153,7 +154,7 @@ class ZipMemoryFile(MemoryFile):
"""
def __init__(self, file_or_bytes=None):
- super(ZipMemoryFile, self).__init__(file_or_bytes, ext='zip')
+ super().__init__(file_or_bytes, ext="zip")
@ensure_env
def open(self, path, driver=None, sharing=False, **kwargs):
=====================================
rasterio/merge.py
=====================================
@@ -330,6 +330,8 @@ def merge(
if math.isnan(nodataval):
region_mask = np.isnan(region)
+ elif np.issubdtype(region.dtype, np.floating):
+ region_mask = np.isclose(region, nodataval)
else:
region_mask = region == nodataval
=====================================
rasterio/rio/overview.py
=====================================
@@ -9,7 +9,7 @@ import click
from . import options
import rasterio
-from rasterio.enums import Resampling
+from rasterio.enums import _OverviewResampling as OverviewResampling
def build_handler(ctx, param, value):
@@ -70,8 +70,7 @@ def get_maximum_overview_level(width, height, minsize=256):
@click.option('--rebuild', help="Reconstruct existing overviews.",
is_flag=True, default=False)
@click.option('--resampling', help="Resampling algorithm.",
- type=click.Choice(
- [it.name for it in Resampling if it.value in [0, 1, 2, 3, 4, 5, 6, 7]]),
+ type=click.Choice([it.name for it in OverviewResampling]),
default='nearest', show_default=True)
@click.pass_context
def overview(ctx, input, build, ls, rebuild, resampling):
@@ -126,14 +125,14 @@ def overview(ctx, input, build, ls, rebuild, resampling):
ns='rio_overview').get('resampling') or resampling
dst.build_overviews(
- list(factors), Resampling[resampling_method])
+ list(factors), OverviewResampling[resampling_method])
elif build:
with rasterio.open(input, 'r+') as dst:
if build == "auto":
overview_level = get_maximum_overview_level(dst.width, dst.height)
build = [2 ** j for j in range(1, overview_level + 1)]
- dst.build_overviews(build, Resampling[resampling])
+ dst.build_overviews(build, OverviewResampling[resampling])
# Save the resampling method to a tag.
dst.update_tags(ns='rio_overview', resampling=resampling)
=====================================
rasterio/windows.py
=====================================
@@ -285,10 +285,10 @@ def from_bounds(
if not isinstance(transform, Affine): # TODO: RPCs?
raise WindowError("A transform object is required to calculate the window")
- if (right - left) / transform.a <= 0:
+ if (right - left) / transform.a < 0:
raise WindowError("Bounds and transform are inconsistent")
- if (bottom - top) / transform.e <= 0:
+ if (bottom - top) / transform.e < 0:
raise WindowError("Bounds and transform are inconsistent")
rows, cols = rowcol(
=====================================
tests/data/float_raster_with_nodata.tif
=====================================
Binary files /dev/null and b/tests/data/float_raster_with_nodata.tif differ
=====================================
tests/test__env.py
=====================================
@@ -34,6 +34,8 @@ def mock_debian(tmpdir):
tmpdir.ensure("share/gdal/3.0/header.dxf")
tmpdir.ensure("share/gdal/3.1/header.dxf")
tmpdir.ensure("share/gdal/3.2/header.dxf")
+ tmpdir.ensure("share/gdal/3.3/header.dxf")
+ tmpdir.ensure("share/gdal/3.4/header.dxf")
tmpdir.ensure("share/proj/epsg")
return tmpdir
=====================================
tests/test_enums.py
=====================================
@@ -1,5 +1,7 @@
"""Enum tests"""
+import pytest
+
from rasterio import enums
@@ -11,3 +13,9 @@ def test_grey_gray():
def test_gray_gray():
"""Name of ColorInterp.gray is 'gray'"""
assert enums.ColorInterp.gray.name == "gray"
+
+
+ at pytest.mark.parametrize("resamp", enums._OverviewResampling)
+def test_resampling(resamp):
+ """Make sure that resampling value are the same."""
+ assert resamp.value == enums.Resampling[resamp.name].value
=====================================
tests/test_merge.py
=====================================
@@ -51,3 +51,11 @@ def test_merge_method(test_data_dir_overlapping, method, value):
datasets, output_count=output_count, method=method, dtype=numpy.uint64
)
numpy.testing.assert_array_equal(arr[:, 5:10, 5:10], value)
+
+
+def test_issue2163():
+ """Demonstrate fix for issue 2163"""
+ with rasterio.open("tests/data/float_raster_with_nodata.tif") as src:
+ data = src.read()
+ result, transform = merge([src])
+ assert numpy.allclose(data, result)
=====================================
tests/test_overviews.py
=====================================
@@ -1,5 +1,4 @@
"""Tests of overview counting and creation."""
-import math
import numpy as np
import pytest
@@ -7,6 +6,7 @@ import pytest
from .conftest import requires_gdal2, requires_gdal33
import rasterio
+from rasterio.enums import _OverviewResampling as OverviewResampling
from rasterio.enums import Resampling
from rasterio.env import GDALVersion
from rasterio.errors import OverviewCreationError
@@ -24,7 +24,7 @@ def test_build_overviews_one(data):
inputfile = str(data.join('RGB.byte.tif'))
with rasterio.open(inputfile, 'r+') as src:
overview_factors = [2]
- src.build_overviews(overview_factors, resampling=Resampling.nearest)
+ src.build_overviews(overview_factors, resampling=OverviewResampling.nearest)
assert src.overviews(1) == [2]
assert src.overviews(2) == [2]
assert src.overviews(3) == [2]
@@ -34,7 +34,7 @@ def test_build_overviews_two(data):
inputfile = str(data.join('RGB.byte.tif'))
with rasterio.open(inputfile, 'r+') as src:
overview_factors = [2, 4]
- src.build_overviews(overview_factors, resampling=Resampling.nearest)
+ src.build_overviews(overview_factors, resampling=OverviewResampling.nearest)
assert src.overviews(1) == [2, 4]
assert src.overviews(2) == [2, 4]
assert src.overviews(3) == [2, 4]
@@ -48,7 +48,7 @@ def test_build_overviews_bilinear(data):
inputfile = str(data.join('RGB.byte.tif'))
with rasterio.open(inputfile, 'r+') as src:
overview_factors = [2, 4]
- src.build_overviews(overview_factors, resampling=Resampling.bilinear)
+ src.build_overviews(overview_factors, resampling=OverviewResampling.bilinear)
assert src.overviews(1) == [2, 4]
assert src.overviews(2) == [2, 4]
assert src.overviews(3) == [2, 4]
@@ -58,7 +58,7 @@ def test_build_overviews_average(data):
inputfile = str(data.join('RGB.byte.tif'))
with rasterio.open(inputfile, 'r+') as src:
overview_factors = [2, 4]
- src.build_overviews(overview_factors, resampling=Resampling.average)
+ src.build_overviews(overview_factors, resampling=OverviewResampling.average)
assert src.overviews(1) == [2, 4]
assert src.overviews(2) == [2, 4]
assert src.overviews(3) == [2, 4]
@@ -68,7 +68,7 @@ def test_build_overviews_gauss(data):
inputfile = str(data.join('RGB.byte.tif'))
with rasterio.open(inputfile, 'r+') as src:
overview_factors = [2, 4]
- src.build_overviews(overview_factors, resampling=Resampling.gauss)
+ src.build_overviews(overview_factors, resampling=OverviewResampling.gauss)
assert src.overviews(1) == [2, 4]
assert src.overviews(2) == [2, 4]
assert src.overviews(3) == [2, 4]
@@ -89,7 +89,7 @@ def test_issue1333(data):
with rasterio.open(inputfile, 'r+') as src:
overview_factors = [1024, 2048]
src.build_overviews(
- overview_factors, resampling=Resampling.average)
+ overview_factors, resampling=OverviewResampling.average)
@requires_gdal2
@@ -101,19 +101,22 @@ def test_build_overviews_new_file(tmpdir, path_rgb_byte_tif):
dst.write(src.read())
overview_factors = [2, 4]
dst.build_overviews(
- overview_factors, resampling=Resampling.nearest)
+ overview_factors, resampling=OverviewResampling.nearest)
with rasterio.open(dst_file, overview_level=1) as src:
data = src.read()
assert data.any()
+ at pytest.mark.parametrize("ovr_levels", [[2], [3], [2, 4, 8]])
@requires_gdal33
-def test_ignore_overviews(data):
- """open dataset with OVERVIEW_LEVEL=-1, overviews should be ignored"""
+def test_ignore_overviews(data, ovr_levels):
+ """open dataset with OVERVIEW_LEVEL=NONE, overviews should be ignored"""
inputfile = str(data.join('RGB.byte.tif'))
+
+ # Add overview levels to the fixture.
with rasterio.open(inputfile, 'r+') as src:
- src.build_overviews([2], resampling=Resampling.nearest)
+ src.build_overviews(ovr_levels, resampling=Resampling.nearest)
with rasterio.open(inputfile, OVERVIEW_LEVEL=-1) as src:
assert src.overviews(1) == []
@@ -124,16 +127,33 @@ def test_ignore_overviews(data):
@requires_gdal33
def test_decimated_no_use_overview(red_green):
"""Force ignore existing overviews when performing decimated read"""
- # Corrupt overview of red file
+ # Corrupt overview of red file by replacing red.tif.ovr with
+ # green.tif.ovr. We have a GDAL overview reading bug if green
+ # pixels appear in a decimated read.
green_ovr = red_green.join("green.tif.ovr")
- green_ovr.rename(red_green.join("red.tif.ovr"))
+ green_ovr.move(red_green.join("red.tif.ovr"))
assert not green_ovr.exists()
- # Read the corrupted red overview
+
+ # Read the corrupted red overview.
with rasterio.open(str(red_green.join("red.tif.ovr"))) as ovr:
- ovr_data = ovr.read()
+ ovr_data = ovr.read(2)
ovr_shape = ovr_data.shape
- assert (ovr_data[1] == 204).all()
- # Perform decimated read and ensure no use of file overview (different from corrupted)
- with rasterio.open(str(red_green.join("red.tif")), OVERVIEW_LEVEL=-1) as src:
- decimated_data = src.read(out_shape=ovr_shape)
+ assert (ovr_data == 204).all() # Green pixels in band 2
+
+ # Perform decimated read and ensure no use of file overview
+ # (different from corrupted).
+ with rasterio.open(str(red_green.join("red.tif")), OVERVIEW_LEVEL="NONE") as src:
+ decimated_data = src.read(2, out_shape=ovr_shape)
assert not np.array_equal(ovr_data, decimated_data)
+
+
+ at requires_gdal33
+def test_build_overviews_rms(data):
+ """Make sure RMS resampling works with gdal3.3."""
+ inputfile = str(data.join('RGB.byte.tif'))
+ with rasterio.open(inputfile, 'r+') as src:
+ overview_factors = [2, 4]
+ src.build_overviews(overview_factors, resampling=OverviewResampling.rms)
+ assert src.overviews(1) == [2, 4]
+ assert src.overviews(2) == [2, 4]
+ assert src.overviews(3) == [2, 4]
=====================================
tests/test_rpcs.py
=====================================
@@ -156,9 +156,12 @@ def test_rpcs_write_read_rpcs(tmpdir):
assert isinstance(rpcs, RPC)
expected = TEST_RPCS_FROM_GDAL
- # GDAL doesn't include these metadata items on write
+ # 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')
+ rpcs.err_bias = None
+ rpcs.err_rand = None
assert sorted(rpcs.to_gdal().keys()) == sorted(expected.keys())
=====================================
tests/test_windows.py
=====================================
@@ -608,10 +608,26 @@ def test_from_bounds_rotation():
assert win.height == pytest.approx(2.0 * height)
-def test_issue_2138():
+ at pytest.mark.parametrize(
+ "sy,left,bottom,right,top",
+ [(-0.001, 1.0, 45.7, 1.2, 45.9), (0.001, 1.0, 45.9, 1.2, 45.7)],
+)
+def test_issue_2138(sy, left, bottom, right, top):
"""WindowError is raised if bounds and transform are inconsistent"""
- w, s, e, n = 1.0, 45.7, 1.2, 45.9
- a = 0.001
- transform = Affine.translation(w, n) * Affine.scale(a, -a)
+ transform = Affine.translation(left, top) * Affine.scale(0.001, sy)
with pytest.raises(WindowError):
- from_bounds(w, n, e, s, transform)
+ from_bounds(left, top, right, bottom, transform)
+
+
+ at pytest.mark.parametrize("sx", [-1.0, 1.0])
+def test_zero_width(sx):
+ """Permit a zero width window"""
+ transform = Affine.translation(0, 45.0) * Affine.scale(sx, -1.0)
+ assert from_bounds(0.0, 44.0, 0.0, 45.0, transform).width == 0
+
+
+ at pytest.mark.parametrize("sy", [-1.0, 1.0])
+def test_zero_height(sy):
+ """Permit a zero height window"""
+ transform = Affine.translation(0, 45.0) * Affine.scale(1.0, sy)
+ assert from_bounds(0.0, 44.0, 1.0, 44.0, transform).height == 0
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/-/compare/55e5da9f10986f76959a12d4e6dde8fa5e44d18d...a5ad29ea97dc8afae72f6f6a59d09712c289f10f
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/-/compare/55e5da9f10986f76959a12d4e6dde8fa5e44d18d...a5ad29ea97dc8afae72f6f6a59d09712c289f10f
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/20210427/803a5385/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list