Spaces:
Running
Running
update app.py
Browse files
app.py
CHANGED
@@ -207,11 +207,12 @@ def aggregate_data_daily(collection):
|
|
207 |
|
208 |
# Worker function for processing a single geometry
|
209 |
def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, custom_formula, kernel_size=None, include_boundary=None, default_scale=None):
|
|
|
210 |
if shape_type.lower() == "point":
|
211 |
latitude = row.get('latitude')
|
212 |
longitude = row.get('longitude')
|
213 |
if pd.isna(latitude) or pd.isna(longitude):
|
214 |
-
return None #
|
215 |
location_name = row.get('name', f"Location_{row.name}")
|
216 |
if kernel_size == "3x3 Kernel":
|
217 |
buffer_size = 45 # 90m x 90m
|
@@ -229,13 +230,17 @@ def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selec
|
|
229 |
if not include_boundary:
|
230 |
roi = roi.buffer(-30).bounds()
|
231 |
except ValueError:
|
232 |
-
return None #
|
233 |
|
234 |
collection = ee.ImageCollection(dataset_id) \
|
235 |
.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
|
236 |
.filterBounds(roi) \
|
237 |
.select(selected_bands)
|
238 |
|
|
|
|
|
|
|
|
|
239 |
if aggregation_period.lower() == 'custom (start date to end date)':
|
240 |
collection = aggregate_data_custom(collection)
|
241 |
elif aggregation_period.lower() == 'daily':
|
@@ -298,7 +303,7 @@ def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selec
|
|
298 |
except Exception as e:
|
299 |
st.error(f"Error retrieving value for {location_name}: {e}")
|
300 |
|
301 |
-
return aggregated_results
|
302 |
|
303 |
# Main processing function
|
304 |
def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, custom_formula="", kernel_size=None, include_boundary=None, default_scale=None):
|
@@ -308,6 +313,7 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
|
|
308 |
default_scale = collection.first().select(0).projection().nominalScale().getInfo()
|
309 |
|
310 |
aggregated_results = []
|
|
|
311 |
total_steps = len(locations_df)
|
312 |
progress_bar = st.progress(0)
|
313 |
progress_text = st.empty()
|
@@ -335,13 +341,14 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
|
|
335 |
|
336 |
completed = 0
|
337 |
for future in as_completed(futures):
|
338 |
-
result = future.result()
|
339 |
if result:
|
340 |
aggregated_results.extend(result)
|
|
|
341 |
completed += 1
|
342 |
progress_percentage = completed / total_steps
|
343 |
progress_bar.progress(progress_percentage)
|
344 |
-
progress_text.markdown(f"Processing: {int(progress_percentage * 100)}%")
|
345 |
|
346 |
end_time = time.time()
|
347 |
processing_time = end_time - start_time
|
@@ -359,10 +366,10 @@ def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id,
|
|
359 |
agg_dict['Longitude'] = 'first'
|
360 |
aggregated_output = result_df.groupby('Location Name').agg(agg_dict).reset_index()
|
361 |
aggregated_output.rename(columns={'Calculated Value': 'Aggregated Value'}, inplace=True)
|
362 |
-
return aggregated_output.to_dict(orient='records'), processing_time
|
363 |
else:
|
364 |
-
return result_df.to_dict(orient='records'), processing_time
|
365 |
-
return [], processing_time
|
366 |
|
367 |
# Streamlit App Logic
|
368 |
st.markdown("<h5>Image Collection</h5>", unsafe_allow_html=True)
|
@@ -691,8 +698,8 @@ if st.button(f"Calculate {custom_formula}"):
|
|
691 |
# Use a spinner to indicate data processing
|
692 |
with st.spinner("Processing Data..."):
|
693 |
try:
|
694 |
-
# Call the aggregation function and capture results and
|
695 |
-
results, processing_time = process_aggregation(
|
696 |
locations_df,
|
697 |
start_date_str,
|
698 |
end_date_str,
|
@@ -710,6 +717,7 @@ if st.button(f"Calculate {custom_formula}"):
|
|
710 |
if results:
|
711 |
result_df = pd.DataFrame(results)
|
712 |
st.write(f"Default Scale for Selected Dataset: {default_scale} meters")
|
|
|
713 |
st.write(f"Processed Results Table ({aggregation_period}) for Formula: {custom_formula}")
|
714 |
st.dataframe(result_df)
|
715 |
# Generate a downloadable CSV file
|
@@ -722,7 +730,7 @@ if st.button(f"Calculate {custom_formula}"):
|
|
722 |
mime='text/csv'
|
723 |
)
|
724 |
# Display processing time
|
725 |
-
st.success(f"Processing complete! Total processing time: {processing_time:.2f} seconds.")
|
726 |
else:
|
727 |
st.warning("No results were generated. Check your inputs or formula.")
|
728 |
st.info(f"Total processing time: {processing_time:.2f} seconds.") # Show processing time even if no results
|
|
|
207 |
|
208 |
# Worker function for processing a single geometry
|
209 |
def process_single_geometry(row, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, custom_formula, kernel_size=None, include_boundary=None, default_scale=None):
|
210 |
+
image_count = 0 # Initialize image counter
|
211 |
if shape_type.lower() == "point":
|
212 |
latitude = row.get('latitude')
|
213 |
longitude = row.get('longitude')
|
214 |
if pd.isna(latitude) or pd.isna(longitude):
|
215 |
+
return None, 0 # Return 0 images for invalid points
|
216 |
location_name = row.get('name', f"Location_{row.name}")
|
217 |
if kernel_size == "3x3 Kernel":
|
218 |
buffer_size = 45 # 90m x 90m
|
|
|
230 |
if not include_boundary:
|
231 |
roi = roi.buffer(-30).bounds()
|
232 |
except ValueError:
|
233 |
+
return None, 0 # Return 0 images for invalid polygons
|
234 |
|
235 |
collection = ee.ImageCollection(dataset_id) \
|
236 |
.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
|
237 |
.filterBounds(roi) \
|
238 |
.select(selected_bands)
|
239 |
|
240 |
+
# Get the count of images before aggregation
|
241 |
+
initial_count = collection.size().getInfo()
|
242 |
+
image_count += initial_count
|
243 |
+
|
244 |
if aggregation_period.lower() == 'custom (start date to end date)':
|
245 |
collection = aggregate_data_custom(collection)
|
246 |
elif aggregation_period.lower() == 'daily':
|
|
|
303 |
except Exception as e:
|
304 |
st.error(f"Error retrieving value for {location_name}: {e}")
|
305 |
|
306 |
+
return aggregated_results, image_count # Return both results and image count
|
307 |
|
308 |
# Main processing function
|
309 |
def process_aggregation(locations_df, start_date_str, end_date_str, dataset_id, selected_bands, reducer_choice, shape_type, aggregation_period, custom_formula="", kernel_size=None, include_boundary=None, default_scale=None):
|
|
|
313 |
default_scale = collection.first().select(0).projection().nominalScale().getInfo()
|
314 |
|
315 |
aggregated_results = []
|
316 |
+
total_images = 0 # Track total images processed
|
317 |
total_steps = len(locations_df)
|
318 |
progress_bar = st.progress(0)
|
319 |
progress_text = st.empty()
|
|
|
341 |
|
342 |
completed = 0
|
343 |
for future in as_completed(futures):
|
344 |
+
result, image_count = future.result()
|
345 |
if result:
|
346 |
aggregated_results.extend(result)
|
347 |
+
total_images += image_count
|
348 |
completed += 1
|
349 |
progress_percentage = completed / total_steps
|
350 |
progress_bar.progress(progress_percentage)
|
351 |
+
progress_text.markdown(f"Processing: {int(progress_percentage * 100)}% (Total images: {total_images})")
|
352 |
|
353 |
end_time = time.time()
|
354 |
processing_time = end_time - start_time
|
|
|
366 |
agg_dict['Longitude'] = 'first'
|
367 |
aggregated_output = result_df.groupby('Location Name').agg(agg_dict).reset_index()
|
368 |
aggregated_output.rename(columns={'Calculated Value': 'Aggregated Value'}, inplace=True)
|
369 |
+
return aggregated_output.to_dict(orient='records'), processing_time, total_images
|
370 |
else:
|
371 |
+
return result_df.to_dict(orient='records'), processing_time, total_images
|
372 |
+
return [], processing_time, total_images
|
373 |
|
374 |
# Streamlit App Logic
|
375 |
st.markdown("<h5>Image Collection</h5>", unsafe_allow_html=True)
|
|
|
698 |
# Use a spinner to indicate data processing
|
699 |
with st.spinner("Processing Data..."):
|
700 |
try:
|
701 |
+
# Call the aggregation function and capture results, processing time, and image count
|
702 |
+
results, processing_time, total_images = process_aggregation(
|
703 |
locations_df,
|
704 |
start_date_str,
|
705 |
end_date_str,
|
|
|
717 |
if results:
|
718 |
result_df = pd.DataFrame(results)
|
719 |
st.write(f"Default Scale for Selected Dataset: {default_scale} meters")
|
720 |
+
st.write(f"Total Images Processed: {total_images}")
|
721 |
st.write(f"Processed Results Table ({aggregation_period}) for Formula: {custom_formula}")
|
722 |
st.dataframe(result_df)
|
723 |
# Generate a downloadable CSV file
|
|
|
730 |
mime='text/csv'
|
731 |
)
|
732 |
# Display processing time
|
733 |
+
st.success(f"Processing complete! Total processing time: {processing_time:.2f} seconds for {total_images} images.")
|
734 |
else:
|
735 |
st.warning("No results were generated. Check your inputs or formula.")
|
736 |
st.info(f"Total processing time: {processing_time:.2f} seconds.") # Show processing time even if no results
|