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

geotrellis.raster.op.zonal.summary.ZonalSummaryOpMethods.scala Maven / Gradle / Ivy

The newest version!
package geotrellis.raster.op.zonal.summary

import geotrellis._
import geotrellis.source._
import geotrellis.feature._
import geotrellis.feature.rasterize._
import geotrellis.statistics._

import scala.collection.mutable
import spire.syntax.cfor._

abstract sealed trait TileIntersection

case class PartialTileIntersection[D](tile:Raster,intersections:List[Polygon[D]]) extends TileIntersection
case class FullTileIntersection(tile:Raster) extends TileIntersection

trait ZonalSummaryOpMethods[+Repr <: RasterSource] { self:Repr =>
  def mapIntersecting[B,That,D](p:Op[feature.Polygon[D]])
                               (handleTileIntersection:TileIntersection=>B)
                               (implicit bf:CanBuildSourceFrom[Repr,B,That]):That =
    _mapIntersecting(p,None)(handleTileIntersection)(bf.apply(this))

  def mapIntersecting[B,That,D](p:Op[feature.Polygon[D]],fullTileResults:DataSource[B,_])
                               (handleTileIntersection:TileIntersection=>B)
                               (implicit bf:CanBuildSourceFrom[Repr,B,That]):That = 
    _mapIntersecting(p,Some(fullTileResults))(handleTileIntersection)(bf.apply(this))

  def mapIntersecting[B,That,D](p:Op[feature.Polygon[D]],fullTileResults:Option[DataSource[B,_]])
                               (handleTileIntersection:TileIntersection=>B)
                               (implicit bf:CanBuildSourceFrom[Repr,B,That]):That = 
    _mapIntersecting(p,fullTileResults)(handleTileIntersection)(bf.apply(this))


  private 
  def _mapIntersecting[B,That,D](p:Op[feature.Polygon[D]],fullTileResults:Option[DataSource[B,_]])
                                (handleTileIntersection:TileIntersection=>B)
                                (builder:SourceBuilder[B,That]):That = {
    val newOp = 
      (rasterDefinition,tiles,p).map { (rd,tiles,p) =>
        val rl = rd.tileLayout.getResolutionLayout(rd.rasterExtent)
        val tileCols = rd.tileLayout.tileCols
        val tileRows = rd.tileLayout.tileRows
        val filtered = mutable.ListBuffer[Op[B]]()

        val handleFullTile:Int => Op[B] =
          fullTileResults match {
            case Some(cached) =>
              { (i:Int) => cached.elements.flatMap(_(i)) }
            case None =>
              { (i:Int) => 
                tiles(i).map { t =>
                  handleTileIntersection(FullTileIntersection(t))
                }
              }
          }

        cfor(0)(_ < tileCols, _ + 1) { col =>
          cfor(0)(_ < tileRows, _ + 1) { row =>
            val tilePoly =
              rl.getRasterExtent(col,row)
                .extent
                .asFeature()
                .geom

            if(p.geom.contains(tilePoly)) {              
              filtered += handleFullTile(row*tileCols + col)
            } else {
              val intersections = tilePoly.intersection(p.geom).asPolygonSet.map(Polygon(_,0))
              if(!intersections.isEmpty) {
                filtered += tiles(row*tileCols + col).map { t =>
                  handleTileIntersection(PartialTileIntersection(t,intersections))
                }
              }
            }
          }
        }
        filtered.toSeq
      }

    builder.setOp(newOp)
    val result = builder.result()
    result
  }

  private 
  def zonalSummary[T,V,That <: DataSource[_,V],D]
    (tileSummary:TileSummary[T,V,That], p:Op[Polygon[D]], cachedResult:Option[DataSource[T,_]]) =
    tileSummary.converge {
      self.mapIntersecting(p,cachedResult) { tileIntersection =>
        tileIntersection match {
          case ft @ FullTileIntersection(_) => tileSummary.handleFullTile(ft)
          case pt @ PartialTileIntersection(_,_) => tileSummary.handlePartialTile(pt)
        }
      }
    }

  def zonalHistogram[D](p:Op[feature.Polygon[D]]):ValueSource[Histogram] =
    zonalSummary(Histogram,p,None)

  def zonalHistogram[D](p:Op[feature.Polygon[D]],cached:DataSource[Histogram,_]):ValueSource[Histogram] =
    zonalSummary(Histogram,p,Some(cached))

  def zonalSum[D](p:Op[feature.Polygon[D]]):ValueSource[Long] =
    zonalSummary(Sum,p,None)

  def zonalSum[D](p:Op[feature.Polygon[D]],cached:DataSource[Long,_]):ValueSource[Long] =
    zonalSummary(Sum,p,Some(cached))

  def zonalSumDouble[D](p:Op[feature.Polygon[D]]):ValueSource[Double] =
    zonalSummary(SumDouble,p,None)

  def zonalSumDouble[D](p:Op[feature.Polygon[D]],cached:DataSource[Double,_]):ValueSource[Double] =
    zonalSummary(SumDouble,p,Some(cached))

  def zonalMin[D](p:Op[feature.Polygon[D]]):ValueSource[Int] =
    zonalSummary(Min,p,None)

  def zonalMin[D](p:Op[feature.Polygon[D]],cached:DataSource[Int,_]):ValueSource[Int] =
    zonalSummary(Min,p,Some(cached))

  def zonalMinDouble[D](p:Op[feature.Polygon[D]]):ValueSource[Double] =
    zonalSummary(MinDouble,p,None)

  def zonalMinDouble[D](p:Op[feature.Polygon[D]],cached:DataSource[Double,_]):ValueSource[Double] =
    zonalSummary(MinDouble,p,Some(cached))

  def zonalMax[D](p:Op[feature.Polygon[D]]):ValueSource[Int] =
    zonalSummary(Max,p,None)

  def zonalMax[D](p:Op[feature.Polygon[D]],cached:DataSource[Int,_]):ValueSource[Int] =
    zonalSummary(Max,p,Some(cached))

  def zonalMaxDouble[D](p:Op[feature.Polygon[D]]):ValueSource[Double] =
    zonalSummary(MaxDouble,p,None)

  def zonalMaxDouble[D](p:Op[feature.Polygon[D]],cached:DataSource[Double,_]):ValueSource[Double] =
    zonalSummary(MaxDouble,p,Some(cached))

  def zonalMean[D](p:Op[feature.Polygon[D]]):ValueSource[Double] =
    zonalSummary(Mean,p,None)

  def zonalMean[D](p:Op[feature.Polygon[D]],cached:DataSource[MeanResult,_]):ValueSource[Double] =
    zonalSummary(Mean,p,Some(cached))

  def zonalMeanDouble[D](p:Op[feature.Polygon[D]]):ValueSource[Double] =
    zonalSummary(MeanDouble,p,None)

  def zonalMeanDouble[D](p:Op[feature.Polygon[D]],cached:DataSource[MeanResult,_]):ValueSource[Double] =
    zonalSummary(MeanDouble,p,Some(cached))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy