Skip to content

Commit

Permalink
Added Sum resampling method
Browse files Browse the repository at this point in the history
Signed-off-by: Christos <xr_xarmatzis@outlook.com>
  • Loading branch information
Charmatzis committed Aug 10, 2017
1 parent 44b5535 commit b27e07d
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2016 Azavea
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package geotrellis.raster.resample

import geotrellis.raster._
import geotrellis.vector.Extent

import org.scalatest._

class SumResampleSpec extends FunSpec with Matchers {

describe("it should resample to nodata when only nodata in tile") {

it("should for a nodata integer tile compute nodata as sum value") {
val tile = IntArrayTile(Array(NODATA, NODATA, NODATA,
NODATA, NODATA, NODATA,
NODATA, NODATA, NODATA), 3, 3)
val extent = Extent(0, 0, 10, 10)
val cellsize = CellSize(extent, 10, 10)
tile.resample(extent, 1, 1, Sum).get(0, 0) should be (NODATA)
}

it("should for a nodata double tile compute nodata as sum value") {
val tile = DoubleArrayTile(Array(NODATA, NODATA, NODATA,
NODATA, NODATA, NODATA,
NODATA, NODATA, NODATA), 3, 3)
val extent = Extent(0, 0, 10, 10)
val cellsize = CellSize(extent, 10, 10)
tile.resample(extent, 1, 1, Sum).get(0, 0) should be (NODATA)
}

it("should for an integer tile compute the correct sum value") {
val tile = ArrayTile(Array(1, 1, 1, 1, 1, 1, 1, 1, 1), 3, 3)
val extent = Extent(0, 0, 3, 3)
val cellsize = CellSize(extent, 3, 3)
tile.resample(extent, 1, 1, Sum).get(0, 0) should be (9)
}

it("should for a int tile compute the correct sum value - ignoring the nodata value") {
val tile = ArrayTile(Array(NODATA, 1, 1, 1, 1, 1, 1, 1, 1), 3, 3)
val extent = Extent(0, 0, 3, 3)
val cellsize = CellSize(extent, 3, 3)
tile.resample(extent, 1, 1, Sum).get(0, 0) should be (8)
}


it("should for a double tile compute the correct sum value") {
val tile = DoubleArrayTile(Array(.1, .1, .1, .1, .1, .1, .1, .1, .1), 3, 3)
val extent = Extent(0, 0, 3, 3)
val cellsize = CellSize(extent, 3, 3)
tile.resample(extent, 1, 1, Sum).getDouble(0, 0) should be (0.9 +- 0.01)
}

// This test is necessitated because of Double.NaN's always being max and min according to scala
it("should for a double tile compute the correct sum value - ignoring the nodata value") {
val tile = DoubleArrayTile(Array(Double.NaN, .1, .1, .1, .1, .1, .1, .1, .1), 3, 3)
val extent = Extent(0, 0, 3, 3)
val cellsize = CellSize(extent, 3, 3)
tile.resample(extent, 1, 1, Sum).getDouble(0, 0) should be (0.8 +- 0.01)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package geotrellis.raster.resample

import geotrellis.raster._
import geotrellis.vector.{Point, Extent}
import geotrellis.vector.{Extent, Point}

sealed trait ResampleMethod

Expand All @@ -34,6 +34,7 @@ case object Mode extends AggregateResampleMethod
case object Median extends AggregateResampleMethod
case object Max extends AggregateResampleMethod
case object Min extends AggregateResampleMethod
case object Sum extends AggregateResampleMethod

object ResampleMethod {
val DEFAULT: PointResampleMethod = NearestNeighbor
Expand Down Expand Up @@ -110,5 +111,6 @@ object Resample {
case Median => new MedianResample(tile, extent, cs)
case Max => new MaxResample(tile, extent, cs)
case Min => new MinResample(tile, extent, cs)
case Sum => new SumResample(tile, extent, cs)
}
}
51 changes: 51 additions & 0 deletions raster/src/main/scala/geotrellis/raster/resample/SumResample.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2016 Azavea
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package geotrellis.raster.resample

import geotrellis.raster._
import geotrellis.vector.Extent

class SumResample (tile: Tile, extent: Extent, targetCS: CellSize)
extends AggregateResample(tile, extent, targetCS) {

private def calculateMax(indices: Seq[(Int, Int)]): Int = {
val (sum, count) =
indices.foldLeft((0, 0)) { case ((sum, count), coords) =>
val v = tile.get(coords._1, coords._2)
if (isData(v)) (sum + v, count + 1)
else (sum, count)
}
if (count > 0) sum else Int.MinValue
}


private def calculateMaxDouble(indices: Seq[(Int, Int)]): Double = {
val (sum, count) =
indices.foldLeft((0.0, 0)) { case ((sum, count), coords) =>
val v = tile.getDouble(coords._1, coords._2)
if (isData(v)) (sum + v, count + 1)
else (sum, count)
}
if (count > 0) sum else Double.NaN
}


def resampleValid(x: Double, y: Double): Int = calculateMax(contributions(x, y))

def resampleDoubleValid(x: Double, y: Double): Double = calculateMaxDouble(contributions(x,y))

}

0 comments on commit b27e07d

Please sign in to comment.