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

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

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

import geotrellis._
import geotrellis.raster._
import scala.math._

/**
 * Focal Operation that takes a raster and a neighborhood.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        getCalc     Function that returns a [[FocalCalculation]] based
 *                           on the raster and neighborhood. This allows flexibility
 *                           in what calculation to use; if some calculations are faster
 *                           for some neighborhoods (e.g., using a [[CellwiseCalculation]]
 *                           for [[Square]] neighborhoods and a [[CursorCalculation]] for
 *                           all other neighborhoods), or if you want to change the calculation
 *                           based on the raster's data type, you can do so by returning the
 *                           correct [[FocalCalculation]] from this function.
 *
 * @tparam       T           Return type of the Operation.
 */
class FocalOp[T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors])
                (getCalc:(Raster,Neighborhood)=>FocalCalculation[T] with Initialization)                  
extends FocalOperation0[T](r,n,tns) {
  def getCalculation(r:Raster,n:Neighborhood) = { getCalc(r,n) }
}

/**
 * Focal Operation that takes a raster, a neighborhood, and one other argument.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        getCalc     See notes for same parameter in [[FocalOp]]
 *
 * @tparam       T           Return type of the Operation.
 */
class FocalOp1[A,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],a:Op[A])
                   (getCalc:(Raster,Neighborhood)=>FocalCalculation[T] with Initialization1[A])
extends FocalOperation1[A,T](r,n,tns,a){
  def getCalculation(r:Raster,n:Neighborhood) = { getCalc(r,n) }
}

/**
 * Focal Operation that takes a raster, a neighborhood, and two other arguments.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        b           Argument of type B.
 * @param        getCalc     See notes for same parameter in [[FocalOp]]
 *
 * @tparam       T           Return type of the Operation.
 */
class FocalOp2[A,B,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],
                      a:Op[A],b:Op[B])
                     (getCalc:(Raster,Neighborhood)=>FocalCalculation[T] with Initialization2[A,B])
extends FocalOperation2[A,B,T](r,n,tns,a,b){
  def getCalculation(r:Raster,n:Neighborhood) = { getCalc(r,n) }
}

/**
 * Focal Operation that takes a raster, a neighborhood, and three other arguments.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        b           Argument of type B.
 * @param        c           Argument of type C.
 * @param        getCalc     See notes for same parameter in [[FocalOp]]
 *
 * @tparam       T           Return type of the Operation.
 */
class FocalOp3[A,B,C,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],
                        a:Op[A],b:Op[B],c:Op[C])
                       (getCalc:(Raster,Neighborhood)=>FocalCalculation[T] with Initialization3[A,B,C])
extends FocalOperation3[A,B,C,T](r,n,tns,a,b,c){
  def getCalculation(r:Raster,n:Neighborhood) = { getCalc(r,n) }
}

/**
 * Focal Operation that takes a raster, a neighborhood, and four other arguments.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        b           Argument of type B.
 * @param        c           Argument of type C.
 * @param        d           Argument of type D.
 * @param        getCalc     See notes for same parameter in [[FocalOp]]
 *
 * @tparam       T           Return type of the Operation.
 */
class FocalOp4[A,B,C,D,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],a:Op[A],b:Op[B],c:Op[C],d:Op[D])
                         (getCalc:(Raster,Neighborhood)=>FocalCalculation[T] with Initialization4[A,B,C,D])
extends FocalOperation4[A,B,C,D,T](r,n,tns,a,b,c,d){
  def getCalculation(r:Raster,n:Neighborhood) = { getCalc(r,n) }
}

trait FocalOperation[T] extends Operation[T]

/**
 * Base class for a focal operation that takes a raster and a neighborhood.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 *
 * @tparam       T           Return type of the Operation.
 */
abstract class FocalOperation0[T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors]) 
         extends FocalOperation[T] {
  def _run() = runAsync(List('init,r,n,tns.flatMap(_.getNeighbors)))
  def productArity = 3
  def canEqual(other:Any) = other.isInstanceOf[FocalOperation0[_]]
  def productElement(index:Int) = index match {
    case 0 => r
    case 1 => n
    case 2 => tns
    case _ => new IndexOutOfBoundsException()
  }


  val nextSteps:PartialFunction[Any,StepOutput[T]] = {
    case 'init :: (r:Raster) :: (n:Neighborhood) :: (neighbors:Seq[_]) :: Nil =>  {
      val calc = getCalculation(r,n)
      calc.init(r)
      calc.execute(r,n,neighbors.asInstanceOf[Seq[Option[Raster]]])
      Result(calc.result)
    }
  }

  /** Gets a calculation to be used with this focal operation for the given raster
   * neighborhood.
   *
   * Choosing the calculation based on on the raster and neighborhood allows flexibility
   * in what calculation to use; if some calculations are faster
   * for some neighborhoods (e.g., using a [[CellwiseCalculation]]
   * for [[Square]] neighborhoods and a [[CursorCalculation]] for
   * all other neighborhoods), or if you want to change the calculation
   * based on the raster's data type, you can do so by returning the
   * correct [[FocalCalculation]] from this function.
   *
   * @param     r       Raster that the focal calculation will run against.
   * @param     n       Neighborhood that will be used in the focal operation.
   */
  def getCalculation(r:Raster,n:Neighborhood):FocalCalculation[T] with Initialization 
}

/**
 * Base class for a focal operation that takes a raster, a neighborhood, and one other argument.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 *
 * @tparam       T           Return type of the Operation.
 */
abstract class FocalOperation1[A,T](r:Op[Raster],n:Op[Neighborhood], tns:Op[TileNeighbors], a:Op[A]) 
    extends FocalOperation[T] {
  var rasterOp = r
  def _run() = runAsync(List('init,rasterOp,n,tns.flatMap(_.getNeighbors),a))
  def productArity = 4
  def canEqual(other:Any) = other.isInstanceOf[FocalOperation1[_,_]]
  def productElement(index:Int) = index match {
    case 0 => r
    case 1 => n
    case 2 => tns
    case 3 => a
    case _ => new IndexOutOfBoundsException()
  }
  val nextSteps:PartialFunction[Any,StepOutput[T]] = {
    case 'init :: (r:Raster) :: (n:Neighborhood) :: (neighbors:Seq[_]) :: a :: Nil => 
      val calc = getCalculation(r,n)
      calc.init(r,a.asInstanceOf[A])
      calc.execute(r,n,neighbors.asInstanceOf[Seq[Option[Raster]]])
      Result(calc.result)
  }

  /** Gets a calculation to be used with this focal operation for the given raster
   * neighborhood.
   *
   * Choosing the calculation based on on the raster and neighborhood allows flexibility
   * in what calculation to use; if some calculations are faster
   * for some neighborhoods (e.g., using a [[CellwiseCalculation]]
   * for [[Square]] neighborhoods and a [[CursorCalculation]] for
   * all other neighborhoods), or if you want to change the calculation
   * based on the raster's data type, you can do so by returning the
   * correct [[FocalCalculation]] from this function.
   *
   * @param     r       Raster that the focal calculation will run against.
   * @param     n       Neighborhood that will be used in the focal operation.
   */  
  def getCalculation(r:Raster,n:Neighborhood):FocalCalculation[T] with Initialization1[A]
}

/**
 * Base class for a focal operation that takes a raster, a neighborhood, and two other argument.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        b           Argument of type B.
 *
 * @tparam       T           Return type of the Operation.
 */
abstract class FocalOperation2[A,B,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],
                                      a:Op[A],b:Op[B])
         extends FocalOperation[T] {
  var rasterOp = r
  def _run() = runAsync(List('init,rasterOp,n,tns.flatMap(_.getNeighbors),a,b))
  def productArity = 5
  def canEqual(other:Any) = other.isInstanceOf[FocalOperation2[_,_,_]]
  def productElement(index:Int) = index match {
    case 0 => r
    case 1 => n
    case 2 => tns
    case 3 => a
    case 4 => b
    case _ => new IndexOutOfBoundsException()
  }
  val nextSteps:PartialFunction[Any,StepOutput[T]] = {
    case 'init :: (r:Raster) :: (n:Neighborhood) :: (neighbors:Seq[_]) :: a :: b :: Nil => 
      val calc = getCalculation(r,n)
      calc.init(r,
                a.asInstanceOf[A],
                b.asInstanceOf[B])
      calc.execute(r,n,neighbors.asInstanceOf[Seq[Option[Raster]]])
      Result(calc.result)
  }

  /** Gets a calculation to be used with this focal operation for the given raster
   * neighborhood.
   *
   * Choosing the calculation based on on the raster and neighborhood allows flexibility
   * in what calculation to use; if some calculations are faster
   * for some neighborhoods (e.g., using a [[CellwiseCalculation]]
   * for [[Square]] neighborhoods and a [[CursorCalculation]] for
   * all other neighborhoods), or if you want to change the calculation
   * based on the raster's data type, you can do so by returning the
   * correct [[FocalCalculation]] from this function.
   *
   * @param     r       Raster that the focal calculation will run against.
   * @param     n       Neighborhood that will be used in the focal operation.
   */  
  def getCalculation(r:Raster,n:Neighborhood):FocalCalculation[T] with Initialization2[A,B]
}

/**
 * Base class for a focal operation that takes a raster, a neighborhood, and three other argument.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        b           Argument of type B.
 * @param        c           Argument of type C.
 *
 * @tparam       T           Return type of the Operation.
 */
abstract class FocalOperation3[A,B,C,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],
                                        a:Op[A],b:Op[B],c:Op[C]) 
         extends FocalOperation[T] {
  var rasterOp:Operation[Raster] = r 
  def _run() = runAsync(List('init,rasterOp,n,tns.flatMap(_.getNeighbors),a,b,c))
  def productArity = 5
  def canEqual(other:Any) = other.isInstanceOf[FocalOperation3[_,_,_,_]]
  def productElement(index:Int) = index match {
    case 0 => r
    case 1 => n
    case 2 => tns
    case 3 => a
    case 4 => b
    case 5 => c
    case _ => new IndexOutOfBoundsException()
  }
  val nextSteps:PartialFunction[Any,StepOutput[T]] = {
    case 'init :: (r:Raster) :: (n:Neighborhood) :: (neighbors:Seq[_]) :: a :: b :: c :: Nil => 
      val calc = getCalculation(r,n)
      calc.init(r,a.asInstanceOf[A],
                b.asInstanceOf[B],
                c.asInstanceOf[C])
      calc.execute(r,n,neighbors.asInstanceOf[Seq[Option[Raster]]])
      Result(calc.result)
  }
  
  /** Gets a calculation to be used with this focal operation for the given raster
   * neighborhood.
   *
   * Choosing the calculation based on on the raster and neighborhood allows flexibility
   * in what calculation to use; if some calculations are faster
   * for some neighborhoods (e.g., using a [[CellwiseCalculation]]
   * for [[Square]] neighborhoods and a [[CursorCalculation]] for
   * all other neighborhoods), or if you want to change the calculation
   * based on the raster's data type, you can do so by returning the
   * correct [[FocalCalculation]] from this function.
   *
   * @param     r       Raster that the focal calculation will run against.
   * @param     n       Neighborhood that will be used in the focal operation.
   */
  def getCalculation(r:Raster,n:Neighborhood):FocalCalculation[T] with Initialization3[A,B,C]
}

/**
 * Base class for a focal operation that takes a raster, a neighborhood, and four other argument.
 *
 * @param        r           Raster the focal operation will run against.
 * @param        n           Neighborhood to use with this focal operation.
 * @param        tns         TileNeighbors that describe the neighboring tiles.
 * @param        a           Argument of type A.
 * @param        b           Argument of type B.
 * @param        c           Argument of type C.
 * @param        d           Argument of type D.
 *
 * @tparam       T           Return type of the Operation.
 */
abstract class FocalOperation4[A,B,C,D,T](r:Op[Raster],n:Op[Neighborhood],tns:Op[TileNeighbors],
                                          a:Op[A],b:Op[B],c:Op[C],d:Op[D])
         extends FocalOperation[T] {
  var rasterOp = r
  def _run() = runAsync(List('init,rasterOp,n,tns.flatMap(_.getNeighbors),a,b,c,d))
  def productArity = 6
  def canEqual(other:Any) = other.isInstanceOf[FocalOperation4[_,_,_,_,_]]
  def productElement(index:Int) = index match {
    case 0 => r
    case 1 => n
    case 2 => tns
    case 3 => a
    case 4 => b
    case 5 => c
    case 6 => d
    case _ => new IndexOutOfBoundsException()
  }
  val nextSteps:PartialFunction[Any,StepOutput[T]] = {
    case 'init :: (r:Raster) :: (n:Neighborhood) :: (neighbors:Seq[_]) :: a :: b :: c :: d :: Nil => 
      val calc = getCalculation(r,n)
      calc.init(r,a.asInstanceOf[A],
                  b.asInstanceOf[B],
                  c.asInstanceOf[C],
                  d.asInstanceOf[D])
      calc.execute(r,n,neighbors.asInstanceOf[Seq[Option[Raster]]])
      Result(calc.result)
  }
  
  /** Gets a calculation to be used with this focal operation for the given raster
   * neighborhood.
   *
   * Choosing the calculation based on on the raster and neighborhood allows flexibility
   * in what calculation to use; if some calculations are faster
   * for some neighborhoods (e.g., using a [[CellwiseCalculation]]
   * for [[Square]] neighborhoods and a [[CursorCalculation]] for
   * all other neighborhoods), or if you want to change the calculation
   * based on the raster's data type, you can do so by returning the
   * correct [[FocalCalculation]] from this function.
   *
   * @param     r       Raster that the focal calculation will run against.
   * @param     n       Neighborhood that will be used in the focal operation.
   */
  def getCalculation(r:Raster,n:Neighborhood):FocalCalculation[T] with Initialization4[A,B,C,D]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy