Esmaeilkianii commited on
Commit
e3132bd
·
verified ·
1 Parent(s): 8737e5e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -323
app.py CHANGED
@@ -18,328 +18,80 @@ eeservice = ee.ServiceAccountCredentials(credentials["client_email"], SERVICE_AC
18
  ee.Initialize(eeservice)
19
 
20
  # Load farm data
21
- @st.cache_data
22
- def load_farm_data():
23
- df = pd.read_csv('tableConvert.com_wftamx (1).csv')
24
- df['planting_date'] = pd.to_datetime(df['planting_date'])
25
- return df
26
-
27
- farms_df = load_farm_data()
28
-
29
- # Streamlit app
30
- st.title('Advanced Sugar Beet Field Analysis')
31
-
32
- # Create two columns
33
- col1, col2 = st.columns(2)
34
-
35
- # Function to calculate vegetation indices
36
- def calculate_indices(image):
37
- ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
38
- evi = image.expression(
39
- '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))',
40
- {
41
- 'NIR': image.select('B8'),
42
- 'RED': image.select('B4'),
43
- 'BLUE': image.select('B2')
44
- }
45
- ).rename('EVI')
46
- savi = image.expression(
47
- '((NIR - RED) / (NIR + RED + 0.5)) * (1.5)',
48
- {
49
- 'NIR': image.select('B8'),
50
- 'RED': image.select('B4')
51
- }
52
- ).rename('SAVI')
53
- lai = ndvi.expression(
54
- '3.618 * EXP(2.5 * NDVI) - 0.118',
55
- {'NDVI': ndvi}
56
- ).rename('LAI')
57
- return image.addBands([ndvi, evi, savi, lai])
58
-
59
- # Function to get satellite data
60
- def get_satellite_data(farm_name, start_date, end_date):
61
- farm = farms_df[farms_df['name'] == farm_name].iloc[0]
62
- point = ee.Geometry.Point([farm['longitude'], farm['latitude']])
63
-
64
- s2 = ee.ImageCollection('COPERNICUS/S2_SR') \
65
- .filterBounds(point) \
66
- .filterDate(start_date, end_date) \
67
- .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) \
68
- .map(calculate_indices)
69
-
70
- return s2
71
-
72
- # Function to display analysis
73
- def display_analysis(farm_name, start_date, end_date, column):
74
- satellite_data = get_satellite_data(farm_name, start_date, end_date)
75
-
76
- farm = farms_df[farms_df['name'] == farm_name].iloc[0]
77
- farm_coords = [farm['longitude'], farm['latitude']]
78
-
79
- # Display map
80
- Map = geemap.Map()
81
- Map.centerObject(ee.Geometry.Point(farm_coords), 13)
82
-
83
- # Add layers
84
- Map.addLayer(satellite_data.select('NDVI').mean(), {'min': 0, 'max': 1, 'palette': ['red', 'yellow', 'green']}, 'NDVI')
85
- Map.addLayer(satellite_data.select('EVI').mean(), {'min': 0, 'max': 1, 'palette': ['blue', 'cyan', 'green']}, 'EVI')
86
- Map.addLayer(satellite_data.select('SAVI').mean(), {'min': 0, 'max': 1, 'palette': ['purple', 'pink', 'white']}, 'SAVI')
87
- Map.addLayer(satellite_data.select('LAI').mean(), {'min': 0, 'max': 6, 'palette': ['brown', 'yellow', 'green']}, 'LAI')
88
-
89
- with column:
90
- st.write(f"Analysis for {farm_name}")
91
- Map.to_streamlit(height=300)
92
-
93
- # Get time series data
94
- time_series = satellite_data.getRegion(ee.Geometry.Point(farm_coords), 500).getInfo()
95
- df = pd.DataFrame(time_series[1:], columns=time_series[0])
96
- df['datetime'] = pd.to_datetime(df['time'], unit='ms')
97
- df = df.sort_values('datetime')
98
-
99
- # Plot time series
100
- fig, ax = plt.subplots(figsize=(10, 5))
101
- ax.plot(df['datetime'], df['NDVI'], label='NDVI')
102
- ax.plot(df['datetime'], df['EVI'], label='EVI')
103
- ax.plot(df['datetime'], df['SAVI'], label='SAVI')
104
- ax.plot(df['datetime'], df['LAI'], label='LAI')
105
- ax.set_xlabel('Date')
106
- ax.set_ylabel('Index Value')
107
- ax.set_title(f'Vegetation Indices Time Series for {farm_name}')
108
- ax.legend()
109
- st.pyplot(fig)
110
-
111
- # Calculate statistics
112
- lai_stats = df['LAI'].agg(['mean', 'max', 'min', 'std', 'var'])
113
- st.write("LAI Statistics:")
114
- st.write(f"Mean: {lai_stats['mean']:.2f}")
115
- st.write(f"Max: {lai_stats['max']:.2f}")
116
- st.write(f"Min: {lai_stats['min']:.2f}")
117
- st.write(f"Standard Deviation: {lai_stats['std']:.2f}")
118
- st.write(f"Variance: {lai_stats['var']:.2f}")
119
-
120
- # Correlation analysis
121
- st.write("\nCorrelation between indices:")
122
- corr = df[['NDVI', 'EVI', 'SAVI', 'LAI']].corr()
123
- fig, ax = plt.subplots(figsize=(8, 6))
124
- sns.heatmap(corr, annot=True, cmap='coolwarm', ax=ax)
125
- st.pyplot(fig)
126
-
127
- return df
128
-
129
- # Farm selection and date range for each year
130
- st.sidebar.header("Farm Selection")
131
- year_selection = st.sidebar.radio("Select Year", ["2023", "2024"])
132
-
133
- farms_of_year = farms_df[farms_df['year'] == int(year_selection)]
134
- selected_farms = st.sidebar.multiselect(
135
- f"Select Farms for {year_selection}",
136
- options=farms_of_year['name'].tolist(),
137
- default=farms_of_year['name'].tolist()[:2] # Select first two farms by default
138
- )
139
-
140
- start_date = st.sidebar.date_input(f"Start Date for {year_selection}",
141
- farms_of_year['planting_date'].min())
142
- end_date = st.sidebar.date_input(f"End Date for {year_selection}",
143
- datetime.now() if year_selection == "2024" else datetime(2024, 3, 20))
144
-
145
- farm_data = []
146
- for i, farm_name in enumerate(selected_farms):
147
- farm_data.append(display_analysis(farm_name, start_date.isoformat(), end_date.isoformat(),
148
- col1 if i % 2 == 0 else col2))
149
-
150
- # Comparison and interpretation
151
- if st.button('Compare and Interpret') and len(farm_data) >= 2:
152
- st.write("Comparison and Interpretation:")
153
-
154
- # LAI difference analysis
155
- st.write("\nLAI Difference Analysis:")
156
- fig, ax = plt.subplots(figsize=(12, 6))
157
- for i, data in enumerate(farm_data):
158
- ax.plot(data['datetime'], data['LAI'], label=selected_farms[i])
159
- ax.set_xlabel('Date')
160
- ax.set_ylabel('LAI')
161
- ax.set_title(f'LAI Comparison for Selected Farms ({year_selection})')
162
- ax.legend()
163
- st.pyplot(fig)
164
-
165
- # Regional comparison
166
- st.write("\nRegional Comparison:")
167
- avg_lai = pd.DataFrame({farm: data['LAI'].mean() for farm, data in zip(selected_farms, farm_data)}, index=['Average LAI'])
168
- st.write(avg_lai)
169
-
170
- fig, ax = plt.subplots(figsize=(10, 6))
171
- avg_lai.T.plot(kind='bar', ax=ax)
172
- ax.set_title(f'Average LAI Comparison for Selected Farms ({year_selection})')
173
- ax.set_ylabel('Average LAI')
174
- st.pyplot(fig)
175
-
176
- # Strengths and weaknesses analysis
177
- st.write("\nStrengths and Weaknesses Analysis:")
178
-
179
- for farm, data in zip(selected_farms, farm_data):
180
- st.write(f"\n{farm}:")
181
-
182
- mean_lai = data['LAI'].mean()
183
- lai_trend = np.polyfit(range(len(data['LAI'])), data['LAI'], 1)[0]
184
-
185
- st.write(f"- Average LAI: {mean_lai:.2f}")
186
-
187
- if mean_lai > 4:
188
- st.write(" Strength: High LAI indicates dense, healthy vegetation.")
189
- elif 2 <= mean_lai <= 4:
190
- st.write(" Moderate LAI suggests average crop development.")
191
- else:
192
- st.write(" Weakness: Low LAI may indicate poor crop health or early growth stage.")
193
-
194
- if lai_trend > 0:
195
- st.write(f" Strength: Positive LAI trend (slope: {lai_trend:.4f}) suggests improving crop health.")
196
  else:
197
- st.write(f" Weakness: Negative LAI trend (slope: {lai_trend:.4f}) may indicate declining crop health.")
198
-
199
- lai_variability = data['LAI'].std()
200
- if lai_variability < 0.5:
201
- st.write(" Strength: Low LAI variability suggests consistent crop conditions.")
202
- else:
203
- st.write(" Weakness: High LAI variability may indicate uneven crop development or stress.")
204
-
205
- # LAI Prediction
206
- st.write("\nLAI Prediction:")
207
- for farm, data in zip(selected_farms, farm_data):
208
- st.write(f"\nPredicting LAI for {farm}:")
209
-
210
- X = data[['NDVI', 'EVI', 'SAVI']]
211
- y = data['LAI']
212
-
213
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
214
-
215
- model = RandomForestRegressor(n_estimators=100, random_state=42)
216
- model.fit(X_train, y_train)
217
-
218
- y_pred = model.predict(X_test)
219
-
220
- mse = mean_squared_error(y_test, y_pred)
221
- r2 = r2_score(y_test, y_pred)
222
-
223
- st.write(f"Mean Squared Error: {mse:.4f}")
224
- st.write(f"R-squared Score: {r2:.4f}")
225
-
226
- # Plot actual vs predicted LAI
227
- fig, ax = plt.subplots(figsize=(8, 6))
228
- ax.scatter(y_test, y_pred)
229
- ax.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
230
- ax.set_xlabel('Actual LAI')
231
- ax.set_ylabel('Predicted LAI')
232
- ax.set_title(f'Actual vs Predicted LAI for {farm}')
233
- st.pyplot(fig)
234
-
235
- st.write("\nRecommendations:")
236
- st.write("1. For areas with low LAI, consider investigating potential issues such as nutrient deficiencies, water stress, or pest problems.")
237
- st.write("2. Monitor areas with high LAI variability to ensure uniform crop development.")
238
- st.write("3. Use the LAI trend information to adjust management practices and optimize crop health throughout the growing season.")
239
- st.write("4. Consider conducting ground-truthing in areas with significant LAI differences to validate satellite-based observations.")
240
- st.write("5. Utilize the LAI prediction model to forecast future crop health and plan interventions accordingly.")
241
- st.write("6. Pay attention to the correlation between different vegetation indices to gain a more comprehensive understanding of crop health.")
242
-
243
- # Environmental analysis
244
- st.write("\nEnvironmental Analysis:")
245
- st.write("To perform a comprehensive environmental analysis, additional data sources for temperature, humidity, rainfall, and solar radiation would be required. This data could be integrated with the satellite imagery to provide insights into how environmental factors affect LAI and overall crop health.")
246
-
247
- # GIS Advanced Features
248
- st.write("\nAdvanced GIS Features:")
249
- st.write("LAI Heatmap")
250
- Map = geemap.Map()
251
- farm_coords = farms_df[farms_df['name'] == selected_farms[0]][['longitude', 'latitude']].values[0]
252
- Map.centerObject(ee.Geometry.Point(farm_coords), 13)
253
- lai_heatmap = get_satellite_data(selected_farms[0], start_date.isoformat(), end_date.isoformat()).select('LAI').mean()
254
- Map.addLayer(lai_heatmap, {'min': 0, 'max': 6, 'palette': ['blue', 'green', 'yellow', 'red']}, 'LAI Heatmap')
255
- Map.to_streamlit(height=300)
256
-
257
- # Year-over-year comparison
258
- if st.button("Year-over-Year Comparison"):
259
- st.write("\nYear-over-Year Comparison:")
260
-
261
- # Get data for both years
262
- data_2023 = [display_analysis(farm, "2023-09-29", "2024-03-20", st.empty())
263
- for farm in farms_df[farms_df['year'] == 2023]['name']]
264
- data_2024 = [display_analysis(farm, "2024-03-21", datetime.now().isoformat(), st.empty())
265
- for farm in farms_df[farms_df['year'] == 2024]['name']]
266
-
267
- # Calculate average LAI for each year
268
- avg_lai_2023 = np.mean([data['LAI'].mean() for data in data_2023])
269
- avg_lai_2024 = np.mean([data['LAI'].mean() for data in data_2024])
270
-
271
- st.write(f"Average LAI for 2023: {avg_lai_2023:.2f}")
272
- st.write(f"Average LAI for 2024: {avg_lai_2024:.2f}")
273
-
274
- # Plot comparison
275
- fig, ax = plt.subplots(figsize=(12, 6))
276
- ax.bar(['2023', '2024'], [avg_lai_2023, avg_lai_2024])
277
- ax.set_ylabel('Average LAI')
278
- ax.set_title('Year-over-Year Comparison of Average LAI')
279
- st.pyplot(fig)
280
-
281
- # Calculate and display percentage change
282
- percent_change = ((avg_lai_2024 - avg_lai_2023) / avg_lai_2023) * 100
283
- st.write(f"Percentage change in LAI from 2023 to 2024: {percent_change:.2f}%")
284
-
285
- if percent_change > 0:
286
- st.write("The increase in LAI suggests improved crop health or more favorable growing conditions in 2024.")
287
- elif percent_change < 0:
288
- st.write("The decrease in LAI may indicate less favorable conditions or potential issues affecting crop health in 2024.")
289
- else:
290
- st.write("The LAI remains relatively stable between the two years, suggesting similar growing conditions.")
291
-
292
- # Add a section for downloading the analysis report
293
- if st.button("Generate Analysis Report"):
294
- report = f"""
295
- Sugar Beet Field Analysis Report
296
- ================================
297
-
298
- Date of Analysis: {datetime.now().strftime('%Y-%m-%d')}
299
-
300
- 1. Farms Analyzed:
301
- {', '.join(selected_farms)}
302
-
303
- 2. Analysis Period:
304
- From {start_date} to {end_date}
305
-
306
- 3. Key Findings:
307
- - Average LAI across all farms: {np.mean([data['LAI'].mean() for data in farm_data]):.2f}
308
- - Highest LAI observed: {max([data['LAI'].max() for data in farm_data]):.2f}
309
- - Lowest LAI observed: {min([data['LAI'].min() for data in farm_data]):.2f}
310
-
311
- 4. Farm-specific Analysis:
312
- """
313
-
314
- for farm, data in zip(selected_farms, farm_data):
315
- report += f"""
316
- {farm}:
317
- - Average LAI: {data['LAI'].mean():.2f}
318
- - LAI Trend: {"Positive" if np.polyfit(range(len(data['LAI'])), data['LAI'], 1)[0] > 0 else "Negative"}
319
- - LAI Variability: {"Low" if data['LAI'].std() < 0.5 else "High"}
320
- """
321
-
322
- report += """
323
- 5. Recommendations:
324
- - Monitor areas with low LAI for potential issues (nutrient deficiencies, water stress, pests)
325
- - Ensure uniform crop development by addressing high LAI variability areas
326
- - Adjust management practices based on LAI trends
327
- - Validate satellite observations with ground-truthing in areas of significant LAI differences
328
- - Use the LAI prediction model for proactive crop health management
329
- - Consider the correlation between vegetation indices for comprehensive crop health assessment
330
-
331
- 6. Next Steps:
332
- - Integrate environmental data (temperature, humidity, rainfall, solar radiation) for more comprehensive analysis
333
- - Conduct regular follow-up analyses to track crop development over time
334
- - Use insights from this analysis to inform precision agriculture practices
335
- """
336
-
337
- st.download_button(
338
- label="Download Analysis Report",
339
- data=report,
340
- file_name="sugar_beet_analysis_report.txt",
341
- mime="text/plain"
342
- )
343
-
344
- st.write("Analysis complete. Use the buttons above to compare farms, view year-over-year changes, and generate a downloadable report.")
345
 
 
 
 
18
  ee.Initialize(eeservice)
19
 
20
  # Load farm data
21
+ farm_data_path = "tableConvert.com_wftamx (1).csv"
22
+ df = pd.read_csv(farm_data_path)
23
+
24
+ # Streamlit UI
25
+ st.title("NDVI Visualization for Dehkhoda Sugarcane Company")
26
+ st.markdown("Select a date range and farm to view NDVI over time.")
27
+
28
+ # Date input widgets
29
+ default_start = date(2023, 1, 1)
30
+ default_end = date(2023, 12, 31)
31
+ start_date = st.date_input("Start Date", default_start)
32
+ end_date = st.date_input("End Date", default_end)
33
+
34
+ # Farm selection
35
+ selected_farm = st.selectbox("Select Farm", df["name"].unique())
36
+ farm_info = df[df["name"] == selected_farm].iloc[0]
37
+ farm_geometry = ee.Geometry.Point([farm_info["longitude"], farm_info["latitude"]])
38
+
39
+ # NDVI or NDRE selection
40
+ index_type = st.selectbox("Select Vegetation Index", ["NDVI", "NDRE"])
41
+ band_selection = {"NDVI": ["B8", "B4"], "NDRE": ["B8", "B5"]}
42
+
43
+ if st.button("Generate NDVI Map"):
44
+ try:
45
+ # Convert to string
46
+ start_date_str = start_date.strftime("%Y-%m-%d")
47
+ end_date_str = end_date.strftime("%Y-%m-%d")
48
+
49
+ # Load Sentinel-2 Image Collection
50
+ s2 = ee.ImageCollection("COPERNICUS/S2")\
51
+ .filterDate(start_date_str, end_date_str)\
52
+ .filterBounds(farm_geometry)\
53
+ .filter(ee.Filter.listContains('system:band_names', 'B8'))\
54
+ .sort('system:time_start', False)
55
+
56
+ # Select latest available image
57
+ latest_image = s2.first()
58
+
59
+ if latest_image:
60
+ # Compute NDVI/NDRE
61
+ index_image = latest_image.normalizedDifference(band_selection[index_type]).rename(index_type).clip(farm_geometry)
62
+
63
+ # Check if valid data exists
64
+ index_stats = index_image.reduceRegion(
65
+ reducer=ee.Reducer.mean(),
66
+ geometry=farm_geometry,
67
+ scale=30,
68
+ bestEffort=True
69
+ ).get(index_type)
70
+
71
+ if index_stats.getInfo() is None:
72
+ st.warning("No valid NDVI/NDRE data found for the selected date range.")
73
+ else:
74
+ st.success(f"NDVI/NDRE data found! Mean value: {index_stats.getInfo()}")
75
+
76
+ # Visualization parameters
77
+ vis_params = {
78
+ 'min': -1, 'max': 1,
79
+ 'palette': ['red', 'yellow', 'green']
80
+ }
81
+
82
+ # Create Folium map
83
+ m = folium.Map(location=[farm_info["latitude"], farm_info["longitude"]], zoom_start=13)
84
+ map_id_dict = index_image.getMapId(vis_params)
85
+ folium.TileLayer(
86
+ tiles=map_id_dict['tile_fetcher'].url_format,
87
+ attr='Google Earth Engine',
88
+ overlay=True,
89
+ name=index_type
90
+ ).add_to(m)
91
+ folium.LayerControl().add_to(m)
92
+ folium_static(m)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  else:
94
+ st.warning("No Sentinel-2 images available for the selected date range and location.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
+ except Exception as e:
97
+ st.error(f"An error occurred: {e}")