Skip to content

Commit ec9f334

Browse files
authored
IntTiles MinResample fix (#3590)
1 parent 95c483e commit ec9f334

File tree

6 files changed

+38
-6
lines changed

6 files changed

+38
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Do not depend on private Spark API, avoids sealing violation [#3586](https://github.com/locationtech/geotrellis/pull/3586)
1212
- Add predictor 2 (integer) and predictor 3 (float) support for writing compressed GTiff files [#3588](https://github.com/locationtech/geotrellis/pull/3588)
1313

14+
### Changed
15+
- MinResample should ignore Int NODATA values [#3590](https://github.com/locationtech/geotrellis/pull/3590)
16+
1417
## [3.8.0] - 2025-04-23
1518

1619
### Added

raster/src/main/scala/geotrellis/raster/IntArrayTile.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ object IntArrayTile {
213213
def apply(arr: Array[Int], cols: Int, rows: Int, cellType: IntCells with NoDataHandling): IntArrayTile =
214214
cellType match {
215215
case IntCellType =>
216-
new IntRawArrayTile(arr, cols, rows)
216+
IntRawArrayTile(arr, cols, rows)
217217
case IntConstantNoDataCellType =>
218-
new IntConstantNoDataArrayTile(arr, cols, rows)
218+
IntConstantNoDataArrayTile(arr, cols, rows)
219219
case udct: IntUserDefinedNoDataCellType =>
220-
new IntUserDefinedNoDataArrayTile(arr, cols, rows, udct)
220+
IntUserDefinedNoDataArrayTile(arr, cols, rows, udct)
221221
}
222222

223223
/**

raster/src/main/scala/geotrellis/raster/resample/MaxResample.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class MaxResample(tile: Tile, extent: Extent, targetCS: CellSize)
2929
extends AggregateResample(tile, extent, targetCS) {
3030

3131
private def calculateMax(indices: Seq[(Int, Int)]): Int =
32+
// NODATA would always be min
3233
indices.foldLeft(Int.MinValue) { case (currentMax, coords) =>
3334
math.max(currentMax, tile.get(coords._1, coords._2))
3435
}

raster/src/main/scala/geotrellis/raster/resample/MinResample.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ import scala.math
2828
class MinResample(tile: Tile, extent: Extent, targetCS: CellSize)
2929
extends AggregateResample(tile, extent, targetCS) {
3030

31-
private def calculateMin(indices: Seq[(Int, Int)]): Int =
32-
indices.foldLeft(Int.MaxValue) { case (currentMin, coords) =>
33-
math.min(currentMin, tile.get(coords._1, coords._2))
31+
private def calculateMin(indices: Seq[(Int, Int)]): Int = {
32+
val intMin = indices.foldLeft(Int.MaxValue) { case (currentMin, coords) =>
33+
val v = tile.get(coords._1, coords._2)
34+
// NODATA would *always* be min
35+
if (isData(v)) math.min(currentMin, v) else currentMin
3436
}
37+
if (intMin == Int.MaxValue) NODATA else intMin
38+
}
3539

3640
private def calculateMinDouble(indices: Seq[(Int, Int)]): Double = {
3741
val doubleMin = indices.foldLeft(Double.MaxValue) { case (currentMin, coords) =>

raster/src/test/scala/geotrellis/raster/resample/MaxResampleSpec.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,11 @@ class MaxResampleSpec extends AnyFunSpec with Matchers {
6666
val cellsize = CellSize(extent, 3, 3)
6767
tile.resample(extent, 1, 1, Max).getDouble(0, 0) should be (100.1)
6868
}
69+
70+
it("should for an int tile compute the correct maximum value - ignoring the user defined nodata value") {
71+
val tile = IntArrayTile(Array(2, 4, 256, 16), 2, 2, noDataValue = 256)
72+
val extent = Extent(0, 0, 2, 2)
73+
tile.resample(extent, 1, 1, method = Max).get(0, 0) should be (16)
74+
}
6975
}
7076
}

raster/src/test/scala/geotrellis/raster/resample/MinResampleSpec.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,23 @@ class MinResampleSpec extends AnyFunSpec with Matchers {
6666
val cellsize = CellSize(extent, 3, 3)
6767
tile.resample(extent, 1, 1, Min).getDouble(0, 0) should be (0.19)
6868
}
69+
70+
it("should for an int tile compute the correct minimum value - ignoring the user defined nodata value") {
71+
val tile = IntArrayTile(Array(2, 4, 256, 16), 2, 2, noDataValue = 256)
72+
val extent = Extent(0, 0, 2, 2)
73+
tile.resample(extent, 1, 1, method = Min).get(0, 0) should be (2)
74+
}
75+
76+
it("should for an int tile compute the correct minimum value - ignoring the int nodata value") {
77+
val tile = IntArrayTile(Array(2, 4, NODATA, 16), 2, 2)
78+
val extent = Extent(0, 0, 2, 2)
79+
tile.resample(extent, 1, 1, method = Min).get(0, 0) should be (2)
80+
}
81+
82+
it("should for a double tile compute the correct minimum value - ignoring the double nodata value") {
83+
val tile = DoubleArrayTile(Array(2d, 4d, doubleNODATA, 16d), 2, 2)
84+
val extent = Extent(0, 0, 2, 2)
85+
tile.resample(extent, 1, 1, method = Min).get(0, 0) should be (2)
86+
}
6987
}
7088
}

0 commit comments

Comments
 (0)