From f3709d0ab524e18cd362af91aab050a21cc5d19b Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Wed, 12 Sep 2018 14:27:35 +0300 Subject: [PATCH] Fix AutoHigherResolution ovr strategy and cover it with tests --- .../raster/io/geotiff/GeoTiff.scala | 4 +- .../reader/MultibandGeoTiffReaderSpec.scala | 47 +++++++++++++++++++ .../reader/SinglebandGeoTiffReaderSpec.scala | 47 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/raster/src/main/scala/geotrellis/raster/io/geotiff/GeoTiff.scala b/raster/src/main/scala/geotrellis/raster/io/geotiff/GeoTiff.scala index 3290b72875..1c75e83d1f 100644 --- a/raster/src/main/scala/geotrellis/raster/io/geotiff/GeoTiff.scala +++ b/raster/src/main/scala/geotrellis/raster/io/geotiff/GeoTiff.scala @@ -109,7 +109,7 @@ trait GeoTiff[T <: CellGrid] extends GeoTiffData { strategy match { case AutoHigherResolution => (this :: list) // overviews can have erased extent information - .map { v => (v.cellSize.resolution - cellSize.resolution) -> v } + .map { v => (cellSize.resolution - v.cellSize.resolution) -> v } .filter(_._1 >= 0) .sortBy(_._1) .map(_._2) @@ -117,7 +117,7 @@ trait GeoTiff[T <: CellGrid] extends GeoTiffData { .getOrElse(this) case Auto(n) => list - .sortBy(v => math.abs(v.cellSize.resolution - cellSize.resolution)) + .sortBy(v => math.abs(cellSize.resolution - v.cellSize.resolution)) .lift(n) .getOrElse(this) // n can be out of bounds, // makes only overview lookup as overview position is important diff --git a/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/MultibandGeoTiffReaderSpec.scala b/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/MultibandGeoTiffReaderSpec.scala index cb81f0e8ce..6a72911d7f 100644 --- a/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/MultibandGeoTiffReaderSpec.scala +++ b/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/MultibandGeoTiffReaderSpec.scala @@ -108,6 +108,53 @@ class MultibandGeoTiffReaderSpec extends FunSpec } } + it("should pick up the tiff overview correct (AutoHigherResolution test)") { + def cellSizesSequence(cellSize: CellSize): List[CellSize] = { + val CellSize(w, h) = cellSize + + val seq = for { + wp <- (w / 2 + w / 4) until (w - w / 100) by 100 + hp <- (h / 2 + h / 4) until (h - h / 100) by 100 + } yield CellSize(wp, hp) + + seq.toList + } + + val tiff = MultibandGeoTiff(geoTiffPath("overviews/multiband.tif")) + + val overviews = tiff :: tiff.overviews + + // cell sizes of overviews, starting with the base ifd + val cellSizes = ({ + // an extra check for the base level overview + val CellSize(w, h) = overviews.head.cellSize + CellSize(w / 2, h / 2) -> -1 + } :: overviews.map(_.cellSize).zipWithIndex) :+ { + // an extra check for the last overview + val CellSize(w, h) = overviews.last.cellSize + CellSize(w * 2, h * 2) -> overviews.length + } + + // check all overviews + cellSizes.foreach { case (cz, i) => + cellSizesSequence(cz).foreach { scz => + if(i == -1) { + val closestOvr = tiff.getClosestOverview(scz, AutoHigherResolution) + val ovr = overviews(0) + closestOvr.raster.cellSize should be(ovr.raster.cellSize) + } else if(i == 0) { + val closestOvr = tiff.getClosestOverview(scz, AutoHigherResolution) + val ovr = overviews(i) + closestOvr.raster.cellSize should be(ovr.raster.cellSize) + } else { + val closestOvr = tiff.getClosestOverview(scz, AutoHigherResolution) + val ovr = overviews(i - 1) + closestOvr.raster.cellSize should be(ovr.raster.cellSize) + } + } + } + } + it("should read tiff with external overviews correct") { // sizes of overviews, starting with the base ifd val sizes = List(1056 -> 1052, 528 -> 526, 264 -> 263, 132 -> 132, 66 -> 66, 33 -> 33) diff --git a/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/SinglebandGeoTiffReaderSpec.scala b/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/SinglebandGeoTiffReaderSpec.scala index 81ed70e8f6..9b72375372 100644 --- a/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/SinglebandGeoTiffReaderSpec.scala +++ b/raster/src/test/scala/geotrellis/raster/io/geotiff/reader/SinglebandGeoTiffReaderSpec.scala @@ -137,6 +137,53 @@ class SinglebandGeoTiffReaderSpec extends FunSpec } } + it("should pick up the tiff overview correct (AutoHigherResolution test)") { + def cellSizesSequence(cellSize: CellSize): List[CellSize] = { + val CellSize(w, h) = cellSize + + val seq = for { + wp <- (w / 2 + w / 4) until (w - w / 100) by 100 + hp <- (h / 2 + h / 4) until (h - h / 100) by 100 + } yield CellSize(wp, hp) + + seq.toList + } + + val tiff = SinglebandGeoTiff(geoTiffPath("overviews/singleband.tif")) + + val overviews = tiff :: tiff.overviews + + // cell sizes of overviews, starting with the base ifd + val cellSizes = ({ + // an extra check for the base level overview + val CellSize(w, h) = overviews.head.cellSize + CellSize(w / 2, h / 2) -> -1 + } :: overviews.map(_.cellSize).zipWithIndex) :+ { + // an extra check for the last overview + val CellSize(w, h) = overviews.last.cellSize + CellSize(w * 2, h * 2) -> overviews.length + } + + // check all overviews + cellSizes.foreach { case (cz, i) => + cellSizesSequence(cz).foreach { scz => + if(i == -1) { + val closestOvr = tiff.getClosestOverview(scz, AutoHigherResolution) + val ovr = overviews(0) + closestOvr.raster.cellSize should be(ovr.raster.cellSize) + } else if(i == 0) { + val closestOvr = tiff.getClosestOverview(scz, AutoHigherResolution) + val ovr = overviews(i) + closestOvr.raster.cellSize should be(ovr.raster.cellSize) + } else { + val closestOvr = tiff.getClosestOverview(scz, AutoHigherResolution) + val ovr = overviews(i - 1) + closestOvr.raster.cellSize should be(ovr.raster.cellSize) + } + } + } + } + it("should read tiff with external overviews correct") { // sizes of overviews, starting with the base ifd val sizes = List(1056 -> 1052, 528 -> 526, 264 -> 263, 132 -> 132, 66 -> 66, 33 -> 33)