-
Notifications
You must be signed in to change notification settings - Fork 124
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
Major bug? get_land_geometry and tc_tracks.track_land_params #495
Comments
As an add-on, I think generally the function |
@bguillod : if you have worked on this, it would be great if you could share the proposal in the form of a pull request. |
Since I'm working on improvements to the TC random walk model I will make sure to include a fix within the same PR. Fine for you @chahank? |
Yes, thank you very much! In case you modify the helper methods in the |
Sounds good, if I see changes to |
Hi @tovogt, On this one I think you might know a very simple way to solve it. I recall in some discussion previously with a similar problem in a different context you mentioned you can shift the longitude range in shapely object or so. Would that be applicable here? For a more concrete example: if I load all IBTraCS data from 1980 to 220 I get the following extent:
Would it be possible to do something like:
and then split land_geom, shift longitude and re-merge so I then get That would be much more efficient than what I'm trying to implement right now: in
What do you think? This could be implemented directly into Although, thinking about it twice: the extent of tracks does not mean that all track points are within that extent, so my adjustment would still likely be needed. Unless we also adjust What do you think? If you don't have time or opinion just let me know and I'll see how I go about it. |
Look at this for instance, both points within Fiji, one on each side of the anti-meridian:
output:
We can blame shapely for not handling spherical coordinates, but that library is very clear about this. I think we need to find a way to ensure these kind of things don't cause mistakes in climada's calculations, because currently they likely do, and this at many places in the code. Best would probably to handle this robustly in all u_coord functions with checks on extents compatibility and corrections in case they don't match. |
Thanks, this is indeed a serious bug that is quite easy to solve. The solution is to store the land geometries in a GeoDataFrame and then rewrap the longitudes according to the central longitude as extracted from the given extent. I would suggest to rewrite the current implementation of df = gpd.read_file(shp_file)
if country_names is not None:
country_mask = np.isin(df[['ISO_A3', 'WB_A3', 'ADM0_A3']].values, country_names).any(axis=1)
df = df[country_mask]
if extent is not None:
lon_mid = 0.5 * (extent[0] + extent[1])
# we don't really change the CRS when rewrapping, so we reset the CRS attribute afterwards
df = df.to_crs({"proj": "longlat", "lon_wrap": lon_mid}).set_crs(DEF_CRS, allow_override=True)
bbox = Polygon([
(extent[0], extent[2]),
(extent[0], extent[3]),
(extent[1], extent[3]),
(extent[1], extent[2])
])
bbox = gpd.GeoSeries(bbox, crs=DEF_CRS)
bbox = gpd.GeoDataFrame({'geometry': bbox}, crs=DEF_CRS)
df = gpd.overlay(df, bbox, how="intersection")
return df.geometry.unary_union I wrote the code from scratch without testing, so please check it thoroughly. Please also consider applying the same fix to the function |
Thanks @tovogt. I'll give it a try. However, since the Of course solving the issue in |
The individual tracks are not within the bounds, but all track points are within the bounds. The only thing that might go wrong is that a track segment between two subsequent track points might not lie completely within the bounds. But I don't think that this is relevant for the |
I'm not sure I agree. In climada_python/climada/hazard/tc_tracks.py Lines 546 to 556 in 8a7e369
Doesn't that imply that any track not crossing the anti-meridian is within [-180,+180] but tracks crossing it are more like within BTW, currently in I'm not sure in which use case one would have to retain only certain countries AND crop them to an extent, but making that clear would be cleaner. |
I think we are talking about different things: I say that all track points actually lie, geographically, within the extent returned by
That's true and I don't think that it is intended. It should work the same as in
That's a different question. You basically say that if a user provides both the |
Excellent, yes we do agree on everything now. Many thanks! And since |
Yes, there is a lot of redundancy in the two functions, and I would very much appreciate if you remove that. However, make sure to take the best from both implementations: |
Ok so I've made an attempt which I think works well in PR #524 . Please have a look. I've already added a small test but feel free to add some or suggests further tests. |
Yes, true. The intersection needs to be done in the [-180, 180] range, with two bounding boxes, if necessary. Then the |
Fixed in #524. |
I think I found a major bug in the assignment of TC track points to land or ocean, which occurs at least in
tc_track_synth
. This seems to be related to how the land geom is retrieved from the track extents. However I am afraid this might have implications elsewhere, too.In essence, in
climada.hazard.tc_tracks_synth
, land_geom is retrieved using:However, if I read global data as follows
Then I get the following value for
extent
:(31.4, 373.6, -44.800000762939455, 70.79999694824218)
, and the following for land_geom:Hence the extent of the land geometry that is being loaded only covers longitude from 31.4 to 180 degrees East. Looks like the underlying function
get_land_geometry
does not handle spherical coordinates.The implication is that any track westward of 31.4 degrees East will be said not to be over land. The issue probably won't show up if I had loaded data only for the, e.g. North Atlantic basin, because then the extent would probably be within the [-180, +180] longitude range.
This is a major issue and it might apply to many other code instances than just for the TC synthetic tracks generation. My questions are then:
get_land_geometry
to properly account for spherical coordinates? That would be the easiest way to fix. If not, then at least the function should raise an error if longitude values are outside of [-180, +180] (and since we're at it let's also make sure latitude never goes outside of [-90,90], although this case is very unlikely).The text was updated successfully, but these errors were encountered: