update app.py
Browse files
app.py
CHANGED
@@ -94,84 +94,6 @@ reducer_choice = st.selectbox(
|
|
94 |
index=0 # Default to 'mean'
|
95 |
)
|
96 |
|
97 |
-
# Function to get the corresponding reducer based on user input
|
98 |
-
def get_reducer(reducer_name):
|
99 |
-
"""
|
100 |
-
Map user-friendly reducer names to Earth Engine reducer objects.
|
101 |
-
|
102 |
-
Args:
|
103 |
-
reducer_name (str): The name of the reducer (e.g., 'mean', 'sum', 'median').
|
104 |
-
|
105 |
-
Returns:
|
106 |
-
ee.Reducer: The corresponding Earth Engine reducer.
|
107 |
-
"""
|
108 |
-
reducers = {
|
109 |
-
'mean': ee.Reducer.mean(),
|
110 |
-
'sum': ee.Reducer.sum(),
|
111 |
-
'median': ee.Reducer.median(),
|
112 |
-
'min': ee.Reducer.min(),
|
113 |
-
'max': ee.Reducer.max(),
|
114 |
-
'count': ee.Reducer.count(),
|
115 |
-
}
|
116 |
-
|
117 |
-
# Default to 'mean' if the reducer_name is not recognized
|
118 |
-
return reducers.get(reducer_name.lower(), ee.Reducer.mean())
|
119 |
-
|
120 |
-
def calculate_index_by_frequency(image_collection, frequency, roi, reducer):
|
121 |
-
"""
|
122 |
-
Calculate the index based on the selected frequency (daily, weekly, monthly, yearly).
|
123 |
-
Args:
|
124 |
-
image_collection (ee.ImageCollection): The Earth Engine image collection.
|
125 |
-
frequency (str): The frequency ('daily', 'weekly', 'monthly', 'yearly').
|
126 |
-
roi (ee.Geometry): The region of interest.
|
127 |
-
reducer (ee.Reducer): The reducer to apply.
|
128 |
-
|
129 |
-
Returns:
|
130 |
-
tuple: The result of applying the calculation, and the date associated with that result.
|
131 |
-
"""
|
132 |
-
if frequency == 'daily':
|
133 |
-
# Apply daily filtering logic (each individual image)
|
134 |
-
image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi)
|
135 |
-
elif frequency == 'weekly':
|
136 |
-
# Apply weekly logic by filtering by week of year
|
137 |
-
image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi).filter(ee.Filter.calendarRange(1, 1, 'month'))
|
138 |
-
elif frequency == 'monthly':
|
139 |
-
# Apply monthly logic by filtering by month
|
140 |
-
image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi).filter(ee.Filter.calendarRange(1, 1, 'month'))
|
141 |
-
elif frequency == 'yearly':
|
142 |
-
# Apply yearly logic
|
143 |
-
image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi).filter(ee.Filter.calendarRange(1, 1, 'year'))
|
144 |
-
else:
|
145 |
-
raise ValueError(f"Unsupported frequency: {frequency}")
|
146 |
-
|
147 |
-
# Apply the reducer on the filtered collection
|
148 |
-
result = image_collection.reduce(reducer)
|
149 |
-
|
150 |
-
# Get the date for the result
|
151 |
-
# If using daily frequency, you can take the date of the first image
|
152 |
-
if frequency == 'daily':
|
153 |
-
result_date = image_collection.first().date().getInfo() # Get the date of the first image
|
154 |
-
elif frequency == 'weekly':
|
155 |
-
result_date = image_collection.mean().date().getInfo() # Take the mean date (or any representative date)
|
156 |
-
elif frequency == 'monthly':
|
157 |
-
result_date = image_collection.mean().date().getInfo()
|
158 |
-
elif frequency == 'yearly':
|
159 |
-
result_date = image_collection.mean().date().getInfo()
|
160 |
-
else:
|
161 |
-
result_date = "Unknown" # Fallback if something goes wrong
|
162 |
-
|
163 |
-
# Return the result and the associated date
|
164 |
-
return result, result_date
|
165 |
-
|
166 |
-
# Add your current Streamlit UI and Earth Engine initialization code here...
|
167 |
-
|
168 |
-
# Get the reducer based on user selection
|
169 |
-
reducer = get_reducer(reducer_choice)
|
170 |
-
|
171 |
-
# Get the frequency selected by the user (you will need to add this UI in your Streamlit app)
|
172 |
-
frequency_choice = st.selectbox("Select Frequency", ['daily', 'weekly', 'monthly', 'yearly'])
|
173 |
-
|
174 |
-
|
175 |
# Function to check if the polygon geometry is valid and convert it to the correct format
|
176 |
def convert_to_ee_geometry(geometry):
|
177 |
if geometry.is_valid:
|
@@ -242,6 +164,82 @@ if parameters_changed():
|
|
242 |
'file_upload': file_upload
|
243 |
}
|
244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
|
246 |
|
247 |
# Function to perform index calculations
|
@@ -393,28 +391,27 @@ if file_upload:
|
|
393 |
.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
|
394 |
.filterBounds(roi)
|
395 |
|
396 |
-
# Apply frequency-based filtering and reduction
|
397 |
-
result, result_date = calculate_index_by_frequency(collection, frequency_choice, roi, reducer)
|
398 |
-
|
399 |
-
if
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
calculated_value = None # Initialize the calculated_value as None
|
407 |
if index_choice == 'NDVI':
|
408 |
-
result = calculate_ndvi(
|
409 |
elif index_choice == 'NDWI':
|
410 |
-
result = calculate_ndwi(
|
411 |
elif index_choice == 'Average NO₂':
|
412 |
if 'NO2' in image.bandNames().getInfo():
|
413 |
-
result = calculate_avg_no2_sentinel5p(
|
414 |
else:
|
415 |
st.warning(f"No NO2 band found for {location_name}. Please use Sentinel-5P for NO₂ data.")
|
416 |
elif index_choice.lower() == 'custom formula' and custom_formula:
|
417 |
-
result = process_custom_formula(
|
418 |
|
419 |
# Validate result before using getInfo
|
420 |
if result is not None:
|
@@ -437,8 +434,8 @@ if file_upload:
|
|
437 |
'Location Name': location_name,
|
438 |
'Latitude': latitude,
|
439 |
'Longitude': longitude,
|
440 |
-
'Calculated Value': calculated_value
|
441 |
-
'Date': result_date # Add the date of the calculation
|
442 |
})
|
443 |
else:
|
444 |
st.warning(f"No value calculated for {location_name}.")
|
|
|
94 |
index=0 # Default to 'mean'
|
95 |
)
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
# Function to check if the polygon geometry is valid and convert it to the correct format
|
98 |
def convert_to_ee_geometry(geometry):
|
99 |
if geometry.is_valid:
|
|
|
164 |
'file_upload': file_upload
|
165 |
}
|
166 |
|
167 |
+
# Function to get the corresponding reducer based on user input
|
168 |
+
def get_reducer(reducer_name):
|
169 |
+
"""
|
170 |
+
Map user-friendly reducer names to Earth Engine reducer objects.
|
171 |
+
|
172 |
+
Args:
|
173 |
+
reducer_name (str): The name of the reducer (e.g., 'mean', 'sum', 'median').
|
174 |
+
|
175 |
+
Returns:
|
176 |
+
ee.Reducer: The corresponding Earth Engine reducer.
|
177 |
+
"""
|
178 |
+
reducers = {
|
179 |
+
'mean': ee.Reducer.mean(),
|
180 |
+
'sum': ee.Reducer.sum(),
|
181 |
+
'median': ee.Reducer.median(),
|
182 |
+
'min': ee.Reducer.min(),
|
183 |
+
'max': ee.Reducer.max(),
|
184 |
+
'count': ee.Reducer.count(),
|
185 |
+
}
|
186 |
+
|
187 |
+
# Default to 'mean' if the reducer_name is not recognized
|
188 |
+
return reducers.get(reducer_name.lower(), ee.Reducer.mean())
|
189 |
+
|
190 |
+
# def calculate_index_by_frequency(image_collection, frequency, roi, reducer):
|
191 |
+
# """
|
192 |
+
# Calculate the index based on the selected frequency (daily, weekly, monthly, yearly).
|
193 |
+
# Args:
|
194 |
+
# image_collection (ee.ImageCollection): The Earth Engine image collection.
|
195 |
+
# frequency (str): The frequency ('daily', 'weekly', 'monthly', 'yearly').
|
196 |
+
# roi (ee.Geometry): The region of interest.
|
197 |
+
# reducer (ee.Reducer): The reducer to apply.
|
198 |
+
|
199 |
+
# Returns:
|
200 |
+
# tuple: The result of applying the calculation, and the date associated with that result.
|
201 |
+
# """
|
202 |
+
# if frequency == 'daily':
|
203 |
+
# # Apply daily filtering logic (each individual image)
|
204 |
+
# image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi)
|
205 |
+
# elif frequency == 'weekly':
|
206 |
+
# # Apply weekly logic by filtering by week of year
|
207 |
+
# image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi).filter(ee.Filter.calendarRange(1, 1, 'month'))
|
208 |
+
# elif frequency == 'monthly':
|
209 |
+
# # Apply monthly logic by filtering by month
|
210 |
+
# image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi).filter(ee.Filter.calendarRange(1, 1, 'month'))
|
211 |
+
# elif frequency == 'yearly':
|
212 |
+
# # Apply yearly logic
|
213 |
+
# image_collection = image_collection.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)).filterBounds(roi).filter(ee.Filter.calendarRange(1, 1, 'year'))
|
214 |
+
# else:
|
215 |
+
# raise ValueError(f"Unsupported frequency: {frequency}")
|
216 |
+
|
217 |
+
# # Apply the reducer on the filtered collection
|
218 |
+
# result = image_collection.reduce(reducer)
|
219 |
+
|
220 |
+
# # Get the date for the result
|
221 |
+
# # If using daily frequency, you can take the date of the first image
|
222 |
+
# if frequency == 'daily':
|
223 |
+
# result_date = image_collection.first().date().getInfo() # Get the date of the first image
|
224 |
+
# elif frequency == 'weekly':
|
225 |
+
# result_date = image_collection.mean().date().getInfo() # Take the mean date (or any representative date)
|
226 |
+
# elif frequency == 'monthly':
|
227 |
+
# result_date = image_collection.mean().date().getInfo()
|
228 |
+
# elif frequency == 'yearly':
|
229 |
+
# result_date = image_collection.mean().date().getInfo()
|
230 |
+
# else:
|
231 |
+
# result_date = "Unknown" # Fallback if something goes wrong
|
232 |
+
|
233 |
+
# # Return the result and the associated date
|
234 |
+
# return result, result_date
|
235 |
+
|
236 |
+
# # Add your current Streamlit UI and Earth Engine initialization code here...
|
237 |
+
|
238 |
+
# # Get the reducer based on user selection
|
239 |
+
# reducer = get_reducer(reducer_choice)
|
240 |
+
|
241 |
+
# # Get the frequency selected by the user (you will need to add this UI in your Streamlit app)
|
242 |
+
# frequency_choice = st.selectbox("Select Frequency", ['daily', 'weekly', 'monthly', 'yearly'])
|
243 |
|
244 |
|
245 |
# Function to perform index calculations
|
|
|
391 |
.filterDate(ee.Date(start_date_str), ee.Date(end_date_str)) \
|
392 |
.filterBounds(roi)
|
393 |
|
394 |
+
# # Apply frequency-based filtering and reduction
|
395 |
+
# result, result_date = calculate_index_by_frequency(collection, frequency_choice, roi, reducer)
|
396 |
+
image = get_most_recent_image(collection)
|
397 |
+
if not image:
|
398 |
+
st.warning(f"No images found for {location_name}.")
|
399 |
+
else:
|
400 |
+
st.write(f"Found images for {location_name}.")
|
401 |
+
# Perform the calculation based on user selection
|
402 |
+
# Perform the calculation based on user selection
|
403 |
+
result = None
|
|
|
404 |
if index_choice == 'NDVI':
|
405 |
+
result = calculate_ndvi(image, roi)
|
406 |
elif index_choice == 'NDWI':
|
407 |
+
result = calculate_ndwi(image, roi)
|
408 |
elif index_choice == 'Average NO₂':
|
409 |
if 'NO2' in image.bandNames().getInfo():
|
410 |
+
result = calculate_avg_no2_sentinel5p(image, roi)
|
411 |
else:
|
412 |
st.warning(f"No NO2 band found for {location_name}. Please use Sentinel-5P for NO₂ data.")
|
413 |
elif index_choice.lower() == 'custom formula' and custom_formula:
|
414 |
+
result = process_custom_formula(image, roi, custom_formula)
|
415 |
|
416 |
# Validate result before using getInfo
|
417 |
if result is not None:
|
|
|
434 |
'Location Name': location_name,
|
435 |
'Latitude': latitude,
|
436 |
'Longitude': longitude,
|
437 |
+
'Calculated Value': calculated_value
|
438 |
+
# 'Date': result_date # Add the date of the calculation
|
439 |
})
|
440 |
else:
|
441 |
st.warning(f"No value calculated for {location_name}.")
|