Skip to content

Commit

Permalink
Edit pr 707 (#708)
Browse files Browse the repository at this point in the history
* Unscale applies each bands scale/offset

* used the wrong shape when setting up the unscaling reshape

* edit PR and change info model

---------

Co-authored-by: Justin Deal <jdeal@aerisweather.com>
  • Loading branch information
vincentsarago and Justin Deal committed May 16, 2024
1 parent ed14eb5 commit 2724e27
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 17 deletions.
17 changes: 17 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@

# Unreleased


* fix type hint for `ImageData.band_names` (author @n8sty, https://github.com/cogeotiff/rio-tiler/pull/704)
* enable `per-band` scale/offset rescaling (co-author @jddeal, https://github.com/cogeotiff/rio-tiler/pull/707)
* replace `scale` and `offset` by `scales` and `offsets` in `rio_tiler.models.Info` model

```python
# before
with Reader("tests/fixtures/cog_scale.tif") as src:
info = src.info()
print(info.scale, info.offset)
>> 0.0001 1000.0

# now
with Reader("tests/fixtures/cog_scale.tif") as src:
info = src.info()
print(info.scales, info.offsets)
>> [0.0001, 0.001] [1000.0, 2000.0]
```

# 6.5.0 (2024-05-03)

Expand Down
6 changes: 2 additions & 4 deletions rio_tiler/io/rasterio.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,9 @@ def _get_descr(ix):
"width": self.dataset.width,
"height": self.dataset.height,
"overviews": self.dataset.overviews(1),
"scales": self.dataset.scales,
"offsets": self.dataset.offsets,
}
if self.dataset.scales[0] != 1.0 or self.dataset.offsets[0] != 0.0:
meta.update(
{"scale": self.dataset.scales[0], "offset": self.dataset.offsets[0]}
)

if self.colormap:
meta.update({"colormap": self.colormap})
Expand Down
4 changes: 2 additions & 2 deletions rio_tiler/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ class Info(SpatialInfo):
dtype: str
nodata_type: Literal["Alpha", "Mask", "Internal", "Nodata", "None"]
colorinterp: Optional[List[str]] = None
scale: Optional[float] = None
offset: Optional[float] = None
scales: Optional[List[float]] = None
offsets: Optional[List[float]] = None
colormap: Optional[GDALColorMapType] = None

model_config = {"extra": "allow"}
Expand Down
9 changes: 7 additions & 2 deletions rio_tiler/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,13 @@ def read(

if unscale:
data = data.astype("float32", casting="unsafe")
numpy.multiply(data, dataset.scales[0], out=data, casting="unsafe")
numpy.add(data, dataset.offsets[0], out=data, casting="unsafe")

# reshaped to match data
scales = numpy.array(dataset.scales).reshape(-1, 1, 1)
offsets = numpy.array(dataset.offsets).reshape(-1, 1, 1)

numpy.multiply(data, scales, out=data, casting="unsafe")
numpy.add(data, offsets, out=data, casting="unsafe")

if post_process:
data = post_process(data)
Expand Down
Binary file modified tests/fixtures/cog_scale.tif
Binary file not shown.
13 changes: 6 additions & 7 deletions tests/test_io_rasterio.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ def test_info_valid():
"""Should work as expected (get file info)"""
with Reader(COG_SCALE) as src:
meta = src.info()
assert meta["scale"]
assert meta.scale
assert meta.offset
assert meta.scales
assert meta.offsets
assert not meta.colormap
assert meta.width
assert meta.height
Expand Down Expand Up @@ -113,8 +112,8 @@ def test_info_valid():
assert meta.dtype == "int16"
assert meta.colorinterp == ["gray"]
assert meta.nodata_type == "Nodata"
assert meta.scale
assert meta.offset
assert meta.scales
assert meta.offsets
assert meta.band_metadata
band_meta = meta.band_metadata[0]
assert band_meta[0] == "b1"
Expand Down Expand Up @@ -439,11 +438,11 @@ def test_Reader_Options():

with Reader(COG_SCALE, options={"unscale": True}) as src:
p = src.point(310000, 4100000, coord_crs=src.dataset.crs)
assert round(float(p.data[0]), 3) == 1000.892
numpy.testing.assert_allclose(p.data, [1000.892, 2008.917], atol=1e-03)

# passing unscale in method should overwrite the defaults
p = src.point(310000, 4100000, coord_crs=src.dataset.crs, unscale=False)
assert p.data[0] == 8917
numpy.testing.assert_equal(p.data, [8917, 8917])

cutline = "POLYGON ((13 1685, 1010 6, 2650 967, 1630 2655, 13 1685))"
with Reader(COGEO, options={"vrt_options": {"cutline": cutline}}) as src:
Expand Down
6 changes: 4 additions & 2 deletions tests/test_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ def test_point():
assert pt.band_names == ["b1"]

pt = reader.point(src_dst, [310000, 4100000], coord_crs=src_dst.crs)
assert pt.data == numpy.array([8917])
assert pt.band_names == ["b1"]
numpy.testing.assert_equal(pt.data, [8917, 8917])
assert pt.band_names == ["b1", "b2"]

with pytest.raises(PointOutsideBounds):
reader.point(src_dst, [810000, 4100000], coord_crs=src_dst.crs)
Expand Down Expand Up @@ -577,6 +577,8 @@ def test_read():
# Unscale Dataset
with rasterio.open(COG_SCALE) as src:
assert not src.dtypes[0] == numpy.float32
assert src.scales == (0.0001, 0.001)
assert src.offsets == (1000, 2000)
img = reader.read(src, unscale=True)
assert img.data.dtype == numpy.float32

Expand Down

0 comments on commit 2724e27

Please sign in to comment.