Skip to content

Add additional overloads to GeoTiffReader + Enhance GeoTiffInfo serialization #3126

Open

Description

@notthatbreezy

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

  1. pomadchin commented on Dec 2, 2019

    @pomadchin
    Member

    Related to #3128

  2. pomadchin commented on Dec 2, 2019

    @pomadchin
    Member

    I'm wondering can it be considered as closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions