[Git][debian-gis-team/trollimage][master] 6 commits: New upstream version 1.16.0
Antonio Valentino (@antonio.valentino)
gitlab at salsa.debian.org
Sat Oct 16 17:39:24 BST 2021
Antonio Valentino pushed to branch master at Debian GIS Project / trollimage
Commits:
64580fed by Antonio Valentino at 2021-10-16T16:13:11+00:00
New upstream version 1.16.0
- - - - -
acae3ea5 by Antonio Valentino at 2021-10-16T16:13:18+00:00
Update upstream source from tag 'upstream/1.16.0'
Update to upstream version '1.16.0'
with Debian dir 36ef0a23c557aed4df78c22184e1d918b6c025c4
- - - - -
289cc390 by Antonio Valentino at 2021-10-16T16:14:39+00:00
New upstream release
- - - - -
972c5c4f by Antonio Valentino at 2021-10-16T16:15:56+00:00
Refresh all patches
- - - - -
5633c906 by Antonio Valentino at 2021-10-16T16:18:28+00:00
Drop versioned dependency on numpy
- - - - -
602642ce by Antonio Valentino at 2021-10-16T16:19:23+00:00
Set distribution to unstable
- - - - -
13 changed files:
- − .github/ISSUE_TEMPLATE.md
- + .github/ISSUE_TEMPLATE/bug_report.md
- + .github/ISSUE_TEMPLATE/feature_request.md
- CHANGELOG.md
- debian/changelog
- debian/control
- debian/patches/0001-No-display.patch
- trollimage/colormap.py
- trollimage/image.py
- trollimage/tests/test_colormap.py
- trollimage/tests/test_image.py
- trollimage/version.py
- trollimage/xrimage.py
Changes:
=====================================
.github/ISSUE_TEMPLATE.md deleted
=====================================
@@ -1,18 +0,0 @@
-#### Code Sample, a minimal, complete, and verifiable piece of code
-
-```python
-# Your code here
-
-```
-#### Problem description
-
-[this should also explain **why** the current behaviour is a problem and why the
-expected output is a better solution.]
-
-#### Expected Output
-
-#### Actual Result, Traceback if applicable
-
-#### Versions of Python, package at hand and relevant dependencies
-
-Thank you for reporting an issue !
=====================================
.github/ISSUE_TEMPLATE/bug_report.md
=====================================
@@ -0,0 +1,34 @@
+---
+name: Bug report
+about: Create a report to help us improve
+labels: bug
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+If you're not sure how, please consider this
+[article on minimal bug reports](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports).
+
+**To Reproduce**
+
+```python
+# Your code here
+
+```
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Actual results**
+Text output of actual results or error messages including full tracebacks if applicable.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Environment Info:**
+ - OS: [e.g. OSX, Windows, Linux]
+ - Satpy Version: [e.g. 0.9.0]
+
+**Additional context**
+Add any other context about the problem here.
=====================================
.github/ISSUE_TEMPLATE/feature_request.md
=====================================
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+labels: enhancement
+
+---
+
+## Feature Request
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe any changes to existing user workflow**
+Are there any backwards compatibility concerns? Changes to the build process? Additional dependencies?
+
+**Additional context**
+Have you considered any alternative solutions or is there anything else that would help describe your request.
=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,28 @@
+## Version 1.16.0 (2021/10/12)
+
+### Issues Closed
+
+* [Issue 87](https://github.com/pytroll/trollimage/issues/87) - ReportError "ValueError: Merged colormap 'values' are not monotonically increasing." ([PR 91](https://github.com/pytroll/trollimage/pull/91) by [@djhoese](https://github.com/djhoese))
+* [Issue 84](https://github.com/pytroll/trollimage/issues/84) - allow customization of GDALMetaData tags for scale and offset ([PR 85](https://github.com/pytroll/trollimage/pull/85) by [@gerritholl](https://github.com/gerritholl))
+
+In this release 2 issues were closed.
+
+### Pull Requests Merged
+
+#### Bugs fixed
+
+* [PR 91](https://github.com/pytroll/trollimage/pull/91) - Fix colormaps not allowing merge points of the same value ([87](https://github.com/pytroll/trollimage/issues/87))
+* [PR 83](https://github.com/pytroll/trollimage/pull/83) - Fix palettize dtype for dask arrays
+
+#### Features added
+
+* [PR 88](https://github.com/pytroll/trollimage/pull/88) - List supported "simple image" formats in docstrings and error message ([86](https://github.com/pytroll/trollimage/issues/86), [1345](https://github.com/pytroll/satpy/issues/1345))
+* [PR 85](https://github.com/pytroll/trollimage/pull/85) - Allow customising scale and offset labels ([84](https://github.com/pytroll/trollimage/issues/84))
+* [PR 82](https://github.com/pytroll/trollimage/pull/82) - Add 'inplace' keyword argument to Colormap.reverse and Colormap.set_range
+
+In this release 5 pull requests were closed.
+
+
## Version 1.15.1 (2021/07/20)
### Pull Requests Merged
=====================================
debian/changelog
=====================================
@@ -1,9 +1,17 @@
-trollimage (1.15.1-2) UNRELEASED; urgency=medium
+trollimage (1.16.0-1) unstable; urgency=medium
- * Team upload.
+ [ Bas Couwenberg ]
* Bump Standards-Version to 4.6.0, no changes.
- -- Bas Couwenberg <sebastic at debian.org> Wed, 08 Sep 2021 17:47:44 +0200
+ [ Antonio Valentino ]
+ * New upstream release.
+ * debian/patches:
+ - refresh all patches.
+ * debian/control:
+ - drop versioned dependency on numpy
+ - reformat with cme
+
+ -- Antonio Valentino <antonio.valentino at tiscali.it> Sat, 16 Oct 2021 16:18:57 +0000
trollimage (1.15.1-1) unstable; urgency=medium
=====================================
debian/control
=====================================
@@ -3,13 +3,12 @@ Maintainer: Debian GIS Project <pkg-grass-devel at lists.alioth.debian.org>
Uploaders: Antonio Valentino <antonio.valentino at tiscali.it>
Section: python
Testsuite: autopkgtest-pkg-python
-Rules-Requires-Root: no
Priority: optional
Build-Depends: debhelper-compat (= 12),
dh-python,
python3-all,
python3-dask,
- python3-numpy (>= 1:1.13),
+ python3-numpy,
python3-pil,
python3-pytest,
python3-rasterio,
@@ -19,10 +18,11 @@ Standards-Version: 4.6.0
Vcs-Browser: https://salsa.debian.org/debian-gis-team/trollimage
Vcs-Git: https://salsa.debian.org/debian-gis-team/trollimage.git
Homepage: https://github.com/pytroll/trollimage
+Rules-Requires-Root: no
Package: python3-trollimage
Architecture: all
-Depends: python3-numpy (>= 1:1.13),
+Depends: python3-numpy,
python3-pil,
${python3:Depends},
${misc:Depends}
=====================================
debian/patches/0001-No-display.patch
=====================================
@@ -8,7 +8,7 @@ Skip tests that require display.
1 file changed, 1 insertion(+)
diff --git a/trollimage/tests/test_image.py b/trollimage/tests/test_image.py
-index 2cd9918..e6a6d72 100644
+index 6469ced..691a49c 100644
--- a/trollimage/tests/test_image.py
+++ b/trollimage/tests/test_image.py
@@ -2036,6 +2036,7 @@ class TestXRImage:
=====================================
trollimage/colormap.py
=====================================
@@ -134,7 +134,7 @@ def palettize(arr, colors, values):
def _palettize_dask(darr, colors, values):
"""Apply a palette to a dask array."""
- return darr.map_blocks(_palettize, values, dtype=colors.dtype)
+ return darr.map_blocks(_palettize, values, dtype=int)
def _palettize(arr, values):
@@ -256,9 +256,9 @@ class Colormap(object):
"""Append colormap together."""
old, other = self._normalize_color_arrays(self, other)
values = np.concatenate((old.values, other.values))
- if not (np.diff(values) > 0).all():
+ if not (np.diff(values) >= 0).all():
raise ValueError("Merged colormap 'values' are not monotonically "
- "increasing.")
+ "increasing or equal.")
colors = np.concatenate((old.colors, other.colors))
return Colormap(
values=values,
@@ -273,17 +273,56 @@ class Colormap(object):
return cmap1, cmap2
return cmap1.to_rgba(), cmap2.to_rgba()
- def reverse(self):
- """Reverse the current colormap in place."""
- self.colors = np.flipud(self.colors)
+ def reverse(self, inplace=True):
+ """Reverse the current colormap in place.
- def set_range(self, min_val, max_val):
- """Set the range of the colormap to [*min_val*, *max_val*]."""
+ Args:
+ inplace (bool): If True (default), modify the colors of this
+ Colormap inplace. If False, return a new instance.
+
+ """
+ colors = np.flipud(self.colors)
+ if not inplace:
+ return Colormap(
+ values=self.values.copy(),
+ colors=colors
+ )
+ self.colors = colors
+ return self
+
+ def set_range(self, min_val, max_val, inplace=True):
+ """Set the range of the colormap to [*min_val*, *max_val*].
+
+ If min is greater than max then the Colormap's colors are reversed
+ before values are updated to the new range. This is done because
+ Colormap ``values`` must always be monotonically increasing.
+
+ Args:
+ min_val (float): New minimum value for the control points in
+ this colormap.
+ max_val (float): New maximum value for the control points in
+ this colormap.
+ inplace (bool): If True (default), modify the values inplace..
+ If False, return a new Colormap instance.
+
+ """
if min_val > max_val:
+ cmap = self.reverse(inplace=inplace)
max_val, min_val = min_val, max_val
- self.values = (((self.values * 1.0 - self.values.min()) /
- (self.values.max() - self.values.min()))
- * (max_val - min_val) + min_val)
+ else:
+ cmap = self
+
+ values = (((cmap.values * 1.0 - cmap.values.min()) /
+ (cmap.values.max() - cmap.values.min()))
+ * (max_val - min_val) + min_val)
+ if not inplace:
+ return Colormap(
+ values=values,
+ colors=cmap.colors.copy()
+ )
+
+ cmap.values = values
+ return cmap
def to_rio(self):
"""Convert the colormap to a rasterio colormap."""
=====================================
trollimage/image.py
=====================================
@@ -42,6 +42,22 @@ except ImportError:
logger = logging.getLogger(__name__)
+PIL_IMAGE_FORMATS = Pil.registered_extensions()
+
+
+def _pprint_pil_formats():
+ res = ''
+ row = []
+ for i in PIL_IMAGE_FORMATS:
+ if len(row) > 12:
+ res = res + ", ".join(row) + ",\n"
+ row = []
+ row.append(i)
+ return res + ", ".join(row)
+
+
+PIL_IMAGE_FORMATS_STR = _pprint_pil_formats()
+
def ensure_dir(filename):
"""Checks if the dir of f exists, otherwise create it.
@@ -58,30 +74,17 @@ class UnknownImageFormat(Exception):
def check_image_format(fformat):
- """Check that *fformat* is valid
+ """Check that *fformat* is valid.
+
+ Valid formats are listed in https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
"""
- cases = {"jpg": "jpeg",
- "jpeg": "jpeg",
- "tif": "tiff",
- "tiff": "tif",
- "pgm": "ppm",
- "pbm": "ppm",
- "ppm": "ppm",
- "bmp": "bmp",
- "dib": "bmp",
- "gif": "gif",
- "im": "im",
- "pcx": "pcx",
- "png": "png",
- "xbm": "xbm",
- "xpm": "xpm",
- 'jp2': 'jp2',
- }
fformat = fformat.lower()
try:
- fformat = cases[fformat]
+ fformat = PIL_IMAGE_FORMATS["." + fformat]
except KeyError:
- raise UnknownImageFormat("Unknown image format '%s'." % fformat)
+ raise UnknownImageFormat(
+ "Unknown image format '%s'. Supported formats for 'simple_image' writer are:\n%s" %
+ (fformat, PIL_IMAGE_FORMATS_STR))
return fformat
@@ -178,7 +181,7 @@ class Image(object):
color_min = color_range[i][0]
color_max = color_range[i][1]
# Add data to image object as a channel
- #self._add_channel(chn, color_min, color_max)
+ # self._add_channel(chn, color_min, color_max)
else:
color_min = 0.0
color_max = 1.0
@@ -366,9 +369,12 @@ class Image(object):
def pil_save(self, filename, compression=6, fformat=None,
thumbnail_name=None, thumbnail_size=None):
- """Save the image to the given *filename* using PIL. For now, the
- compression level [0-9] is ignored, due to PIL's lack of support. See
- also :meth:`save`.
+ """Save the image to the given *filename* using PIL.
+
+ For now, the compression level [0-9] is ignored, due to PIL's lack of support.
+ See also :meth:`save`.
+
+ Supported image formats are listed in https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
"""
# PIL does not support compression option.
del compression
@@ -384,12 +390,12 @@ class Image(object):
params = {}
- if fformat == 'png':
+ if fformat == 'PNG':
# Take care of GeoImage.tags (if any).
params['pnginfo'] = self._pngmeta()
# JPEG images does not support transparency
- if fformat == 'jpeg' and not self.fill_value:
+ if fformat == 'JPEG' and not self.fill_value:
self.fill_value = [0, 0, 0, 0]
logger.debug("No fill_value provided, setting it to 0.")
=====================================
trollimage/tests/test_colormap.py
=====================================
@@ -125,6 +125,7 @@ class TestColormapClass(unittest.TestCase):
self.assertTrue(np.allclose(channels.compute(), [[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]]))
+ assert channels.dtype == int
def test_set_range(self):
"""Test set_range."""
@@ -357,3 +358,93 @@ class TestColormap:
)
new_cmap = cmap1 + cmap2
assert new_cmap.values.shape[0] == colors1.shape[0] + colors2.shape[0]
+
+ def test_merge_equal_values(self):
+ """Test that merged colormaps can have equal values at the merge point."""
+ cmap1 = colormap.Colormap(
+ colors=np.arange(5 * 3).reshape((5, 3)),
+ values=np.linspace(0, 1, 5),
+ )
+ cmap2 = colormap.Colormap(
+ colors=np.arange(5 * 3).reshape((5, 3)),
+ values=np.linspace(1, 2, 5),
+ )
+ assert cmap1.values[-1] == cmap2.values[0]
+ # this should succeed
+ _ = cmap1 + cmap2
+
+ @pytest.mark.parametrize('inplace', [False, True])
+ def test_reverse(self, inplace):
+ """Test colormap reverse."""
+ values = np.linspace(0.2, 0.5, 10)
+ colors = np.repeat(np.linspace(0.2, 0.8, 10)[:, np.newaxis], 3, 1)
+ orig_values = values.copy()
+ orig_colors = colors.copy()
+
+ cmap = colormap.Colormap(values=values, colors=colors)
+ new_cmap = cmap.reverse(inplace)
+ self._assert_inplace_worked(cmap, new_cmap, inplace)
+ self._compare_reversed_colors(cmap, new_cmap, inplace, orig_colors)
+ self._assert_unchanged_values(cmap, new_cmap, inplace, orig_values)
+
+ @pytest.mark.parametrize(
+ 'new_range',
+ [
+ (0.0, 1.0),
+ (1.0, 0.0),
+ (210.0, 300.0),
+ (300.0, 210.0),
+ ])
+ @pytest.mark.parametrize('inplace', [False, True])
+ def test_set_range(self, new_range, inplace):
+ """Test 'set_range' method."""
+ values = np.linspace(0.2, 0.5, 10)
+ colors = np.repeat(np.linspace(0.2, 0.8, 10)[:, np.newaxis], 3, 1)
+ orig_values = values.copy()
+ orig_colors = colors.copy()
+
+ cmap = colormap.Colormap(values=values, colors=colors)
+ new_cmap = cmap.set_range(*new_range, inplace)
+ self._assert_inplace_worked(cmap, new_cmap, inplace)
+ self._assert_monotonic_values(cmap)
+ self._assert_monotonic_values(new_cmap)
+ self._assert_values_changed(cmap, new_cmap, inplace, orig_values)
+ if new_range[0] > new_range[1]:
+ self._compare_reversed_colors(cmap, new_cmap, inplace, orig_colors)
+
+ @staticmethod
+ def _assert_monotonic_values(cmap):
+ np.testing.assert_allclose(np.diff(cmap.values) > 0, True)
+
+ @staticmethod
+ def _assert_unchanged_values(cmap, new_cmap, inplace, orig_values):
+ if inplace:
+ np.testing.assert_allclose(cmap.values, orig_values)
+ else:
+ np.testing.assert_allclose(cmap.values, orig_values)
+ np.testing.assert_allclose(new_cmap.values, orig_values)
+
+ @staticmethod
+ def _compare_reversed_colors(cmap, new_cmap, inplace, orig_colors):
+ if inplace:
+ assert cmap is new_cmap
+ np.testing.assert_allclose(cmap.colors, orig_colors[::-1])
+ else:
+ assert cmap is not new_cmap
+ np.testing.assert_allclose(cmap.colors, orig_colors)
+ np.testing.assert_allclose(new_cmap.colors, orig_colors[::-1])
+
+ @staticmethod
+ def _assert_values_changed(cmap, new_cmap, inplace, orig_values):
+ assert not np.allclose(new_cmap.values, orig_values)
+ if not inplace:
+ np.testing.assert_allclose(cmap.values, orig_values)
+ else:
+ assert not np.allclose(cmap.values, orig_values)
+
+ @staticmethod
+ def _assert_inplace_worked(cmap, new_cmap, inplace):
+ if not inplace:
+ assert new_cmap is not cmap
+ else:
+ assert new_cmap is cmap
=====================================
trollimage/tests/test_image.py
=====================================
@@ -2123,11 +2123,14 @@ class TestXRImageSaveScaleOffset(unittest.TestCase):
expected_tags = {'scale': 24.0 / 255, 'offset': 0}
self.img.stretch()
- self._save_and_check_tags(expected_tags)
+ with pytest.warns(DeprecationWarning):
+ self._save_and_check_tags(
+ expected_tags,
+ include_scale_offset_tags=True)
- def _save_and_check_tags(self, expected_tags):
+ def _save_and_check_tags(self, expected_tags, **kwargs):
with NamedTemporaryFile(suffix='.tif') as tmp:
- self.img.save(tmp.name, include_scale_offset_tags=True)
+ self.img.save(tmp.name, **kwargs)
import rasterio as rio
with rio.open(tmp.name) as f:
@@ -2141,7 +2144,18 @@ class TestXRImageSaveScaleOffset(unittest.TestCase):
expected_tags = {'scale': 23.0 / 255, 'offset': 1}
self.img.crude_stretch([1], [24])
- self._save_and_check_tags(expected_tags)
+ self._save_and_check_tags(
+ expected_tags,
+ scale_offset_tags=("scale", "offset"))
+
+ @pytest.mark.skipif(sys.platform.startswith('win'), reason="'NamedTemporaryFile' not supported on Windows")
+ def test_save_scale_offset_custom_labels(self):
+ """Test saving GeoTIFF with different scale/offset tag labels."""
+ expected_tags = {"gradient": 24.0 / 255, "axis_intercept": 0}
+ self.img.stretch()
+ self._save_and_check_tags(
+ expected_tags,
+ scale_offset_tags=("gradient", "axis_intercept"))
def _get_tags_after_writing_to_geotiff(data):
=====================================
trollimage/version.py
=====================================
@@ -23,9 +23,9 @@ def get_keywords():
# setup.py/versioneer.py will grep for the variable names, so they must
# each be defined on a line of their own. _version.py will just call
# get_keywords().
- git_refnames = " (HEAD -> main, tag: v1.15.1)"
- git_full = "c160f34f1c773a927c9e944f727003cbd185dee5"
- git_date = "2021-07-20 09:06:09 -0500"
+ git_refnames = " (HEAD -> main, tag: v1.16.0)"
+ git_full = "844ca2a2a005fe3016bda9dca3db294b0b71f0c1"
+ git_date = "2021-10-12 19:58:23 -0500"
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
return keywords
=====================================
trollimage/xrimage.py
=====================================
@@ -428,6 +428,7 @@ class XRImage(object):
keep_palette=False, cmap=None, overviews=None,
overviews_minsize=256, overviews_resampling=None,
include_scale_offset_tags=False,
+ scale_offset_tags=None,
**format_kwargs):
"""Save the image using rasterio.
@@ -464,9 +465,10 @@ class XRImage(object):
provided. Common values include `nearest` (default),
`bilinear`, `average`, and many others. See the rasterio
documentation for more information.
- include_scale_offset_tags (bool): Whether or not (default) to
- include a ``scale`` and an ``offset`` tag in the data that would
- help retrieving original data values from pixel values.
+ scale_offset_tags (Tuple[str, str] or None)
+ If set to a ``(str, str)`` tuple, scale and offset will be
+ stored in GDALMetaData tags. Those can then be used to
+ retrieve the original data values from pixel values.
Returns:
The delayed or computed result of the saving.
@@ -479,6 +481,12 @@ class XRImage(object):
'tiff': 'GTiff',
'jp2': 'JP2OpenJPEG'}
driver = drivers.get(fformat, fformat)
+ if include_scale_offset_tags:
+ warnings.warn(
+ "include_scale_offset_tags is deprecated, please use "
+ "scale_offset_tags to indicate tag labels",
+ DeprecationWarning)
+ scale_offset_tags = scale_offset_tags or ("scale", "offset")
if tags is None:
tags = {}
@@ -537,9 +545,10 @@ class XRImage(object):
elif driver == 'JPEG' and 'A' in mode:
raise ValueError('JPEG does not support alpha')
- if include_scale_offset_tags:
+ if scale_offset_tags:
+ scale_label, offset_label = scale_offset_tags
scale, offset = self.get_scaling_from_history(data.attrs.get('enhancement_history', []))
- tags['scale'], tags['offset'] = invert_scale_offset(scale, offset)
+ tags[scale_label], tags[offset_label] = invert_scale_offset(scale, offset)
# FIXME add metadata
r_file = RIOFile(filename, 'w', driver=driver,
View it on GitLab: https://salsa.debian.org/debian-gis-team/trollimage/-/compare/0f0609e2d4e089e34c04c632a4ef8e836ce1d3c5...602642cec50aeb05f5acb315598b4990ec08fb84
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/trollimage/-/compare/0f0609e2d4e089e34c04c632a4ef8e836ce1d3c5...602642cec50aeb05f5acb315598b4990ec08fb84
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/20211016/5731f75f/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list