Repository navigation
Add additional overloads to GeoTiffReader + Enhance GeoTiffInfo serialization #3126
Description
I think it would be helpful as a GT consumer to add overloads and make a few other adjustments to make it easier to cache/store geotiff metadata so that subsequent reads from a geotiff (especially in a server environment) do not require reading geotiff metadata. The reading of geotiff metadata (essentially creating GeoTiffInfo) is in my timings the slowest part of lazily reading tiles from a GeoTiff - that might warrant its own issue for speeding up or improving its laziness.
I think the first set of changes would involved adding a new overload to GeoTiffReader that returns a GeoTiff based on just the information provided:
def readMultiband(providedInfo: GeoTiffInfo): MultibandGeoTiff = {
def getMultiband(geoTiffTile: GeoTiffMultibandTile,
info: GeoTiffInfo): MultibandGeoTiff = {
new MultibandGeoTiff(
geoTiffTile,
info.extent,
info.crs,
info.tags,
info.options,
info.overviews.map { i =>
getMultiband(geoTiffMultibandTile(i), i)
}
)
}
val geoTiffTile = geoTiffMultibandTile(providedInfo)
getMultiband(geoTiffTile, providedInfo)
}I think there's probably a second set of changes to make caching and storing GeoTiffInfo easier for end users easier. The way it is now, I don't think it's possible to create a serializable version of GeoTiffInfo because both SegmentBytes and Decompressor require a SegmentReader in GeoTiffInfo which needs to be provided outside of just the information. At a minimum I think adding unapply methods to those classes would help a lot in being able to extract TiffTags from GeoTiffInfo when storing the necessary metadata to recreate GeoTiffInfo.
A potential alternative (and larger set of changes) would be to split the info from the segment readers so that GeoTrellis provides a more easily serializable GeoTiffInfo for library users. As it stands right now I end up storing that information in a class that is essentially GeoTiffInfo-lite with methods to go to/from GeoTiffInfo:
@JsonCodec
case class BacksplashGeoTiffInfo(extent: Extent,
crs: CRS,
tags: Tags,
tiffTags: TiffTags,
options: GeoTiffOptions,
bandType: BandType,
segmentLayout: GeoTiffSegmentLayout,
compression: Compression,
bandCount: Int,
noDataValue: Option[Double],
overviews: List[BacksplashGeoTiffInfo] = Nil,
allTags: List[TiffTags] = Nil) {
def toGeotiffInfo(segmentReader: StreamingByteReader): GeoTiffInfo = {
???
}
}
object BacksplashGeoTiffInfo {
def fromGeotiffInfo(info: GeoTiffInfo,
tiffTags: List[TiffTags]): BacksplashGeoTiffInfo = {
// tiff tags are necessary because we need them for the list of overviews
???
}
}Lastly, I'm not sure if it is desirable, but most parts of the metadata are already case classes so providing circe encoders + decoders would be nice, but also not strictly necessary. There are a few parts that require custom codecs so having those in the library would be preferable in my opinion, but also I understand that could be a bit of a heavy dependency depending on what submodule the codecs end up in.
Activity
pomadchin commentedon Dec 2, 2019
Related to #3128
pomadchin commentedon Dec 2, 2019
I'm wondering can it be considered as closed?