YashMK89 commited on
Commit
297322f
·
verified ·
1 Parent(s): b6a4aaa

update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -197
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: # Ensure at least lon, lat
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
- if 'latitude' not in locations_df.columns or 'longitude' not in locations_df.columns:
639
- st.error("Uploaded file is missing required 'latitude' or 'longitude' columns.")
640
- else:
641
- st.write("Preview of the uploaded points data:")
642
- st.dataframe(locations_df.head())
643
- m = leafmap.Map(center=[locations_df['latitude'].mean(), locations_df['longitude'].mean()], zoom=10)
644
- for _, row in locations_df.iterrows():
645
- latitude = row['latitude']
646
- longitude = row['longitude']
647
- if pd.isna(latitude) or pd.isna(longitude):
648
- continue
649
- m.add_marker(location=[latitude, longitude], popup=row.get('name', 'No Name'))
650
- st.write("Map of Uploaded Points:")
651
- m.to_streamlit()
652
- st.session_state.map_data = m
653
-
 
654
  elif shape_type.lower() == "polygon":
655
  if file_upload.name.endswith('.csv'):
656
- locations_df = pd.read_csv(file_upload)
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()) # Normalize whitespace
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: # Minimum 4 points for a closed polygon
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
- locations_df = pd.DataFrame()
684
- else:
685
- st.error("Unsupported file format. Please upload CSV, GeoJSON, or KML.")
686
- locations_df = pd.DataFrame()
687
-
688
- if 'geometry' in locations_df.columns:
689
- if locations_df.geometry.geom_type.isin(['Point', 'MultiPoint']).any():
690
- st.warning("The uploaded file contains point data. Please select 'Point' for processing.")
691
- st.stop()
692
-
693
- with st.spinner('Processing Map...'):
694
- if locations_df is not None and not locations_df.empty:
695
- if 'geometry' not in locations_df.columns:
696
- st.error("Uploaded file is missing required 'geometry' column.")
697
- else:
698
- st.write("Preview of the uploaded polygons data:")
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.") # Show processing time even if no results
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)}")