Round-trip transform, crs, and tag metadata through to_geotiff/open_geotiff#1494
Merged
brendancol merged 1 commit intomainfrom May 5, 2026
Merged
Round-trip transform, crs, and tag metadata through to_geotiff/open_geotiff#1494brendancol merged 1 commit intomainfrom
brendancol merged 1 commit intomainfrom
Conversation
…eotiff (#1484) Findings M-1 through M-4 from the geotiff metadata audit. - attrs['transform'] (rasterio 6-tuple) now lands on every read path so to_geotiff can rebuild the source GeoTransform without going through _coords_to_transform. That route can drift on fractional pixel sizes because x[1] - x[0] is recomputed in float64 from already-rounded coords. Coord-derived transform stays as the fallback when the attr is absent. - Document the int-EPSG convention for attrs['crs'] in open_geotiff and read_vrt; keep tolerating WKT strings on the write side. - Drop ColorMap (320) from _MANAGED_TAGS so the tag rides extra_tags and round-trips without a dedicated writer path. Surface the raw uint16 ColorMap value as attrs['colormap']. - Surface ImageDescription (270) as attrs['image_description'] and ExtraSamples (338) as attrs['extra_samples']. to_geotiff folds user-edited values back into extra_tags before write, with verbatim entries winning to keep round-trips byte-stable. - Document the int-with-nodata -> float64 promotion in open_geotiff's docstring along with the dtype= override. Tests added in test_metadata_round_trip_1484.py cover transform double round-trip on a fractional transform, ColorMap on a uint8 indexed raster, ImageDescription read and write, ExtraSamples surface, and the uint16 nodata promotion plus the dtype='uint16' ValueError. Mirrors the polish from #1462 (reproject) and #1472 (resample). Closes #1484
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1484. Findings M-1 through M-4 from the geotiff metadata audit, mirroring the polish from #1462 (reproject) and #1472 (resample).
Summary
attrs['transform'](rasterio 6-tuple(pixel_width, 0, origin_x, 0, pixel_height, origin_y)) is now stored on every read path.to_geotiffprefers it over_coords_to_transform, which can drift on fractional pixel sizes becausex[1] - x[0]is recomputed from already-rounded coord arrays. Coord-derived transform stays as the fallback when the attr is absent.attrs['crs']is now documented inopen_geotiffandread_vrt. WKT strings are still tolerated on the write side for backward compatibility.ColorMap(tag 320) drops out of_MANAGED_TAGSso it ridesextra_tagsand round-trips without dedicated writer plumbing. The raw uint16 value lands onattrs['colormap'].ImageDescription(tag 270) andExtraSamples(tag 338) get friendlyattrs['image_description']/attrs['extra_samples']entries.to_geotifffolds user-edited values back intoextra_tagsbefore write, with any verbatim entries winning so byte-stable round-trips stay byte-stable.open_geotiffdocstring along with thedtype=...override.Test plan
pytest xrspatial/geotiff/tests/test_metadata_round_trip_1484.py(10 new tests, all pass)pytest xrspatial/geotiff/tests/(483 passed, 4 skipped, 3 deselected; the 3 deselectedTestPalette::test_xrs_plot_*tests were already failing onmainwith a matplotlib deepcopy recursion unrelated to this PR)pytest xrspatial/tests/test_resample.py xrspatial/tests/test_reproject.py(362 passed) -- confirms the newattrs['transform']does not break callers that compare result attrsNotes
existing_idsguard in the writer'sextra_tagsloop already deduplicates so the friendly attr round-trip stays consistent.extra_tagspass-through. Adding a writer-managed ColorMap path with full validation would be a heavier lift; that's out of scope here.