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

geotrellis.raster.Kernel.scala Maven / Gradle / Ivy

The newest version!
package geotrellis.raster

import geotrellis._

/** 
 * Kernel
 *
 * Represents a neighborhood that is represented by
 * a raster.
 */
case class Kernel(raster:Raster) {
  if(raster.rows != raster.cols) sys.error("Kernel raster must be square")
  if(raster.rows % 2 != 1) sys.error("Kernel raster must have odd dimension")
}

object Kernel {
  implicit def raster2Kernel(r:Raster):Kernel = Kernel(r)
  implicit def raster2KernelOp(r:Raster):Op[Kernel] = Literal(Kernel(r))
  implicit def rasterOp2Kernel(r:Op[Raster]):Op[Kernel] = r.map(Kernel(_))

  /**
   * Creates a Gaussian kernel. Can be used with the [[Convolve]] or [[KernelDensity]] operations.
   *
   * @param    size           Number of rows of the resulting raster.
   * @param    cellWidth      Cell width of the resulting raster
   * @param    sigma          Sigma parameter for Gaussian
   * @param    amp            Amplitude for Gaussian. Will be the value at the center of
   *                          the resulting raster.
   *
   * @note                    Raster will be TypeInt
   */
  def gaussian(size:Int, cellWidth:Double, sigma:Double, amp:Double) = {
    val extent = Extent(0,0,size*cellWidth,size*cellWidth)
    val rasterExtent = RasterExtent(extent, cellWidth, cellWidth, size, size)
    val output = IntArrayRasterData.empty(rasterExtent.cols, rasterExtent.rows)

    val denom = 2.0*sigma*sigma

    var r = 0
    var c = 0
    while(r < size) {
      c = 0
      while(c < size) {
        val rsqr = (c - size/2)*(c - size/2) + (r - size/2)*(r - size/2)
        val g = (amp * (math.exp(-rsqr / denom))).toInt
        output.set(c,r,g)
        c += 1
      }
      r += 1
    }

    Kernel(Raster(output,rasterExtent))
  }

  /**
   * Creates a Circle kernel. Can be used with the [[Convolve]] or [[KernelDensity]] operations.
   *
   * @param       size           Number of rows in the resulting raster.
   * @param       cellWidth      Cell width of the resutling raster.
   * @param       rad            Radius of the circle.
   *
   * @note                       Raster will be TypeInt 
   */
  def circle(size:Int, cellWidth:Double, rad:Int) = {
    val extent = Extent(0,0,size*cellWidth,size*cellWidth)
    val rasterExtent = RasterExtent(extent, cellWidth, cellWidth, size, size)
    val output = IntArrayRasterData.empty(rasterExtent.cols, rasterExtent.rows)

    val rad2 = rad*rad

    var r = 0
    var c = 0
    while(r < size) {
      while(c < size) {
        output.set(c,r, if (r*r + c*c < rad2) 1 else 0)
        c += 1
      }
      c = 0
      r += 1
    }

    Kernel(Raster(output,rasterExtent))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy