Skip to content

Commit af360c8

Browse files
vpipktmetasim
authored andcommitted
GeoTiff spec more info logged (+1 squashed commit)
Squashed commits: [d104949] spark.write.geotiff correct full res output for heterogenous tile size Signed-off-by: Simeon H.K. Fitch <[email protected]>
1 parent d05d6c6 commit af360c8

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

datasource/src/main/scala/astraea/spark/rasterframes/datasource/geotiff/DefaultSource.scala

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import astraea.spark.rasterframes.datasource._
2525
import astraea.spark.rasterframes.util._
2626
import com.typesafe.scalalogging.LazyLogging
2727
import org.apache.spark.sql.sources.{BaseRelation, CreatableRelationProvider, DataSourceRegister, RelationProvider}
28-
import org.apache.spark.sql.{DataFrame, SQLContext, SaveMode}
28+
import org.apache.spark.sql.types.LongType
29+
import org.apache.spark.sql.{DataFrame, SQLContext, SaveMode, functions F}
2930

3031
/**
3132
* Spark SQL data source over GeoTIFF files.
@@ -50,22 +51,44 @@ class DefaultSource extends DataSourceRegister with RelationProvider with Creata
5051
require(pathO.get.getScheme == "file" || pathO.get.getScheme == null, "Currently only 'file://' destinations are supported")
5152
sqlContext.withRasterFrames
5253

53-
5454
require(data.isRF, "GeoTIFF can only be constructed from a RasterFrame")
5555
val rf = data.certify
5656

57-
val tl = rf.tileLayerMetadata.merge.layout.tileLayout
57+
// If no desired image size is given, write at full size.
58+
lazy val (fullResCols, fullResRows) = {
59+
// get the layout size given that the tiles may be heterogenously sized
60+
// first get any valid row and column in the spatial key structure
61+
val sk = rf.select(SPATIAL_KEY_COLUMN).first()
62+
63+
val tc = rf.tileColumns.head
64+
65+
val c = rf
66+
.where(SPATIAL_KEY_COLUMN("row") === sk.row)
67+
.agg(
68+
F.sum(tileDimensions(tc)("cols") cast(LongType))
69+
).first()
70+
.getLong(0)
71+
72+
val r = rf
73+
.where(SPATIAL_KEY_COLUMN("col") === sk.col)
74+
.agg(
75+
F.sum(tileDimensions(tc)("rows") cast(LongType))
76+
).first()
77+
.getLong(0)
78+
79+
(c, r)
80+
}
5881

59-
val cols = numParam(DefaultSource.IMAGE_WIDTH_PARAM, parameters).getOrElse(tl.totalCols)
60-
val rows = numParam(DefaultSource.IMAGE_HEIGHT_PARAM, parameters).getOrElse(tl.totalRows)
82+
val cols = numParam(DefaultSource.IMAGE_WIDTH_PARAM, parameters).getOrElse(fullResCols)
83+
val rows = numParam(DefaultSource.IMAGE_HEIGHT_PARAM, parameters).getOrElse(fullResRows)
6184

6285
require(cols <= Int.MaxValue && rows <= Int.MaxValue, s"Can't construct a GeoTIFF of size $cols x $rows. (Too big!)")
6386

6487
// Should we really play traffic cop here?
6588
if(cols.toDouble * rows * 64.0 > Runtime.getRuntime.totalMemory() * 0.5)
6689
logger.warn(s"You've asked for the construction of a very large image ($cols x $rows), destined for ${pathO.get}. Out of memory error likely.")
6790

68-
println()
91+
logger.debug(s"Writing DataFrame to GeoTIFF ($cols by $rows) at ${pathO.get}")
6992
val raster = rf.toMultibandRaster(rf.tileColumns, cols.toInt, rows.toInt)
7093

7194
GeoTiff(raster).write(pathO.get.getPath)

datasource/src/test/scala/astraea/spark/rasterframes/datasource/geotiff/GeoTiffDataSourceSpec.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,28 @@ class GeoTiffDataSourceSpec
108108
.geotiff
109109
.loadRF(cogPath)
110110

111+
logger.info(s"Read extent: ${rf.tileLayerMetadata.merge.extent}")
112+
113+
val cellsize = rf.groupBy(
114+
tileDimensions(col("tile_1"))("rows") as "tileRows",
115+
tileDimensions(col("tile_1"))("cols") as "tileCols"
116+
).count()
117+
118+
cellsize.show(false)
119+
120+
rf.withBounds().select(
121+
tileDimensions(col("tile_1"))("rows") as "tileRows",
122+
tileDimensions(col("tile_1"))("cols") as "tileCols",
123+
BOUNDS_COLUMN)
124+
.show(false)
125+
111126
val out = Paths.get(outputLocalPath, "example-geotiff.tiff")
127+
logger.info(s"Writing to $out")
112128
//val out = Paths.get("target", "example-geotiff.tiff")
113129
noException shouldBe thrownBy {
114130
rf.write.geotiff.save(out.toString)
115131
}
132+
logger.info("Done!")
116133
}
117134
}
118135
}

0 commit comments

Comments
 (0)