YashMK89 commited on
Commit
d80d309
·
verified ·
1 Parent(s): 4c16148

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -83
app.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
  import streamlit as st
3
  import json
4
  import ee
@@ -229,77 +228,38 @@ def aggregate_data_yearly(collection):
229
  yearly_images = ee.List(grouped_by_year.map(calculate_yearly_mean))
230
  return ee.ImageCollection(yearly_images)
231
 
232
- # # Cloud percentage calculation
233
- # def calculate_cloud_percentage(image, cloud_band='QA60'):
234
- # qa60 = image.select(cloud_band)
235
- # opaque_clouds = qa60.bitwiseAnd(1 << 10)
236
- # cirrus_clouds = qa60.bitwiseAnd(1 << 11)
237
- # cloud_mask = opaque_clouds.Or(cirrus_clouds)
238
- # total_pixels = qa60.reduceRegion(
239
- # reducer=ee.Reducer.count(),
240
- # geometry=image.geometry(),
241
- # scale=60,
242
- # maxPixels=1e13
243
- # ).get(cloud_band)
244
- # cloudy_pixels = cloud_mask.reduceRegion(
245
- # reducer=ee.Reducer.sum(),
246
- # geometry=image.geometry(),
247
- # scale=60,
248
- # maxPixels=1e13
249
- # ).get(cloud_band)
250
- # if total_pixels == 0:
251
- # return 0
252
- # return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
253
-
254
- def calculate_cloud_percentage(image):
255
- # Check if QA60 band exists (Level-1C)
256
- bands = image.bandNames().getInfo()
257
- if 'QA60' in bands:
258
- qa60 = image.select('QA60')
259
- opaque_clouds = qa60.bitwiseAnd(1 << 10)
260
- cirrus_clouds = qa60.bitwiseAnd(1 << 11)
261
- cloud_mask = opaque_clouds.Or(cirrus_clouds)
262
- elif 'SCL' in bands: # Check if SCL band exists (Level-2A)
263
- scl = image.select('SCL')
264
- cloud_mask = scl.eq(8).Or(scl.eq(9)).Or(scl.eq(10)) # Cloud, cirrus, snow/ice
265
- else:
266
- raise ValueError("Cloud masking bands (QA60 or SCL) not found in the dataset.")
267
-
268
- total_pixels = cloud_mask.reduceRegion(
269
  reducer=ee.Reducer.count(),
270
  geometry=image.geometry(),
271
  scale=60,
272
  maxPixels=1e13
273
- ).get('constant') # Use 'constant' for renamed bands
274
-
275
  cloudy_pixels = cloud_mask.reduceRegion(
276
  reducer=ee.Reducer.sum(),
277
  geometry=image.geometry(),
278
  scale=60,
279
  maxPixels=1e13
280
- ).get('constant')
281
-
282
  if total_pixels == 0:
283
  return 0
284
  return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
285
-
 
286
  def preprocess_collection(collection, pixel_cloud_threshold):
287
  def mask_cloudy_pixels(image):
288
- bands = image.bandNames().getInfo()
289
- if 'QA60' in bands: # Level-1C
290
- qa60 = image.select('QA60')
291
- opaque_clouds = qa60.bitwiseAnd(1 << 10)
292
- cirrus_clouds = qa60.bitwiseAnd(1 << 11)
293
- cloud_mask = opaque_clouds.Or(cirrus_clouds)
294
- elif 'SCL' in bands: # Level-2A
295
- scl = image.select('SCL')
296
- cloud_mask = scl.eq(8).Or(scl.eq(9)).Or(scl.eq(10)) # Cloud, cirrus, snow/ice
297
- else:
298
- raise ValueError("Cloud masking bands (QA60 or SCL) not found in the dataset.")
299
-
300
  clear_pixels = cloud_mask.Not()
301
  return image.updateMask(clear_pixels)
302
-
303
  if pixel_cloud_threshold > 0:
304
  return collection.map(mask_cloudy_pixels)
305
  return collection
@@ -329,18 +289,19 @@ def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selec
329
  roi = roi.buffer(-30).bounds()
330
  except ValueError:
331
  return None
332
-
333
  # Filter collection by date and area first
334
  collection = ee.ImageCollection(dataset_id) \
335
  .filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
336
  .filterBounds(roi)
337
-
338
- # Apply cloud filtering if applicable
 
 
339
  if pixel_cloud_threshold > 0:
340
  collection = preprocess_collection(collection, pixel_cloud_threshold)
341
  st.write(f"After cloud masking: {collection.size().getInfo()} images")
342
-
343
- # Apply temporal aggregation
344
  if aggregation_period.lower() == 'custom (start date to end date)':
345
  collection = aggregate_data_custom(collection)
346
  elif aggregation_period.lower() == 'daily':
@@ -351,8 +312,7 @@ def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selec
351
  collection = aggregate_data_monthly(collection, start_date_str, end_date_str)
352
  elif aggregation_period.lower() == 'yearly':
353
  collection = aggregate_data_yearly(collection)
354
-
355
- # Process the filtered collection
356
  image_list = collection.toList(collection.size())
357
  processed_weeks = set()
358
  aggregated_results = []
@@ -383,7 +343,7 @@ def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selec
383
  timestamp = image.get('year')
384
  period_label = 'Year'
385
  date = ee.Date(timestamp).format('YYYY').getInfo()
386
-
387
  index_image = calculate_custom_formula(image, roi, selected_bands, custom_formula, reducer_choice, dataset_id, user_scale=user_scale)
388
  try:
389
  index_value = index_image.reduceRegion(
@@ -415,23 +375,16 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
415
  progress_bar = st.progress(0)
416
  progress_text = st.empty()
417
  start_time = time.time()
418
-
419
- # Fetch the original collection
420
  raw_collection = ee.ImageCollection(dataset_id) \
421
  .filterDate(ee.Date(start_date_str), ee.Date(end_date_str))
422
-
423
  st.write(f"Original Collection Size: {raw_collection.size().getInfo()}")
424
-
425
- # Apply cloud filtering if applicable
426
- if pixel_cloud_threshold > 0:
427
- try:
428
- raw_collection = preprocess_collection(raw_collection, pixel_cloud_threshold)
429
- st.write(f"Filtered Collection Size (After Cloud Masking): {raw_collection.size().getInfo()}")
430
- except Exception as e:
431
- st.error(f"Cloud masking failed: {str(e)}")
432
- st.stop()
433
-
434
- # Use ThreadPoolExecutor to process each geometry
435
  with ThreadPoolExecutor(max_workers=10) as executor:
436
  futures = []
437
  for idx, row in locations_df.iterrows():
@@ -453,7 +406,6 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
453
  user_scale=user_scale
454
  )
455
  futures.append(future)
456
-
457
  completed = 0
458
  for future in as_completed(futures):
459
  result = future.result()
@@ -463,10 +415,10 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
463
  progress_percentage = completed / total_steps
464
  progress_bar.progress(progress_percentage)
465
  progress_text.markdown(f"Processing: {int(progress_percentage * 100)}%")
466
-
467
  end_time = time.time()
468
  processing_time = end_time - start_time
469
-
470
  if aggregated_results:
471
  result_df = pd.DataFrame(aggregated_results)
472
  if aggregation_period.lower() == 'custom (start date to end date)':
@@ -484,8 +436,8 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
484
  else:
485
  return result_df.to_dict(orient='records'), processing_time
486
  return [], processing_time
487
-
488
- #streamlit logic
489
  st.markdown("<h5>Image Collection</h5>", unsafe_allow_html=True)
490
  imagery_base = st.selectbox("Select Imagery Base", ["Sentinel", "Landsat", "MODIS", "VIIRS", "Custom Input"], index=0)
491
  data = {}
 
 
1
  import streamlit as st
2
  import json
3
  import ee
 
228
  yearly_images = ee.List(grouped_by_year.map(calculate_yearly_mean))
229
  return ee.ImageCollection(yearly_images)
230
 
231
+ # Cloud percentage calculation
232
+ def calculate_cloud_percentage(image, cloud_band='QA60'):
233
+ qa60 = image.select(cloud_band)
234
+ opaque_clouds = qa60.bitwiseAnd(1 << 10)
235
+ cirrus_clouds = qa60.bitwiseAnd(1 << 11)
236
+ cloud_mask = opaque_clouds.Or(cirrus_clouds)
237
+ total_pixels = qa60.reduceRegion(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  reducer=ee.Reducer.count(),
239
  geometry=image.geometry(),
240
  scale=60,
241
  maxPixels=1e13
242
+ ).get(cloud_band)
 
243
  cloudy_pixels = cloud_mask.reduceRegion(
244
  reducer=ee.Reducer.sum(),
245
  geometry=image.geometry(),
246
  scale=60,
247
  maxPixels=1e13
248
+ ).get(cloud_band)
 
249
  if total_pixels == 0:
250
  return 0
251
  return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
252
+
253
+ # Preprocessing function
254
  def preprocess_collection(collection, pixel_cloud_threshold):
255
  def mask_cloudy_pixels(image):
256
+ qa60 = image.select('QA60')
257
+ opaque_clouds = qa60.bitwiseAnd(1 << 10)
258
+ cirrus_clouds = qa60.bitwiseAnd(1 << 11)
259
+ cloud_mask = opaque_clouds.Or(cirrus_clouds)
 
 
 
 
 
 
 
 
260
  clear_pixels = cloud_mask.Not()
261
  return image.updateMask(clear_pixels)
262
+
263
  if pixel_cloud_threshold > 0:
264
  return collection.map(mask_cloudy_pixels)
265
  return collection
 
289
  roi = roi.buffer(-30).bounds()
290
  except ValueError:
291
  return None
292
+
293
  # Filter collection by date and area first
294
  collection = ee.ImageCollection(dataset_id) \
295
  .filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
296
  .filterBounds(roi)
297
+
298
+ st.write(f"After initial filtering: {collection.size().getInfo()} images")
299
+
300
+ # Apply pixel cloud masking if threshold > 0
301
  if pixel_cloud_threshold > 0:
302
  collection = preprocess_collection(collection, pixel_cloud_threshold)
303
  st.write(f"After cloud masking: {collection.size().getInfo()} images")
304
+
 
305
  if aggregation_period.lower() == 'custom (start date to end date)':
306
  collection = aggregate_data_custom(collection)
307
  elif aggregation_period.lower() == 'daily':
 
312
  collection = aggregate_data_monthly(collection, start_date_str, end_date_str)
313
  elif aggregation_period.lower() == 'yearly':
314
  collection = aggregate_data_yearly(collection)
315
+
 
316
  image_list = collection.toList(collection.size())
317
  processed_weeks = set()
318
  aggregated_results = []
 
343
  timestamp = image.get('year')
344
  period_label = 'Year'
345
  date = ee.Date(timestamp).format('YYYY').getInfo()
346
+
347
  index_image = calculate_custom_formula(image, roi, selected_bands, custom_formula, reducer_choice, dataset_id, user_scale=user_scale)
348
  try:
349
  index_value = index_image.reduceRegion(
 
375
  progress_bar = st.progress(0)
376
  progress_text = st.empty()
377
  start_time = time.time()
378
+
 
379
  raw_collection = ee.ImageCollection(dataset_id) \
380
  .filterDate(ee.Date(start_date_str), ee.Date(end_date_str))
381
+
382
  st.write(f"Original Collection Size: {raw_collection.size().getInfo()}")
383
+
384
+ if tile_cloud_threshold > 0 or pixel_cloud_threshold > 0:
385
+ raw_collection = preprocess_collection(raw_collection, pixel_cloud_threshold)
386
+ st.write(f"Preprocessed Collection Size: {raw_collection.size().getInfo()}")
387
+
 
 
 
 
 
 
388
  with ThreadPoolExecutor(max_workers=10) as executor:
389
  futures = []
390
  for idx, row in locations_df.iterrows():
 
406
  user_scale=user_scale
407
  )
408
  futures.append(future)
 
409
  completed = 0
410
  for future in as_completed(futures):
411
  result = future.result()
 
415
  progress_percentage = completed / total_steps
416
  progress_bar.progress(progress_percentage)
417
  progress_text.markdown(f"Processing: {int(progress_percentage * 100)}%")
418
+
419
  end_time = time.time()
420
  processing_time = end_time - start_time
421
+
422
  if aggregated_results:
423
  result_df = pd.DataFrame(aggregated_results)
424
  if aggregation_period.lower() == 'custom (start date to end date)':
 
436
  else:
437
  return result_df.to_dict(orient='records'), processing_time
438
  return [], processing_time
439
+
440
+ # Streamlit App Logic
441
  st.markdown("<h5>Image Collection</h5>", unsafe_allow_html=True)
442
  imagery_base = st.selectbox("Select Imagery Base", ["Sentinel", "Landsat", "MODIS", "VIIRS", "Custom Input"], index=0)
443
  data = {}