Skip to content

Cannot work with line exposures and hazards outside of CRS EPSG:4326Β #1062

Open
@mncosta

Description

@mncosta

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:

  1. Have exposure object created from lines
  2. Have hazard object
  3. Have both in a meters-based CRS (e.g., "epsg:28992")
  4. 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.

Image

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions