[Git][debian-gis-team/rasterio][upstream] New upstream version 1.0.16
Bas Couwenberg
gitlab at salsa.debian.org
Tue Feb 5 14:58:42 GMT 2019
Bas Couwenberg pushed to branch upstream at Debian GIS Project / rasterio
Commits:
aa8c0f07 by Bas Couwenberg at 2019-02-05T14:33:39Z
New upstream version 1.0.16
- - - - -
12 changed files:
- CHANGES.txt
- rasterio/__init__.py
- rasterio/_base.pyx
- rasterio/_crs.pyx
- rasterio/_io.pyx
- rasterio/_shim1.pyx
- rasterio/crs.py
- rasterio/env.py
- rasterio/shim_rasterioex.pxi
- tests/test_crs.py
- tests/test_env.py
- tests/test_gcps.py
Changes:
=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,22 @@
Changes
=======
+1.0.16 (2019-02-04)
+-------------------
+
+- A bug preventing GCPs from being created with new BufferedDatasetWriter
+ instances (#1600) has been fixed (#1610).
+- A previously unreported bug preventing BufferedDatasetWriters from being
+ opened in r+ mode has been fixed.
+- A regression in creating CRS objects from PROJ4 strings that include
+ "+wktext" (#1609) has been fixed.
+- Regressions in str representations of empty CRS objects and the handling of
+ unreferenced datasets in rasterio._base have been fixed (#1616).
+- GDAL seems to work best if GDAL_DATA is set as early as possible. Ideally it
+ is set when building the library or in the environment before importing
+ Rasterio, but for wheels we patch GDAL_DATA into os.environ when rasterio.env
+ is imported. This resolves #1611.
+
1.0.15 (2019-01-27)
-------------------
=====================================
rasterio/__init__.py
=====================================
@@ -42,7 +42,7 @@ import rasterio.path
__all__ = ['band', 'open', 'pad', 'Env']
-__version__ = "1.0.15"
+__version__ = "1.0.16"
__gdal_version__ = gdal_version()
# Rasterio attaches NullHandler to the 'rasterio' logger and its
=====================================
rasterio/_base.pyx
=====================================
@@ -267,7 +267,7 @@ cdef class DatasetBase(object):
if wkt:
return CRS.from_wkt(wkt)
else:
- return CRS()
+ return None
def read_crs(self):
"""Return the GDAL dataset's stored CRS"""
=====================================
rasterio/_crs.pyx
=====================================
@@ -3,10 +3,10 @@
import logging
+import rasterio._env
from rasterio._err import CPLE_BaseError, CPLE_NotSupportedError
from rasterio.compat import string_types
from rasterio.errors import CRSError
-from rasterio.env import env_ctx_if_needed
from rasterio._base cimport _osr_from_crs as osr_from_crs
from rasterio._base cimport _safe_osr_release
@@ -175,10 +175,8 @@ cdef class _CRS(object):
try:
exc_wrap_ogrerr(exc_wrap_int(OSRImportFromProj4(obj._osr, <const char *>proj_b)))
-
except CPLE_BaseError as exc:
raise CRSError("The PROJ4 dict could not be understood. {}".format(exc))
-
else:
return obj
@@ -247,13 +245,10 @@ cdef class _CRS(object):
try:
errcode = exc_wrap_ogrerr(OSRImportFromWkt(obj._osr, &wkt_c))
-
if morph_from_esri_dialect:
exc_wrap_ogrerr(OSRMorphFromESRI(obj._osr))
-
except CPLE_BaseError as exc:
raise CRSError("The WKT could not be parsed. {}".format(exc))
-
else:
return obj
@@ -414,12 +409,11 @@ _param_data = """
+vopt
+W
+westo
++wktext
+x_0 False easting
+y_0 False northing
+zone UTM zone
"""
-with env_ctx_if_needed():
- _lines = filter(lambda x: len(x) > 1, _param_data.split("\n"))
- all_proj_keys = list(set(line.split()[0].lstrip("+").strip()
- for line in _lines)) + ['no_mayo']
+_lines = filter(lambda x: len(x) > 1, _param_data.split("\n"))
+all_proj_keys = list(set(line.split()[0].lstrip("+").strip() for line in _lines)) + ['no_mayo']
=====================================
rasterio/_io.pyx
=====================================
@@ -117,15 +117,20 @@ cdef int io_auto(data, GDALRasterBandH band, bint write, int resampling=0) excep
cdef float height = data.shape[-2]
cdef float width = data.shape[-1]
- if ndims == 2:
- return io_band(band, write, 0.0, 0.0, width, height, data,
- resampling=resampling)
- elif ndims == 3:
- indexes = np.arange(1, data.shape[0] + 1, dtype='intp')
- return io_multi_band(band, write, 0.0, 0.0, width, height, data,
- indexes, resampling=resampling)
- else:
- raise ValueError("Specified data must have 2 or 3 dimensions")
+ try:
+
+ if ndims == 2:
+ return io_band(band, write, 0.0, 0.0, width, height, data, resampling=resampling)
+
+ elif ndims == 3:
+ indexes = np.arange(1, data.shape[0] + 1, dtype='intp')
+ return io_multi_band(band, write, 0.0, 0.0, width, height, data, indexes, resampling=resampling)
+
+ else:
+ raise ValueError("Specified data must have 2 or 3 dimensions")
+
+ except CPLE_BaseError as cplerr:
+ raise RasterioIOError(str(cplerr))
cdef class DatasetReaderBase(DatasetBase):
@@ -673,25 +678,22 @@ cdef class DatasetReaderBase(DatasetBase):
indexes_arr = np.array(indexes, dtype='intp')
indexes_count = <int>indexes_arr.shape[0]
- if masks:
- # Warn if nodata attribute is shadowing an alpha band.
- if self.count == 4 and self.colorinterp[3] == ColorInterp.alpha:
- for flags in self.mask_flag_enums:
- if MaskFlags.nodata in flags:
- warnings.warn(NodataShadowWarning())
+ try:
+
+ if masks:
+ # Warn if nodata attribute is shadowing an alpha band.
+ if self.count == 4 and self.colorinterp[3] == ColorInterp.alpha:
+ for flags in self.mask_flag_enums:
+ if MaskFlags.nodata in flags:
+ warnings.warn(NodataShadowWarning())
- retval = io_multi_mask(
- self._hds, 0, xoff, yoff, width, height,
- out, indexes_arr, resampling=resampling)
+ io_multi_mask(self._hds, 0, xoff, yoff, width, height, out, indexes_arr, resampling=resampling)
- else:
- retval = io_multi_band(self._hds, 0, xoff, yoff, width, height,
- out, indexes_arr, resampling=resampling)
+ else:
+ io_multi_band(self._hds, 0, xoff, yoff, width, height, out, indexes_arr, resampling=resampling)
- if retval in (1, 2, 3):
- raise IOError("Read or write failed")
- elif retval == 4:
- raise ValueError("NULL band")
+ except CPLE_BaseError as cplerr:
+ raise RasterioIOError("Read or write failed. {}".format(cplerr))
return out
@@ -1354,13 +1356,11 @@ cdef class DatasetWriterBase(DatasetReaderBase):
indexes_arr = np.array(indexes, dtype='intp')
indexes_count = <int>indexes_arr.shape[0]
- retval = io_multi_band(self._hds, 1, xoff, yoff, width, height,
- src, indexes_arr)
- if retval in (1, 2, 3):
- raise IOError("Read or write failed")
- elif retval == 4:
- raise ValueError("NULL band")
+ try:
+ io_multi_band(self._hds, 1, xoff, yoff, width, height, src, indexes_arr)
+ except CPLE_BaseError as cplerr:
+ raise RasterioIOError("Read or write failed. {}".format(cplerr))
def write_band(self, bidx, src, window=None):
"""Write the src array into the `bidx` band.
@@ -1540,15 +1540,19 @@ cdef class DatasetWriterBase(DatasetReaderBase):
width = self.width
height = self.height
- if mask_array is True:
- GDALFillRaster(mask, 255, 0)
- elif mask_array is False:
- GDALFillRaster(mask, 0, 0)
- elif mask_array.dtype == np.bool:
- array = 255 * mask_array.astype(np.uint8)
- retval = io_band(mask, 1, xoff, yoff, width, height, array)
- else:
- retval = io_band(mask, 1, xoff, yoff, width, height, mask_array)
+ try:
+ if mask_array is True:
+ GDALFillRaster(mask, 255, 0)
+ elif mask_array is False:
+ GDALFillRaster(mask, 0, 0)
+ elif mask_array.dtype == np.bool:
+ array = 255 * mask_array.astype(np.uint8)
+ io_band(mask, 1, xoff, yoff, width, height, array)
+ else:
+ io_band(mask, 1, xoff, yoff, width, height, mask_array)
+
+ except CPLE_BaseError as cplerr:
+ raise RasterioIOError("Read or write failed. {}".format(cplerr))
def build_overviews(self, factors, resampling=Resampling.nearest):
"""Build overviews at one or more decimation factors for all
@@ -1782,22 +1786,32 @@ cdef class InMemoryRaster:
self._hds = NULL
def read(self):
+
if self._image is None:
- raise IOError("You need to write data before you can read the data.")
+ raise RasterioIOError("You need to write data before you can read the data.")
+
+ try:
+ if self._image.ndim == 2:
+ io_auto(self._image, self.band(1), False)
+ else:
+ io_auto(self._image, self._hds, False)
+
+ except CPLE_BaseError as cplerr:
+ raise RasterioIOError("Read or write failed. {}".format(cplerr))
- if self._image.ndim == 2:
- exc_wrap_int(io_auto(self._image, self.band(1), False))
- else:
- exc_wrap_int(io_auto(self._image, self._hds, False))
return self._image
def write(self, np.ndarray image):
self._image = image
- if image.ndim == 2:
- exc_wrap_int(io_auto(self._image, self.band(1), True))
- else:
- exc_wrap_int(io_auto(self._image, self._hds, True))
+ try:
+ if image.ndim == 2:
+ io_auto(self._image, self.band(1), True)
+ else:
+ io_auto(self._image, self._hds, True)
+
+ except CPLE_BaseError as cplerr:
+ raise RasterioIOError("Read or write failed. {}".format(cplerr))
cdef class BufferedDatasetWriterBase(DatasetWriterBase):
@@ -1956,10 +1970,11 @@ cdef class BufferedDatasetWriterBase(DatasetWriterBase):
self.write_transform(self._transform)
if self._crs:
self._set_crs(self._crs)
- if self._gcps:
- self._set_gcps(self._gcps, self._crs)
+ if self._init_gcps:
+ self._set_gcps(self._init_gcps, self._crs)
elif self.mode == 'r+':
+ fname = name_b
try:
temp = exc_wrap_pointer(GDALOpenShared(fname, <GDALAccess>0))
except Exception as exc:
@@ -1969,7 +1984,7 @@ cdef class BufferedDatasetWriterBase(DatasetWriterBase):
GDALCreateCopy(memdrv, "temp", temp, 1, NULL, NULL, NULL))
drv = GDALGetDatasetDriver(temp)
- self.driver = get_driver_name(drv)
+ self.driver = get_driver_name(drv).decode('utf-8')
GDALClose(temp)
# Instead of calling _begin() we do the following.
=====================================
rasterio/_shim1.pyx
=====================================
@@ -10,7 +10,7 @@ from rasterio import dtypes
from rasterio.enums import Resampling
cimport numpy as np
-from rasterio._err cimport exc_wrap_pointer
+from rasterio._err cimport exc_wrap_int, exc_wrap_pointer
from rasterio.errors import GDALOptionNotImplementedError
@@ -88,7 +88,7 @@ cdef int io_band(
band, mode, xoff, yoff, xsize, ysize, buf, bufxsize, bufysize,
buftype, bufpixelspace, buflinespace)
- return retval
+ return exc_wrap_int(retval)
cdef int io_multi_band(
@@ -121,17 +121,21 @@ cdef int io_multi_band(
cdef int xsize = <int>width
cdef int ysize = <int>height
- with nogil:
- bandmap = <int *>CPLMalloc(count*sizeof(int))
- for i in range(count):
- bandmap[i] = <int>indexes[i]
- retval = GDALDatasetRasterIO(
- hds, mode, xoff, yoff, xsize, ysize, buf,
- bufxsize, bufysize, buftype, count, bandmap,
- bufpixelspace, buflinespace, bufbandspace)
- CPLFree(bandmap)
+ bandmap = <int *>CPLMalloc(count*sizeof(int))
+ for i in range(count):
+ bandmap[i] = <int>indexes[i]
- return retval
+ try:
+ with nogil:
+ retval = GDALDatasetRasterIO(
+ hds, mode, xoff, yoff, xsize, ysize, buf,
+ bufxsize, bufysize, buftype, count, bandmap,
+ bufpixelspace, buflinespace, bufbandspace)
+
+ return exc_wrap_int(retval)
+
+ finally:
+ CPLFree(bandmap)
cdef int io_multi_mask(
@@ -183,4 +187,4 @@ cdef int io_multi_mask(
if retval:
break
- return retval
+ return exc_wrap_int(retval)
=====================================
rasterio/crs.py
=====================================
@@ -71,7 +71,17 @@ class CRS(collections.Mapping):
if 'init' in data:
data['init'] = data['init'].replace('EPSG:', 'epsg:')
- proj = ' '.join(['+{}={}'.format(key, val) for key, val in data.items()])
+ proj_parts = []
+
+ for key, val in data.items():
+ if val is False or None:
+ continue
+ elif val is True:
+ proj_parts.append('+{}'.format(key))
+ else:
+ proj_parts.append('+{}={}'.format(key, val))
+
+ proj = ' '.join(proj_parts)
self._crs = _CRS.from_proj4(proj)
else:
@@ -157,11 +167,18 @@ class CRS(collections.Mapping):
dict
"""
- epsg_code = self.to_epsg()
- if epsg_code:
- return {'init': 'epsg:{}'.format(epsg_code)}
+ if self._crs is None:
+ raise CRSError("Undefined CRS has no dict representation")
+
else:
- return self._crs.to_dict()
+ epsg_code = self.to_epsg()
+ if epsg_code:
+ return {'init': 'epsg:{}'.format(epsg_code)}
+ else:
+ try:
+ return self._crs.to_dict()
+ except CRSError:
+ return {}
@property
def data(self):
=====================================
rasterio/env.py
=====================================
@@ -8,7 +8,9 @@ import re
import threading
import warnings
-from rasterio._env import GDALEnv, get_gdal_config, set_gdal_config
+from rasterio._env import (
+ GDALEnv, get_gdal_config, set_gdal_config,
+ GDALDataFinder, PROJDataFinder)
from rasterio.compat import string_types, getargspec
from rasterio.errors import (
EnvError, GDALVersionError, RasterioDeprecationWarning)
@@ -598,3 +600,22 @@ def require_gdal_version(version, param=None, values=None, is_max_version=False,
return wrapper
return decorator
+
+
+# Patch the environment if needed, such as in the installed wheel case.
+
+if 'GDAL_DATA' not in os.environ:
+
+ path = GDALDataFinder().search()
+
+ if path:
+ os.environ['GDAL_DATA'] = path
+ log.debug("GDAL_DATA not found in environment, set to %r.", path)
+
+if 'PROJ_LIB' not in os.environ:
+
+ path = PROJDataFinder().search()
+
+ if path:
+ os.environ['PROJ_LIB'] = path
+ log.debug("PROJ data not found in environment, set to %r.", path)
=====================================
rasterio/shim_rasterioex.pxi
=====================================
@@ -6,6 +6,8 @@ from rasterio.enums import Resampling
cimport numpy as np
+from rasterio._err cimport exc_wrap_int
+
cdef extern from "cpl_progress.h":
@@ -73,7 +75,7 @@ cdef int io_band(GDALRasterBandH band, int mode, float x0, float y0,
band, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf, bufxsize, bufysize,
buftype, bufpixelspace, buflinespace, &extras)
- return retval
+ return exc_wrap_int(retval)
cdef int io_multi_band(GDALDatasetH hds, int mode, float x0, float y0,
@@ -117,17 +119,21 @@ cdef int io_multi_band(GDALDatasetH hds, int mode, float x0, float y0,
extras.pfnProgress = NULL
extras.pProgressData = NULL
- with nogil:
- bandmap = <int *>CPLMalloc(count*sizeof(int))
- for i in range(count):
- bandmap[i] = <int>indexes[i]
- retval = GDALDatasetRasterIOEx(
- hds, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf,
- bufxsize, bufysize, buftype, count, bandmap,
- bufpixelspace, buflinespace, bufbandspace, &extras)
- CPLFree(bandmap)
+ bandmap = <int *>CPLMalloc(count*sizeof(int))
+ for i in range(count):
+ bandmap[i] = <int>indexes[i]
- return retval
+ try:
+ with nogil:
+ retval = GDALDatasetRasterIOEx(
+ hds, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf,
+ bufxsize, bufysize, buftype, count, bandmap,
+ bufpixelspace, buflinespace, bufbandspace, &extras)
+
+ return exc_wrap_int(retval)
+
+ finally:
+ CPLFree(bandmap)
cdef int io_multi_mask(GDALDatasetH hds, int mode, float x0, float y0,
@@ -187,7 +193,8 @@ cdef int io_multi_mask(GDALDatasetH hds, int mode, float x0, float y0,
retval = GDALRasterIOEx(
hmask, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf, bufxsize,
bufysize, <GDALDataType>1, bufpixelspace, buflinespace, &extras)
+
if retval:
break
- return retval
+ return exc_wrap_int(retval)
=====================================
tests/test_crs.py
=====================================
@@ -88,6 +88,12 @@ def test_read_esri_wkt():
}
+def test_read_no_crs():
+ """crs of a dataset with no SRS is None"""
+ with rasterio.open('tests/data/389225main_sw_1965_1024.jpg') as src:
+ assert src.crs is None
+
+
# Ensure that CRS sticks when we write a file.
@pytest.mark.gdalbin
def test_write_3857(tmpdir):
@@ -385,3 +391,38 @@ def test_implicit_proj_dict(projection_string):
def test_capitalized_epsg_init():
"""Ensure that old behavior is preserved"""
assert CRS(init='EPSG:4326').to_epsg() == 4326
+
+
+def test_issue1609_wktext_a():
+ """Check on fix of issue 1609"""
+ src_proj = {'ellps': 'WGS84',
+ 'proj': 'stere',
+ 'lat_0': -90.0,
+ 'lon_0': 0.0,
+ 'x_0': 0.0,
+ 'y_0': 0.0,
+ 'lat_ts': -70,
+ 'no_defs': True}
+ wkt = CRS(src_proj).wkt
+ assert 'PROJECTION["Polar_Stereographic"]' in wkt
+ assert 'PARAMETER["latitude_of_origin",-70]' in wkt
+
+
+def test_issue1609_wktext_b():
+ """Check on fix of issue 1609"""
+ dst_proj = {'ellps': 'WGS84',
+ 'h': 9000000.0,
+ 'lat_0': -78.0,
+ 'lon_0': 0.0,
+ 'proj': 'nsper',
+ 'units': 'm',
+ 'x_0': 0,
+ 'y_0': 0,
+ 'wktext': True}
+ wkt = CRS(dst_proj).wkt
+ assert '+wktext' in wkt
+
+
+def test_empty_crs_str():
+ """str(CRS()) should be empty string"""
+ assert str(CRS()) == ''
\ No newline at end of file
=====================================
tests/test_env.py
=====================================
@@ -126,6 +126,7 @@ def test_ensure_env_decorator_sets_gdal_data(gdalenv, monkeypatch):
def test_ensure_env_decorator_sets_gdal_data_prefix(gdalenv, monkeypatch, tmpdir):
"""ensure_env finds GDAL data under a prefix"""
+
@ensure_env
def f():
return getenv()['GDAL_DATA']
=====================================
tests/test_gcps.py
=====================================
@@ -1,5 +1,6 @@
"""Tests of ground control points"""
+import numpy
import pytest
import rasterio
@@ -79,6 +80,35 @@ def test_write_read_gcps(tmpdir):
assert (200.0, 2000.0, 0.0) == (point.x, point.y, point.z)
+def test_write_read_gcps_buffereddatasetwriter(tmpdir):
+ filename = str(tmpdir.join('test.jpg'))
+ gcps = [GroundControlPoint(1, 1, 100.0, 1000.0, z=0.0)]
+
+ with rasterio.open(filename, 'w', driver='JPEG', dtype='uint8', count=3,
+ width=10, height=10, crs='epsg:4326', gcps=gcps) as dst:
+ dst.write(numpy.ones((3, 10, 10), dtype='uint8'))
+
+ with rasterio.open(filename, 'r+') as dst:
+ gcps, crs = dst.gcps
+ assert crs.to_epsg() == 4326
+ assert len(gcps) == 1
+ point = gcps[0]
+ assert (1, 1) == (point.row, point.col)
+ assert (100.0, 1000.0, 0.0) == (point.x, point.y, point.z)
+
+ dst.gcps = [
+ GroundControlPoint(1, 1, 100.0, 1000.0, z=0.0),
+ GroundControlPoint(2, 2, 200.0, 2000.0, z=0.0)], crs
+
+ gcps, crs = dst.gcps
+
+ assert crs.to_epsg() == 4326
+ assert len(gcps) == 2
+ point = gcps[1]
+ assert (2, 2) == (point.row, point.col)
+ assert (200.0, 2000.0, 0.0) == (point.x, point.y, point.z)
+
+
def test_read_vrt_gcps(tmpdir):
vrtfile = tmpdir.join('test.vrt')
vrtfile.write("""
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/commit/aa8c0f070ddc59335aa8cd353a63d9334697c42d
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/commit/aa8c0f070ddc59335aa8cd353a63d9334697c42d
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/20190205/1d6cd11d/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list