Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -229,27 +229,66 @@ 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 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
|
254 |
# Preprocessing function
|
255 |
def preprocess_collection(collection, pixel_cloud_threshold):
|
@@ -370,7 +409,6 @@ def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selec
|
|
370 |
st.error(f"Error retrieving value for {location_name}: {e}")
|
371 |
return aggregated_results
|
372 |
|
373 |
-
# Process aggregation
|
374 |
# Process aggregation
|
375 |
def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, original_lat_col, original_lon_col, custom_formula="", kernel_size=None, include_boundary=None, tile_cloud_threshold=0, pixel_cloud_threshold=0, user_scale=None):
|
376 |
aggregated_results = []
|
@@ -379,14 +417,15 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
|
|
379 |
progress_text = st.empty()
|
380 |
start_time = time.time()
|
381 |
|
382 |
-
#
|
383 |
raw_collection = ee.ImageCollection(dataset_id) \
|
384 |
.filterDate(ee.Date(start_date_str), ee.Date(end_date_str))
|
|
|
385 |
st.write(f"Original Collection Size: {raw_collection.size().getInfo()}")
|
386 |
|
387 |
-
# Apply cloud filtering
|
388 |
if pixel_cloud_threshold > 0:
|
389 |
-
raw_collection =
|
390 |
st.write(f"Filtered Collection Size (After Cloud Masking): {raw_collection.size().getInfo()}")
|
391 |
|
392 |
# Use ThreadPoolExecutor to process each geometry
|
|
|
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 filter_images_by_cloud_percentage(collection, max_cloud_percentage):
|
255 |
+
def calculate_cloud_percentage(image):
|
256 |
+
# Extract the QA60 band
|
257 |
+
qa60 = image.select('QA60')
|
258 |
+
|
259 |
+
# Identify opaque and cirrus clouds
|
260 |
+
opaque_clouds = qa60.bitwiseAnd(1 << 10)
|
261 |
+
cirrus_clouds = qa60.bitwiseAnd(1 << 11)
|
262 |
+
cloud_mask = opaque_clouds.Or(cirrus_clouds)
|
263 |
+
|
264 |
+
# Count total pixels and cloudy pixels
|
265 |
+
total_pixels = qa60.reduceRegion(
|
266 |
+
reducer=ee.Reducer.count(),
|
267 |
+
geometry=image.geometry(),
|
268 |
+
scale=60,
|
269 |
+
maxPixels=1e13
|
270 |
+
).get('QA60')
|
271 |
+
|
272 |
+
cloudy_pixels = cloud_mask.reduceRegion(
|
273 |
+
reducer=ee.Reducer.sum(),
|
274 |
+
geometry=image.geometry(),
|
275 |
+
scale=60,
|
276 |
+
maxPixels=1e13
|
277 |
+
).get('QA60')
|
278 |
+
|
279 |
+
# Calculate cloud percentage
|
280 |
+
cloud_percentage = ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
|
281 |
+
|
282 |
+
# Return the cloud percentage as a property of the image
|
283 |
+
return image.set('cloud_percentage', cloud_percentage)
|
284 |
+
|
285 |
+
# Map the cloud percentage calculation over the collection
|
286 |
+
collection_with_clouds = collection.map(calculate_cloud_percentage)
|
287 |
+
|
288 |
+
# Filter out images with cloud percentage exceeding the threshold
|
289 |
+
filtered_collection = collection_with_clouds.filter(ee.Filter.lt('cloud_percentage', max_cloud_percentage))
|
290 |
+
|
291 |
+
return filtered_collection
|
292 |
|
293 |
# Preprocessing function
|
294 |
def preprocess_collection(collection, pixel_cloud_threshold):
|
|
|
409 |
st.error(f"Error retrieving value for {location_name}: {e}")
|
410 |
return aggregated_results
|
411 |
|
|
|
412 |
# Process aggregation
|
413 |
def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, original_lat_col, original_lon_col, custom_formula="", kernel_size=None, include_boundary=None, tile_cloud_threshold=0, pixel_cloud_threshold=0, user_scale=None):
|
414 |
aggregated_results = []
|
|
|
417 |
progress_text = st.empty()
|
418 |
start_time = time.time()
|
419 |
|
420 |
+
# Fetch the original collection
|
421 |
raw_collection = ee.ImageCollection(dataset_id) \
|
422 |
.filterDate(ee.Date(start_date_str), ee.Date(end_date_str))
|
423 |
+
|
424 |
st.write(f"Original Collection Size: {raw_collection.size().getInfo()}")
|
425 |
|
426 |
+
# Apply cloud filtering at the image level
|
427 |
if pixel_cloud_threshold > 0:
|
428 |
+
raw_collection = filter_images_by_cloud_percentage(raw_collection, pixel_cloud_threshold)
|
429 |
st.write(f"Filtered Collection Size (After Cloud Masking): {raw_collection.size().getInfo()}")
|
430 |
|
431 |
# Use ThreadPoolExecutor to process each geometry
|