flood-adapt 1.0.3__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/PKG-INFO +3 -3
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/__init__.py +2 -3
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/fiat_adapter.py +8 -3
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/sfincs_adapter.py +3 -3
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/sfincs_offshore.py +1 -1
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/fiat.py +1 -1
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/gui.py +185 -8
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/database_builder.py +155 -129
- flood_adapt-1.1.0/flood_adapt/database_builder/metrics_utils.py +1834 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/database.py +23 -28
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_benefit.py +0 -26
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_event.py +2 -2
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_measure.py +2 -2
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_scenario.py +0 -24
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_static.py +4 -9
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_strategy.py +2 -4
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_template.py +65 -25
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/flood_adapt.py +64 -13
- flood_adapt-1.1.0/flood_adapt/misc/exceptions.py +59 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt.egg-info/PKG-INFO +3 -3
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt.egg-info/SOURCES.txt +2 -22
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt.egg-info/requires.txt +2 -2
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/pyproject.toml +2 -2
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/tests/test_flood_adapt.py +25 -20
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +0 -90
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +0 -57
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +0 -121
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +0 -65
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +0 -126
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +0 -60
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +0 -121
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +0 -65
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +0 -45
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +0 -4
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +0 -143
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +0 -153
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +0 -127
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +0 -57
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +0 -4
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +0 -191
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +0 -153
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +0 -178
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +0 -57
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +0 -9
- flood_adapt-1.0.3/flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +0 -65
- flood_adapt-1.0.3/flood_adapt/misc/exceptions.py +0 -22
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/LICENSE +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/README.md +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/interface/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/interface/hazard_adapter.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/interface/impact_adapter.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/interface/model_adapter.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/adapter/interface/offshore.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/config.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/hazard.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/impacts.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/sfincs.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/config/site.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/default_units/imperial.toml +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/default_units/metric.toml +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/black_down_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/black_left_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/black_right_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/black_up_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_down.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_left.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_right.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-16_white_up.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_down.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_left.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_right.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_black_up.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_left.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/icons8-triangle-arrow-24_white_right.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/white_down_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/white_left_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/white_right_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/icons/white_up_48x48.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/ambulance.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/car.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/cart.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/firetruck.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/hospital.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/house.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/info.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/money.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/person.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/school.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/truck.png +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/infographics/images/walking_person.png +0 -0
- {flood_adapt-1.0.3/flood_adapt/database_builder/templates/infographics/OSM → flood_adapt-1.1.0/flood_adapt/database_builder/templates/infographics}/styles.css +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/database_builder/templates/output_layers/bin_colors.toml +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/dbs_projection.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/interface/database.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/interface/element.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/dbs_classes/interface/static.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/misc/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/misc/database_user.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/misc/debug_timer.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/misc/log.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/misc/path_builder.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/misc/utils.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/benefits/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/benefits/benefits.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/event_factory.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/event_set.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/events.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/historical.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/hurricane.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/events/synthetic.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/csv.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/discharge.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/forcing.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/forcing_factory.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/meteo_handler.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/netcdf.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/plotting.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/rainfall.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/tide_gauge.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/time_frame.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/timeseries.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/unit_system.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/waterlevels.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/forcing/wind.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/measures/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/measures/measure_factory.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/measures/measures.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/object_model.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/output/floodmap.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/projections/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/projections/projections.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/scenarios/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/scenarios/scenarios.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/strategies/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/objects/strategies/strategies.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/workflows/__init__.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/workflows/benefit_runner.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt/workflows/scenario_runner.py +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt.egg-info/dependency_links.txt +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt.egg-info/not-zip-safe +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/flood_adapt.egg-info/top_level.txt +0 -0
- {flood_adapt-1.0.3 → flood_adapt-1.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: flood-adapt
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: A software package support system which can be used to assess the benefits and costs of flood resilience measures
|
|
5
5
|
Author-email: Gundula Winter <Gundula.Winter@deltares.nl>, Panos Athanasiou <Panos.Athanasiou@deltares.nl>, Frederique de Groen <Frederique.deGroen@deltares.nl>, Tim de Wilde <Tim.deWilde@deltares.nl>, Julian Hofer <Julian.Hofer@deltares.nl>, Daley Adrichem <Daley.Adrichem@deltares.nl>, Luuk Blom <Luuk.Blom@deltares.nl>
|
|
6
6
|
License: ====================================================
|
|
@@ -714,7 +714,7 @@ Requires-Dist: cht-observations==0.2.1
|
|
|
714
714
|
Requires-Dist: cht-tide==0.1.1
|
|
715
715
|
Requires-Dist: dask==2024.11.2
|
|
716
716
|
Requires-Dist: numba_celltree==0.2.2
|
|
717
|
-
Requires-Dist: fiat-toolbox
|
|
717
|
+
Requires-Dist: fiat-toolbox<0.2.0,>=0.1.22
|
|
718
718
|
Requires-Dist: fiona<2.0,>=1.0
|
|
719
719
|
Requires-Dist: geojson<4.0,>=3.0
|
|
720
720
|
Requires-Dist: geopandas<2.0,>=1.0
|
|
@@ -723,7 +723,7 @@ Requires-Dist: hydromt-sfincs==1.2.0
|
|
|
723
723
|
Requires-Dist: numpy<2.0,>=1.0
|
|
724
724
|
Requires-Dist: numpy-financial<2.0,>=1.0
|
|
725
725
|
Requires-Dist: pandas<3.0,>=2.0
|
|
726
|
-
Requires-Dist: plotly<
|
|
726
|
+
Requires-Dist: plotly<6.3,>=6.0
|
|
727
727
|
Requires-Dist: pydantic<3.0,>=2.0
|
|
728
728
|
Requires-Dist: pydantic-settings<3.0,>=2.0
|
|
729
729
|
Requires-Dist: pyogrio<1.0
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# has to be here at the start to avoid circular imports
|
|
2
|
-
__version__ = "1.0
|
|
2
|
+
__version__ = "1.1.0"
|
|
3
3
|
|
|
4
4
|
from flood_adapt import adapter, database_builder, dbs_classes, objects
|
|
5
5
|
from flood_adapt.config.config import Settings
|
|
6
6
|
from flood_adapt.config.site import Site
|
|
7
7
|
from flood_adapt.flood_adapt import FloodAdapt
|
|
8
|
-
from flood_adapt.misc.exceptions import
|
|
8
|
+
from flood_adapt.misc.exceptions import DatabaseError, FloodAdaptError
|
|
9
9
|
from flood_adapt.misc.log import FloodAdaptLogging
|
|
10
10
|
from flood_adapt.objects.forcing import unit_system
|
|
11
11
|
|
|
@@ -21,7 +21,6 @@ __all__ = [
|
|
|
21
21
|
"database_builder",
|
|
22
22
|
"FloodAdaptError",
|
|
23
23
|
"DatabaseError",
|
|
24
|
-
"ComponentError",
|
|
25
24
|
]
|
|
26
25
|
|
|
27
26
|
FloodAdaptLogging() # Initialize logging once for the entire package
|
|
@@ -205,7 +205,7 @@ class FiatAdapter(IImpactAdapter):
|
|
|
205
205
|
self.close_files()
|
|
206
206
|
if self.model_root.exists():
|
|
207
207
|
logger.info(f"Deleting {self.model_root}")
|
|
208
|
-
shutil.rmtree(self.model_root)
|
|
208
|
+
shutil.rmtree(self.model_root, ignore_errors=True)
|
|
209
209
|
|
|
210
210
|
def fiat_completed(self) -> bool:
|
|
211
211
|
"""Check if fiat has run as expected.
|
|
@@ -353,7 +353,7 @@ class FiatAdapter(IImpactAdapter):
|
|
|
353
353
|
os.remove(os.path.join(subdir, file))
|
|
354
354
|
|
|
355
355
|
if not os.listdir(subdir):
|
|
356
|
-
|
|
356
|
+
shutil.rmtree(subdir, ignore_errors=True)
|
|
357
357
|
|
|
358
358
|
if strict:
|
|
359
359
|
raise RuntimeError(f"FIAT model failed to run in {path}.")
|
|
@@ -1365,6 +1365,11 @@ class FiatAdapter(IImpactAdapter):
|
|
|
1365
1365
|
True,
|
|
1366
1366
|
True,
|
|
1367
1367
|
]
|
|
1368
|
+
metrics_new.loc["Show In Metrics Map", ["EW", "EWEAD", "EWCEAD"]] = [
|
|
1369
|
+
False,
|
|
1370
|
+
True,
|
|
1371
|
+
False,
|
|
1372
|
+
]
|
|
1368
1373
|
metrics_new.loc["Long Name", ["EW", "EWEAD", "EWCEAD"]] = [
|
|
1369
1374
|
"Equity weight",
|
|
1370
1375
|
"Equity weighted expected annual damage",
|
|
@@ -1574,5 +1579,5 @@ class FiatAdapter(IImpactAdapter):
|
|
|
1574
1579
|
)
|
|
1575
1580
|
if simulation_path.exists():
|
|
1576
1581
|
self.close_files()
|
|
1577
|
-
shutil.rmtree(simulation_path)
|
|
1582
|
+
shutil.rmtree(simulation_path, ignore_errors=True)
|
|
1578
1583
|
logger.info(f"Deleted Delft-FIAT simulation folder: {simulation_path}")
|
|
@@ -212,7 +212,7 @@ class SfincsAdapter(IHazardAdapter):
|
|
|
212
212
|
os.remove(os.path.join(subdir, file))
|
|
213
213
|
|
|
214
214
|
if not os.listdir(subdir):
|
|
215
|
-
|
|
215
|
+
shutil.rmtree(subdir, ignore_errors=True)
|
|
216
216
|
|
|
217
217
|
if strict:
|
|
218
218
|
raise RuntimeError(f"SFINCS model failed to run in {path}.")
|
|
@@ -828,7 +828,7 @@ class SfincsAdapter(IHazardAdapter):
|
|
|
828
828
|
|
|
829
829
|
if sim_path.parent.exists() and not any(sim_path.parent.iterdir()):
|
|
830
830
|
# Remove the parent directory `simulations` if it is empty
|
|
831
|
-
sim_path.parent
|
|
831
|
+
shutil.rmtree(sim_path.parent, ignore_errors=True)
|
|
832
832
|
|
|
833
833
|
def _run_risk_scenario(self, scenario: Scenario):
|
|
834
834
|
"""Run the whole workflow for a risk scenario.
|
|
@@ -1778,7 +1778,7 @@ class SfincsAdapter(IHazardAdapter):
|
|
|
1778
1778
|
units=us.UnitTypesLength(units),
|
|
1779
1779
|
)
|
|
1780
1780
|
|
|
1781
|
-
if df_gauge is None:
|
|
1781
|
+
if df_gauge is None or df_gauge.empty:
|
|
1782
1782
|
logger.warning(
|
|
1783
1783
|
"No water level data available for the tide gauge. Could not add it to the plot."
|
|
1784
1784
|
)
|
|
@@ -97,7 +97,7 @@ class OffshoreSfincsHandler(IOffshoreSfincsHandler, DatabaseUser):
|
|
|
97
97
|
sim_path = self._get_simulation_path()
|
|
98
98
|
# SfincsAdapter.write() doesnt write the bca file apparently so we need to copy the template
|
|
99
99
|
if sim_path.exists():
|
|
100
|
-
shutil.rmtree(sim_path)
|
|
100
|
+
shutil.rmtree(sim_path, ignore_errors=True)
|
|
101
101
|
|
|
102
102
|
with SfincsAdapter(model_root=self.template_path) as _offshore_model:
|
|
103
103
|
# Load objects, set root & write template model
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from enum import Enum
|
|
1
3
|
from pathlib import Path
|
|
2
|
-
from typing import Optional
|
|
4
|
+
from typing import Any, Literal, Optional, Union
|
|
3
5
|
|
|
4
6
|
import geopandas as gpd
|
|
5
7
|
import numpy as np
|
|
@@ -25,6 +27,7 @@ class Layer(BaseModel):
|
|
|
25
27
|
|
|
26
28
|
bins: list[float]
|
|
27
29
|
colors: list[str]
|
|
30
|
+
decimals: Optional[int] = 0
|
|
28
31
|
|
|
29
32
|
@model_validator(mode="after")
|
|
30
33
|
def check_bins_and_colors(self) -> "Layer":
|
|
@@ -42,20 +45,118 @@ class FloodMapLayer(Layer):
|
|
|
42
45
|
roads_min_zoom_level: int = 14
|
|
43
46
|
|
|
44
47
|
|
|
45
|
-
class AggregationDmgLayer(Layer):
|
|
46
|
-
damage_decimals: Optional[int] = 0
|
|
47
|
-
|
|
48
|
-
|
|
49
48
|
class FootprintsDmgLayer(Layer):
|
|
50
49
|
type: DamageType = DamageType.absolute
|
|
51
|
-
damage_decimals: Optional[int] = 0
|
|
52
|
-
buildings_min_zoom_level: int = 13
|
|
53
50
|
|
|
54
51
|
|
|
55
52
|
class BenefitsLayer(Layer):
|
|
56
53
|
threshold: Optional[float] = None
|
|
57
54
|
|
|
58
55
|
|
|
56
|
+
class LogicalOperator(str, Enum):
|
|
57
|
+
AND = "and"
|
|
58
|
+
OR = "or"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class FieldName(str, Enum):
|
|
62
|
+
"""Enum for valid field names with mapping to dictionary keys."""
|
|
63
|
+
|
|
64
|
+
NAME = "name"
|
|
65
|
+
LONG_NAME = "long_name"
|
|
66
|
+
DESCRIPTION = "description"
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def dict_key(self) -> str:
|
|
70
|
+
"""Get the actual dictionary key for this field name."""
|
|
71
|
+
mapping = {
|
|
72
|
+
"name": "name",
|
|
73
|
+
"long_name": "Long Name",
|
|
74
|
+
"description": "Description",
|
|
75
|
+
}
|
|
76
|
+
return mapping[self.value]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FilterCondition(BaseModel):
|
|
80
|
+
"""A single filter condition."""
|
|
81
|
+
|
|
82
|
+
field_name: FieldName
|
|
83
|
+
values: list[Any]
|
|
84
|
+
operator: LogicalOperator = (
|
|
85
|
+
LogicalOperator.OR
|
|
86
|
+
) # How to combine values within this condition
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class FilterGroup(BaseModel):
|
|
90
|
+
"""A group of filter conditions with logical operators."""
|
|
91
|
+
|
|
92
|
+
conditions: list[FilterCondition]
|
|
93
|
+
operator: LogicalOperator = (
|
|
94
|
+
LogicalOperator.OR
|
|
95
|
+
) # How to combine conditions within this group
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class MetricLayer(Layer):
|
|
99
|
+
type: str
|
|
100
|
+
# Simplified: just a single FilterGroup or FilterCondition
|
|
101
|
+
filters: Union[FilterGroup, FilterCondition] = Field(
|
|
102
|
+
default_factory=lambda: FilterGroup(conditions=[])
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def matches(self, data_dict: dict) -> bool:
|
|
106
|
+
"""Check if the given data dictionary matches the filter criteria."""
|
|
107
|
+
if isinstance(self.filters, FilterCondition):
|
|
108
|
+
return self._evaluate_condition(self.filters, data_dict)
|
|
109
|
+
else: # FilterGroup
|
|
110
|
+
return self._evaluate_filter_group(self.filters, data_dict)
|
|
111
|
+
|
|
112
|
+
def _evaluate_filter_group(self, group: FilterGroup, data_dict: dict) -> bool:
|
|
113
|
+
"""Evaluate a single filter group."""
|
|
114
|
+
if not group.conditions:
|
|
115
|
+
return True
|
|
116
|
+
|
|
117
|
+
condition_results = []
|
|
118
|
+
for condition in group.conditions:
|
|
119
|
+
condition_results.append(self._evaluate_condition(condition, data_dict))
|
|
120
|
+
|
|
121
|
+
if group.operator == LogicalOperator.AND:
|
|
122
|
+
return all(condition_results)
|
|
123
|
+
else: # OR
|
|
124
|
+
return any(condition_results)
|
|
125
|
+
|
|
126
|
+
def _evaluate_condition(self, condition: FilterCondition, data_dict: dict) -> bool:
|
|
127
|
+
"""Evaluate a single condition."""
|
|
128
|
+
# Use the dict_key property to get the actual dictionary key
|
|
129
|
+
field_value = data_dict.get(condition.field_name.dict_key)
|
|
130
|
+
if field_value is None:
|
|
131
|
+
return False
|
|
132
|
+
|
|
133
|
+
value_matches = [value in field_value for value in condition.values] # noqa: PD011
|
|
134
|
+
|
|
135
|
+
if condition.operator == LogicalOperator.AND:
|
|
136
|
+
return all(value_matches)
|
|
137
|
+
else: # OR
|
|
138
|
+
return any(value_matches)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class AggregationDmgLayer(MetricLayer):
|
|
142
|
+
type: str = "damage"
|
|
143
|
+
filters: FilterGroup = Field(
|
|
144
|
+
default_factory=lambda: FilterGroup(
|
|
145
|
+
conditions=[
|
|
146
|
+
FilterCondition(
|
|
147
|
+
field_name=FieldName.NAME,
|
|
148
|
+
values=[
|
|
149
|
+
"TotalDamageEvent",
|
|
150
|
+
"ExpectedAnnualDamages",
|
|
151
|
+
"TotalDamageRP",
|
|
152
|
+
"EWEAD",
|
|
153
|
+
],
|
|
154
|
+
)
|
|
155
|
+
]
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
59
160
|
class OutputLayers(BaseModel):
|
|
60
161
|
"""The configuration of the mapbox layers in the gui.
|
|
61
162
|
|
|
@@ -75,9 +176,84 @@ class OutputLayers(BaseModel):
|
|
|
75
176
|
floodmap: FloodMapLayer
|
|
76
177
|
aggregation_dmg: AggregationDmgLayer
|
|
77
178
|
footprints_dmg: FootprintsDmgLayer
|
|
78
|
-
|
|
179
|
+
aggregated_metrics: list[MetricLayer] = Field(default_factory=list)
|
|
79
180
|
benefits: Optional[BenefitsLayer] = None
|
|
80
181
|
|
|
182
|
+
def get_aggr_metrics_layers(
|
|
183
|
+
self,
|
|
184
|
+
metrics: list[dict],
|
|
185
|
+
type: Literal["single_event", "risk"] = "single_event",
|
|
186
|
+
rp: Optional[int] = None,
|
|
187
|
+
equity: bool = False,
|
|
188
|
+
):
|
|
189
|
+
layer_types = [self.aggregation_dmg] + self.aggregated_metrics
|
|
190
|
+
filtered_input_metrics = self._filter_metrics(metrics, type, rp, equity)
|
|
191
|
+
return self._match_metrics_to_layers(filtered_input_metrics, layer_types)
|
|
192
|
+
|
|
193
|
+
def _should_skip_metric(
|
|
194
|
+
self, metric_name: str, rp: Optional[int], equity: bool
|
|
195
|
+
) -> bool:
|
|
196
|
+
rp_match = re.search(r"RP(\d+)", metric_name)
|
|
197
|
+
y_match = re.search(r"(\d+)Y", metric_name)
|
|
198
|
+
name_match = rp_match or y_match
|
|
199
|
+
|
|
200
|
+
if rp is None:
|
|
201
|
+
if name_match:
|
|
202
|
+
return True
|
|
203
|
+
if not equity and "EW" in metric_name:
|
|
204
|
+
return True
|
|
205
|
+
if equity and "EW" not in metric_name:
|
|
206
|
+
return True
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
def _process_metric_name(
|
|
210
|
+
self, metric_name: str, rp: Optional[int]
|
|
211
|
+
) -> tuple[str, bool]:
|
|
212
|
+
rp_match = re.search(r"RP(\d+)", metric_name)
|
|
213
|
+
y_match = re.search(r"(\d+)Y", metric_name)
|
|
214
|
+
name_match = rp_match or y_match
|
|
215
|
+
if rp is not None:
|
|
216
|
+
if name_match:
|
|
217
|
+
extracted_rp = int(name_match.group(1))
|
|
218
|
+
name_check = extracted_rp == int(rp)
|
|
219
|
+
cleaned_name = re.sub(r"(RP\d+|\d+Y)", "", metric_name)
|
|
220
|
+
return cleaned_name.rstrip("_"), name_check
|
|
221
|
+
else:
|
|
222
|
+
return metric_name, False
|
|
223
|
+
return metric_name, True
|
|
224
|
+
|
|
225
|
+
def _filter_metrics(self, metrics, type, rp, equity):
|
|
226
|
+
filtered = []
|
|
227
|
+
for metric in metrics:
|
|
228
|
+
metric_name = metric.get("name", "")
|
|
229
|
+
metric["name_to_show"] = metric_name
|
|
230
|
+
if type == "risk":
|
|
231
|
+
if self._should_skip_metric(metric_name, rp, equity):
|
|
232
|
+
continue
|
|
233
|
+
metric["name_to_show"], name_check = self._process_metric_name(
|
|
234
|
+
metric_name, rp
|
|
235
|
+
)
|
|
236
|
+
if rp is not None and not name_check:
|
|
237
|
+
continue
|
|
238
|
+
filtered.append(metric)
|
|
239
|
+
return filtered
|
|
240
|
+
|
|
241
|
+
def _match_metrics_to_layers(self, metrics, layer_types):
|
|
242
|
+
filtered_metrics = []
|
|
243
|
+
for metric in metrics:
|
|
244
|
+
for layer in layer_types:
|
|
245
|
+
if layer.matches(metric):
|
|
246
|
+
filtered_metrics.append(
|
|
247
|
+
{
|
|
248
|
+
"metric": metric,
|
|
249
|
+
"bins": getattr(layer, "bins", None),
|
|
250
|
+
"colors": getattr(layer, "colors", None),
|
|
251
|
+
"decimals": getattr(layer, "decimals", None),
|
|
252
|
+
}
|
|
253
|
+
)
|
|
254
|
+
break
|
|
255
|
+
return filtered_metrics
|
|
256
|
+
|
|
81
257
|
|
|
82
258
|
class VisualizationLayer(Layer):
|
|
83
259
|
"""The configuration of a layer to visualize in the gui.
|
|
@@ -157,6 +333,7 @@ class VisualizationLayers(BaseModel):
|
|
|
157
333
|
The layers to visualize.
|
|
158
334
|
"""
|
|
159
335
|
|
|
336
|
+
buildings_min_zoom_level: int = 13
|
|
160
337
|
layers: list[VisualizationLayer] = Field(default_factory=list)
|
|
161
338
|
|
|
162
339
|
def add_layer(
|