Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,230 +1,125 @@
|
|
1 |
import streamlit as st
|
2 |
-
import pandas as pd
|
3 |
import folium
|
4 |
from streamlit_folium import folium_static
|
5 |
import ee
|
6 |
-
import
|
7 |
import altair as alt
|
|
|
|
|
8 |
|
9 |
# احراز هویت Google Earth Engine
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
ee.Initialize(credentials)
|
14 |
-
st.sidebar.success("اتصال به Google Earth Engine برقرار شد!")
|
15 |
-
except Exception as e:
|
16 |
-
st.sidebar.error(f"خطا در اتصال: {str(e)}")
|
17 |
-
st.stop()
|
18 |
|
19 |
# بارگذاری دادهها
|
20 |
-
|
21 |
-
|
22 |
-
try:
|
23 |
-
df = pd.read_csv('پایگاه داده (1).csv')
|
24 |
-
farm_coords = pd.read_csv('farm_coordinates.csv')
|
25 |
-
return df, farm_coords
|
26 |
-
except Exception as e:
|
27 |
-
st.error(f"خطا در بارگذاری دادهها: {str(e)}")
|
28 |
-
return None, None
|
29 |
|
30 |
-
# دریافت NDVI
|
31 |
@st.cache_data
|
32 |
-
def
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
)
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
.
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
if
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
.
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
#
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
st.
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
tab1, tab2, tab3 = st.tabs(["نقشه NDVI", "تحلیل هفتگی", "نمودار رشد"])
|
139 |
-
|
140 |
-
with tab1:
|
141 |
-
st.subheader(f"نقشه NDVI برای مزرعه {selected_farm}")
|
142 |
-
if st.button("نمایش نقشه"):
|
143 |
-
with st.spinner("در حال بارگذاری نقشه..."):
|
144 |
-
lon = farm_coords[farm_coords['نام'] == selected_farm]['طول جغرافیایی'].values[0]
|
145 |
-
lat = farm_coords[farm_coords['نام'] == selected_farm]['عرض جغرافیایی'].values[0]
|
146 |
-
coords = (lon, lat)
|
147 |
-
ndvi_image, vis_params = get_ndvi_map(selected_date, coords)
|
148 |
-
if ndvi_image:
|
149 |
-
m = folium.Map(location=[lat, lon], zoom_start=15)
|
150 |
-
folium.TileLayer(
|
151 |
-
tiles=ndvi_image.getMapId(vis_params)['tile_fetcher'].url_format,
|
152 |
-
attr='Google Earth Engine',
|
153 |
-
name='NDVI',
|
154 |
-
overlay=True
|
155 |
-
).add_to(m)
|
156 |
-
folium_static(m, width=1200, height=600)
|
157 |
-
st.success("نقشه با موفقیت بارگذاری شد!")
|
158 |
-
else:
|
159 |
-
st.error("دادههای NDVI برای این تاریخ یافت نشد.")
|
160 |
-
|
161 |
-
with tab2:
|
162 |
-
st.subheader("تحلیل هفتگی رشد مزارع")
|
163 |
-
if st.button("نمایش تحلیل هفتگی"):
|
164 |
-
with st.spinner("در حال پردازش دادههای هفتگی..."):
|
165 |
-
dates = [selected_date - datetime.timedelta(weeks=i) for i in range(5)]
|
166 |
-
dates = sorted(dates)
|
167 |
-
|
168 |
-
weekly_data = []
|
169 |
-
for date in dates:
|
170 |
-
ndvi_values = get_ndvi_for_all_farms(date, farm_coords)
|
171 |
-
for farm, ndvi in ndvi_values.items():
|
172 |
-
if ndvi is not None:
|
173 |
-
weekly_data.append({
|
174 |
-
'تاریخ': date.strftime('%Y-%m-%d'),
|
175 |
-
'مزرعه': farm,
|
176 |
-
'NDVI': ndvi
|
177 |
-
})
|
178 |
-
|
179 |
-
if weekly_data:
|
180 |
-
df_weekly = pd.DataFrame(weekly_data)
|
181 |
-
df_weekly['تاریخ'] = pd.to_datetime(df_weekly['تاریخ'])
|
182 |
-
|
183 |
-
# تحلیل هفته اخیر
|
184 |
-
last_week = df_weekly[df_weekly['تاریخ'] == dates[-1]]
|
185 |
-
prev_week = df_weekly[df_weekly['تاریخ'] == dates[-2]]
|
186 |
-
|
187 |
-
# محاسبه تغییرات
|
188 |
-
merged = pd.merge(last_week, prev_week, on='مزرعه', suffixes=('_last', '_prev'))
|
189 |
-
merged['تغییر'] = merged['NDVI_last'] - merged['NDVI_prev']
|
190 |
-
|
191 |
-
max_growth_farm = merged.loc[merged['تغییر'].idxmax()]
|
192 |
-
min_growth_farm = merged.loc[merged['تغییر'].idxmin()]
|
193 |
-
|
194 |
-
st.markdown("### نتایج تحلیل هفته اخیر:")
|
195 |
-
col1, col2 = st.columns(2)
|
196 |
-
with col1:
|
197 |
-
st.markdown('<div class="metric-card"><h3>بیشترین رشد</h3>' +
|
198 |
-
f'{max_growth_farm["مزرعه"]}: {max_growth_farm["تغییر"]:.2f}</div>',
|
199 |
-
unsafe_allow_html=True)
|
200 |
-
with col2:
|
201 |
-
st.markdown('<div class="metric-card"><h3>کمترین رشد</h3>' +
|
202 |
-
f'{min_growth_farm["مزرعه"]}: {min_growth_farm["تغییر"]:.2f}</div>',
|
203 |
-
unsafe_allow_html=True)
|
204 |
-
|
205 |
-
# هشدار برای مزارع ضعیف
|
206 |
-
low_growth_farms = last_week[last_week['NDVI'] < 0.3]
|
207 |
-
if not low_growth_farms.empty:
|
208 |
-
st.markdown('<div class="alert-box">هشدار: مزارع زیر رشد ضعیفی دارند!</div>', unsafe_allow_html=True)
|
209 |
-
st.dataframe(low_growth_farms[['مزرعه', 'NDVI']])
|
210 |
-
st.write("**پیشنهاد:** بررسی وضعیت آبیاری یا کوددهی این مزارع.")
|
211 |
-
|
212 |
-
with tab3:
|
213 |
-
st.subheader("نمودار میانگین رشد هفتگی")
|
214 |
-
if st.button("نمایش نمودار"):
|
215 |
-
with st.spinner("در حال تولید نمودار..."):
|
216 |
-
df_weekly = pd.DataFrame(weekly_data)
|
217 |
-
df_weekly['تاریخ'] = pd.to_datetime(df_weekly['تاریخ'])
|
218 |
-
df_weekly_avg_all = df_weekly.groupby('تاریخ')['NDVI'].mean().reset_index()
|
219 |
-
|
220 |
-
chart = alt.Chart(df_weekly_avg_all).mark_line(point=True).encode(
|
221 |
-
x='تاریخ:T',
|
222 |
-
y='NDVI:Q',
|
223 |
-
tooltip=['تاریخ', 'NDVI']
|
224 |
-
).properties(width=600, height=400).interactive()
|
225 |
-
|
226 |
-
st.altair_chart(chart, use_container_width=True)
|
227 |
-
st.success("نمودار با موفقیت رسم شد!")
|
228 |
-
|
229 |
-
if __name__ == "__main__":
|
230 |
-
main()
|
|
|
1 |
import streamlit as st
|
|
|
2 |
import folium
|
3 |
from streamlit_folium import folium_static
|
4 |
import ee
|
5 |
+
import pandas as pd
|
6 |
import altair as alt
|
7 |
+
from concurrent.futures import ThreadPoolExecutor
|
8 |
+
import numpy as np
|
9 |
|
10 |
# احراز هویت Google Earth Engine
|
11 |
+
service_account = '[email protected]'
|
12 |
+
credentials = ee.ServiceAccountCredentials(service_account, 'path/to/your/json/file.json')
|
13 |
+
ee.Initialize(credentials)
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
# بارگذاری دادهها
|
16 |
+
farms_data = pd.read_csv('farm_coordinates.csv')
|
17 |
+
local_data = pd.read_csv('local_data.csv')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
+
# تابع دریافت NDVI
|
20 |
@st.cache_data
|
21 |
+
def get_ndvi_image(farm_id, date):
|
22 |
+
farm = farms_data[farms_data['Farm_ID'] == farm_id]
|
23 |
+
geometry = ee.Geometry.Point([farm['Longitude'].values[0], farm['Latitude'].values[0]]).buffer(100)
|
24 |
+
date_range = ee.Date(date).advance(-3, 'day'), ee.Date(date).advance(3, 'day')
|
25 |
+
collection = ee.ImageCollection('COPERNICUS/S2') \
|
26 |
+
.filterDate(date_range[0], date_range[1]) \
|
27 |
+
.filterBounds(geometry) \
|
28 |
+
.select(['B4', 'B8']) \
|
29 |
+
.reduce(ee.Reducer.mean())
|
30 |
+
ndvi = collection.normalizedDifference(['B8_mean', 'B4_mean']).rename('NDVI')
|
31 |
+
return ndvi.clip(geometry)
|
32 |
+
|
33 |
+
# تابع نمایش نقشه
|
34 |
+
def show_ndvi_map(farm_id, date):
|
35 |
+
ndvi_image = get_ndvi_image(farm_id, date)
|
36 |
+
map_center = [farms_data[farms_data['Farm_ID'] == farm_id]['Latitude'].values[0],
|
37 |
+
farms_data[farms_data['Farm_ID'] == farm_id]['Longitude'].values[0]]
|
38 |
+
map = folium.Map(location=map_center, zoom_start=15)
|
39 |
+
ndvi_vis = {'min': 0, 'max': 1, 'palette': ['red', 'yellow', 'green']}
|
40 |
+
map.add_child(folium.GeoJson(ndvi_image.geometry(), name='Farm Boundary'))
|
41 |
+
map.add_ee_layer(ndvi_image, ndvi_vis, 'NDVI')
|
42 |
+
folium.LayerControl().add_to(map)
|
43 |
+
return map
|
44 |
+
|
45 |
+
# تابع تحلیل هفتگی
|
46 |
+
def weekly_analysis(farm_id):
|
47 |
+
dates = pd.date_range(end='2023-12-24', periods=5, freq='7D')
|
48 |
+
ndvi_values = []
|
49 |
+
height_values = []
|
50 |
+
for date in dates:
|
51 |
+
ndvi_image = get_ndvi_image(farm_id, date)
|
52 |
+
ndvi_value = ndvi_image.reduceRegion(reducer=ee.Reducer.mean(), geometry=ndvi_image.geometry(), scale=10).get('NDVI').getInfo()
|
53 |
+
ndvi_values.append(ndvi_value if ndvi_value else 0)
|
54 |
+
local = local_data[(local_data['Farm_ID'] == farm_id) & (local_data['Date'] == str(date.date()))]
|
55 |
+
height = local['Average_Height'].mean() if not local.empty else 0
|
56 |
+
height_values.append(height)
|
57 |
+
|
58 |
+
df = pd.DataFrame({'Date': dates, 'NDVI': ndvi_values, 'Height': height_values})
|
59 |
+
df['NDVI_Change'] = df['NDVI'].diff()
|
60 |
+
warnings = df[df['NDVI'] < 0.3].copy()
|
61 |
+
suggestions = ["بررسی سیستم آبیاری" if h < df['Height'].mean() else "استفاده از کود" for h in warnings['Height']]
|
62 |
+
warnings['Suggestions'] = suggestions
|
63 |
+
return df, warnings
|
64 |
+
|
65 |
+
# تابع نمودار رشد
|
66 |
+
def growth_chart(farm_id):
|
67 |
+
df, _ = weekly_analysis(farm_id)
|
68 |
+
ndvi_chart = alt.Chart(df).mark_line().encode(
|
69 |
+
x='Date:T', y='NDVI:Q', tooltip=['Date', 'NDVI']
|
70 |
+
).properties(title='رشد NDVI هفتگی').interactive()
|
71 |
+
height_chart = alt.Chart(df).mark_line(color='green').encode(
|
72 |
+
x='Date:T', y='Height:Q', tooltip=['Date', 'Height']
|
73 |
+
).properties(title='رشد ارتفاع هفتگی').interactive()
|
74 |
+
return ndvi_chart, height_chart
|
75 |
+
|
76 |
+
# رابط کاربری Streamlit
|
77 |
+
st.title("پایش مزارع نیشکر")
|
78 |
+
|
79 |
+
# سایدبار
|
80 |
+
st.sidebar.title("تنظیمات")
|
81 |
+
farm_id = st.sidebar.selectbox("انتخاب مزرعه", farms_data['Farm_ID'].astype(str) + " - " + farms_data['Farm_Name'])
|
82 |
+
farm_id = int(farm_id.split(" - ")[0]) # استخراج Farm_ID
|
83 |
+
date = st.sidebar.date_input("انتخاب تاریخ")
|
84 |
+
|
85 |
+
# تبها
|
86 |
+
tabs = st.tabs(["نقشه NDVI", "تحلیل هفتگی", "نمودار رشد", "ورود دادههای محلی"])
|
87 |
+
|
88 |
+
# تب نقشه NDVI
|
89 |
+
with tabs[0]:
|
90 |
+
if st.button("نمایش نقشه"):
|
91 |
+
with st.spinner("در حال بارگذاری نقشه..."):
|
92 |
+
map = show_ndvi_map(farm_id, date)
|
93 |
+
folium_static(map)
|
94 |
+
st.write(f"وضعیت هواشناسی: ⛅ 18°C") # مثال ساده
|
95 |
+
|
96 |
+
# تب تحلیل هفتگی
|
97 |
+
with tabs[1]:
|
98 |
+
if st.button("نمایش تحلیل هفتگی"):
|
99 |
+
df, warnings = weekly_analysis(farm_id)
|
100 |
+
st.write("تغییرات NDVI و ارتفاع:")
|
101 |
+
st.dataframe(df)
|
102 |
+
if not warnings.empty:
|
103 |
+
st.error("هشدارها:")
|
104 |
+
for _, row in warnings.iterrows():
|
105 |
+
st.write(f"تاریخ: {row['Date'].date()} - NDVI: {row['NDVI']:.2f} - پیشنهاد: {row['Suggestions']}")
|
106 |
+
|
107 |
+
# تب نمودار رشد
|
108 |
+
with tabs[2]:
|
109 |
+
if st.button("نمایش نمودار"):
|
110 |
+
ndvi_chart, height_chart = growth_chart(farm_id)
|
111 |
+
st.altair_chart(ndvi_chart, use_container_width=True)
|
112 |
+
st.altair_chart(height_chart, use_container_width=True)
|
113 |
+
|
114 |
+
# تب ورود دادههای محلی
|
115 |
+
with tabs[3]:
|
116 |
+
day = st.selectbox("انتخاب روز", ["شنبه", "یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه"])
|
117 |
+
cols = st.columns(5)
|
118 |
+
stations = [cols[i].number_input(f"ایستگاه {i+1}", min_value=0.0) for i in range(5)]
|
119 |
+
groundwater = [st.number_input(f"چاهک {i+1}", min_value=0.0) for i in range(2)]
|
120 |
+
moisture = st.number_input("رطوبت غلاف", min_value=0.0)
|
121 |
+
nitrogen = st.number_input("نیتروژن", min_value=0.0)
|
122 |
+
avg_height = np.mean(stations) if stations else 0
|
123 |
+
st.write(f"میانگین ارتفاع: {avg_height:.2f}")
|
124 |
+
if st.button("ذخیره دادهها"):
|
125 |
+
st.success("دادهها ذخیره شدند!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|