| import gradio as gr |
| import importlib |
| import os |
|
|
| from data.options import iso_options, rp_options |
| from data.geometry import fetch_gis_subdivisions, has_associated_features |
| from data.hotosm import download_hotosm_data |
| from data.ckan import download_resource_ckan |
|
|
| from analysis import run_analyses |
|
|
| |
| def get_available_hazards(): |
| hazard_dir = "hazards" |
| files = os.listdir(hazard_dir) |
| hazards = [ |
| f.replace(".py", "") for f in files |
| if f.endswith(".py") and f != "__init__.py" |
| ] |
| return sorted([(h.capitalize(), h) for h in hazards]) |
|
|
| hazard_options = get_available_hazards() |
|
|
| |
| with gr.Blocks(title="Hazard Raster Downloader") as demo: |
| gr.Markdown("## eVCA Hazard and Exposure Data Downloader\nSelect a country, hazard, and return period to generate hazard rasters and supporting exposure data.") |
|
|
| with gr.Row(): |
| hazard_input = gr.Dropdown(choices=hazard_options, label="Hazard", value="flood", interactive=True) |
| iso_input = gr.Dropdown(choices=iso_options, label="Country", interactive=True, value=None) |
| rp_input = gr.Dropdown(choices=rp_options, label="Return Period (years)", value=10) |
|
|
| subdivision_input = gr.Dropdown(choices=[], label="Subdivision", interactive=True, visible=False) |
|
|
| generate_btn = gr.Button("Generate Raster", visible=False) |
| status_text = gr.Markdown("") |
| file_output = gr.Files(label="Downloads", interactive=False) |
| analysis_output = gr.Markdown("", label="Analysis Results") |
|
|
| def wrapper(hazard, iso, rp, subdivision): |
| |
| try: |
| hazard_module = importlib.import_module(f"hazards.{hazard}") |
| generate_func = getattr(hazard_module, f"generate_{hazard}_raster") |
| except (ModuleNotFoundError, AttributeError): |
| return [], f"β Error: No raster generation function found for hazard '{hazard}'." |
| |
| |
| subdivision_name = None |
| if subdivision and not subdivision.endswith("(Country level)"): |
| subdivision_name = subdivision |
| |
| |
| raster_path, msg = generate_func(iso, rp, subdivision_name) |
|
|
| iso3 = iso.split(",")[-1].strip() if "," in iso else iso |
|
|
| |
| pp_path = download_hotosm_data(iso3, feature_type="populated_places", geometry="points") |
| roads_path = download_hotosm_data(iso3, feature_type="roads", geometry="lines") |
| buildings_path = download_hotosm_data(iso3, feature_type="buildings", geometry="polygons") |
|
|
| |
| pop_paths = download_resource_ckan(iso3, dataset_prefix="cod-ps") |
| admin_path = download_resource_ckan(iso3, dataset_prefix="cod-ab") |
|
|
| files = [] |
| if raster_path: |
| files.append(raster_path) |
| if pp_path: |
| files.append(pp_path) |
| if roads_path: |
| files.append(roads_path) |
| if buildings_path: |
| files.append(buildings_path) |
| if admin_path: |
| files.extend(admin_path) |
| if pop_paths: |
| files.extend(pop_paths) |
| |
| analysis_results = run_analyses( |
| raster_path=raster_path, |
| pp_path=pp_path, |
| roads_path=roads_path, |
| buildings_path=buildings_path, |
| admin_path=admin_path, |
| pop_paths=pop_paths |
| ) |
| |
| if analysis_results: |
| analysis_msg = analysis_results |
| else: |
| analysis_msg = "β
No analyses could be run." |
| |
| if not files: |
| msg += " β οΈ No data could be downloaded." |
| return files, msg, analysis_msg |
|
|
| def get_subdivision_options(iso_code): |
| has_features, data = has_associated_features(iso_code) |
| subdivisions = fetch_gis_subdivisions(iso_code) |
|
|
| |
| country_name = next((name for name, code in iso_options if code == iso_code), iso_code) |
|
|
| if not has_features: |
| |
| return ( |
| gr.update(choices=subdivisions, visible=True, value=None), |
| gr.update(visible=False), |
| gr.update(value=f"β
Subdivisions loaded for {country_name}. Please select one.") |
| ) |
| else: |
| |
| country_option = f"{country_name} (Country level)" |
| return ( |
| gr.update(choices=[country_option] + subdivisions, visible=True, value=country_option), |
| gr.update(visible=False), |
| gr.update(value=f"β
Country and subdivisions loaded for {country_name}. You may choose either.") |
| ) |
|
|
| iso_input.change( |
| fn=lambda iso: gr.update(value="π Loading subdivisions..."), |
| inputs=iso_input, |
| outputs=status_text |
| ).then( |
| fn=get_subdivision_options, |
| inputs=iso_input, |
| outputs=[subdivision_input, generate_btn, status_text] |
| ) |
|
|
| subdivision_input.change( |
| fn=lambda s: gr.update(visible=True) if s else gr.update(visible=False), |
| inputs=subdivision_input, |
| outputs=generate_btn |
| ) |
|
|
| generate_btn.click( |
| fn=wrapper, |
| inputs=[hazard_input, iso_input, rp_input, subdivision_input], |
| outputs=[file_output, status_text, analysis_output] |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch(share=True) |
|
|