Skip to content

Commit 5b6e6cc

Browse files
committed
Add more unit tests around RasterSource read tiling, round trip writing with GeoTiff datasource
Signed-off-by: Jason T. Brown <[email protected]>
1 parent afb8765 commit 5b6e6cc

File tree

4 files changed

+66
-46
lines changed

4 files changed

+66
-46
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ trait TestData {
146146

147147
lazy val localSentinel: URI = getClass.getResource("/B01.jp2").toURI
148148
lazy val cogPath: URI = getClass.getResource("/LC08_RGB_Norfolk_COG.tiff").toURI
149+
lazy val singlebandCogPath: URI = getClass.getResource("/LC08_B7_Memphis_COG.tiff").toURI
149150
lazy val nonCogPath: URI = getClass.getResource("/L8-B8-Robinson-IL.tiff").toURI
150151

151152
lazy val l8B1SamplePath: URI = l8SamplePath(1)

datasource/src/main/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSource.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class GeoTiffDataSource
121121
rf_dimensions(tileCol)
122122
))
123123
.first()
124+
logger.debug(s"Contructed TileLayerMetadata: ${tlm.toString}")
124125

125126
val c = ProjectedRasterDefinition(tlm)
126127

datasource/src/test/scala/org/locationtech/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ package org.locationtech.rasterframes.datasource.geotiff
2323
import java.nio.file.Paths
2424

2525
import geotrellis.proj4._
26+
import geotrellis.raster.ProjectedRaster
2627
import geotrellis.raster.io.geotiff.{MultibandGeoTiff, SinglebandGeoTiff}
2728
import geotrellis.vector.Extent
2829
import org.locationtech.rasterframes._
@@ -43,7 +44,7 @@ class GeoTiffDataSourceSpec
4344
assert(rf.count() > 10)
4445
}
4546

46-
it("should lay out tiles correctly"){
47+
it("should lay out tiles correctly") {
4748

4849
val rf = spark.read.format("geotiff").load(cogPath.toASCIIString).asLayer
4950

@@ -85,6 +86,9 @@ class GeoTiffDataSourceSpec
8586

8687
assert(result === expected)
8788
}
89+
}
90+
91+
describe("GeoTiff writing") {
8892

8993
it("should write GeoTIFF RF to parquet") {
9094
val rf = spark.read.format("geotiff").load(cogPath.toASCIIString).asLayer
@@ -132,13 +136,31 @@ class GeoTiffDataSourceSpec
132136
}
133137

134138
it("should round trip unstructured raster from COG"){
135-
val df = spark.read.format("raster")
136-
.load(getClass.getResource("/LC08_B7_Memphis_COG.tiff").toURI.toASCIIString())
139+
import spark.implicits._
140+
import org.locationtech.rasterframes.datasource.raster._
141+
142+
val df = spark.read.raster.withTileDimensions(64, 64).load(singlebandCogPath.toASCIIString)
143+
144+
val resourceCols = 963 // from gdalinfo
145+
val resourceRows = 754
146+
val resourceExtent = Extent(752325.0, 3872685.0, 781215.0, 3895305.0)
137147

138148
df.count() should be > 0L
139149

140150
val crs = df.select(rf_crs(col("proj_raster"))).first()
141151

152+
val totalExtentRow = df.select(rf_extent($"proj_raster").alias("ext"))
153+
.agg(
154+
min($"ext.xmin").alias("xmin"),
155+
min($"ext.ymin").alias("ymin"),
156+
max($"ext.xmax").alias("xmax"),
157+
max($"ext.ymax").alias("ymax")
158+
).first()
159+
val dfExtent = Extent(totalExtentRow.getDouble(0), totalExtentRow.getDouble(1), totalExtentRow.getDouble(2), totalExtentRow.getDouble(3))
160+
logger.info(s"Dataframe extent: ${dfExtent.toString()}")
161+
162+
dfExtent shouldBe (resourceExtent)
163+
142164
noException shouldBe thrownBy {
143165
df.write.geotiff.withCRS(crs).save("target/unstructured_cog.tif")
144166
}
@@ -150,57 +172,16 @@ class GeoTiffDataSourceSpec
150172
}
151173
inCols should be (963)
152174
inRows should be (754) //from gdalinfo
153-
inExtent should be (Extent(752325.0, 3872685.0, 781215.0, 3895305.0))
175+
inExtent should be (resourceExtent)
154176

155177
val outputTif = SinglebandGeoTiff("target/unstructured_cog.tif")
156178
outputTif.imageData.cols should be (inCols)
157179
outputTif.imageData.rows should be (inRows)
158-
outputTif.extent should be (inExtent)
180+
outputTif.extent should be (resourceExtent)
159181
outputTif.cellType should be (inCellType)
160182

161183
}
162184

163-
/*
164-
it("should round trip jasons favorite unstructured raster round trip okay") {
165-
import org.locationtech.rasterframes.datasource.raster._
166-
import spark.implicits._
167-
168-
val jasonsRasterPath = "https://modis-pds.s3.amazonaws.com/MCD43A4.006/17/03/2019193/" +
169-
"MCD43A4.A2019193.h17v03.006.2019202033615_B06.TIF"
170-
val df = spark.read.raster
171-
.withTileDimensions(233, 133)
172-
.from(Seq(jasonsRasterPath))
173-
.load()
174-
175-
logger.debug("Read local file metadata")
176-
val (inCols, inRows) = {
177-
val in = readSingleband("MCD43A4.A2019193.h17v03.006.2019202033615_B06.TIF")
178-
(in.cols, in.rows)
179-
}
180-
inCols should be (2400) // from GDAL
181-
inRows should be (2400) // from GDAL
182-
183-
val outPath = "datasources/target/rf_mcd43a4.A2019193.h17v03.tif"
184-
185-
// now take actions on the read df
186-
logger.debug("Actions on raster ref dataframe")
187-
df.count() should be > 100L
188-
val crs = df.select(rf_crs($"proj_raster")).first()
189-
logger.debug("Write full res geotiff from dataframe")
190-
df.write.geotiff.withCRS(crs).save(outPath)
191-
192-
// compare written file to path
193-
logger.debug("Inspect written geotiff metadata")
194-
val (outCols, outRows) = {
195-
val outputTif = SinglebandGeoTiff(outPath)
196-
(outputTif.cols, outputTif.rows)
197-
}
198-
outCols should be (inCols)
199-
outRows should be (inRows)
200-
// todo check extent and crs just for grins.
201-
202-
}*/
203-
204185
it("should write GeoTIFF without layer") {
205186
import org.locationtech.rasterframes.datasource.raster._
206187
val pr = col("proj_raster_b0")

datasource/src/test/scala/org/locationtech/rasterframes/datasource/raster/RasterSourceDataSourceSpec.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,41 @@ class RasterSourceDataSourceSpec extends TestEnvironment with TestData {
245245

246246
}
247247
}
248+
249+
describe("RasterSource breaks up scenes into tiles") {
250+
val modis_df = spark.read.raster
251+
.withTileDimensions(128, 128)
252+
.withLazyTiles(true)
253+
.load(remoteMODIS.toASCIIString())
254+
255+
val l8_df = spark.read.raster
256+
.withTileDimensions(32, 33)
257+
.withLazyTiles(true)
258+
.load(remoteL8.toASCIIString())
259+
260+
ignore("should have at most four tile dimensions reading MODIS; ignore until fix #242") {
261+
val dims = modis_df.select(rf_dimensions($"proj_raster")).distinct().collect()
262+
dims.length should be > (0)
263+
dims.length should be <= (4)
264+
}
265+
266+
it("should have at most four tile dimensions reading landsat") {
267+
val dims = l8_df.select(rf_dimensions($"proj_raster")).distinct().collect()
268+
dims.length should be > (0)
269+
dims.length should be <= (4)
270+
}
271+
272+
ignore("should have consistent tile resolution reading MODIS; ignore until fix #242") {
273+
val res = modis_df.select((rf_extent($"proj_raster").getField("xmax") - rf_extent($"proj_raster").getField("xmin")) /
274+
rf_dimensions($"proj_raster").getField("cols")).distinct().collect()
275+
res.length should be (1)
276+
}
277+
278+
it("should have consistent tile resolution reading Landsat") {
279+
val res = l8_df.select((rf_extent($"proj_raster").getField("xmax") - rf_extent($"proj_raster").getField("xmin")) /
280+
rf_dimensions($"proj_raster").getField("cols")).distinct().collect()
281+
res.length should be (1)
282+
}
283+
284+
}
248285
}

0 commit comments

Comments
 (0)