Visitar URL original
LayoutTileSource.requireGridAligned is failing with GDALRasterSource · Issue #3292 · locationtech/geotrellis · GitHub
Skip to content

LayoutTileSource.requireGridAligned is failing with GDALRasterSource #3292

Open

Description

@jdenisgiguere

Describe the bug

When I try to create a RasterSourceRDD from the GeoTIFF provided below with the GDALRasterSource driver, this requirement is not respected and this causes an Executor error .

To Reproduce

See the following code: https://gist.github.com/jdenisgiguere/9256cec690c335f6a993866b71a99878

a sample image is available here:
https://drive.google.com/file/d/18e6LtenDaHFVkU_D65oZrkmNaCv0SECC/view?usp=sharing

  • Actual output

The error message looks like:

0/09/09 15:45:24 ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1)
java.lang.IllegalArgumentException: requirement failed: x-aligned: offset by CellSize(0.3,0.3) 0.22367999985969317
	at scala.Predef$.require(Predef.scala:281)
	at geotrellis.layer.LayoutTileSource$.geotrellis$layer$LayoutTileSource$$requireGridAligned(LayoutTileSource.scala:216)

More log at:
https://gist.github.com/jdenisgiguere/9256cec690c335f6a993866b71a99878#file-log

  • Expected output

I would expect to be able to create a RasterSourceRDD with GDALRasterSource as I can with GeotiffRasterSource.

Expected behavior

I would expect to be able to create a RasterSourceRDD with GDALRasterSource as I can with GeotiffRasterSource.

Environment

  • Java version: OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~18.04-b01)
  • Scala version: 2.12.10
  • GeoTrellis version: 3.5.0

Activity

  1. zacdezgeo commented on May 13, 2021

    @zacdezgeo
    Contributor

    Hi @pomadchin,

    I have been encountering this error inconsistently depending on the input image as well. I was able to find the definition of the requireGridAligned method. There is a TODO comment that confused me a bit. It says that the following code is ignored at the moment, but it is not. Should the comment read it is not ignored at the moment? There is also a mention of making the require condition softer.

    LayoutTileSourceScala

    /**
          * TODO: This is ignored at the moment to make it soft and to make GDAL work,
          * we need to reconsider these things to be softer (?)
          */
    
        require(a.extent.xmin === resultX +- epsX,
          s"x-aligned: offset by ${a.cellSize} ${offset(a.extent.xmin, resultX, a.cellwidth)}")
    
        require(a.extent.ymin === resultY +- epsY,
          s"y-aligned: offset by ${a.cellSize} ${offset(a.extent.ymin, resultY, a.cellheight)}")

    Are there any related issues around the topic and decision of the condition given? On my end, I am capable of reading the images with GDAL without using geotrellis even when the require condition does not pass within Geotrellis. I would expect to be able to ingest the geotiff with Geotrellis if GDAL is capable.

    A little background on the use case. I am ingesting geotiff and creating Tiles for different zoom levels. I am trying to define potential workarounds. Some options I have considered but am not completely sure that they would actually change anything:

    • Redefine the layout scheme used to indirectly meet the requireGridAligned condition
    • Pass an overview strategy different from the generic default one to the RasterSourceRDD
    • Modify the requireGridAligned method.

    I will be working on sorting out the data of images that meet the requireGridAligned from those that do not.

    Here is a snippet of the code for slicing an image into Tiles:

    def run(layerName: String)(implicit sc: SparkContext): (Int, Int) = {
    
        // TODO In a future version, base Zoom level should be computed based on pixel size.
        // This is not required to go in production
        val baseZoomLevel: Int = 21
        val path = s"s3://${Configurations.S3.bucket}/$geoimageryFileName"
        val source: GDALRasterSource = GDALRasterSource(path)
    
        // validation happens regardless
        validateCrs(source, path)
    
        val floatingLayoutScheme: FloatingLayoutScheme = FloatingLayoutScheme(
          Configurations.Geotrellis.tileWidth
        )
        val numberOfBands: Int = source.bandCount
        val layout: LayoutDefinition =
          floatingLayoutScheme.levelFor(source.extent, source.cellSize).layout
    
        val rasterSourceRDD = RasterSourceRDD.spatial(source, layout)
    
        val s3AttributeStore: S3AttributeStore = utils.ConfiguredS3AttributeStore.originalTileset()
        val s3LayerWriter = new S3LayerWriter(
          s3AttributeStore,
          Configurations.S3.bucket,
          Configurations.Geotrellis.originalTilesetCatalog
        )
        val layerId = LayerId(layerName, baseZoomLevel)
        s3LayerWriter.write(layerId, rasterSourceRDD, ZCurveKeyIndexMethod) // TODO: call to requireGridAligned happens here
        (numberOfBands, baseZoomLevel)
      }
    

    Would love to get your insights on a potential resolution!

  2. pomadchin commented on May 13, 2021

    @pomadchin
    Member

    Hey @zacharyDez, that is a comment that reminds us (me in particular) that there are some differences in math between GeoTiffRasterSource and GDALRasterSource operations (reprojection and resample).

    The issue here is a bit wider than it is written in a comment. Just relaxing this required condition may make the code pass but it still may fail somewhere else.

    Just to clarify: to write a layer you'd need to tileToLayout (which is resampleToGrid) an RDD of RasterSources. That's where this issue happens.

    I don't have any insights on a potential solution, this can be not a trivial issue.

  3. jdenisgiguere commented on May 13, 2021

    @jdenisgiguere
    Author

    @pomadchin, we are creating a specific Layout for a given GDALRasterSource.

    I'm a bit surprised that the resampleToGrid returns too big offset as they should be perfectly aligned. Shouldn't be a GeoTiffRasterSource GDALRasterSource be perfectly aligned with a Layout that is based on it?

  4. pomadchin commented on May 13, 2021

    @pomadchin
    Member

    @jdenisgiguere GeoTiffRasterSource should work fine, or what is your question?

  5. pomadchin commented on May 13, 2021

    @pomadchin
    Member

    @jdenisgiguere I'm sorry, I don't have any guessses right now, it should be but there are definitely some differences with how the GeoTiffRasterSource behaves. That can be related to some heuristics that are used by GDAL, to math differences or to some a bit incorrect parameters passed into the underlying GDALWarp.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions