YashMK89 commited on
Commit
e2914ee
·
verified ·
1 Parent(s): 4a04431

update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -74
app.py CHANGED
@@ -12,7 +12,7 @@ import re
12
  st.set_page_config(layout="wide")
13
 
14
  # Custom button styling
15
- m = st.markdown(
16
  """
17
  <style>
18
  div.stButton > button:first-child {
@@ -25,7 +25,7 @@ m = st.markdown(
25
 
26
  # Logo
27
  st.write(
28
- f"""
29
  <div style="display: flex; justify-content: space-between; align-items: center;">
30
  <img src="https://huggingface.co/spaces/YashMK89/GEE_Calculator/resolve/main/ISRO_Logo.png" style="width: 20%; margin-right: auto;">
31
  <img src="https://huggingface.co/spaces/YashMK89/GEE_Calculator/resolve/main/SAC_Logo.png" style="width: 20%; margin-left: auto;">
@@ -36,9 +36,7 @@ st.write(
36
 
37
  # Title
38
  st.markdown(
39
- f"""
40
- <h1 style="text-align: center;">Precision Analysis for Vegetation, Water, and Air Quality</h1>
41
- """,
42
  unsafe_allow_html=True,
43
  )
44
  st.write("<h2><div style='text-align: center;'>User Inputs</div></h2>", unsafe_allow_html=True)
@@ -185,36 +183,19 @@ def calculate_avg_no2_sentinel5p(image, geometry):
185
  return no2
186
 
187
  def calculate_custom_formula(image, geometry, formula, scale=30):
188
- """
189
- Calculate a custom formula on an image and return the result for a given geometry.
190
-
191
- Args:
192
- image (ee.Image): The input image.
193
- geometry (ee.Geometry): The region of interest (ROI) geometry.
194
- formula (str): A string representing the mathematical formula to apply to the image.
195
- scale (int): The scale for the reduceRegion operation (default is 30).
196
-
197
- Returns:
198
- ee.Dictionary: The result of applying the custom formula in the region.
199
- """
200
- # Dynamically generate the dictionary of band references from the image
201
  band_names = image.bandNames().getInfo()
202
  band_dict = {band: image.select(band) for band in band_names}
203
 
204
- # Use the formula with the bands in the image
205
  result_image = image.expression(formula, band_dict).rename('CustomResult')
206
 
207
- # Reduce the region to get the mean value for the given geometry
208
  result = result_image.reduceRegion(
209
  reducer=ee.Reducer.mean(),
210
  geometry=geometry,
211
  scale=scale
212
  )
213
 
214
- # Return the result
215
  return result
216
 
217
-
218
  # Function to get the most recent image from the collection
219
  def get_most_recent_image(image_collection):
220
  image = image_collection.sort('system:time_start', False).first()
@@ -232,11 +213,7 @@ locations_df = None # Initialize locations_df to None
232
  polygons_df = None # Ensure polygons_df is initialized at the beginning
233
 
234
  # Process each point (with additional checks for file validity)
235
- # Check the shape type and assign polygons_df only for Polygon data
236
  if file_upload:
237
- # locations_df = None # Initialize locations_df to None
238
- # polygons_df = None # Ensure polygons_df is initialized at the beginning
239
-
240
  file_extension = os.path.splitext(file_upload.name)[1].lower()
241
 
242
  # Read file based on shape type
@@ -250,58 +227,45 @@ if file_upload:
250
  else:
251
  st.error("Unsupported file type. Please upload a CSV, GeoJSON, or KML file for points.")
252
  elif shape_type == 'Polygon':
253
- if file_extension == '.geojson':
254
  polygons_df = read_geojson(file_upload)
255
  elif file_extension == '.kml':
256
  polygons_df = read_kml(file_upload)
257
  else:
258
  st.error("Unsupported file type. Please upload a GeoJSON or KML file for polygons.")
259
 
260
-
261
  if locations_df is not None and not locations_df.empty:
262
- # Ensure the necessary columns exist in the dataframe
263
  if 'latitude' not in locations_df.columns or 'longitude' not in locations_df.columns:
264
  st.error("Uploaded file is missing required 'latitude' or 'longitude' columns.")
265
  else:
266
- # Display a preview of the points data
267
  st.write("Preview of the uploaded points data:")
268
  st.dataframe(locations_df.head())
269
 
270
- # Create a LeafMap object to display the points
271
  m = leafmap.Map(center=[locations_df['latitude'].mean(), locations_df['longitude'].mean()], zoom=10)
272
 
273
- # Add points to the map using a loop
274
  for _, row in locations_df.iterrows():
275
  latitude = row['latitude']
276
  longitude = row['longitude']
277
 
278
- # Check if latitude or longitude are NaN and skip if they are
279
  if pd.isna(latitude) or pd.isna(longitude):
280
- continue # Skip this row and move to the next one
281
 
282
  m.add_marker(location=[latitude, longitude], popup=row.get('name', 'No Name'))
283
 
284
- # Display map
285
  st.write("Map of Uploaded Points:")
286
  m.to_streamlit()
287
-
288
- # Store the map in session_state
289
  st.session_state.map_data = m
290
 
291
- # Process each point for index calculation
292
  for idx, row in locations_df.iterrows():
293
  latitude = row['latitude']
294
  longitude = row['longitude']
295
  location_name = row.get('name', f"Location_{idx}")
296
 
297
- # Skip processing if latitude or longitude is NaN
298
  if pd.isna(latitude) or pd.isna(longitude):
299
- continue # Skip this row and move to the next one
300
 
301
- # Define the region of interest (ROI)
302
  roi = ee.Geometry.Point([longitude, latitude])
303
 
304
- # Load Sentinel-2 image collection
305
  collection = ee.ImageCollection(sub_options[sub_selection]) \
306
  .filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
307
  .filterBounds(roi)
@@ -311,8 +275,6 @@ if file_upload:
311
  st.warning(f"No images found for {location_name}.")
312
  else:
313
  st.write(f"Found images for {location_name}.")
314
- # Perform the calculation based on user selection
315
- # Perform the calculation based on user selection
316
  result = None
317
  if index_choice == 'NDVI':
318
  result = calculate_ndvi(image, roi)
@@ -326,22 +288,17 @@ if file_upload:
326
  elif index_choice.lower() == 'custom formula' and custom_formula:
327
  result = process_custom_formula(image, roi, custom_formula)
328
 
329
- # Validate result before using getInfo
330
  if result is not None:
331
- calculated_value = None # Initialize the calculated_value as None
332
 
333
- # Check if the result is a dictionary
334
  if isinstance(result, dict):
335
- # Extract the value using the appropriate key (adjust the key name as needed)
336
- calculated_value = result.get('CustomResult', None) # Replace 'CustomResult' if using NDVI, NDWI, etc.
337
  else:
338
  try:
339
- # If it's an Earth Engine object, get the value using getInfo
340
  calculated_value = result.getInfo()
341
  except Exception as e:
342
  st.error(f"Error getting result info: {e}")
343
-
344
- # If a valid calculated_value is found, append the result to session_state
345
  if calculated_value is not None:
346
  st.session_state.results.append({
347
  'Location Name': location_name,
@@ -353,9 +310,7 @@ if file_upload:
353
  st.warning(f"No value calculated for {location_name}.")
354
  else:
355
  st.warning(f"No value calculated for {location_name}.")
356
-
357
 
358
- # Check if polygons_df is populated for polygons
359
  if polygons_df is not None:
360
  st.write("Preview of the uploaded polygons data:")
361
  st.dataframe(polygons_df.head())
@@ -364,9 +319,9 @@ if polygons_df is not None:
364
 
365
  for _, row in polygons_df.iterrows():
366
  polygon = row['geometry']
367
- if polygon.is_valid:
368
- gdf = gpd.GeoDataFrame([row], geometry=[polygon], crs=polygons_df.crs)
369
- m.add_gdf(gdf=gdf, layer_name=row.get('name', 'Unnamed Polygon'))
370
 
371
  st.write("Map of Uploaded Polygons:")
372
  m.to_streamlit()
@@ -395,7 +350,8 @@ if polygons_df is not None:
395
  result = None
396
  if index_choice.lower() == 'ndvi':
397
  result = calculate_ndvi(image, roi)
398
- elif index_choice.lower() == 'ndwi':
 
399
  result = calculate_ndwi(image, roi)
400
  elif index_choice.lower() == 'average no₂':
401
  if 'NO2' in image.bandNames().getInfo():
@@ -406,22 +362,18 @@ if polygons_df is not None:
406
  result = process_custom_formula(image, roi, custom_formula)
407
 
408
  if result is not None:
409
- # Initialize the calculated_value as None
410
  calculated_value = None
411
-
412
- # Check if the result is a dictionary (e.g., custom formula result)
413
- if isinstance(result, dict) and 'CustomResult' in result:
414
- calculated_value = result['CustomResult'] # Extract the numeric value from the dictionary
415
- # If the result is a numeric value (e.g., NDVI, NDWI, or NO2)
416
- elif isinstance(result, (int, float)):
417
- calculated_value = result
418
-
419
- # If a valid calculated_value is found, append the result to session_state
420
- if calculated_value is not None:
421
- st.session_state.results.append({
422
- 'Location Name': location_name,
423
- 'Calculated Value': calculated_value
424
- })
425
 
426
  # After processing, show the results
427
  if st.session_state.results:
@@ -441,4 +393,4 @@ if st.session_state.results:
441
  data=result_df.to_csv(index=False).encode('utf-8'),
442
  file_name=filename,
443
  mime='text/csv'
444
- )
 
12
  st.set_page_config(layout="wide")
13
 
14
  # Custom button styling
15
+ st.markdown(
16
  """
17
  <style>
18
  div.stButton > button:first-child {
 
25
 
26
  # Logo
27
  st.write(
28
+ """
29
  <div style="display: flex; justify-content: space-between; align-items: center;">
30
  <img src="https://huggingface.co/spaces/YashMK89/GEE_Calculator/resolve/main/ISRO_Logo.png" style="width: 20%; margin-right: auto;">
31
  <img src="https://huggingface.co/spaces/YashMK89/GEE_Calculator/resolve/main/SAC_Logo.png" style="width: 20%; margin-left: auto;">
 
36
 
37
  # Title
38
  st.markdown(
39
+ "<h1 style='text-align: center;'>Precision Analysis for Vegetation, Water, and Air Quality</h1>",
 
 
40
  unsafe_allow_html=True,
41
  )
42
  st.write("<h2><div style='text-align: center;'>User Inputs</div></h2>", unsafe_allow_html=True)
 
183
  return no2
184
 
185
  def calculate_custom_formula(image, geometry, formula, scale=30):
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  band_names = image.bandNames().getInfo()
187
  band_dict = {band: image.select(band) for band in band_names}
188
 
 
189
  result_image = image.expression(formula, band_dict).rename('CustomResult')
190
 
 
191
  result = result_image.reduceRegion(
192
  reducer=ee.Reducer.mean(),
193
  geometry=geometry,
194
  scale=scale
195
  )
196
 
 
197
  return result
198
 
 
199
  # Function to get the most recent image from the collection
200
  def get_most_recent_image(image_collection):
201
  image = image_collection.sort('system:time_start', False).first()
 
213
  polygons_df = None # Ensure polygons_df is initialized at the beginning
214
 
215
  # Process each point (with additional checks for file validity)
 
216
  if file_upload:
 
 
 
217
  file_extension = os.path.splitext(file_upload.name)[1].lower()
218
 
219
  # Read file based on shape type
 
227
  else:
228
  st.error("Unsupported file type. Please upload a CSV, GeoJSON, or KML file for points.")
229
  elif shape_type == 'Polygon':
230
+ if file _extension == '.geojson':
231
  polygons_df = read_geojson(file_upload)
232
  elif file_extension == '.kml':
233
  polygons_df = read_kml(file_upload)
234
  else:
235
  st.error("Unsupported file type. Please upload a GeoJSON or KML file for polygons.")
236
 
 
237
  if locations_df is not None and not locations_df.empty:
 
238
  if 'latitude' not in locations_df.columns or 'longitude' not in locations_df.columns:
239
  st.error("Uploaded file is missing required 'latitude' or 'longitude' columns.")
240
  else:
 
241
  st.write("Preview of the uploaded points data:")
242
  st.dataframe(locations_df.head())
243
 
 
244
  m = leafmap.Map(center=[locations_df['latitude'].mean(), locations_df['longitude'].mean()], zoom=10)
245
 
 
246
  for _, row in locations_df.iterrows():
247
  latitude = row['latitude']
248
  longitude = row['longitude']
249
 
 
250
  if pd.isna(latitude) or pd.isna(longitude):
251
+ continue
252
 
253
  m.add_marker(location=[latitude, longitude], popup=row.get('name', 'No Name'))
254
 
 
255
  st.write("Map of Uploaded Points:")
256
  m.to_streamlit()
 
 
257
  st.session_state.map_data = m
258
 
 
259
  for idx, row in locations_df.iterrows():
260
  latitude = row['latitude']
261
  longitude = row['longitude']
262
  location_name = row.get('name', f"Location_{idx}")
263
 
 
264
  if pd.isna(latitude) or pd.isna(longitude):
265
+ continue
266
 
 
267
  roi = ee.Geometry.Point([longitude, latitude])
268
 
 
269
  collection = ee.ImageCollection(sub_options[sub_selection]) \
270
  .filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
271
  .filterBounds(roi)
 
275
  st.warning(f"No images found for {location_name}.")
276
  else:
277
  st.write(f"Found images for {location_name}.")
 
 
278
  result = None
279
  if index_choice == 'NDVI':
280
  result = calculate_ndvi(image, roi)
 
288
  elif index_choice.lower() == 'custom formula' and custom_formula:
289
  result = process_custom_formula(image, roi, custom_formula)
290
 
 
291
  if result is not None:
292
+ calculated_value = None
293
 
 
294
  if isinstance(result, dict):
295
+ calculated_value = result.get('CustomResult', None)
 
296
  else:
297
  try:
 
298
  calculated_value = result.getInfo()
299
  except Exception as e:
300
  st.error(f"Error getting result info: {e}")
301
+
 
302
  if calculated_value is not None:
303
  st.session_state.results.append({
304
  'Location Name': location_name,
 
310
  st.warning(f"No value calculated for {location_name}.")
311
  else:
312
  st.warning(f"No value calculated for {location_name}.")
 
313
 
 
314
  if polygons_df is not None:
315
  st.write("Preview of the uploaded polygons data:")
316
  st.dataframe(polygons_df.head())
 
319
 
320
  for _, row in polygons_df.iterrows():
321
  polygon = row['geometry']
322
+ if polygon.is_valid:
323
+ gdf = gpd.GeoDataFrame([row], geometry=[polygon], crs=polygons_df.crs)
324
+ m.add_gdf(gdf=gdf, layer_name=row.get('name', 'Unnamed Polygon'))
325
 
326
  st.write("Map of Uploaded Polygons:")
327
  m.to_streamlit()
 
350
  result = None
351
  if index_choice.lower() == 'ndvi':
352
  result = calculate_ndvi(image, roi)
353
+ elif index_choice.lower() ```python
354
+ == 'ndwi':
355
  result = calculate_ndwi(image, roi)
356
  elif index_choice.lower() == 'average no₂':
357
  if 'NO2' in image.bandNames().getInfo():
 
362
  result = process_custom_formula(image, roi, custom_formula)
363
 
364
  if result is not None:
 
365
  calculated_value = None
366
+
367
+ if isinstance(result, dict) and 'CustomResult' in result:
368
+ calculated_value = result['CustomResult']
369
+ elif isinstance(result, (int, float)):
370
+ calculated_value = result
371
+
372
+ if calculated_value is not None:
373
+ st.session_state.results.append({
374
+ 'Location Name': location_name,
375
+ 'Calculated Value': calculated_value
376
+ })
 
 
 
377
 
378
  # After processing, show the results
379
  if st.session_state.results:
 
393
  data=result_df.to_csv(index=False).encode('utf-8'),
394
  file_name=filename,
395
  mime='text/csv'
396
+ )