-
Notifications
You must be signed in to change notification settings - Fork 94
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
Fix SwathDefinition get_bbox_lonlats returning counter-clockwise coordinates #389
Conversation
Codecov Report
@@ Coverage Diff @@
## main #389 +/- ##
=======================================
Coverage 93.80% 93.80%
=======================================
Files 65 65
Lines 11038 11061 +23
=======================================
+ Hits 10354 10376 +22
- Misses 684 685 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
I've also added a small patch to the DynamicAreaDefinition. I discovered that dask |
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.
Thanks for looking into this! I believe this could be made a bit more generic.
pyresample/geometry.py
Outdated
# compare the first two pixels in the right column | ||
lat_is_increasing = lats[1][0] < lats[1][1] | ||
# compare the first two pixels in the "top" column | ||
lon_is_increasing = lons[0][0] < lons[0][1] | ||
is_ccw = (lon_is_increasing and lat_is_increasing) or (not lon_is_increasing and not lat_is_increasing) |
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 can see two issues with this approach:
- This assumes two things: a. the top and right edges of the swath are perpendicular, and b. the swath is never aligned with the equator. For b., it would indeed be a very strange orbit, so I think we can live with this assumption (although it should be mentioned at least in the code), while a. could be a bit problematic with sensors that are not our usual imagers. An alternative test could be to check that the oriented angle around the top-right corner of the swath is not reflex.
- pole or antimeridian situations. A solution could be to convert the three points to cartesian and use the angle check described above.
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.
Oh good point on the poles. So I could do the math on the first corner to get the angle between the two vectors in 3D space, but won't that always give the smallest angle between them? It's been a while since I've done this type of math (and I have a cold) but looking at https://www.omnicalculator.com/math/angle-between-two-vectors, how do I know if it is clockwise or counter-clockwise in 3D space?
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.
because you are on the surface of a spheroid, you can give it an orientation...
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.e. the normal of the angle has to point away from the centre of the earth
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.
maybe this can help? https://math.stackexchange.com/a/1715844
pyresample/geometry.py
Outdated
This is important for compatibility with | ||
:class:`pyresample.spherical.AreaBoundary`. This is required in | ||
cases where data is not oriented in the traditional way where | ||
the first element of data (row 0, col 0) is the north-west |
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.
An ascending pass and descending pass of a well behaved sensor (clockwise edges) have opposite first element orientations: north-west and south-east (not necessarily respectively, depending on how you look at it).
So I don't think north-west should be mentioned here, since the flip of lons and lats doesn't actually change the position of the first corner of the swath, right?
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 if I mentioned north-west and south-east?
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 think north-east and south-west cases can also happen (I'm thinking with Sentinel1 where I've seen this happen)
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.
So you're saying that Sentinel1 data has either north-east or south-west as its first corner and the path followed by the existing logic still produces a clockwise series of coordinates? I suppose anything's possible. I'll see if I can remove the mention of north-west and be clearer about what I'm saying.
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.
yes exactly. The sentinel 1 data we use comes flipped horizontally or vertically depending whether the pass is ascending or descending...
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.
Good work, just some minor notes
@@ -1050,8 +1078,10 @@ def _compute_bound_centers_dask(self, proj_dict, lons, lats): | |||
y_is_pole = (ymax >= 90 - epsilon) or (ymin <= -90 + epsilon) | |||
if crs.is_geographic and x_passes_antimeridian and not y_is_pole: |
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.
If the crs is geographic, I would rather go to cartesian coordinates to do the computations here... but maybe this should be another PR?
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.
Yes probably another PR. However, I'm not sure why cartesian coordinates would work better for this math. It is meant to be a simple workaround so my hope was that it wouldn't get too complicated. But if you see something then of course we could do it.
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.
it's just that I don't like the thresholding needed around poles and antimeridian...
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.
LGTM
This is a continuation of #385. That PR originally started as a "my data isn't clockwise so things are incorrect". I then found out that the fake data I was using was actually incorrect and didn't match the real world data I was trying to work with. So switching to 64-bit floats fixed that issue.
Now I'm working with other real world data (MiRS algorithm output) where the lon/lat arrays have their first element (row 0, column 0) in the south-west corner which results in the
get_bbox_lonlats
producing coordinates in a counter-clockwise path. This PR fixes this issue in a very similar way as my original fix #385 except for a few important points:create_test_longitude
was actually not allowed. That is, requesting longitudes in decreasing order resulted in the function thinking we were crossing the anti-meridian. This is now fixed in this PR.I also discovered that
get_edge_lonlats
was depending on the non-clockwise path of the data or at least a test it had was checking for that. So I added theforce_clockwise
keyword argument and set it to False forget_edge_lonlats
as this makes sure the lonlats follow the data rather than provide a clockwise bbox.git diff origin/main **/*py | flake8 --diff