Description
Describe the bug
When trying to assign centroids of hazards to exposure objects from lines, if they are in a CRS that uses meters as units, function is likely to fail. From the check it is performed in "_nearest_neighbor_antimeridian" I assume it would only work when in a "standard" CRS (e.g., epsg:4326).
To Reproduce
Steps to reproduce the behavior/error (code based on the example from the tutorial:
- Have exposure object created from lines
- Have hazard object
- Have both in a meters-based CRS (e.g., "epsg:28992")
- Try to assign centroids
Code example:
# Imports
import geopandas as gpd
import pandas as pd
from pathlib import Path
from climada.entity import Exposures
from climada.entity.impact_funcs.storm_europe import ImpfStormEurope
from climada.entity.impact_funcs import ImpactFuncSet
from climada.engine import ImpactCalc
from climada.hazard.storm_europe import StormEurope
import climada.util.lines_polys_handler as u_lp
from climada.util.constants import DEMO_DIR, WS_DEMO_NC
def gdf_lines():
gdf_lines = gpd.read_file(Path(DEMO_DIR,'nl_rails.gpkg'))
gdf_lines = gdf_lines.to_crs(epsg=4326).to_crs(epsg=28992) # Reproject to EPSG:28992 Amersfoort / RD New -- Netherlands - Holland - Dutch
return gdf_lines
# Create a GeoDataFrame with lines (railways) in the Netherlands
exp_nl_lines = Exposures(gdf_lines())
exp_nl_lines.gdf['impf_WS'] = 1
exp_nl_lines.gdf['value'] = 1
exp_nl_lines.gdf.head()
# define hazard
storms = StormEurope.from_footprints(WS_DEMO_NC)
# define impact function
impf = ImpfStormEurope.from_welker()
impf_set = ImpactFuncSet([impf])
# Reproject the hazard to match the exposures CRS
storms.reproject_vector(exp_nl_lines.crs)
# Calculate the impact
imp_deg = u_lp.calc_geom_impact(
exp=exp_nl_lines, impf_set=impf_set, haz=storms,
res=100, disagg_met=u_lp.DisaggMethod.DIV, disagg_val=None,
agg_met=u_lp.AggMethod.SUM
)
# Or alternatively, you can use the below code. It fails in the "assign_centroids".
# exp_pnt = u_lp.exp_geom_to_pnt(
# exp=exp_nl_lines,
# res=100,
# to_meters=False,
# disagg_met=u_lp.DisaggMethod.DIV,
# disagg_val=None
# )
# exp_pnt.assign_centroids(storms)
Expected behavior
Centroids are assigned to disaggregated exposure lines.
Screenshots
Attached.
Climada Version: 6.0.1
System Information (please complete the following information):
- Operating system and version: Ubuntu 24.04
- Python version: 3.11
Additional observations
To bypass the bug, one can set check_antimeridian
to False in the function call, but, the parameter itself cannot be set when doing assign_centroids
as kwargs are not passed further down the chain. They become available at some point, but not all the way up to assign_centroids
.