All Downloads are FREE. Search and download functionalities are using the official Maven repository.

geotrellis.raster.op.focal.Sum.scala Maven / Gradle / Ivy

The newest version!
package geotrellis.raster.op.focal

import geotrellis._
import geotrellis.raster.TileNeighbors

/** Computes the sum of values of a neighborhood for a given raster 
 *
 * @param    r      Raster on which to run the focal operation.
 * @param    n      Neighborhood to use for this operation (e.g., [[Square]](1))
 *
 * @note            If the neighborhood is a [[Square]] neighborhood, the sum calucation will use
 *                  the [[CellwiseSumCalc]] to perform the calculation, because it is faster.
 *                  If the neighborhood is of any other type, then [[CursorSumCalc]] is used.
 *
 * @note            Sum does not currently support Double raster data.
 *                  If you use a Raster with a Double RasterType (TypeFloat,TypeDouble)
 *                  the data values will be rounded to integers.
 */
case class Sum(r:Op[Raster], n:Op[Neighborhood],ns:Op[TileNeighbors]) extends FocalOp[Raster](r,n,ns)({ 
  (r,n) =>
    if(r.isFloat){
      n match {
        case Square(ext) => new CellwiseDoubleSumCalc
        case _ => new CursorDoubleSumCalc
      }
    }else{
      n match {
        case Square(ext) => new CellwiseSumCalc
        case _ => new CursorSumCalc
      }
    }
})

object Sum {
  def apply(r:Op[Raster], n:Op[Neighborhood]) = new Sum(r,n,TileNeighbors.NONE)
}

class CursorSumCalc extends CursorCalculation[Raster] 
    with IntRasterDataResult {
  var total = 0

  def calc(r:Raster,cursor:Cursor) = {

    val added = collection.mutable.Set[(Int,Int,Int)]()
    cursor.addedCells.foreach { (x,y) => 
      val v = r.get(x,y)
      added += ((x,y,v))
      if(isData(v)) { total += r.get(x,y) }
    }

    val removed = collection.mutable.Set[(Int,Int,Int)]()
    cursor.removedCells.foreach { (x,y) => 
      val v = r.get(x,y)
      removed += ((x,y,v))
      if(isData(v)) { total -= r.get(x,y) }
    }

    data.set(cursor.col,cursor.row,total)
  }
}

class CellwiseSumCalc extends CellwiseCalculation[Raster]
    with IntRasterDataResult {
  var total = 0
  
  def add(r:Raster,x:Int,y:Int) = { 
    val v = r.get(x,y)
    if(isData(v)) { total += r.get(x,y) }
  }

  def remove(r:Raster,x:Int,y:Int) = { 
    val v = r.get(x,y)
    if(isData(v)) { total -= r.get(x,y) }
  }

  def reset() = { total = 0}
  def setValue(x:Int,y:Int) = { 
    data.set(x,y,total) 
  }
}

class CursorDoubleSumCalc extends CursorCalculation[Raster] 
    with DoubleRasterDataResult {
  var total = 0.0

  def calc(r:Raster,cursor:Cursor) = {

    val added = collection.mutable.Set[(Int,Int,Double)]()
    cursor.addedCells.foreach { (x,y) => 
      val v = r.getDouble(x,y)
      added += ((x,y,v))
      if(isData(v)) { total += r.getDouble(x,y) }
    }

    val removed = collection.mutable.Set[(Int,Int,Double)]()
    cursor.removedCells.foreach { (x,y) => 
      val v = r.getDouble(x,y)
      removed += ((x,y,v))
      if(isData(v)) { total -= r.getDouble(x,y) }
    }

    data.setDouble(cursor.col,cursor.row,total)
  }
}

class CellwiseDoubleSumCalc extends CellwiseCalculation[Raster]
    with DoubleRasterDataResult {
  var total = 0.0
  
  def add(r:Raster,x:Int,y:Int) = { 
    val v = r.getDouble(x,y)
    if(isData(v)) { total += r.getDouble(x,y) }
  }

  def remove(r:Raster,x:Int,y:Int) = { 
    val v = r.getDouble(x,y)
    if(isData(v)) { total -= r.getDouble(x,y) }
  }

  def reset() = { total = 0.0 }
  def setValue(x:Int,y:Int) = { 
    data.setDouble(x,y,total) 
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy