Spaces:
Running
Running
update app.py
Browse files
app.py
CHANGED
@@ -493,6 +493,12 @@ if shape_type.lower() == "point":
|
|
493 |
index=0,
|
494 |
help="Choose 'Point' for exact point calculation, or a kernel size for area averaging."
|
495 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
496 |
elif shape_type.lower() == "polygon":
|
497 |
include_boundary = st.checkbox(
|
498 |
"Include Boundary Pixels",
|
@@ -503,102 +509,51 @@ elif shape_type.lower() == "polygon":
|
|
503 |
file_upload = st.file_uploader(f"Upload your {shape_type} data (CSV, GeoJSON, KML)", type=["csv", "geojson", "kml"])
|
504 |
locations_df = pd.DataFrame()
|
505 |
|
506 |
-
# if file_upload is not None:
|
507 |
-
# if shape_type.lower() == "point":
|
508 |
-
# if file_upload.name.endswith('.csv'):
|
509 |
-
# locations_df = pd.read_csv(file_upload)
|
510 |
-
# elif file_upload.name.endswith('.geojson'):
|
511 |
-
# locations_df = gpd.read_file(file_upload)
|
512 |
-
# elif file_upload.name.endswith('.kml'):
|
513 |
-
# kml_string = file_upload.read().decode('utf-8')
|
514 |
-
# try:
|
515 |
-
# root = XET.fromstring(kml_string)
|
516 |
-
# ns = {'kml': 'http://www.opengis.net/kml/2.2'}
|
517 |
-
# points = []
|
518 |
-
# for placemark in root.findall('.//kml:Placemark', ns):
|
519 |
-
# name = placemark.findtext('kml:name', default=f"Point_{len(points)}", namespaces=ns)
|
520 |
-
# coords_elem = placemark.find('.//kml:Point/kml:coordinates', ns)
|
521 |
-
# if coords_elem is not None:
|
522 |
-
# coords_text = coords_elem.text.strip()
|
523 |
-
# coords = [c.strip() for c in coords_text.split(',')]
|
524 |
-
# if len(coords) >= 2:
|
525 |
-
# lon, lat = float(coords[0]), float(coords[1])
|
526 |
-
# points.append({'name': name, 'geometry': f"POINT ({lon} {lat})"})
|
527 |
-
# if not points:
|
528 |
-
# st.error("No valid Point data found in the KML file.")
|
529 |
-
# else:
|
530 |
-
# locations_df = gpd.GeoDataFrame(points, geometry=gpd.GeoSeries.from_wkt([p['geometry'] for p in points]), crs="EPSG:4326")
|
531 |
-
# except Exception as e:
|
532 |
-
# st.error(f"Error parsing KML file: {str(e)}")
|
533 |
-
# elif shape_type.lower() == "polygon":
|
534 |
-
# if file_upload.name.endswith('.csv'):
|
535 |
-
# locations_df = pd.read_csv(file_upload)
|
536 |
-
# elif file_upload.name.endswith('.geojson'):
|
537 |
-
# locations_df = gpd.read_file(file_upload)
|
538 |
-
# elif file_upload.name.endswith('.kml'):
|
539 |
-
# kml_string = file_upload.read().decode('utf-8')
|
540 |
-
# try:
|
541 |
-
# root = XET.fromstring(kml_string)
|
542 |
-
# ns = {'kml': 'http://www.opengis.net/kml/2.2'}
|
543 |
-
# polygons = []
|
544 |
-
# for placemark in root.findall('.//kml:Placemark', ns):
|
545 |
-
# name = placemark.findtext('kml:name', default=f"Polygon_{len(polygons)}", namespaces=ns)
|
546 |
-
# coords_elem = placemark.find('.//kml:Polygon//kml:coordinates', ns)
|
547 |
-
# if coords_elem is not None:
|
548 |
-
# coords_text = ' '.join(coords_elem.text.split())
|
549 |
-
# coord_pairs = [pair.split(',')[:2] for pair in coords_text.split() if pair]
|
550 |
-
# if len(coord_pairs) >= 4:
|
551 |
-
# coords_str = " ".join([f"{float(lon)} {float(lat)}" for lon, lat in coord_pairs])
|
552 |
-
# polygons.append({'name': name, 'geometry': f"POLYGON (({coords_str}))"})
|
553 |
-
# if not polygons:
|
554 |
-
# st.error("No valid Polygon data found in the KML file.")
|
555 |
-
# else:
|
556 |
-
# locations_df = gpd.GeoDataFrame(polygons, geometry=gpd.GeoSeries.from_wkt([p['geometry'] for p in polygons]), crs="EPSG:4326")
|
557 |
-
# except Exception as e:
|
558 |
-
# st.error(f"Error parsing KML file: {str(e)}")
|
559 |
-
|
560 |
-
# # Display uploaded data preview and map
|
561 |
-
# if not locations_df.empty:
|
562 |
-
# st.write("Preview of Uploaded Data:")
|
563 |
-
# st.dataframe(locations_df.head())
|
564 |
-
|
565 |
-
# if 'geometry' in locations_df.columns:
|
566 |
-
# if shape_type.lower() == "point":
|
567 |
-
# locations_df['latitude'] = locations_df['geometry'].y
|
568 |
-
# locations_df['longitude'] = locations_df['geometry'].x
|
569 |
-
# m = leafmap.Map(center=[locations_df['latitude'].mean(), locations_df['longitude'].mean()], zoom=10)
|
570 |
-
# for _, row in locations_df.iterrows():
|
571 |
-
# latitude = row['latitude']
|
572 |
-
# longitude = row['longitude']
|
573 |
-
# if pd.isna(latitude) or pd.isna(longitude):
|
574 |
-
# continue
|
575 |
-
# m.add_marker(location=[latitude, longitude], popup=row.get('name', 'No Name'))
|
576 |
-
# st.write("Map of Uploaded Points:")
|
577 |
-
# m.to_streamlit()
|
578 |
-
# elif shape_type.lower() == "polygon":
|
579 |
-
# centroid_lat = locations_df.geometry.centroid.y.mean()
|
580 |
-
# centroid_lon = locations_df.geometry.centroid.x.mean()
|
581 |
-
# m = leafmap.Map(center=[centroid_lat, centroid_lon], zoom=10)
|
582 |
-
# for _, row in locations_df.iterrows():
|
583 |
-
# polygon = row['geometry']
|
584 |
-
# if polygon.is_valid:
|
585 |
-
# gdf = gpd.GeoDataFrame([row], geometry=[polygon], crs=locations_df.crs)
|
586 |
-
# m.add_gdf(gdf=gdf, layer_name=row.get('name', 'Unnamed Polygon'))
|
587 |
-
# st.write("Map of Uploaded Polygons:")
|
588 |
-
# m.to_streamlit()
|
589 |
-
|
590 |
if file_upload is not None:
|
591 |
-
# Read the user-uploaded file
|
592 |
if shape_type.lower() == "point":
|
593 |
if file_upload.name.endswith('.csv'):
|
|
|
594 |
locations_df = pd.read_csv(file_upload)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
595 |
elif file_upload.name.endswith('.geojson'):
|
596 |
locations_df = gpd.read_file(file_upload)
|
|
|
|
|
|
|
597 |
elif file_upload.name.endswith('.kml'):
|
598 |
-
# Parse KML file for point data
|
599 |
kml_string = file_upload.read().decode('utf-8')
|
600 |
try:
|
601 |
-
# Use xml.etree.ElementTree with unique alias
|
602 |
root = XET.fromstring(kml_string)
|
603 |
ns = {'kml': 'http://www.opengis.net/kml/2.2'}
|
604 |
points = []
|
@@ -607,57 +562,40 @@ if file_upload is not None:
|
|
607 |
coords_elem = placemark.find('.//kml:Point/kml:coordinates', ns)
|
608 |
if coords_elem is not None:
|
609 |
coords_text = coords_elem.text.strip()
|
610 |
-
st.write(f"Debug: Point coordinates found - {coords_text}") # Debug output
|
611 |
coords = [c.strip() for c in coords_text.split(',')]
|
612 |
-
if len(coords) >= 2:
|
613 |
lon, lat = float(coords[0]), float(coords[1])
|
614 |
points.append({'name': name, 'geometry': f"POINT ({lon} {lat})"})
|
615 |
if not points:
|
616 |
st.error("No valid Point data found in the KML file.")
|
617 |
-
locations_df = pd.DataFrame()
|
618 |
else:
|
619 |
locations_df = gpd.GeoDataFrame(points, geometry=gpd.GeoSeries.from_wkt([p['geometry'] for p in points]), crs="EPSG:4326")
|
620 |
-
except Exception as e:
|
621 |
-
st.error(f"Error parsing KML file: {str(e)}")
|
622 |
-
locations_df = pd.DataFrame()
|
623 |
-
else:
|
624 |
-
st.error("Unsupported file format. Please upload CSV, GeoJSON, or KML.")
|
625 |
-
locations_df = pd.DataFrame()
|
626 |
-
|
627 |
-
if 'geometry' in locations_df.columns:
|
628 |
-
if locations_df.geometry.geom_type.isin(['Polygon', 'MultiPolygon']).any():
|
629 |
-
st.warning("The uploaded file contains polygon data. Please select 'Polygon' for processing.")
|
630 |
-
st.stop()
|
631 |
-
|
632 |
-
with st.spinner('Processing Map...'):
|
633 |
-
if locations_df is not None and not locations_df.empty:
|
634 |
-
if 'geometry' in locations_df.columns:
|
635 |
locations_df['latitude'] = locations_df['geometry'].y
|
636 |
locations_df['longitude'] = locations_df['geometry'].x
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
|
|
654 |
elif shape_type.lower() == "polygon":
|
655 |
if file_upload.name.endswith('.csv'):
|
656 |
-
|
657 |
elif file_upload.name.endswith('.geojson'):
|
658 |
locations_df = gpd.read_file(file_upload)
|
659 |
elif file_upload.name.endswith('.kml'):
|
660 |
-
# Parse KML file for polygon data
|
661 |
kml_string = file_upload.read().decode('utf-8')
|
662 |
try:
|
663 |
root = XET.fromstring(kml_string)
|
@@ -667,89 +605,38 @@ if file_upload is not None:
|
|
667 |
name = placemark.findtext('kml:name', default=f"Polygon_{len(polygons)}", namespaces=ns)
|
668 |
coords_elem = placemark.find('.//kml:Polygon//kml:coordinates', ns)
|
669 |
if coords_elem is not None:
|
670 |
-
coords_text = ' '.join(coords_elem.text.split())
|
671 |
-
st.write(f"Debug: Polygon coordinates found - {coords_text}") # Debug output
|
672 |
coord_pairs = [pair.split(',')[:2] for pair in coords_text.split() if pair]
|
673 |
-
if len(coord_pairs) >= 4:
|
674 |
coords_str = " ".join([f"{float(lon)} {float(lat)}" for lon, lat in coord_pairs])
|
675 |
polygons.append({'name': name, 'geometry': f"POLYGON (({coords_str}))"})
|
676 |
if not polygons:
|
677 |
st.error("No valid Polygon data found in the KML file.")
|
678 |
-
locations_df = pd.DataFrame()
|
679 |
else:
|
680 |
locations_df = gpd.GeoDataFrame(polygons, geometry=gpd.GeoSeries.from_wkt([p['geometry'] for p in polygons]), crs="EPSG:4326")
|
681 |
except Exception as e:
|
682 |
st.error(f"Error parsing KML file: {str(e)}")
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
st.dataframe(locations_df.head())
|
700 |
-
centroid_lat = locations_df.geometry.centroid.y.mean()
|
701 |
-
centroid_lon = locations_df.geometry.centroid.x.mean()
|
702 |
-
m = leafmap.Map(center=[centroid_lat, centroid_lon], zoom=10)
|
703 |
-
for _, row in locations_df.iterrows():
|
704 |
-
polygon = row['geometry']
|
705 |
-
if polygon.is_valid:
|
706 |
-
gdf = gpd.GeoDataFrame([row], geometry=[polygon], crs=locations_df.crs)
|
707 |
-
m.add_gdf(gdf=gdf, layer_name=row.get('name', 'Unnamed Polygon'))
|
708 |
-
st.write("Map of Uploaded Polygons:")
|
709 |
-
m.to_streamlit()
|
710 |
-
st.session_state.map_data = m
|
711 |
-
|
712 |
-
# if st.button(f"Calculate {custom_formula}"):
|
713 |
-
# if not locations_df.empty:
|
714 |
-
# with st.spinner("Processing Data..."):
|
715 |
-
# results, processing_time = process_aggregation( # Capture results and processing time
|
716 |
-
# locations_df,
|
717 |
-
# start_date_str,
|
718 |
-
# end_date_str,
|
719 |
-
# dataset_id,
|
720 |
-
# selected_bands,
|
721 |
-
# reducer_choice,
|
722 |
-
# shape_type,
|
723 |
-
# aggregation_period,
|
724 |
-
# custom_formula,
|
725 |
-
# kernel_size,
|
726 |
-
# include_boundary
|
727 |
-
# )
|
728 |
-
# if results:
|
729 |
-
# result_df = pd.DataFrame(results)
|
730 |
-
# st.write(f"Processed Results Table ({aggregation_period}) for Formula: {custom_formula}")
|
731 |
-
# st.dataframe(result_df)
|
732 |
-
# filename = f"{main_selection}_{dataset_id}_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}_{aggregation_period.lower()}.csv"
|
733 |
-
# st.download_button(
|
734 |
-
# label="Download results as CSV",
|
735 |
-
# data=result_df.to_csv(index=False).encode('utf-8'),
|
736 |
-
# file_name=filename,
|
737 |
-
# mime='text/csv'
|
738 |
-
# )
|
739 |
-
# # Display processing time
|
740 |
-
# st.success(f"Processing complete! Total processing time: {processing_time:.2f} seconds.")
|
741 |
-
# else:
|
742 |
-
# st.warning("No results were generated. Check your inputs or formula.")
|
743 |
-
# st.info(f"Total processing time: {processing_time:.2f} seconds.") # Show processing time even if no results
|
744 |
-
# else:
|
745 |
-
# st.warning("Please upload a file to proceed.")
|
746 |
|
747 |
if st.button(f"Calculate {custom_formula}"):
|
748 |
if not locations_df.empty:
|
749 |
-
# Use a spinner to indicate data processing
|
750 |
with st.spinner("Processing Data..."):
|
751 |
try:
|
752 |
-
# Call the aggregation function and capture results and processing time
|
753 |
results, processing_time = process_aggregation(
|
754 |
locations_df,
|
755 |
start_date_str,
|
@@ -764,13 +651,11 @@ if st.button(f"Calculate {custom_formula}"):
|
|
764 |
include_boundary
|
765 |
)
|
766 |
|
767 |
-
# Check if results were generated
|
768 |
if results:
|
769 |
result_df = pd.DataFrame(results)
|
770 |
st.write(f"Processed Results Table ({aggregation_period}) for Formula: {custom_formula}")
|
771 |
st.dataframe(result_df)
|
772 |
|
773 |
-
# Generate a downloadable CSV file
|
774 |
filename = f"{main_selection}_{dataset_id}_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}_{aggregation_period.lower()}.csv"
|
775 |
st.download_button(
|
776 |
label="Download results as CSV",
|
@@ -779,11 +664,10 @@ if st.button(f"Calculate {custom_formula}"):
|
|
779 |
mime='text/csv'
|
780 |
)
|
781 |
|
782 |
-
# Display processing time
|
783 |
st.success(f"Processing complete! Total processing time: {processing_time:.2f} seconds.")
|
784 |
else:
|
785 |
st.warning("No results were generated. Check your inputs or formula.")
|
786 |
-
st.info(f"Total processing time: {processing_time:.2f} seconds.")
|
787 |
|
788 |
except Exception as e:
|
789 |
st.error(f"An error occurred during processing: {str(e)}")
|
|
|
493 |
index=0,
|
494 |
help="Choose 'Point' for exact point calculation, or a kernel size for area averaging."
|
495 |
)
|
496 |
+
|
497 |
+
# Initialize column names in session state
|
498 |
+
if 'lat_col' not in st.session_state:
|
499 |
+
st.session_state.lat_col = None
|
500 |
+
if 'lon_col' not in st.session_state:
|
501 |
+
st.session_state.lon_col = None
|
502 |
elif shape_type.lower() == "polygon":
|
503 |
include_boundary = st.checkbox(
|
504 |
"Include Boundary Pixels",
|
|
|
509 |
file_upload = st.file_uploader(f"Upload your {shape_type} data (CSV, GeoJSON, KML)", type=["csv", "geojson", "kml"])
|
510 |
locations_df = pd.DataFrame()
|
511 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
if file_upload is not None:
|
|
|
513 |
if shape_type.lower() == "point":
|
514 |
if file_upload.name.endswith('.csv'):
|
515 |
+
# Read the CSV file
|
516 |
locations_df = pd.read_csv(file_upload)
|
517 |
+
|
518 |
+
# Get numeric columns for coordinate selection
|
519 |
+
numeric_cols = locations_df.select_dtypes(include=['number']).columns.tolist()
|
520 |
+
|
521 |
+
if numeric_cols:
|
522 |
+
# Let user select latitude and longitude columns
|
523 |
+
col1, col2 = st.columns(2)
|
524 |
+
with col1:
|
525 |
+
st.session_state.lat_col = st.selectbox(
|
526 |
+
"Select Latitude Column",
|
527 |
+
options=numeric_cols,
|
528 |
+
index=numeric_cols.index(st.session_state.lat_col) if st.session_state.lat_col in numeric_cols else 0,
|
529 |
+
key="lat_col_select"
|
530 |
+
)
|
531 |
+
with col2:
|
532 |
+
st.session_state.lon_col = st.selectbox(
|
533 |
+
"Select Longitude Column",
|
534 |
+
options=numeric_cols,
|
535 |
+
index=numeric_cols.index(st.session_state.lon_col) if st.session_state.lon_col in numeric_cols else 0,
|
536 |
+
key="lon_col_select"
|
537 |
+
)
|
538 |
+
|
539 |
+
# Update the dataframe with selected columns
|
540 |
+
if st.session_state.lat_col and st.session_state.lon_col:
|
541 |
+
locations_df = locations_df.rename(columns={
|
542 |
+
st.session_state.lat_col: 'latitude',
|
543 |
+
st.session_state.lon_col: 'longitude'
|
544 |
+
})
|
545 |
+
else:
|
546 |
+
st.error("No numeric columns found in the CSV file for coordinates.")
|
547 |
+
locations_df = pd.DataFrame()
|
548 |
+
|
549 |
elif file_upload.name.endswith('.geojson'):
|
550 |
locations_df = gpd.read_file(file_upload)
|
551 |
+
if 'geometry' in locations_df.columns:
|
552 |
+
locations_df['latitude'] = locations_df['geometry'].y
|
553 |
+
locations_df['longitude'] = locations_df['geometry'].x
|
554 |
elif file_upload.name.endswith('.kml'):
|
|
|
555 |
kml_string = file_upload.read().decode('utf-8')
|
556 |
try:
|
|
|
557 |
root = XET.fromstring(kml_string)
|
558 |
ns = {'kml': 'http://www.opengis.net/kml/2.2'}
|
559 |
points = []
|
|
|
562 |
coords_elem = placemark.find('.//kml:Point/kml:coordinates', ns)
|
563 |
if coords_elem is not None:
|
564 |
coords_text = coords_elem.text.strip()
|
|
|
565 |
coords = [c.strip() for c in coords_text.split(',')]
|
566 |
+
if len(coords) >= 2:
|
567 |
lon, lat = float(coords[0]), float(coords[1])
|
568 |
points.append({'name': name, 'geometry': f"POINT ({lon} {lat})"})
|
569 |
if not points:
|
570 |
st.error("No valid Point data found in the KML file.")
|
|
|
571 |
else:
|
572 |
locations_df = gpd.GeoDataFrame(points, geometry=gpd.GeoSeries.from_wkt([p['geometry'] for p in points]), crs="EPSG:4326")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
locations_df['latitude'] = locations_df['geometry'].y
|
574 |
locations_df['longitude'] = locations_df['geometry'].x
|
575 |
+
except Exception as e:
|
576 |
+
st.error(f"Error parsing KML file: {str(e)}")
|
577 |
+
|
578 |
+
# Display map for points
|
579 |
+
if not locations_df.empty and 'latitude' in locations_df.columns and 'longitude' in locations_df.columns:
|
580 |
+
st.write("Preview of Uploaded Points Data:")
|
581 |
+
st.dataframe(locations_df.head())
|
582 |
+
|
583 |
+
m = leafmap.Map(center=[locations_df['latitude'].mean(), locations_df['longitude'].mean()], zoom=10)
|
584 |
+
for _, row in locations_df.iterrows():
|
585 |
+
latitude = row['latitude']
|
586 |
+
longitude = row['longitude']
|
587 |
+
if pd.isna(latitude) or pd.isna(longitude):
|
588 |
+
continue
|
589 |
+
m.add_marker(location=[latitude, longitude], popup=row.get('name', 'No Name'))
|
590 |
+
st.write("Map of Uploaded Points:")
|
591 |
+
m.to_streamlit()
|
592 |
+
|
593 |
elif shape_type.lower() == "polygon":
|
594 |
if file_upload.name.endswith('.csv'):
|
595 |
+
st.error("CSV upload not supported for polygons. Please upload a GeoJSON or KML file.")
|
596 |
elif file_upload.name.endswith('.geojson'):
|
597 |
locations_df = gpd.read_file(file_upload)
|
598 |
elif file_upload.name.endswith('.kml'):
|
|
|
599 |
kml_string = file_upload.read().decode('utf-8')
|
600 |
try:
|
601 |
root = XET.fromstring(kml_string)
|
|
|
605 |
name = placemark.findtext('kml:name', default=f"Polygon_{len(polygons)}", namespaces=ns)
|
606 |
coords_elem = placemark.find('.//kml:Polygon//kml:coordinates', ns)
|
607 |
if coords_elem is not None:
|
608 |
+
coords_text = ' '.join(coords_elem.text.split())
|
|
|
609 |
coord_pairs = [pair.split(',')[:2] for pair in coords_text.split() if pair]
|
610 |
+
if len(coord_pairs) >= 4:
|
611 |
coords_str = " ".join([f"{float(lon)} {float(lat)}" for lon, lat in coord_pairs])
|
612 |
polygons.append({'name': name, 'geometry': f"POLYGON (({coords_str}))"})
|
613 |
if not polygons:
|
614 |
st.error("No valid Polygon data found in the KML file.")
|
|
|
615 |
else:
|
616 |
locations_df = gpd.GeoDataFrame(polygons, geometry=gpd.GeoSeries.from_wkt([p['geometry'] for p in polygons]), crs="EPSG:4326")
|
617 |
except Exception as e:
|
618 |
st.error(f"Error parsing KML file: {str(e)}")
|
619 |
+
|
620 |
+
# Display map for polygons
|
621 |
+
if not locations_df.empty and 'geometry' in locations_df.columns:
|
622 |
+
st.write("Preview of Uploaded Polygons Data:")
|
623 |
+
st.dataframe(locations_df.head())
|
624 |
+
|
625 |
+
centroid_lat = locations_df.geometry.centroid.y.mean()
|
626 |
+
centroid_lon = locations_df.geometry.centroid.x.mean()
|
627 |
+
m = leafmap.Map(center=[centroid_lat, centroid_lon], zoom=10)
|
628 |
+
for _, row in locations_df.iterrows():
|
629 |
+
polygon = row['geometry']
|
630 |
+
if polygon.is_valid:
|
631 |
+
gdf = gpd.GeoDataFrame([row], geometry=[polygon], crs=locations_df.crs)
|
632 |
+
m.add_gdf(gdf=gdf, layer_name=row.get('name', 'Unnamed Polygon'))
|
633 |
+
st.write("Map of Uploaded Polygons:")
|
634 |
+
m.to_streamlit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
635 |
|
636 |
if st.button(f"Calculate {custom_formula}"):
|
637 |
if not locations_df.empty:
|
|
|
638 |
with st.spinner("Processing Data..."):
|
639 |
try:
|
|
|
640 |
results, processing_time = process_aggregation(
|
641 |
locations_df,
|
642 |
start_date_str,
|
|
|
651 |
include_boundary
|
652 |
)
|
653 |
|
|
|
654 |
if results:
|
655 |
result_df = pd.DataFrame(results)
|
656 |
st.write(f"Processed Results Table ({aggregation_period}) for Formula: {custom_formula}")
|
657 |
st.dataframe(result_df)
|
658 |
|
|
|
659 |
filename = f"{main_selection}_{dataset_id}_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}_{aggregation_period.lower()}.csv"
|
660 |
st.download_button(
|
661 |
label="Download results as CSV",
|
|
|
664 |
mime='text/csv'
|
665 |
)
|
666 |
|
|
|
667 |
st.success(f"Processing complete! Total processing time: {processing_time:.2f} seconds.")
|
668 |
else:
|
669 |
st.warning("No results were generated. Check your inputs or formula.")
|
670 |
+
st.info(f"Total processing time: {processing_time:.2f} seconds.")
|
671 |
|
672 |
except Exception as e:
|
673 |
st.error(f"An error occurred during processing: {str(e)}")
|