Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Get affine transformation from GeoTIFF #8

Merged
merged 4 commits into from
Mar 13, 2024
Merged

Conversation

weiji14
Copy link
Owner

@weiji14 weiji14 commented Mar 10, 2024

Implement transform method in CogReader struct to get affine transformation matrix from GeoTIFF via ModelPixelScaleTag and ModelTiepointTag.

Uses the AffineTransform struct from the geo crate. Note that the fields in the struct (a, b, xoff, c, d, yoff) are not made public, but it might be useful if it was!

TODO:

  • Initial implementation with basic unit test
  • Document transform method more
  • Raise proper errors when tags cannot be parsed (InvalidTag isn't too descriptive, but good enough 🤞)

TODO in the future:

References:

Geospatial primitives and algorithms!
Implement transform method in CogReader struct to get affine transformation matrix from GeoTIFF via ModelPixelScaleTag and ModelTiepointTag. Added a unit test to check that the x/y pixel size and top left origin pixel coordinates is correct.
@weiji14 weiji14 added the feature New feature or request label Mar 10, 2024
@weiji14 weiji14 added this to the 0.1.0 milestone Mar 10, 2024
@weiji14 weiji14 self-assigned this Mar 10, 2024
Explicitly mentioning the internal fields of the AffineTransform struct, specifically the pixel resolution, rotation and origin, and included a reference to the GeoTIFF standard. Also renamed origin_x/origin_y to x_origin/y_origin.
Supposed to be parsed from the ModelTransformationTag, but haven't found a sample GeoTIFF online with non-zero rotation to implement this properly with a unit test, so marking as unimplemented for now.
@weiji14 weiji14 marked this pull request as ready for review March 13, 2024 04:31
Comment on lines +44 to +51
/// - <https://docs.ogc.org/is/19-008r4/19-008r4.html#_coordinate_transformations>
fn transform(&mut self) -> TiffResult<AffineTransform<f64>> {
// Get x and y axis rotation (not yet implemented)
let (x_rotation, y_rotation): (f64, f64) =
match self.decoder.get_tag_f64_vec(Tag::ModelTransformationTag) {
Ok(_model_transformation) => unimplemented!("Non-zero rotation is not handled yet"),
Err(_) => (0.0, 0.0),
};
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to future self (or someone else), find a GeoTIFF with non-zero rotation values and implement this properly.

Comment on lines +53 to +63
// Get pixel size in x and y direction
let pixel_scale: Vec<f64> = self.decoder.get_tag_f64_vec(Tag::ModelPixelScaleTag)?;
let [x_scale, y_scale, _z_scale] = pixel_scale[0..3] else {
return Err(TiffError::FormatError(TiffFormatError::InvalidTag));
};

// Get x and y coordinates of upper left pixel
let tie_points: Vec<f64> = self.decoder.get_tag_f64_vec(Tag::ModelTiepointTag)?;
let [_i, _j, _k, x_origin, y_origin, _z_origin] = tie_points[0..6] else {
return Err(TiffError::FormatError(TiffFormatError::InvalidTag));
};
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried a few different ways to convert the Vec to an array (e.g. following https://stackoverflow.com/questions/29570607/is-there-a-good-way-to-convert-a-vect-to-an-array), but couldn't quite get it to work, and the code was very messy. The code here works, but might silently handle cases where pixel_scale.len() > 3 or tie_points.len() > 6 incorrectly, rather than raising an error, so should come back and refactor this sometime.

@weiji14 weiji14 merged commit 1b8fac8 into main Mar 13, 2024
13 checks passed
@weiji14 weiji14 deleted the affine_transform branch March 13, 2024 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant