locationtech / geotrellis

GeoTrellis is a geographic data processing engine for high performance applications.
http://geotrellis.io
Other
1.32k stars 360 forks source link

Fix numerical errors #3520

Closed jdries closed 9 months ago

jdries commented 10 months ago

Overview

When working in epsg:4326 coordinates, I recently observed separate bugs caused by the same problem. Basically transformations between geographical coordinates and grid coordinates where wrong due to floating point imprecision. In both cases, grid coordinates were calculated as doubles and resulted in e.g. 4.9999999 but were done floored (toLong) resulting in 4.

This resulted in an actual pixel shift in one case, and in another case a missing row of pixels at the bottom of a saved geotiff.

Checklist

Notes

Optional. Ancillary topics, caveats, alternative strategies that didn't work out, anything else.

Closes #XXX

jdries commented 10 months ago

Found a simple test that exposes the issue. It's all about gridextents that are in fact aligned, but due to very small numerical differences, things go wrong. Still have to figure out where and how to integrate this as part of geotrellis unit tests.

   val targetBounds = GridBounds(55L,103,55+73,103+111)
    val ge = GridExtent[Long](Extent(1.8973214288275528, 49.352678585684544, 6.299107143119465, 51.7276785856839), CellSize(0.008928571428584,0.008928571428568996))
    val targetExtent = ge.extentFor(targetBounds)

    //second, aligned extent based on a LayoutDefinition
    val ge2 = GridExtent[Long](Extent(2.3883928573996727, 49.66517858568254, 3.5312500002584244, 50.80803572854129), CellSize(0.008928571428583998,0.008928571428583998))

    //gridextents have to be aligned for test to be valid
    //basically copy of geotrellis.layer.LayoutTileSource#requireGridAligned
    requireGridAligned(ge,ge2)
    val resultingBounds = ge2.gridBoundsFor(targetExtent)

    assertEquals(targetBounds.height,resultingBounds.height)
    assertEquals(targetBounds.width,resultingBounds.width)
pomadchin commented 10 months ago

@jdries a nice find! Could you add this unit test?