Esmaeilkianii commited on
Commit
722e552
·
verified ·
1 Parent(s): 471ddc6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -219
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 datetime
7
  import altair as alt
 
 
8
 
9
  # احراز هویت Google Earth Engine
10
- def authenticate_gee():
11
- try:
12
- credentials = ee.ServiceAccountCredentials(None, 'ee-esmaeilkiani13877-cfdea6eaf411.json')
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
- @st.cache_data
21
- def load_data():
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 get_ndvi_for_all_farms(date, farm_coords):
33
- aoi = ee.FeatureCollection(
34
- farm_coords.apply(
35
- lambda row: ee.Feature(
36
- ee.Geometry.Point([row['طول جغرافیایی'], row['عرض جغرافیایی']]),
37
- {'name': row['نام']}
38
- ),
39
- axis=1
40
- ).to_list()
41
- )
42
- start_date = (date - datetime.timedelta(days=3)).strftime('%Y-%m-%d')
43
- end_date = (date + datetime.timedelta(days=3)).strftime('%Y-%m-%d')
44
- s2 = ee.ImageCollection('COPERNICUS/S2_SR') \
45
- .filterBounds(aoi) \
46
- .filterDate(start_date, end_date) \
47
- .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) \
48
- .sort('CLOUDY_PIXEL_PERCENTAGE') \
49
- .first()
50
- if s2:
51
- ndvi = s2.normalizedDifference(['B8', 'B4']).rename('NDVI')
52
- ndvi_values = ndvi.reduceRegions(
53
- collection=aoi,
54
- reducer=ee.Reducer.mean(),
55
- scale=10
56
- ).getInfo()['features']
57
- return {v['properties']['name']: v['properties'].get('NDVI') for v in ndvi_values if 'name' in v['properties'] and 'NDVI' in v['properties']}
58
- return {}
59
-
60
- # دریافت نقشه NDVI برای یک مزرعه
61
- @st.cache_data
62
- def get_ndvi_map(date, coords):
63
- aoi = ee.Geometry.Point(coords).buffer(100)
64
- start_date = (date - datetime.timedelta(days=3)).strftime('%Y-%m-%d')
65
- end_date = (date + datetime.timedelta(days=3)).strftime('%Y-%m-%d')
66
- s2 = ee.ImageCollection('COPERNICUS/S2_SR') \
67
- .filterBounds(aoi) \
68
- .filterDate(start_date, end_date) \
69
- .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) \
70
- .sort('CLOUDY_PIXEL_PERCENTAGE') \
71
- .first()
72
- if s2:
73
- ndvi = s2.normalizedDifference(['B8', 'B4']).rename('NDVI')
74
- vis_params = {'min': 0, 'max': 1, 'palette': ['red', 'yellow', 'green']}
75
- return ndvi, vis_params
76
- return None, None
77
-
78
- # استایل‌دهی CSS
79
- def apply_css():
80
- st.markdown("""
81
- <style>
82
- body {
83
- background: linear-gradient(to right, #e0f7fa, #b2ebf2);
84
- font-family: 'Vazir', sans-serif;
85
- }
86
- .big-font {
87
- font-size: 36px !important;
88
- font-weight: bold;
89
- color: #0277BD;
90
- text-align: center;
91
- }
92
- .stButton>button {
93
- width: 100%;
94
- background: linear-gradient(45deg, #0277BD, #4FC3F7);
95
- color: white;
96
- border-radius: 25px;
97
- padding: 10px;
98
- font-size: 18px;
99
- transition: all 0.3s ease;
100
- }
101
- .stButton>button:hover {
102
- background: linear-gradient(45deg, #4FC3F7, #0277BD);
103
- transform: scale(1.05);
104
- }
105
- .metric-card {
106
- background-color: #f0f2f6;
107
- border-radius: 10px;
108
- padding: 15px;
109
- margin: 10px 0;
110
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
111
- }
112
- .metric-card h3 {
113
- margin-top: 0;
114
- color: #1E88E5;
115
- }
116
- .alert-box {
117
- background-color: #ffebee;
118
- padding: 10px;
119
- border-radius: 5px;
120
- color: #c62828;
121
- }
122
- </style>
123
- """, unsafe_allow_html=True)
124
-
125
- # برنامه اصلی
126
- def main():
127
- authenticate_gee()
128
- df, farm_coords = load_data()
129
- if df is None or farm_coords is None:
130
- st.error("داده‌ها بارگذاری نشدند!")
131
- st.stop()
132
-
133
- apply_css()
134
- st.sidebar.markdown('<p class="big-font">کراپ لاگ پایش مزارع</p>', unsafe_allow_html=True)
135
- selected_farm = st.sidebar.selectbox('انتخاب مزرعه', farm_coords['نام'].unique())
136
- selected_date = st.sidebar.date_input('انتخاب تاریخ', value=datetime.date.today())
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("داده‌ها ذخیره شدند!")