Files changed (1) hide show
  1. app.py +37 -12
app.py CHANGED
@@ -3,23 +3,49 @@ import rasterio
3
  import numpy as np
4
  import matplotlib.pyplot as plt
5
  import plotly.graph_objs as go
 
 
 
 
 
6
 
7
  def process_dem(dem_path):
8
- # --- OPEN DEM ---
9
- with rasterio.open(dem_path.name) as src:
10
- dem = src.read(1).astype(float)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  nrows, ncols = dem.shape
13
  Z = dem
14
 
15
  # --- COMPUTE SLOPE ---
16
- # Assuming square pixels (ok for visualization)
17
  dy, dx = np.gradient(Z)
18
  slope = np.sqrt(dx**2 + dy**2)
19
 
20
  # --- RISK MASK ---
21
- threshold = np.percentile(slope, 95) # Top 5% steepest slopes
22
- risk_mask = slope > threshold
 
 
 
 
 
23
 
24
  # --- 2D RISK MAP ---
25
  fig2d, ax = plt.subplots(figsize=(8, 6))
@@ -32,16 +58,16 @@ def process_dem(dem_path):
32
  risk_map_path = "risk_map.png"
33
  plt.savefig(risk_map_path, dpi=150, bbox_inches="tight")
34
  plt.close(fig2d)
 
35
 
36
  # --- INTERACTIVE 3D DEM (Plotly) ---
37
  step = max(1, nrows // 200)
38
-
39
  fig3d = go.Figure()
40
 
41
  # Base DEM surface
42
  fig3d.add_trace(go.Surface(
43
  z=Z[::step, ::step],
44
- colorscale="Earth", # similar to matplotlib 'terrain'
45
  showscale=True,
46
  opacity=0.9,
47
  contours=dict(z=dict(show=True, usecolormap=True, highlightcolor="black", project_z=True))
@@ -65,10 +91,10 @@ def process_dem(dem_path):
65
  aspectmode="data"
66
  )
67
  )
 
68
 
69
  return risk_map_path, fig3d
70
 
71
-
72
  # --- GRADIO APP ---
73
  demo = gr.Interface(
74
  fn=process_dem,
@@ -78,8 +104,7 @@ demo = gr.Interface(
78
  gr.Plot(label="Interactive 3D DEM (with Contours & Risk Zones)")
79
  ],
80
  title="3D DEM & Landslide Risk Visualizer",
81
- description="Upload a GeoTIFF DEM file to see a 2D slope risk map and an interactive 3D DEM with contours & steep slope zones highlighted."
82
- )
83
 
84
  if __name__ == "__main__":
85
- demo.launch()
 
3
  import numpy as np
4
  import matplotlib.pyplot as plt
5
  import plotly.graph_objs as go
6
+ import logging
7
+
8
+ # Configure logging for better debugging
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(__name__)
11
 
12
  def process_dem(dem_path):
13
+ """
14
+ Analyzes a DEM file to generate a 2D slope risk map and a 3D interactive plot.
15
+ """
16
+ if dem_path is None:
17
+ return None, None
18
+
19
+ try:
20
+ # --- OPEN DEM ---
21
+ logger.info(f"Processing file: {dem_path.name}")
22
+ with rasterio.open(dem_path.name) as src:
23
+ dem = src.read(1).astype(float)
24
+ profile = src.profile
25
+ logger.info("Successfully opened DEM file.")
26
+ except rasterio.errors.RasterioIOError as e:
27
+ logger.error(f"Rasterio error: Failed to open or read the DEM file. Error: {e}")
28
+ # Return an error message to be displayed by Gradio
29
+ raise gr.Error("Failed to process the DEM file. Please ensure it is a valid GeoTIFF (.tif) file.")
30
+ except Exception as e:
31
+ logger.error(f"An unexpected error occurred during file processing: {e}")
32
+ raise gr.Error(f"An unexpected error occurred: {e}")
33
 
34
  nrows, ncols = dem.shape
35
  Z = dem
36
 
37
  # --- COMPUTE SLOPE ---
 
38
  dy, dx = np.gradient(Z)
39
  slope = np.sqrt(dx**2 + dy**2)
40
 
41
  # --- RISK MASK ---
42
+ try:
43
+ threshold = np.percentile(slope, 95) # Top 5% steepest slopes
44
+ risk_mask = slope > threshold
45
+ except IndexError:
46
+ # Handle case where slope array is empty or too small
47
+ logger.warning("Slope array is empty, skipping percentile calculation.")
48
+ risk_mask = np.zeros_like(slope, dtype=bool)
49
 
50
  # --- 2D RISK MAP ---
51
  fig2d, ax = plt.subplots(figsize=(8, 6))
 
58
  risk_map_path = "risk_map.png"
59
  plt.savefig(risk_map_path, dpi=150, bbox_inches="tight")
60
  plt.close(fig2d)
61
+ logger.info("Generated 2D risk map.")
62
 
63
  # --- INTERACTIVE 3D DEM (Plotly) ---
64
  step = max(1, nrows // 200)
 
65
  fig3d = go.Figure()
66
 
67
  # Base DEM surface
68
  fig3d.add_trace(go.Surface(
69
  z=Z[::step, ::step],
70
+ colorscale="Earth",
71
  showscale=True,
72
  opacity=0.9,
73
  contours=dict(z=dict(show=True, usecolormap=True, highlightcolor="black", project_z=True))
 
91
  aspectmode="data"
92
  )
93
  )
94
+ logger.info("Generated 3D Plotly figure.")
95
 
96
  return risk_map_path, fig3d
97
 
 
98
  # --- GRADIO APP ---
99
  demo = gr.Interface(
100
  fn=process_dem,
 
104
  gr.Plot(label="Interactive 3D DEM (with Contours & Risk Zones)")
105
  ],
106
  title="3D DEM & Landslide Risk Visualizer",
107
+ description="Upload a GeoTIFF DEM file to see a 2D slope risk map and an interactive 3D DEM with contours & steep slope zones highlighted.")
 
108
 
109
  if __name__ == "__main__":
110
+ demo.launch()