Esmaeilkiani commited on
Commit
09fd0b6
·
verified ·
1 Parent(s): c0921c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -77
app.py CHANGED
@@ -4,97 +4,196 @@ import folium
4
  from streamlit_folium import st_folium
5
  import ee
6
  import geemap.foliumap as geemap
 
7
 
8
- # احراز هویت GEE با فایل json
 
 
9
  SERVICE_ACCOUNT = 'dehkhodamap-e9f0da4ce9f6514021@ee-esmaeilkiani13877.iam.gserviceaccount.com'
10
- KEY_PATH = 'ee-esmaeilkiani13877-cfdea6eaf411 (3).json'
11
- ee.Initialize(ee.ServiceAccountCredentials(SERVICE_ACCOUNT, KEY_PATH))
12
-
 
 
 
 
 
 
 
13
  st.set_page_config(page_title="داشبورد مزارع نماینده", layout="wide")
14
  st.title("📡 داشبورد پایش مزارع نماینده نیشکر دهخدا")
15
 
16
- # خواندن فایل‌ها
17
- df_links = pd.read_csv("مزارع نماینده راتون.csv", encoding='utf-8-sig')
18
- df_coords = pd.read_csv("مختصات و مشخصات کامل مزارع (4).csv", encoding='utf-8-sig')
19
-
20
- df_links.columns = df_links.columns.str.strip()
21
- df_coords.columns = df_coords.columns.str.strip()
22
- df_coords = df_coords.dropna(subset=["طول جغرافیایی", "عرض جغرافیایی"])
23
-
 
 
 
 
 
 
 
24
  # انتخاب مزرعه نماینده
 
25
  representatives = df_links["مزرعه نماینده"].dropna().unique()
26
  selected_rep = st.selectbox("🔍 انتخاب مزرعه نماینده:", sorted(representatives), index=0)
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  if selected_rep:
29
  subset_df = df_links[df_links["مزرعه نماینده"] == selected_rep]
30
  sub_farms = subset_df["زیر مجموعه"].dropna().tolist()
31
-
 
32
  rep_coords = df_coords[df_coords["مزرعه"] == selected_rep]
33
  if not rep_coords.empty:
34
- rep_lat = rep_coords["عرض جغرافیایی"].values[0]
35
- rep_lon = rep_coords["طول جغرافیایی"].values[0]
36
-
37
- m = folium.Map(
38
- location=[rep_lat, rep_lon],
39
- zoom_start=14,
40
- tiles="https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
41
- attr="Google Satellite"
42
- )
43
-
44
- folium.Marker(
45
- location=[rep_lat, rep_lon],
46
- tooltip=f"🌟 مزرعه نماینده: {selected_rep}",
47
- icon=folium.Icon(color='blue', icon='star')
48
- ).add_to(m)
49
-
50
- # نمایش زیرمزارعه‌ها روی نقشه
51
- for i, row in subset_df.iterrows():
52
- farm = row["زیر مجموعه"]
53
- coords = df_coords[df_coords["مزرعه"] == farm]
54
- if not coords.empty:
55
- lat = coords["عرض جغرافیایی"].values[0]
56
- lon = coords["طول جغرافیایی"].values[0]
57
- folium.CircleMarker(
58
- location=[lat, lon],
59
- radius=8,
60
- color="red",
61
- fill=True,
62
- fill_color="yellow",
63
- fill_opacity=0.8,
64
- tooltip=f"{farm} - سن: {row['سن']}، واریته: {row['واریته']}"
65
- ).add_to(m)
66
-
67
- st_folium(m, width=1000, height=600)
68
-
69
- # نمایش جدول اطلاعات زیرمزارعه‌ها
70
- st.subheader("📋 اطلاعات زیرمزارعه‌ها")
71
- st.dataframe(subset_df[["زیر مجموعه", "سن", "واریته", "تهیه قلمه", "��ساحت کلی"]])
72
-
73
- # نمودار NDVI برای هر زیرمزرعه
74
- st.subheader("📈 نمودار سری زمانی NDVI (S2)")
75
- for farm in sub_farms:
76
- coords = df_coords[df_coords["مزرعه"] == farm]
77
- if not coords.empty:
78
- lat = coords["عرض جغرافیایی"].values[0]
79
- lon = coords["طول جغرافیایی"].values[0]
80
- point = ee.Geometry.Point(float(lon), float(lat))
81
- collection = ee.ImageCollection('COPERNICUS/S2_SR') \
82
- .filterBounds(point) \
83
- .filterDate('2024-01-01', '2024-12-31') \
84
- .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) \
85
- .map(lambda img: img.addBands(img.normalizedDifference(['B8', 'B4']).rename('NDVI')))
86
-
87
- ndvi_ts = collection.select('NDVI').getRegion(point, 30).getInfo()
88
-
89
- if len(ndvi_ts) > 1:
90
- df_ndvi = pd.DataFrame(ndvi_ts[1:], columns=ndvi_ts[0])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  df_ndvi["datetime"] = pd.to_datetime(df_ndvi["time"], unit='ms')
92
  df_ndvi = df_ndvi[["datetime", "NDVI"]].dropna()
93
-
94
- st.line_chart(df_ndvi.set_index("datetime")["NDVI"], height=200, use_container_width=True)
95
- st.markdown(f"📍 **{farm}**")
 
96
  else:
97
- st.warning(f"📍 داده‌ای برای NDVI مزرعه {farm} پیدا نشد.")
98
-
99
- else:
100
- st.warning("مختصات مزرعه نماینده یافت نشد.")
 
4
  from streamlit_folium import st_folium
5
  import ee
6
  import geemap.foliumap as geemap
7
+ from datetime import date
8
 
9
+ #########################################
10
+ # تنظیمات احراز هویت Google Earth Engine
11
+ #########################################
12
  SERVICE_ACCOUNT = 'dehkhodamap-e9f0da4ce9f6514021@ee-esmaeilkiani13877.iam.gserviceaccount.com'
13
+ KEY_PATH = 'ee-esmaeilkiani13877-cfdea6eaf411.json'
14
+ try:
15
+ ee.Initialize(ee.ServiceAccountCredentials(SERVICE_ACCOUNT, KEY_PATH))
16
+ except Exception as e:
17
+ ee.Authenticate()
18
+ ee.Initialize()
19
+
20
+ #########################################
21
+ # تنظیمات صفحه Streamlit
22
+ #########################################
23
  st.set_page_config(page_title="داشبورد مزارع نماینده", layout="wide")
24
  st.title("📡 داشبورد پایش مزارع نماینده نیشکر دهخدا")
25
 
26
+ #########################################
27
+ # بارگذاری فایل‌های CSV
28
+ #########################################
29
+ @st.cache_data
30
+ def load_data():
31
+ df_links = pd.read_csv("مزارع نماینده راتون.csv", encoding='utf-8-sig')
32
+ df_coords = pd.read_csv("مختصات و مشخصات کامل مزارع (4).csv", encoding='utf-8-sig')
33
+ df_links.columns = df_links.columns.str.strip()
34
+ df_coords.columns = df_coords.columns.str.strip()
35
+ df_coords = df_coords.dropna(subset=["طول جغرافیایی", "عرض جغرافیایی"])
36
+ return df_links, df_coords
37
+
38
+ df_links, df_coords = load_data()
39
+
40
+ #########################################
41
  # انتخاب مزرعه نماینده
42
+ #########################################
43
  representatives = df_links["مزرعه نماینده"].dropna().unique()
44
  selected_rep = st.selectbox("🔍 انتخاب مزرعه نماینده:", sorted(representatives), index=0)
45
 
46
+ #########################################
47
+ # تنظیم بازه زمانی NDVI
48
+ #########################################
49
+ st.sidebar.subheader("تنظیم بازه زمانی NDVI")
50
+ start_date = st.sidebar.date_input("تاریخ شروع", value=date(2024, 1, 1))
51
+ end_date = st.sidebar.date_input("تاریخ پایان", value=date(2024, 12, 31))
52
+ if start_date > end_date:
53
+ st.sidebar.error("تاریخ شروع باید قبل از تاریخ پایان باشد.")
54
+ st.stop()
55
+
56
+ #########################################
57
+ # استخراج اطلاعات مزرعه نماینده و زیرمزارعه‌ها
58
+ #########################################
59
  if selected_rep:
60
  subset_df = df_links[df_links["مزرعه نماینده"] == selected_rep]
61
  sub_farms = subset_df["زیر مجموعه"].dropna().tolist()
62
+
63
+ # گرفتن مختصات مزرعه نماینده
64
  rep_coords = df_coords[df_coords["مزرعه"] == selected_rep]
65
  if not rep_coords.empty:
66
+ rep_lat = float(rep_coords["عرض جغرافیایی"].values[0])
67
+ rep_lon = float(rep_coords["طول جغرافیایی"].values[0])
68
+ else:
69
+ st.error("مختصات مزرعه نماینده یافت نشد.")
70
+ st.stop()
71
+
72
+ #########################################
73
+ # ساخت نقشه با کاشی‌های ماهواره‌ای (Google Satellite)
74
+ #########################################
75
+ m = folium.Map(
76
+ location=[rep_lat, rep_lon],
77
+ zoom_start=14,
78
+ tiles="https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
79
+ attr="Google Satellite"
80
+ )
81
+
82
+ # افزودن مارکر مزرعه نماینده
83
+ folium.Marker(
84
+ location=[rep_lat, rep_lon],
85
+ tooltip=f"🌟 مزرعه نماینده: {selected_rep}",
86
+ icon=folium.Icon(color='blue', icon='star')
87
+ ).add_to(m)
88
+
89
+ #########################################
90
+ # آماده‌سازی مجموعه Sentinel-2 در بازه انتخابی
91
+ #########################################
92
+ # برای بهبود زمان پاسخ، از یک منطقه کلی به عنوان فیلتر استفاده می‌کنیم؛
93
+ # از نقطه نماینده استفاده می‌کنیم.
94
+ roi = ee.Geometry.Point(rep_lon, rep_lat)
95
+
96
+ collection = (ee.ImageCollection('COPERNICUS/S2_SR')
97
+ .filterDate(str(start_date), str(end_date))
98
+ .filterBounds(roi)
99
+ .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
100
+ .map(lambda img: img.addBands(img.normalizedDifference(['B8', 'B4']).rename('NDVI'))))
101
+
102
+ # محاسبه تصویر میانی NDVI برای استخراج مقدار متوسط
103
+ median_img = collection.median()
104
+
105
+ #########################################
106
+ # نمایش زیرمزارعه‌ها روی نقشه به همراه محاسبه NDVI
107
+ #########################################
108
+ st.subheader("🗺️ نقشه مزارع نماینده و زیرمزارعه‌ها")
109
+ for i, row in subset_df.iterrows():
110
+ farm = row["زیر مجموعه"]
111
+ coords = df_coords[df_coords["مزرعه"] == farm]
112
+ if not coords.empty:
113
+ lat = float(coords["عرض جغرافیایی"].values[0])
114
+ lon = float(coords["طول جغرافیایی"].values[0])
115
+ point = ee.Geometry.Point(lon, lat)
116
+
117
+ # استخراج مقدار NDVI از تصویر میانی برای نقطه مورد نظر
118
+ try:
119
+ ndvi_dict = median_img.reduceRegion(
120
+ reducer=ee.Reducer.mean(),
121
+ geometry=point,
122
+ scale=10
123
+ ).getInfo()
124
+ ndvi_val = ndvi_dict.get('NDVI', None)
125
+ if ndvi_val is not None:
126
+ ndvi_val = float(ndvi_val)
127
+ else:
128
+ ndvi_val = 0
129
+ except Exception as e:
130
+ ndvi_val = 0
131
+
132
+ # تعیین رنگ بر اساس مقدار NDVI
133
+ if ndvi_val >= 0.6:
134
+ color = 'green'
135
+ status = "سلامت بالا"
136
+ elif 0.3 <= ndvi_val < 0.6:
137
+ color = 'yellow'
138
+ status = "متوسط"
139
+ elif 0 < ndvi_val < 0.3:
140
+ color = 'orange'
141
+ status = "ضعیف"
142
+ else:
143
+ color = 'gray'
144
+ status = "بدون پوشش گیاهی"
145
+
146
+ tooltip_text = (f"{farm}<br>"
147
+ f"سن: {row['سن']}<br>"
148
+ f"واریته: {row['واریته']}<br>"
149
+ f"تهیه قلمه: {row['تهیه قلمه']}<br>"
150
+ f"مساحت کلی: {row['مساحت کلی']}<br>"
151
+ f"NDVI: {ndvi_val:.2f} ({status})")
152
+
153
+ folium.CircleMarker(
154
+ location=[lat, lon],
155
+ radius=8,
156
+ color=color,
157
+ fill=True,
158
+ fill_color=color,
159
+ fill_opacity=0.8,
160
+ tooltip=tooltip_text
161
+ ).add_to(m)
162
+
163
+ # نمایش نقشه در Streamlit
164
+ st_folium(m, width=1000, height=600)
165
+
166
+ #########################################
167
+ # نمایش اطلاعات زیرمزارعه‌ها به صورت جدول
168
+ #########################################
169
+ st.subheader("📋 اطلاعات زیرمزارعه‌ها")
170
+ st.dataframe(subset_df[["زیر مجموعه", "سن", "واریته", "تهیه قلمه", "مساحت کلی"]])
171
+
172
+ #########################################
173
+ # نمایش نمودار سری زمانی NDVI برای هر زیرمزرعه
174
+ #########################################
175
+ st.subheader("📈 نمودار سری زمانی NDVI برای زیرمزارعه‌ها")
176
+ for farm in sub_farms:
177
+ coords = df_coords[df_coords["مزرعه"] == farm]
178
+ if not coords.empty:
179
+ lat = float(coords["عرض جغرافیایی"].values[0])
180
+ lon = float(coords["طول جغرافیایی"].values[0])
181
+ point = ee.Geometry.Point(lon, lat)
182
+
183
+ # استخراج سری زمانی NDVI از مجموعه تصاویر
184
+ try:
185
+ region_data = collection.select('NDVI').getRegion(point, 10).getInfo()
186
+ if len(region_data) > 1:
187
+ columns = region_data[0]
188
+ data = region_data[1:]
189
+ df_ndvi = pd.DataFrame(data, columns=columns)
190
  df_ndvi["datetime"] = pd.to_datetime(df_ndvi["time"], unit='ms')
191
  df_ndvi = df_ndvi[["datetime", "NDVI"]].dropna()
192
+ df_ndvi = df_ndvi.sort_values("datetime")
193
+
194
+ with st.expander(f"نمایش نمودار NDVI برای {farm}"):
195
+ st.line_chart(df_ndvi.set_index("datetime")["NDVI"])
196
  else:
197
+ st.warning(f"داده‌ای برای NDVI مزرعه {farm} پیدا نشد.")
198
+ except Exception as ex:
199
+ st.error(f"خطا در استخراج NDVI برای {farm}: {ex}")