-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1614 from pomadchin/feature/collections-psummary
Collections polygonal summary functions
- Loading branch information
Showing
26 changed files
with
977 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
spark/src/main/scala/geotrellis/spark/CellGridLayoutCollectionMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package geotrellis.spark | ||
|
||
import geotrellis.raster._ | ||
import geotrellis.spark.tiling.LayoutDefinition | ||
import geotrellis.util._ | ||
|
||
import scala.reflect.ClassTag | ||
|
||
abstract class CellGridLayoutCollectionMethods[K: SpatialComponent, V <: CellGrid, M: GetComponent[?, LayoutDefinition]] | ||
extends MethodExtensions[Seq[(K, V)] with Metadata[M]] { | ||
def asRasters(): Seq[(K, Raster[V])] = { | ||
val mapTransform = self.metadata.getComponent[LayoutDefinition].mapTransform | ||
self.map { case (key, tile) => | ||
(key, Raster(tile, mapTransform(key))) | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
spark/src/main/scala/geotrellis/spark/mapalgebra/TileCollectionMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package geotrellis.spark.mapalgebra | ||
|
||
import geotrellis.raster.Tile | ||
import geotrellis.util.MethodExtensions | ||
import org.apache.spark.rdd.RDD | ||
|
||
import scala.reflect.ClassTag | ||
|
||
|
||
trait TileCollectionMethods[K] extends MethodExtensions[Seq[(K, Tile)]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
spark/src/main/scala/geotrellis/spark/stitch/StitchCollectionMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package geotrellis.spark.stitch | ||
|
||
import geotrellis.raster._ | ||
import geotrellis.raster.stitch.Stitcher | ||
import geotrellis.vector.Extent | ||
import geotrellis.spark._ | ||
import geotrellis.spark.tiling._ | ||
import geotrellis.util._ | ||
|
||
import org.apache.spark.rdd.RDD | ||
|
||
abstract class SpatialTileLayoutCollectionStitchMethods[V <: CellGrid: Stitcher, M: GetComponent[?, LayoutDefinition]] | ||
extends MethodExtensions[Seq[(SpatialKey, V)] with Metadata[M]] { | ||
|
||
def stitch(): Raster[V] = { | ||
val (tile, bounds) = TileLayoutStitcher.stitch(self) | ||
val mapTransform = self.metadata.getComponent[LayoutDefinition].mapTransform | ||
Raster(tile, mapTransform(bounds)) | ||
} | ||
} | ||
|
||
abstract class SpatialTileCollectionStitchMethods[V <: CellGrid: Stitcher] | ||
extends MethodExtensions[Seq[(SpatialKey, V)]] { | ||
|
||
def stitch(): V = TileLayoutStitcher.stitch(self)._1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
spark/src/main/scala/geotrellis/spark/summary/StatsTileCollectionMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package geotrellis.spark.summary | ||
|
||
import geotrellis.raster._ | ||
import geotrellis.raster.histogram._ | ||
import geotrellis.spark.mapalgebra._ | ||
|
||
trait StatsTileCollectionMethods[K] extends TileCollectionMethods[K] { | ||
|
||
def averageByKey(): Seq[(K, Tile)] = | ||
self.groupBy(_._1).mapValues { seq => seq.map(_._2).reduce(_ + _) / seq.size } toSeq | ||
|
||
def histogram(): Histogram[Double] = | ||
histogram(StreamingHistogram.DEFAULT_NUM_BUCKETS) | ||
|
||
def histogram(numBuckets: Int): Histogram[Double] = | ||
self | ||
.map { case (key, tile) => tile.histogramDouble(numBuckets) } | ||
.reduce { _ merge _ } | ||
|
||
/** Gives a histogram that uses exact counts of integer values. | ||
* | ||
* @note This cannot handle counts that are larger than Int.MaxValue, and | ||
* should not be used with very large datasets whose counts will overflow. | ||
* These histograms can get very large with a wide range of values. | ||
*/ | ||
def histogramExactInt: Histogram[Int] = { | ||
self | ||
.map { case (key, tile) => tile.histogram } | ||
.reduce { _ merge _ } | ||
} | ||
|
||
def classBreaks(numBreaks: Int): Array[Int] = | ||
classBreaksDouble(numBreaks).map(_.toInt) | ||
|
||
def classBreaksDouble(numBreaks: Int): Array[Double] = | ||
histogram(numBreaks).quantileBreaks(numBreaks) | ||
|
||
/** Gives class breaks using a histogram that uses exact counts of integer values. | ||
* | ||
* @note This cannot handle counts that are larger than Int.MaxValue, and | ||
* should not be used with very large datasets whose counts will overflow. | ||
* These histograms can get very large with a wide range of values. | ||
*/ | ||
def classBreaksExactInt(numBreaks: Int): Array[Int] = | ||
histogramExactInt.quantileBreaks(numBreaks) | ||
|
||
def minMax: (Int, Int) = | ||
self.map(_._2.findMinMax) | ||
.reduce { (t1, t2) => | ||
val (min1, max1) = t1 | ||
val (min2, max2) = t2 | ||
val min = | ||
if(isNoData(min1)) min2 | ||
else { | ||
if(isNoData(min2)) min1 | ||
else math.min(min1, min2) | ||
} | ||
val max = | ||
if(isNoData(max1)) max2 | ||
else { | ||
if(isNoData(max2)) max1 | ||
else math.max(max1, max2) | ||
} | ||
(min, max) | ||
} | ||
|
||
def minMaxDouble: (Double, Double) = | ||
self | ||
.map(_._2.findMinMaxDouble) | ||
.reduce { (t1, t2) => | ||
val (min1, max1) = t1 | ||
val (min2, max2) = t2 | ||
val min = | ||
if(isNoData(min1)) min2 | ||
else { | ||
if(isNoData(min2)) min1 | ||
else math.min(min1, min2) | ||
} | ||
val max = | ||
if(isNoData(max1)) max2 | ||
else { | ||
if(isNoData(max2)) max1 | ||
else math.max(max1, max2) | ||
} | ||
(min, max) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...n/scala/geotrellis/spark/summary/polygonal/PolygonalSummaryFeatureCollectionMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package geotrellis.spark.summary.polygonal | ||
|
||
import geotrellis.vector._ | ||
import geotrellis.vector.summary.polygonal._ | ||
|
||
trait PolygonalSummaryFeatureCollectionMethods[G <: Geometry, D] { | ||
val featureCollection: Seq[Feature[G, D]] | ||
|
||
def polygonalSummary[T](polygon: Polygon, zeroValue: T)(handler: PolygonalSummaryHandler[G, D, T]): T = | ||
featureCollection.aggregate(zeroValue)(handler.mergeOp(polygon, zeroValue), handler.combineOp) | ||
|
||
def polygonalSummary[T](multiPolygon: MultiPolygon, zeroValue: T)(handler: PolygonalSummaryHandler[G, D, T]): T = | ||
featureCollection.aggregate(zeroValue)(handler.mergeOp(multiPolygon, zeroValue), handler.combineOp) | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
...la/geotrellis/spark/summary/polygonal/PolygonalSummaryKeyedFeatureCollectionMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package geotrellis.spark.summary.polygonal | ||
|
||
import geotrellis.vector._ | ||
import geotrellis.vector.summary.polygonal._ | ||
|
||
trait PolygonalSummaryKeyedFeatureCollectionMethods[K, G <: Geometry, D] { | ||
val featureCollection: Seq[(K, Feature[G, D])] | ||
|
||
private def aggregateByKey[T](self: Seq[(K, Feature[G, D])])(zeroValue: T)(seqOp: (T, Feature[G, D]) => T, combOp: (T, T) => T): Seq[(K, T)] = | ||
self.groupBy(_._1).mapValues { _.map(_._2).aggregate(zeroValue)(seqOp, combOp) } toSeq | ||
|
||
def polygonalSummaryByKey[T](polygon: Polygon, zeroValue: T)(handler: PolygonalSummaryHandler[G, D, T]): Seq[(K, T)] = | ||
aggregateByKey(featureCollection)(zeroValue)(handler.mergeOp(polygon, zeroValue), handler.combineOp) | ||
|
||
def polygonalSummaryByKey[T](multiPolygon: MultiPolygon, zeroValue: T)(handler: PolygonalSummaryHandler[G, D, T]): Seq[(K, T)] = | ||
aggregateByKey(featureCollection)(zeroValue)(handler.mergeOp(multiPolygon, zeroValue), handler.combineOp) | ||
} |
Oops, something went wrong.