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

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

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

import geotrellis._
import geotrellis.raster.TileNeighbors

import scala.math._

/** Computes the mean value of a neighborhood for a given raster. Returns a raster of TypeDouble
 *
 * @param    r      Raster on which to run the focal operation.
 * @param    n      Neighborhood to use for this operation (e.g., [[Square]](1))
 * @param    tns    TileNeighbors that describe the neighboring tiles.

 * @return          Returns a double value raster that is the computed mean for each neighborhood.
 *
 * @note            If the neighborhood is a [[Square]] neighborhood, the mean calucation will use
 *                  the [[CellwiseMeanCalc]] to perform the calculation, because it is faster.
 *                  If the neighborhood is of any other type, then [[CursorMeanCalc]] is used.
 */
case class Mean(r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors]) 
    extends FocalOp[Raster](r,n,tns)({
  (r,n) =>
      if(r.isFloat) {
        n match {
          case Square(ext) => new CellwiseMeanCalcDouble
          case _ => new CursorMeanCalcDouble
        }
      } else {
        n match {
          case Square(ext) => new CellwiseMeanCalc
          case _ => new CursorMeanCalc
        }
      }
})

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

case class CursorMeanCalc() extends CursorCalculation[Raster] with DoubleRasterDataResult {
  var count:Int = 0
  var sum:Int = 0

  def calc(r:Raster,c:Cursor) = {
    c.removedCells.foreach { (x,y) => 
      val v = r.get(x,y)
      if(isData(v)) { count -= 1; sum -= v } 
    }
    c.addedCells.foreach { (x,y) => 
      val v = r.get(x,y)
      if(isData(v)) { count += 1; sum += v } 
    }
    data.setDouble(c.col,c.row,sum / count.toDouble)
  }
}

case class CellwiseMeanCalc() extends CellwiseCalculation[Raster] with DoubleRasterDataResult {
  var count:Int = 0
  var sum:Int = 0

 def add(r:Raster, x:Int, y:Int) = {
    val z = r.get(x,y)
    if (isData(z)) {
      count += 1
      sum   += z
    }
  }

  def remove(r:Raster, x:Int, y:Int) = {
    val z = r.get(x,y)
    if (isData(z)) {
      count -= 1
      sum -= z
    }
  } 

  def setValue(x:Int,y:Int) = { data.setDouble(x,y, sum / count.toDouble) }
  def reset() = { count = 0 ; sum = 0 }
}

case class CursorMeanCalcDouble() extends CursorCalculation[Raster] with DoubleRasterDataResult {
  var count:Int = 0
  var sum:Double = 0.0

  def calc(r:Raster,c:Cursor) = {
    c.removedCells.foreach { (x,y) => 
      val v = r.getDouble(x,y)
      if(isData(v)) { count -= 1; sum -= v } 
    }
    c.addedCells.foreach { (x,y) => 
      val v = r.getDouble(x,y)
      if(isData(v)) { count += 1; sum += v } 
    }
    data.setDouble(c.col,c.row,sum / count)
  }
}

case class CellwiseMeanCalcDouble() extends CellwiseCalculation[Raster] with DoubleRasterDataResult {
  var count:Int = 0
  var sum:Double = 0.0

 def add(r:Raster, x:Int, y:Int) = {
    val z = r.getDouble(x,y)
    if (isData(z)) {
      count += 1
      sum   += z
    }
  }

  def remove(r:Raster, x:Int, y:Int) = {
    val z = r.getDouble(x,y)
    if (isData(z)) {
      count -= 1
      sum -= z
    }
  } 

  def setValue(x:Int,y:Int) = { data.setDouble(x,y, sum / count) }
  def reset() = { count = 0 ; sum = 0.0 }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy