SATRANG / app.py
YashMK89's picture
update app.py
2fd3301 verified
raw
history blame
6.46 kB
import streamlit as st
import json
import ee
import geemap
import os
import time
import pandas as pd
import geopandas as gpd
from shapely.geometry import shape
st.set_page_config(layout="wide")
# Custom styling for the button
m = st.markdown(
"""
<style>
div.stButton > button:first-child {
background-color: #006400;
color:#ffffff;
}
</style>""",
unsafe_allow_html=True,
)
# Authenticate and initialize Earth Engine
earthengine_credentials = os.environ.get("EE_Authentication")
# Initialize Earth Engine with the secret credentials
os.makedirs(os.path.expanduser("~/.config/earthengine/"), exist_ok=True)
with open(os.path.expanduser("~/.config/earthengine/credentials"), "w") as f:
f.write(earthengine_credentials)
ee.Initialize(project='ee-yashsacisro24')
# Load Sentinel dataset options from JSON file
with open("sentinel_datasets.json") as f:
data = json.load(f)
# Display title and dataset selection
st.title("Sentinel Dataset and Index Calculator")
# Step 1: Select main dataset category
main_selection = st.selectbox("Select Sentinel Dataset Category", list(data.keys()))
# Step 2: Display sub-options based on main selection
if main_selection:
sub_options = data[main_selection]["sub_options"]
sub_selection = st.selectbox("Select Specific Dataset ID", list(sub_options.keys()))
# Earth Engine Index Calculator Section
st.header("Earth Engine Index Calculator")
# Step 3: Choose Index or Custom Formula
index_choice = st.selectbox("Select an Index or Enter Custom Formula", ['NDVI', 'NDWI', 'Average NO₂', 'Custom Formula'])
# Step 4: Enter Custom Formula if selected
custom_formula = ""
if index_choice == 'Custom Formula':
custom_formula = st.text_input("Enter Custom Formula (e.g., 'B5 - B4 / B5 + B4')")
# Step 5: File Upload (CSV, GeoJSON, KML)
uploaded_file = st.file_uploader("Upload CSV, GeoJSON, or KML file", type=["csv", "geojson", "kml"])
def parse_file(uploaded_file):
"""
Parse the uploaded file (CSV, GeoJSON, or KML) and return the geometry.
"""
if uploaded_file is not None:
# Determine file type
file_type = uploaded_file.type
# Handle CSV file
if file_type == "text/csv":
df = pd.read_csv(uploaded_file)
st.write("CSV file content:")
st.write(df.head())
# Assuming the CSV has columns named 'latitude' and 'longitude' for points
if 'latitude' in df.columns and 'longitude' in df.columns:
# Convert to GeoDataFrame with points
geometry = gpd.GeoSeries.from_xy(df.longitude, df.latitude)
return geometry
# Handle GeoJSON file
elif file_type == "application/geo+json":
gdf = gpd.read_file(uploaded_file)
st.write("GeoJSON file content:")
st.write(gdf.head())
return gdf.geometry
# Handle KML file
elif file_type == "application/vnd.google-earth.kml+xml":
gdf = gpd.read_file(uploaded_file)
st.write("KML file content:")
st.write(gdf.head())
return gdf.geometry
else:
st.error("Unsupported file format. Please upload a CSV, GeoJSON, or KML file.")
return None
else:
st.warning("Please upload a file.")
return None
# Parse the file if uploaded
geometry = parse_file(uploaded_file)
# Define functions for index calculations
def calculate_ndvi(image, geometry):
return image.normalizedDifference(['B5', 'B4']).rename('NDVI').reduceRegion(
reducer=ee.Reducer.mean(),
geometry=geometry,
scale=30
)
def calculate_ndwi(image, geometry):
return image.normalizedDifference(['B3', 'B5']).rename('NDWI').reduceRegion(
reducer=ee.Reducer.mean(),
geometry=geometry,
scale=30
)
def calculate_avg_no2(image, geometry):
return image.select('NO2').reduceRegion(
reducer=ee.Reducer.mean(),
geometry=geometry,
scale=1000
).get('NO2')
def calculate_custom_formula(image, geometry, formula):
return image.expression(formula).rename('Custom Index').reduceRegion(
reducer=ee.Reducer.mean(),
geometry=geometry,
scale=30
)
# Step 6: Perform the calculation based on user choice
if st.button("Calculate Index"):
if geometry is not None:
try:
# Verify if the dataset_id is correct
dataset_id = sub_options[sub_selection] # Earth Engine dataset ID
if not ee.data.getInfo(dataset_id):
st.error(f"The dataset '{dataset_id}' does not exist or is not accessible.")
st.stop()
# Load dataset
collection = ee.ImageCollection(dataset_id).filterDate('2020-01-01', '2020-12-31')
image = collection.first()
# Choose calculation based on user selection
if index_choice == 'NDVI':
result = calculate_ndvi(image, geometry)
st.write("NDVI result:", result.getInfo())
elif index_choice == 'NDWI':
result = calculate_ndwi(image, geometry)
st.write("NDWI result:", result.getInfo())
elif index_choice == 'Average NO₂':
result = calculate_avg_no2(image, geometry)
st.write("Average NO₂ Concentration:", result.getInfo())
elif index_choice == 'Custom Formula' and custom_formula:
result = calculate_custom_formula(image, geometry, custom_formula)
st.write("Custom Index result:", result.getInfo())
# Visualization Parameters for Index Layers
vis_params = {"min": 0, "max": 1, "palette": ["blue", "white", "green"]}
# Add loading spinner while the map is loading
with st.spinner('Loading the map, please wait...'):
time.sleep(2) # Simulate processing delay (you can adjust/remove this in production)
# If an index image is generated, add it to the map
Map = geemap.Map()
Map.setCenter(-100.0, 40.0, 4) # Adjusted for example
Map.addLayer(image, vis_params, index_choice)
Map.to_streamlit(height=600)
except ee.EEException as e:
st.error(f"Earth Engine Error: {e}")
else:
st.error("No geometry data found in the uploaded file.")