-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
GeoHEIF: Fixed respecting CRS axis order (e.g., for EPSG:4326) #11384
base: master
Are you sure you want to change the base?
Conversation
@@ -857,6 +865,10 @@ CPLErr GDALHEIFDataset::GetGeoTransform(double *padfTransform) | |||
/************************************************************************/ | |||
const OGRSpatialReference *GDALHEIFDataset::GetSpatialRef() const | |||
{ | |||
// REVIEW: This function being declared this-const should mean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand that comment. "const" means that it does not change the observable state of the object (that is the GDALHEIFDataset instance). What observable side effects does GetSpatialRef() cause ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how the "observable state of the object" is defined in C++ and whether this "set things up the first time" is an OK practice (assuming it's done in a thread-safe manner).
The main issue is that this function might not be thread-safe, since if it's called for the first time by two different threads, they both might be trying to modify the geoHEIF member of the instance at the same time.
But as it turns out and was the source of the problem I chased for the last few hours, there was a very observable side-effect causing problems. Calling GDALGetGeoTransform() before and after calling GetSpatialRef() yielded a completely different result since geoHEIF.m_oSRS
was null before and non-null after.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main issue is that this function might not be thread-safe,
that's by design. No GDAL objects are thread-safe unless otherwise stated: cf https://gdal.org/en/stable/user/multithreading.html#gdal-api-re-entrant-but-generally-not-thread-safe
Calling GDALGetGeoTransform() before and after calling GetSpatialRef() yielded a completely different result since geoHEIF.m_oSRS was null before and non-null after.
That's a different thing, an implementation bug. I believe the comment in GetGeoTransform() is sufficient, and the one in GetSpatialRef() can be removed
Actually looking further at that code, I believe that GDALHEIFDataset::GetGeoTransform() should not call GDALHEIFDataset::GetSpatialRef() itself. But rather GeoHEIF::GetGeoTransform() should make sure that its m_oSRS member is properly initialized if it needs it to access it, since that's the one that needs the SRS. Perhaps the right thing to do is to set m_oSRS as mutable in the GeoHEIF class itself, and make GeoHEIF::GetGeoTransform() call GeoHEIF::GetSpatialRef()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the right thing to do is to set m_oSRS as mutable in the GeoHEIF class itself, and make GeoHEIF::GetGeoTransform() call GeoHEIF::GetSpatialRef()
yes we definitely want to do that since the GeoHEIF class is also used by the AVIF driver, and thus we don't want to do the same hack in both drivers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be simpler / preferable to automatically set up the SRS when initializing the dataset, before either of these methods can get called?
No GDAL objects are thread-safe unless otherwise stated
Even after reading this, I would have been very surprised that a method declared const behaves this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be simpler / preferable to automatically set up the SRS when initializing the dataset, before either of these methods can get called?
Actually I do see my suggestion of calling GeoHEIF::GetSpatialRef() from GeoHEIF::GetGeoTransform() woudn't work since the geoHEIF.extractSRS() must be called with the relevant metadata first. So, I'm backing away my latest suggestion. I believe you're current fix is OK. (and the AVIF driver doesn't need a fix since it has a method processProperties() that feeds all needed metadata to the GeoHEIF instance)
This would deserve a new test case in autotest/gdrivers/heif.py reading a file with EPSG:4326 cheking that: |
CC @bradh |
Co-authored-by: Martin Desruisseaux <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this PR do?
Fixes an axis-ordering bug in GeoHEIF driver, in particular for EPSG:4326 CRS.
What are related issues/pull requests?
https://gitlab.ogc.org/ogc/T20-GIMI/-/issues/59
Tasklist
Environment
N/A