Skip to content

Commit 87a26e6

Browse files
authored
Merge pull request #373 from s22s/fix/372
Fixed eager loading of RasterRef fields.
2 parents cfff3c8 + 6699954 commit 87a26e6

File tree

13 files changed

+56
-45
lines changed

13 files changed

+56
-45
lines changed

core/src/main/scala/org/apache/spark/sql/rf/TileUDT.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.apache.spark.sql.types.{DataType, _}
2626
import org.locationtech.rasterframes.encoders.CatalystSerializer
2727
import org.locationtech.rasterframes.encoders.CatalystSerializer._
2828
import org.locationtech.rasterframes.model.{Cells, TileDataContext}
29+
import org.locationtech.rasterframes.ref.RasterRef.RasterRefTile
2930
import org.locationtech.rasterframes.tiles.InternalRowTile
3031

3132

@@ -75,12 +76,15 @@ case object TileUDT {
7576
implicit def tileSerializer: CatalystSerializer[Tile] = new CatalystSerializer[Tile] {
7677

7778
override val schema: StructType = StructType(Seq(
78-
StructField("cell_context", schemaOf[TileDataContext], false),
79+
StructField("cell_context", schemaOf[TileDataContext], true),
7980
StructField("cell_data", schemaOf[Cells], false)
8081
))
8182

8283
override def to[R](t: Tile, io: CatalystIO[R]): R = io.create(
83-
io.to(TileDataContext(t)),
84+
t match {
85+
case _: RasterRefTile => null
86+
case o => io.to(TileDataContext(o))
87+
},
8488
io.to(Cells(t))
8589
)
8690

core/src/main/scala/org/locationtech/rasterframes/ref/DelegatingRasterSource.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ abstract class DelegatingRasterSource(source: URI, delegateBuilder: () => GTRast
4343
f(_delRef)
4444
}
4545
catch {
46-
// On this exeception we attempt to recreate the delegate and read again.
46+
// On this Exeception we attempt to recreate the delegate and read again.
4747
case _: java.nio.BufferUnderflowException =>
4848
_delRef = null
4949
val newDel = delegateBuilder()
@@ -62,7 +62,7 @@ abstract class DelegatingRasterSource(source: URI, delegateBuilder: () => GTRast
6262
override def hashCode(): Int = source.hashCode()
6363

6464
// This helps reduce header reads between serializations
65-
def info: SimpleRasterInfo = SimpleRasterInfo.cache.get(source.toASCIIString, _ =>
65+
def info: SimpleRasterInfo = SimpleRasterInfo(source.toASCIIString, _ =>
6666
retryableRead(rs => SimpleRasterInfo(rs))
6767
)
6868

core/src/main/scala/org/locationtech/rasterframes/ref/GDALRasterSource.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ case class GDALRasterSource(source: URI) extends RasterSource with URIRasterSour
4848
VLMRasterSource(tweaked)
4949
}
5050

51-
protected def tiffInfo = SimpleRasterInfo.cache.get(source.toASCIIString, _ => SimpleRasterInfo(gdal))
51+
protected def tiffInfo = SimpleRasterInfo(source.toASCIIString, _ => SimpleRasterInfo(gdal))
5252

5353
override def crs: CRS = tiffInfo.crs
5454

core/src/main/scala/org/locationtech/rasterframes/ref/RasterRef.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ object RasterRef extends LazyLogging {
6161
private val log = logger
6262

6363
case class RasterRefTile(rr: RasterRef) extends ProjectedRasterTile {
64-
val extent: Extent = rr.extent
65-
val crs: CRS = rr.crs
64+
def extent: Extent = rr.extent
65+
def crs: CRS = rr.crs
6666
override def cellType = rr.cellType
6767

68-
override val cols: Int = rr.cols
69-
override val rows: Int = rr.rows
68+
override def cols: Int = rr.cols
69+
override def rows: Int = rr.rows
7070

7171
protected def delegate: Tile = rr.realizedTile
7272
// NB: This saves us from stack overflow exception

core/src/main/scala/org/locationtech/rasterframes/ref/RasterSource.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ object RasterSource extends LazyLogging {
9292

9393
val cacheTimeout: Duration = Duration.fromNanos(rfConfig.getDuration("raster-source-cache-timeout").toNanos)
9494

95-
private val rsCache = Scaffeine()
95+
private[ref] val rsCache = Scaffeine()
9696
.recordStats()
9797
.expireAfterAccess(RasterSource.cacheTimeout)
9898
.build[String, RasterSource]

core/src/main/scala/org/locationtech/rasterframes/ref/SimpleRasterInfo.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ case class SimpleRasterInfo(
4444
)
4545

4646
object SimpleRasterInfo {
47+
// Not a fan of this.... need a better abstraction that doesn't put the
48+
// type-specific logic in here.
49+
def apply(key: String, builder: String => SimpleRasterInfo): SimpleRasterInfo =
50+
cache.get(key, builder)
51+
4752
def apply(info: GeoTiffReader.GeoTiffInfo): SimpleRasterInfo =
4853
SimpleRasterInfo(
4954
info.segmentLayout.totalCols,
@@ -76,10 +81,9 @@ object SimpleRasterInfo {
7681
)
7782
}
7883

79-
private[rasterframes]
80-
lazy val cache = Scaffeine()
84+
private lazy val cache = Scaffeine()
8185
.recordStats()
8286
.build[String, SimpleRasterInfo]
8387

8488
def cacheStats = cache.stats()
85-
}
89+
}

core/src/main/scala/org/locationtech/rasterframes/tiles/ProjectedRasterTile.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,15 @@ object ProjectedRasterTile {
7272
}
7373
implicit val serializer: CatalystSerializer[ProjectedRasterTile] = new CatalystSerializer[ProjectedRasterTile] {
7474
override val schema: StructType = StructType(Seq(
75-
StructField("tile_context", schemaOf[TileContext], false),
75+
StructField("tile_context", schemaOf[TileContext], true),
7676
StructField("tile", TileType, false))
7777
)
7878

7979
override protected def to[R](t: ProjectedRasterTile, io: CatalystIO[R]): R = io.create(
80-
io.to(TileContext(t.extent, t.crs)),
80+
t match {
81+
case _: RasterRefTile => null
82+
case o => io.to(TileContext(o.extent, o.crs))
83+
},
8184
io.to[Tile](t)(TileUDT.tileSerializer)
8285
)
8386

core/src/test/scala/org/locationtech/rasterframes/RasterFrameSpec.scala

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -232,23 +232,6 @@ class RasterFrameSpec extends TestEnvironment with MetadataKeys
232232
assert(bounds._2 === SpaceTimeKey(3, 1, now))
233233
}
234234

235-
// it("should clip TileLayerMetadata extent") {
236-
// val tiled = sampleTileLayerRDD
237-
//
238-
// val rf = tiled.reproject(LatLng, tiled.metadata.layout)._2.toLayer
239-
//
240-
// val worldish = Extent(-179, -89, 179, 89)
241-
// val areaish = Extent(-90, 30, -81, 40)
242-
//
243-
// val orig = rf.tileLayerMetadata.widen.extent
244-
// assert(worldish.contains(orig))
245-
// assert(areaish.contains(orig))
246-
//
247-
// val clipped = rf.clipLayerExtent.tileLayerMetadata.widen.extent
248-
// assert(!clipped.contains(worldish))
249-
// assert(clipped.contains(areaish))
250-
// }
251-
252235
def basicallySame(expected: Extent, computed: Extent): Unit = {
253236
val components = Seq(
254237
(expected.xmin, computed.xmin),

core/src/test/scala/org/locationtech/rasterframes/ref/RasterRefSpec.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,5 +252,16 @@ class RasterRefSpec extends TestEnvironment with TestData {
252252
assertEqual(t.toArrayTile(), result)
253253
}
254254
}
255+
256+
it("should construct a RasterRefTile without I/O") {
257+
new Fixture {
258+
// SimpleRasterInfo is a proxy for header data requests.
259+
val start = SimpleRasterInfo.cacheStats.hitCount()
260+
val t: ProjectedRasterTile = RasterRefTile(subRaster)
261+
val result = Seq(t).toDF("tile").first()
262+
val end = SimpleRasterInfo.cacheStats.hitCount()
263+
end should be(start)
264+
}
265+
}
255266
}
256267
}

project/plugins.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.1")
1515
addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.10")
1616
addSbtPlugin("com.github.gseitz" %% "sbt-release" % "1.0.9")
1717
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.19")
18+
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0")
1819

1920

0 commit comments

Comments
 (0)