From 44bbfb10cd1fae58e4091c8ccc307cdfa4bf00e8 Mon Sep 17 00:00:00 2001 From: Grigory Pomadchin Date: Mon, 7 Oct 2019 16:56:33 -0400 Subject: [PATCH] Make PointFeatureExctractor more generic --- docs/CHANGELOG.rst | 2 ++ ...xtraction.scala => FeatureExtractor.scala} | 24 +++++++++---------- .../scala/geotrellis/raster/Implicits.scala | 12 +++++----- .../scala/geotrellis/raster/package.scala | 2 +- ...nSpec.scala => FeatureExtractorSpec.scala} | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) rename raster/src/main/scala/geotrellis/raster/{FeatureExtraction.scala => FeatureExtractor.scala} (79%) rename raster/src/test/scala/geotrellis/raster/{FeatureExtractionSpec.scala => FeatureExtractorSpec.scala} (98%) diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index d084ca57fd..1c8642f434 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -100,6 +100,8 @@ API Changes & Project structure changes ``import geotrellis.raster._`` + - **New:** Rasters FeatureExtraction (`#3117 `_): + - ``geotrellis.vectortile`` - **Add:** ``geotrellis.vectortile.MVTFeature`` which properly conforms to the MVT 2.0 spec. Specifically, MVTFeature adds support for an ``Option[Long]`` id property. diff --git a/raster/src/main/scala/geotrellis/raster/FeatureExtraction.scala b/raster/src/main/scala/geotrellis/raster/FeatureExtractor.scala similarity index 79% rename from raster/src/main/scala/geotrellis/raster/FeatureExtraction.scala rename to raster/src/main/scala/geotrellis/raster/FeatureExtractor.scala index f07714f03e..16fabe52cc 100644 --- a/raster/src/main/scala/geotrellis/raster/FeatureExtraction.scala +++ b/raster/src/main/scala/geotrellis/raster/FeatureExtractor.scala @@ -23,14 +23,14 @@ import spire.syntax.cfor._ import scala.collection.mutable.ListBuffer -trait FeatureExtraction[I <: Geometry, T <: CellGrid[Int], O <: Geometry, D] { - def features(geom: I, raster: Raster[T]): Array[Feature[O, Array[D]]] +trait FeatureExtractor[I <: Geometry, T <: CellGrid[Int], O <: Geometry, D] { + def features(geom: I, raster: Raster[T]): Array[Feature[O, D]] } -object FeatureExtraction { - def apply[I <: Geometry: FeatureExtraction[*, T, O, D], T <: CellGrid[Int], O <: Geometry, D] = implicitly[FeatureExtraction[I, T, O, D]] +object FeatureExtractor { + def apply[I <: Geometry: FeatureExtractor[*, T, O, D], T <: CellGrid[Int], O <: Geometry, D] = implicitly[FeatureExtractor[I, T, O, D]] - implicit def multibandTile[I <: Geometry] = new PointFeatureExtraction[I, MultibandTile, Int] { + implicit def multibandTile[I <: Geometry] = new PointFeatureExtractor[I, MultibandTile, Array[Int]] { def features(geom: I, raster: Raster[MultibandTile]): Array[PointFeature[Array[Int]]] = { val buffer = ListBuffer[PointFeature[Array[Int]]]() @@ -44,7 +44,7 @@ object FeatureExtraction { } } - implicit def multibandTileDouble[I <: Geometry] = new PointFeatureExtraction[I, MultibandTile, Double] { + implicit def multibandTileDouble[I <: Geometry] = new PointFeatureExtractor[I, MultibandTile, Array[Double]] { def features(geom: I, raster: Raster[MultibandTile]): Array[PointFeature[Array[Double]]] = { val buffer = ListBuffer[PointFeature[Array[Double]]]() @@ -58,14 +58,14 @@ object FeatureExtraction { } } - implicit def tile[I <: Geometry] = new PointFeatureExtraction[I, Tile, Int] { - def features(geom: I, raster: Raster[Tile]): Array[PointFeature[Array[Int]]] = - multibandTile[I].features(geom, raster.mapTile(MultibandTile(_))) + implicit def tile[I <: Geometry] = new PointFeatureExtractor[I, Tile, Int] { + def features(geom: I, raster: Raster[Tile]): Array[PointFeature[Int]] = + multibandTile[I].features(geom, raster.mapTile(MultibandTile(_))).map(_.mapData(_.head)) } - implicit def tileDouble[I <: Geometry] = new PointFeatureExtraction[I, Tile, Double] { - def features(geom: I, raster: Raster[Tile]): Array[PointFeature[Array[Double]]] = { - multibandTileDouble[I].features(geom, raster.mapTile(MultibandTile(_))) + implicit def tileDouble[I <: Geometry] = new PointFeatureExtractor[I, Tile, Double] { + def features(geom: I, raster: Raster[Tile]): Array[PointFeature[Double]] = { + multibandTileDouble[I].features(geom, raster.mapTile(MultibandTile(_))).map(_.mapData(_.head)) } } } diff --git a/raster/src/main/scala/geotrellis/raster/Implicits.scala b/raster/src/main/scala/geotrellis/raster/Implicits.scala index a277f80042..91013d0997 100644 --- a/raster/src/main/scala/geotrellis/raster/Implicits.scala +++ b/raster/src/main/scala/geotrellis/raster/Implicits.scala @@ -125,17 +125,17 @@ trait Implicits } } - implicit class MultibandRasterPointFeatureExtractionMethods(val self: Raster[MultibandTile]) extends MethodExtensions[Raster[MultibandTile]] { + implicit class MultibandRasterPointFeatureExtractorMethods(val self: Raster[MultibandTile]) extends MethodExtensions[Raster[MultibandTile]] { def pointFeatures[D] = new { - def apply[I <: Geometry: PointFeatureExtraction[*, MultibandTile, D]](geom: I): Array[PointFeature[Array[D]]] = - FeatureExtraction[I, MultibandTile, Point, D].features(geom, self) + def apply[I <: Geometry: PointFeatureExtractor[*, MultibandTile, Array[D]]](geom: I): Array[PointFeature[Array[D]]] = + FeatureExtractor[I, MultibandTile, Point, Array[D]].features(geom, self) } } - implicit class rasterPointFeatureExtractionMethods(val self: Raster[Tile]) extends MethodExtensions[Raster[Tile]] { + implicit class RasterPointFeatureExtractorMethods(val self: Raster[Tile]) extends MethodExtensions[Raster[Tile]] { def pointFeatures[D] = new { - def apply[I <: Geometry: PointFeatureExtraction[*, Tile, D]](geom: I): Array[PointFeature[D]] = - FeatureExtraction[I, Tile, Point, D].features(geom, self).map(_.mapData(_.head)) + def apply[I <: Geometry: PointFeatureExtractor[*, Tile, D]](geom: I): Array[PointFeature[D]] = + FeatureExtractor[I, Tile, Point, D].features(geom, self) } } } diff --git a/raster/src/main/scala/geotrellis/raster/package.scala b/raster/src/main/scala/geotrellis/raster/package.scala index ca37678d0f..efb43659a9 100644 --- a/raster/src/main/scala/geotrellis/raster/package.scala +++ b/raster/src/main/scala/geotrellis/raster/package.scala @@ -185,7 +185,7 @@ package object raster extends Implicits { def fill(v: Double) = { java.util.Arrays.fill(arr, v) ; arr } } - type PointFeatureExtraction[I <: Geometry, T <: CellGrid[Int], D] = FeatureExtraction[I, T, Point, D] + type PointFeatureExtractor[I <: Geometry, T <: CellGrid[Int], D] = FeatureExtractor[I, T, Point, D] /* http://stackoverflow.com/questions/3508077/how-to-define-type-disjunction-union-types */ sealed class TileOrMultibandTile[T] diff --git a/raster/src/test/scala/geotrellis/raster/FeatureExtractionSpec.scala b/raster/src/test/scala/geotrellis/raster/FeatureExtractorSpec.scala similarity index 98% rename from raster/src/test/scala/geotrellis/raster/FeatureExtractionSpec.scala rename to raster/src/test/scala/geotrellis/raster/FeatureExtractorSpec.scala index c74c291f6a..e519e8808e 100644 --- a/raster/src/test/scala/geotrellis/raster/FeatureExtractionSpec.scala +++ b/raster/src/test/scala/geotrellis/raster/FeatureExtractorSpec.scala @@ -21,7 +21,7 @@ import geotrellis.raster.testkit._ import org.scalatest._ -class FeatureExtractionSpec extends FunSpec with Matchers { +class FeatureExtractorSpec extends FunSpec with Matchers { describe("Tile") { it("should extract all int point features") { val ext = Extent(0.0, 0.0, 3.0, 3.0)