Spaces:
Running
Running
update app.py
Browse files
app.py
CHANGED
@@ -128,19 +128,21 @@ if parameters_changed():
|
|
128 |
# Function to perform index calculations
|
129 |
def calculate_ndvi(image, geometry):
|
130 |
ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
|
131 |
-
|
132 |
reducer=ee.Reducer.mean(),
|
133 |
geometry=geometry,
|
134 |
scale=30
|
135 |
)
|
|
|
136 |
|
137 |
def calculate_ndwi(image, geometry):
|
138 |
ndwi = image.normalizedDifference(['B3', 'B8']).rename('NDWI')
|
139 |
-
|
140 |
reducer=ee.Reducer.mean(),
|
141 |
geometry=geometry,
|
142 |
scale=30
|
143 |
)
|
|
|
144 |
|
145 |
def calculate_avg_no2_sentinel5p(image, geometry):
|
146 |
no2 = image.select('NO2').reduceRegion(
|
@@ -151,13 +153,14 @@ def calculate_avg_no2_sentinel5p(image, geometry):
|
|
151 |
return no2
|
152 |
|
153 |
def calculate_custom_formula(image, geometry, formula):
|
154 |
-
|
155 |
reducer=ee.Reducer.mean(),
|
156 |
geometry=geometry,
|
157 |
scale=30
|
158 |
)
|
|
|
159 |
|
160 |
-
# Process each point
|
161 |
if file_upload:
|
162 |
locations_df = None # Initialize locations_df to None
|
163 |
polygons_df = None # Initialize polygons_df to None
|
@@ -182,46 +185,49 @@ if file_upload:
|
|
182 |
else:
|
183 |
st.error("Unsupported file type. Please upload a GeoJSON or KML file for polygons.")
|
184 |
|
185 |
-
# Display a preview of the dataframe
|
186 |
if locations_df is not None:
|
|
|
187 |
st.write("Preview of the uploaded points data:")
|
188 |
st.dataframe(locations_df.head())
|
189 |
|
190 |
-
#
|
191 |
-
|
192 |
-
|
193 |
-
#
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
|
|
|
|
|
|
208 |
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
|
217 |
-
|
218 |
-
|
219 |
|
220 |
# Process each point
|
221 |
-
if locations_df is not None
|
222 |
for idx, row in locations_df.iterrows():
|
223 |
-
latitude = row[
|
224 |
-
longitude = row[
|
225 |
location_name = row.get('name', f"Location_{idx}")
|
226 |
|
227 |
# Define the region of interest (ROI)
|
@@ -241,6 +247,7 @@ if file_upload:
|
|
241 |
image = collection.first()
|
242 |
|
243 |
# Perform the calculation based on user selection
|
|
|
244 |
if index_choice == 'NDVI':
|
245 |
result = calculate_ndvi(image, roi)
|
246 |
elif index_choice == 'NDWI':
|
@@ -250,13 +257,13 @@ if file_upload:
|
|
250 |
result = calculate_avg_no2_sentinel5p(image, roi)
|
251 |
else:
|
252 |
st.warning(f"No NO2 band found for {location_name}. Please use Sentinel-5P for NO₂ data.")
|
253 |
-
result = None
|
254 |
elif index_choice == 'Custom Formula' and custom_formula:
|
255 |
result = calculate_custom_formula(image, roi, custom_formula)
|
256 |
|
257 |
-
if result:
|
258 |
-
#
|
259 |
-
calculated_value = result.getInfo()
|
|
|
260 |
# Store the result in session state
|
261 |
st.session_state.results.append({
|
262 |
'Location Name': location_name,
|
@@ -265,21 +272,19 @@ if file_upload:
|
|
265 |
'Calculated Value': calculated_value
|
266 |
})
|
267 |
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
mime='text/csv'
|
285 |
-
)
|
|
|
128 |
# Function to perform index calculations
|
129 |
def calculate_ndvi(image, geometry):
|
130 |
ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
|
131 |
+
result = ndvi.reduceRegion(
|
132 |
reducer=ee.Reducer.mean(),
|
133 |
geometry=geometry,
|
134 |
scale=30
|
135 |
)
|
136 |
+
return result.get('NDVI')
|
137 |
|
138 |
def calculate_ndwi(image, geometry):
|
139 |
ndwi = image.normalizedDifference(['B3', 'B8']).rename('NDWI')
|
140 |
+
result = ndwi.reduceRegion(
|
141 |
reducer=ee.Reducer.mean(),
|
142 |
geometry=geometry,
|
143 |
scale=30
|
144 |
)
|
145 |
+
return result.get('NDWI')
|
146 |
|
147 |
def calculate_avg_no2_sentinel5p(image, geometry):
|
148 |
no2 = image.select('NO2').reduceRegion(
|
|
|
153 |
return no2
|
154 |
|
155 |
def calculate_custom_formula(image, geometry, formula):
|
156 |
+
result = image.expression(formula).rename('Custom Index').reduceRegion(
|
157 |
reducer=ee.Reducer.mean(),
|
158 |
geometry=geometry,
|
159 |
scale=30
|
160 |
)
|
161 |
+
return result.get('Custom Index')
|
162 |
|
163 |
+
# Process each point
|
164 |
if file_upload:
|
165 |
locations_df = None # Initialize locations_df to None
|
166 |
polygons_df = None # Initialize polygons_df to None
|
|
|
185 |
else:
|
186 |
st.error("Unsupported file type. Please upload a GeoJSON or KML file for polygons.")
|
187 |
|
|
|
188 |
if locations_df is not None:
|
189 |
+
# Display a preview of the points data
|
190 |
st.write("Preview of the uploaded points data:")
|
191 |
st.dataframe(locations_df.head())
|
192 |
|
193 |
+
# Create a LeafMap object to display the points
|
194 |
+
m = leafmap.Map(center=[locations_df['latitude'].mean(), locations_df['longitude'].mean()], zoom=10)
|
195 |
+
|
196 |
+
# Add points to the map
|
197 |
+
for _, row in locations_df.iterrows():
|
198 |
+
m.add_marker(location=[row['latitude'], row['longitude']], popup=row.get('name', 'No Name'))
|
199 |
+
|
200 |
+
# Display map
|
201 |
+
st.write("Map of Uploaded Points:")
|
202 |
+
m.to_streamlit()
|
203 |
+
|
204 |
+
# Store the map in session_state
|
205 |
+
st.session_state.map_data = m
|
206 |
+
|
207 |
+
if polygons_df is not None:
|
208 |
+
# Display a preview of the polygons data
|
209 |
+
st.write("Preview of the uploaded polygons data:")
|
210 |
+
st.dataframe(polygons_df.head())
|
211 |
+
|
212 |
+
# Create a LeafMap object to display the polygons
|
213 |
+
m = leafmap.Map(center=[polygons_df.geometry.centroid.y.mean(), polygons_df.geometry.centroid.x.mean()], zoom=4)
|
214 |
|
215 |
+
# Plot polygons on the map
|
216 |
+
for _, row in polygons_df.iterrows():
|
217 |
+
m.add_geojson(geojson=row['geometry'].__geo_interface__)
|
218 |
|
219 |
+
# Display map
|
220 |
+
st.write("Map of Uploaded Polygons:")
|
221 |
+
m.to_streamlit()
|
222 |
|
223 |
+
# Store the map in session_state
|
224 |
+
st.session_state.map_data = m
|
225 |
|
226 |
# Process each point
|
227 |
+
if locations_df is not None:
|
228 |
for idx, row in locations_df.iterrows():
|
229 |
+
latitude = row['latitude']
|
230 |
+
longitude = row['longitude']
|
231 |
location_name = row.get('name', f"Location_{idx}")
|
232 |
|
233 |
# Define the region of interest (ROI)
|
|
|
247 |
image = collection.first()
|
248 |
|
249 |
# Perform the calculation based on user selection
|
250 |
+
result = None
|
251 |
if index_choice == 'NDVI':
|
252 |
result = calculate_ndvi(image, roi)
|
253 |
elif index_choice == 'NDWI':
|
|
|
257 |
result = calculate_avg_no2_sentinel5p(image, roi)
|
258 |
else:
|
259 |
st.warning(f"No NO2 band found for {location_name}. Please use Sentinel-5P for NO₂ data.")
|
|
|
260 |
elif index_choice == 'Custom Formula' and custom_formula:
|
261 |
result = calculate_custom_formula(image, roi, custom_formula)
|
262 |
|
263 |
+
if result is not None:
|
264 |
+
# Only store the numeric value (not the dictionary structure)
|
265 |
+
calculated_value = result.getInfo() # Get the numeric value
|
266 |
+
|
267 |
# Store the result in session state
|
268 |
st.session_state.results.append({
|
269 |
'Location Name': location_name,
|
|
|
272 |
'Calculated Value': calculated_value
|
273 |
})
|
274 |
|
275 |
+
# After processing, show the results
|
276 |
+
if st.session_state.results:
|
277 |
+
# Convert the results to a DataFrame for better visualization
|
278 |
+
result_df = pd.DataFrame(st.session_state.results)
|
279 |
+
|
280 |
+
# Show the results in a table format
|
281 |
+
st.write("Processed Results Table:")
|
282 |
+
st.dataframe(result_df[['Location Name', 'Latitude', 'Longitude', 'Calculated Value']])
|
283 |
+
|
284 |
+
# Allow downloading of the results as CSV
|
285 |
+
st.download_button(
|
286 |
+
label="Download results as CSV",
|
287 |
+
data=result_df.to_csv(index=False).encode('utf-8'),
|
288 |
+
file_name="calculated_results.csv",
|
289 |
+
mime='text/csv'
|
290 |
+
)
|
|
|
|