Spaces:
Running
Running
update app.py
Browse files
app.py
CHANGED
@@ -242,10 +242,42 @@ def aggregate_data_yearly(collection):
|
|
242 |
yearly_images = ee.List(grouped_by_year.map(calculate_yearly_mean))
|
243 |
return ee.ImageCollection(yearly_images)
|
244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
def preprocess_collection(collection, tile_cloud_threshold, pixel_cloud_threshold):
|
246 |
def filter_tile(image):
|
247 |
cloud_percentage = calculate_cloud_percentage(image, cloud_band='QA60')
|
248 |
return image.set('cloud_percentage', cloud_percentage).updateMask(cloud_percentage.lt(tile_cloud_threshold))
|
|
|
249 |
def mask_cloudy_pixels(image):
|
250 |
qa60 = image.select('QA60')
|
251 |
opaque_clouds = qa60.bitwiseAnd(1 << 10)
|
@@ -253,6 +285,7 @@ def preprocess_collection(collection, tile_cloud_threshold, pixel_cloud_threshol
|
|
253 |
cloud_mask = opaque_clouds.Or(cirrus_clouds)
|
254 |
clear_pixels = cloud_mask.Not()
|
255 |
return image.updateMask(clear_pixels)
|
|
|
256 |
filtered_collection = collection.map(filter_tile)
|
257 |
masked_collection = filtered_collection.map(mask_cloudy_pixels)
|
258 |
return masked_collection
|
|
|
242 |
yearly_images = ee.List(grouped_by_year.map(calculate_yearly_mean))
|
243 |
return ee.ImageCollection(yearly_images)
|
244 |
|
245 |
+
# Define the function before using it
|
246 |
+
def calculate_cloud_percentage(image, cloud_band='QA60'):
|
247 |
+
"""
|
248 |
+
Calculate the percentage of cloud-covered pixels in an image using the QA60 bitmask.
|
249 |
+
Assumes the presence of the QA60 cloud mask band.
|
250 |
+
"""
|
251 |
+
# Decode the QA60 bitmask
|
252 |
+
qa60 = image.select(cloud_band)
|
253 |
+
opaque_clouds = qa60.bitwiseAnd(1 << 10) # Bit 10: Opaque clouds
|
254 |
+
cirrus_clouds = qa60.bitwiseAnd(1 << 11) # Bit 11: Cirrus clouds
|
255 |
+
# Combine both cloud types into a single cloud mask
|
256 |
+
cloud_mask = opaque_clouds.Or(cirrus_clouds)
|
257 |
+
# Count total pixels and cloudy pixels
|
258 |
+
total_pixels = qa60.reduceRegion(
|
259 |
+
reducer=ee.Reducer.count(),
|
260 |
+
geometry=image.geometry(),
|
261 |
+
scale=60, # QA60 resolution is 60 meters
|
262 |
+
maxPixels=1e13
|
263 |
+
).get(cloud_band)
|
264 |
+
cloudy_pixels = cloud_mask.reduceRegion(
|
265 |
+
reducer=ee.Reducer.sum(),
|
266 |
+
geometry=image.geometry(),
|
267 |
+
scale=60, # QA60 resolution is 60 meters
|
268 |
+
maxPixels=1e13
|
269 |
+
).get(cloud_band)
|
270 |
+
# Calculate cloud percentage
|
271 |
+
if total_pixels == 0:
|
272 |
+
return 0 # Avoid division by zero
|
273 |
+
return ee.Number(cloudy_pixels).divide(ee.Number(total_pixels)).multiply(100)
|
274 |
+
|
275 |
+
# Use the function in preprocessing
|
276 |
def preprocess_collection(collection, tile_cloud_threshold, pixel_cloud_threshold):
|
277 |
def filter_tile(image):
|
278 |
cloud_percentage = calculate_cloud_percentage(image, cloud_band='QA60')
|
279 |
return image.set('cloud_percentage', cloud_percentage).updateMask(cloud_percentage.lt(tile_cloud_threshold))
|
280 |
+
|
281 |
def mask_cloudy_pixels(image):
|
282 |
qa60 = image.select('QA60')
|
283 |
opaque_clouds = qa60.bitwiseAnd(1 << 10)
|
|
|
285 |
cloud_mask = opaque_clouds.Or(cirrus_clouds)
|
286 |
clear_pixels = cloud_mask.Not()
|
287 |
return image.updateMask(clear_pixels)
|
288 |
+
|
289 |
filtered_collection = collection.map(filter_tile)
|
290 |
masked_collection = filtered_collection.map(mask_cloudy_pixels)
|
291 |
return masked_collection
|