Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import rasterio | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import plotly.graph_objs as go | |
| import logging | |
| # Configure logging for better debugging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| def process_dem(dem_path): | |
| """ | |
| Analyzes a DEM file to generate a 2D slope risk map and a 3D interactive plot. | |
| """ | |
| if dem_path is None: | |
| return None, None | |
| try: | |
| # --- OPEN DEM --- | |
| logger.info(f"Processing file: {dem_path.name}") | |
| with rasterio.open(dem_path.name) as src: | |
| dem = src.read(1).astype(float) | |
| profile = src.profile | |
| logger.info("Successfully opened DEM file.") | |
| except rasterio.errors.RasterioIOError as e: | |
| logger.error(f"Rasterio error: Failed to open or read the DEM file. Error: {e}") | |
| # Return an error message to be displayed by Gradio | |
| raise gr.Error("Failed to process the DEM file. Please ensure it is a valid GeoTIFF (.tif) file.") | |
| except Exception as e: | |
| logger.error(f"An unexpected error occurred during file processing: {e}") | |
| raise gr.Error(f"An unexpected error occurred: {e}") | |
| nrows, ncols = dem.shape | |
| Z = dem | |
| # --- COMPUTE SLOPE --- | |
| dy, dx = np.gradient(Z) | |
| slope = np.sqrt(dx**2 + dy**2) | |
| # --- RISK MASK --- | |
| try: | |
| threshold = np.percentile(slope, 95) # Top 5% steepest slopes | |
| risk_mask = slope > threshold | |
| except IndexError: | |
| # Handle case where slope array is empty or too small | |
| logger.warning("Slope array is empty, skipping percentile calculation.") | |
| risk_mask = np.zeros_like(slope, dtype=bool) | |
| # --- 2D RISK MAP --- | |
| fig2d, ax = plt.subplots(figsize=(8, 6)) | |
| c = ax.imshow(slope, cmap="hot", origin="upper") | |
| ax.contour(risk_mask, levels=[0.5], colors="blue", linewidths=0.8) | |
| plt.colorbar(c, ax=ax, label="Slope (steepness)") | |
| ax.set_title("Slope Risk Map (Hot = Steep, Blue = Risk zones)") | |
| ax.set_xlabel("Column Index (X)") | |
| ax.set_ylabel("Row Index (Y)") | |
| risk_map_path = "risk_map.png" | |
| plt.savefig(risk_map_path, dpi=150, bbox_inches="tight") | |
| plt.close(fig2d) | |
| logger.info("Generated 2D risk map.") | |
| # --- INTERACTIVE 3D DEM (Plotly) --- | |
| step = max(1, nrows // 200) | |
| fig3d = go.Figure() | |
| # Base DEM surface | |
| fig3d.add_trace(go.Surface( | |
| z=Z[::step, ::step], | |
| colorscale="Earth", | |
| showscale=True, | |
| opacity=0.9, | |
| contours=dict(z=dict(show=True, usecolormap=True, highlightcolor="black", project_z=True)) | |
| )) | |
| # Risk overlay (purple) | |
| fig3d.add_trace(go.Surface( | |
| z=np.where(risk_mask[::step, ::step], Z[::step, ::step], np.nan), | |
| surfacecolor=np.ones_like(Z[::step, ::step]), | |
| colorscale=[[0, "purple"], [1, "purple"]], | |
| showscale=False, | |
| opacity=0.6 | |
| )) | |
| fig3d.update_layout( | |
| title="Interactive 3D DEM with Contours & Steep Slope Highlight", | |
| scene=dict( | |
| xaxis_title="X (grid cols)", | |
| yaxis_title="Y (grid rows)", | |
| zaxis_title="Elevation (m)", | |
| aspectmode="data" | |
| ) | |
| ) | |
| logger.info("Generated 3D Plotly figure.") | |
| return risk_map_path, fig3d | |
| # --- GRADIO APP --- | |
| demo = gr.Interface( | |
| fn=process_dem, | |
| inputs=gr.File(label="Upload DEM (.tif)", file_types=[".tif"]), | |
| outputs=[ | |
| gr.Image(type="filepath", label="2D Slope Risk Map"), | |
| gr.Plot(label="Interactive 3D DEM (with Contours & Risk Zones)") | |
| ], | |
| title="3D DEM & Landslide Risk Visualizer", | |
| description="Upload a GeoTIFF DEM file to see a 2D slope risk map and an interactive 3D DEM with contours & steep slope zones highlighted.") | |
| if __name__ == "__main__": | |
| demo.launch() |