UjjwalKGupta commited on
Commit
967a934
·
verified ·
1 Parent(s): ca95339

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -29
app.py CHANGED
@@ -205,57 +205,59 @@ def get_wayback_data():
205
  print(f"Could not fetch or parse Wayback data: {e}")
206
  return pd.DataFrame() # Return empty dataframe on failure
207
 
208
- def get_dem_slope_maps(ee_geometry, wayback_url=None, wayback_title=None):
209
  """Creates DEM and Slope maps from SRTM data, using wayback tiles as a basemap if available."""
210
  one_time_setup()
211
 
212
  # --- DEM Map ---
213
- dem_map = gee_folium.Map(center_object=ee_geometry, zoom_start=12)
214
  if wayback_url:
215
  dem_map.add_tile_layer(wayback_url, name=wayback_title, attribution="Esri")
216
  else:
217
  dem_map.add_basemap("SATELLITE")
218
 
 
219
  try:
220
  dem_layer = ee.Image("USGS/SRTMGL1_003").resample("bilinear").reproject(crs="EPSG:4326", scale=30).clip(ee_geometry)
221
  stats = dem_layer.reduceRegion(reducer=ee.Reducer.minMax(), geometry=ee_geometry, scale=30, maxPixels=1e9).getInfo()
222
 
223
  if stats and stats.get('elevation_min') is not None:
224
  min_val, max_val = stats['elevation_min'], stats['elevation_max']
225
- vis_params = {"min": min_val, "max": max_val, "palette": ['#0000FF', '#00FF00', '#FFFF00', '#FF0000']} # Blue to Red
226
  dem_map.addLayer(dem_layer, vis_params, "Elevation")
227
  dem_map.add_colorbar(vis_params=vis_params, label="Elevation (m)")
228
- else:
229
- dem_map_html = "<div>No DEM data available for this area.</div>"
 
 
230
  except Exception as e:
231
  print(f"Error creating DEM map: {e}")
232
  dem_map_html = f"<div>Error creating DEM map: {e}</div>"
233
 
234
- dem_map.addLayerControl()
235
- dem_map_html = dem_map._repr_html_()
236
 
237
  # --- Slope Map ---
238
- slope_map = gee_folium.Map(center_object=ee_geometry, zoom_start=12)
239
  if wayback_url:
240
  slope_map.add_tile_layer(wayback_url, name=wayback_title, attribution="Esri")
241
  else:
242
  slope_map.add_basemap("SATELLITE")
243
 
 
244
  try:
245
  slope_layer = ee.Terrain.slope(dem_layer)
246
- slope_vis_params = {"min": 0, "max": 60, "palette": ['#00FF00', '#FFFF00', '#FFA500', '#FF0000']} # Green to Red
247
  slope_map.addLayer(slope_layer, slope_vis_params, "Slope")
248
  slope_map.add_colorbar(vis_params=slope_vis_params, label="Slope (degrees)")
 
 
 
 
249
  except Exception as e:
250
  print(f"Error creating Slope map: {e}")
251
  slope_map_html = f"<div>Error creating Slope map: {e}</div>"
252
 
253
- slope_map.addLayerControl()
254
- slope_map_html = slope_map._repr_html_()
255
-
256
  return dem_map_html, slope_map_html
257
 
258
-
259
  def add_indices(image, nir_band, red_band, blue_band, green_band, evi_vars):
260
  """Calculates and adds multiple vegetation indices to an Earth Engine image."""
261
  # It's safer to work with the image bands directly
@@ -331,25 +333,19 @@ def process_and_display(file_obj, url_str, buffer_m, progress=gr.Progress()):
331
 
332
  progress(0, desc="Reading and processing geometry...")
333
  try:
 
334
  input_gdf = get_gdf_from_file(file_obj) if file_obj is not None else get_gdf_from_url(url_str)
335
  input_gdf = preprocess_gdf(input_gdf)
336
-
337
- # Find the first valid polygon
338
  geometry_gdf = next((input_gdf.iloc[[i]] for i in range(len(input_gdf)) if is_valid_polygon(input_gdf.iloc[[i]])), None)
339
-
340
  if geometry_gdf is None:
341
  return None, "No valid polygon found in the provided file.", None, None, None, None, None
342
-
343
  geometry_gdf = to_best_crs(geometry_gdf)
344
-
345
- # Create buffer
346
  outer_geometry_gdf = geometry_gdf.copy()
347
  outer_geometry_gdf["geometry"] = outer_geometry_gdf["geometry"].buffer(buffer_m)
348
  buffer_geometry_gdf = gpd.GeoDataFrame(
349
  geometry=[outer_geometry_gdf.unary_union.difference(geometry_gdf.unary_union)],
350
  crs=geometry_gdf.crs
351
  )
352
-
353
  except Exception as e:
354
  return None, f"Error processing file: {e}", None, None, None, None, None
355
 
@@ -368,13 +364,15 @@ def process_and_display(file_obj, url_str, buffer_m, progress=gr.Progress()):
368
  .replace("{TileCol}", "{x}")
369
  )
370
 
371
- # Convert to EE geometry for DEM/Slope maps
372
- ee_geometry = ee.Geometry(json.loads(geometry_gdf.to_crs(4326).to_json())['features'][0]['geometry'])
373
- dem_html, slope_html = get_dem_slope_maps(ee_geometry, wayback_url, wayback_title)
374
-
375
- # Create main map with folium
376
  bounds = geometry_gdf.to_crs(epsg=4326).total_bounds
377
  map_center = [(bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2]
 
 
 
 
 
 
378
  m = folium.Map(location=map_center)
379
 
380
  if wayback_url:
@@ -384,17 +382,14 @@ def process_and_display(file_obj, url_str, buffer_m, progress=gr.Progress()):
384
  m.add_child(folium.LayerControl())
385
  m.fit_bounds([[bounds[1], bounds[0]], [bounds[3], bounds[2]]])
386
 
387
- # Generate stats
388
  stats_df = pd.DataFrame({
389
  "Area (ha)": [f"{geometry_gdf.area.item() / 10000:.2f}"],
390
  "Perimeter (m)": [f"{geometry_gdf.length.item():.2f}"],
391
  "Centroid (Lat, Lon)": [f"({geometry_gdf.to_crs(4326).centroid.y.iloc[0]:.6f}, {geometry_gdf.to_crs(4326).centroid.x.iloc[0]:.6f})"]
392
  })
393
-
394
- # Save geometry data for later use
395
  geometry_json = geometry_gdf.to_json()
396
  buffer_geometry_json = buffer_geometry_gdf.to_json()
397
-
398
  progress(1, desc="Done!")
399
  return m._repr_html_(), None, stats_df, dem_html, slope_html, geometry_json, buffer_geometry_json
400
 
 
205
  print(f"Could not fetch or parse Wayback data: {e}")
206
  return pd.DataFrame() # Return empty dataframe on failure
207
 
208
+ def get_dem_slope_maps(ee_geometry, map_center, zoom=12, wayback_url=None, wayback_title=None):
209
  """Creates DEM and Slope maps from SRTM data, using wayback tiles as a basemap if available."""
210
  one_time_setup()
211
 
212
  # --- DEM Map ---
213
+ dem_map = gee_folium.Map(location=map_center, zoom_start=zoom)
214
  if wayback_url:
215
  dem_map.add_tile_layer(wayback_url, name=wayback_title, attribution="Esri")
216
  else:
217
  dem_map.add_basemap("SATELLITE")
218
 
219
+ dem_map_html = "<div>No DEM data available for this area.</div>"
220
  try:
221
  dem_layer = ee.Image("USGS/SRTMGL1_003").resample("bilinear").reproject(crs="EPSG:4326", scale=30).clip(ee_geometry)
222
  stats = dem_layer.reduceRegion(reducer=ee.Reducer.minMax(), geometry=ee_geometry, scale=30, maxPixels=1e9).getInfo()
223
 
224
  if stats and stats.get('elevation_min') is not None:
225
  min_val, max_val = stats['elevation_min'], stats['elevation_max']
226
+ vis_params = {"min": min_val, "max": max_val, "palette": ['#0000FF', '#00FF00', '#FFFF00', '#FF0000']}
227
  dem_map.addLayer(dem_layer, vis_params, "Elevation")
228
  dem_map.add_colorbar(vis_params=vis_params, label="Elevation (m)")
229
+
230
+ dem_map.addLayerControl()
231
+ dem_map_html = dem_map._repr_html_()
232
+
233
  except Exception as e:
234
  print(f"Error creating DEM map: {e}")
235
  dem_map_html = f"<div>Error creating DEM map: {e}</div>"
236
 
 
 
237
 
238
  # --- Slope Map ---
239
+ slope_map = gee_folium.Map(location=map_center, zoom_start=zoom)
240
  if wayback_url:
241
  slope_map.add_tile_layer(wayback_url, name=wayback_title, attribution="Esri")
242
  else:
243
  slope_map.add_basemap("SATELLITE")
244
 
245
+ slope_map_html = "<div>No Slope data available for this area.</div>"
246
  try:
247
  slope_layer = ee.Terrain.slope(dem_layer)
248
+ slope_vis_params = {"min": 0, "max": 60, "palette": ['#00FF00', '#FFFF00', '#FFA500', '#FF0000']}
249
  slope_map.addLayer(slope_layer, slope_vis_params, "Slope")
250
  slope_map.add_colorbar(vis_params=slope_vis_params, label="Slope (degrees)")
251
+
252
+ slope_map.addLayerControl()
253
+ slope_map_html = slope_map._repr_html_()
254
+
255
  except Exception as e:
256
  print(f"Error creating Slope map: {e}")
257
  slope_map_html = f"<div>Error creating Slope map: {e}</div>"
258
 
 
 
 
259
  return dem_map_html, slope_map_html
260
 
 
261
  def add_indices(image, nir_band, red_band, blue_band, green_band, evi_vars):
262
  """Calculates and adds multiple vegetation indices to an Earth Engine image."""
263
  # It's safer to work with the image bands directly
 
333
 
334
  progress(0, desc="Reading and processing geometry...")
335
  try:
336
+ # ... (no changes to the geometry processing part) ...
337
  input_gdf = get_gdf_from_file(file_obj) if file_obj is not None else get_gdf_from_url(url_str)
338
  input_gdf = preprocess_gdf(input_gdf)
 
 
339
  geometry_gdf = next((input_gdf.iloc[[i]] for i in range(len(input_gdf)) if is_valid_polygon(input_gdf.iloc[[i]])), None)
 
340
  if geometry_gdf is None:
341
  return None, "No valid polygon found in the provided file.", None, None, None, None, None
 
342
  geometry_gdf = to_best_crs(geometry_gdf)
 
 
343
  outer_geometry_gdf = geometry_gdf.copy()
344
  outer_geometry_gdf["geometry"] = outer_geometry_gdf["geometry"].buffer(buffer_m)
345
  buffer_geometry_gdf = gpd.GeoDataFrame(
346
  geometry=[outer_geometry_gdf.unary_union.difference(geometry_gdf.unary_union)],
347
  crs=geometry_gdf.crs
348
  )
 
349
  except Exception as e:
350
  return None, f"Error processing file: {e}", None, None, None, None, None
351
 
 
364
  .replace("{TileCol}", "{x}")
365
  )
366
 
367
+ # **NEW**: Calculate map center from the geometry's bounds
 
 
 
 
368
  bounds = geometry_gdf.to_crs(epsg=4326).total_bounds
369
  map_center = [(bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2]
370
+
371
+ # **MODIFIED**: Pass map_center to the function
372
+ ee_geometry = ee.Geometry(json.loads(geometry_gdf.to_crs(4326).to_json())['features'][0]['geometry'])
373
+ dem_html, slope_html = get_dem_slope_maps(ee_geometry, map_center, wayback_url=wayback_url, wayback_title=wayback_title)
374
+
375
+ # Create main map with folium using the calculated center
376
  m = folium.Map(location=map_center)
377
 
378
  if wayback_url:
 
382
  m.add_child(folium.LayerControl())
383
  m.fit_bounds([[bounds[1], bounds[0]], [bounds[3], bounds[2]]])
384
 
385
+ # ... (rest of the function remains the same) ...
386
  stats_df = pd.DataFrame({
387
  "Area (ha)": [f"{geometry_gdf.area.item() / 10000:.2f}"],
388
  "Perimeter (m)": [f"{geometry_gdf.length.item():.2f}"],
389
  "Centroid (Lat, Lon)": [f"({geometry_gdf.to_crs(4326).centroid.y.iloc[0]:.6f}, {geometry_gdf.to_crs(4326).centroid.x.iloc[0]:.6f})"]
390
  })
 
 
391
  geometry_json = geometry_gdf.to_json()
392
  buffer_geometry_json = buffer_geometry_gdf.to_json()
 
393
  progress(1, desc="Done!")
394
  return m._repr_html_(), None, stats_df, dem_html, slope_html, geometry_json, buffer_geometry_json
395