Esmaeilkiani commited on
Commit
cfba302
·
verified ·
1 Parent(s): d697c35

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -129
app.py CHANGED
@@ -1,139 +1,198 @@
1
  import streamlit as st
2
  import pandas as pd
3
- import numpy as np
4
- from datetime import datetime
 
5
  import plotly.express as px
6
- import sqlite3
7
  from pathlib import Path
8
 
9
- # تنظیمات اولیه
10
- st.set_page_config(page_title="سامانه مدیریت مزارع نیشکر", layout="wide", direction="rtl")
11
-
12
- # ایجاد دیتابیس
13
- def init_db():
14
- conn = sqlite3.connect('sugarcane_farms.db')
15
- c = conn.cursor()
16
- c.execute('''
17
- CREATE TABLE IF NOT EXISTS farm_data (
18
- id INTEGER PRIMARY KEY AUTOINCREMENT,
19
- row_number INTEGER,
20
- representative TEXT,
21
- channel INTEGER,
22
- department INTEGER,
23
- production INTEGER,
24
- cultivation_area REAL,
25
- sub_area REAL,
26
- variety TEXT,
27
- age TEXT,
28
- station1 REAL,
29
- station2 REAL,
30
- station3 REAL,
31
- station4 REAL,
32
- station5 REAL,
33
- current_height REAL,
34
- previous_height REAL,
35
- current_growth REAL,
36
- previous_growth REAL,
37
- current_nitrogen REAL,
38
- current_nitrogen_std REAL,
39
- previous_nitrogen REAL,
40
- previous_nitrogen_std REAL,
41
- current_moisture REAL,
42
- current_moisture_std REAL,
43
- previous_moisture REAL,
44
- previous_moisture_std REAL,
45
- well1_depth REAL,
46
- well2_depth REAL,
47
- reading_date DATE
48
- )
49
- ''')
50
- conn.commit()
51
- conn.close()
52
-
53
- # فرم ورود داده
54
- def data_entry_form():
55
- st.header("فرم ورود داده‌های مزارع نیشکر")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- col1, col2, col3 = st.columns(3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- with col1:
60
- row_number = st.number_input("ردیف", min_value=1, max_value=99)
61
- representative = st.text_input("نماینده (مثال: 01-22)")
62
- channel = st.selectbox("کانال", options=[i for i in range(1, 31) if i != 28])
63
- department = st.selectbox("اداره", options=[1, 2, 3, 4])
64
- production = st.selectbox("تولید", options=[1, 2])
 
 
 
 
 
 
 
 
 
 
65
 
66
- with col2:
67
- cultivation_area = st.number_input("مساحت داشت", min_value=0.0)
68
- sub_area = st.number_input("مساحت زیرمجموعه", min_value=0.0)
69
- variety = st.selectbox("واریته", options=["CP69", "CP48", "CP57"])
70
- age = st.selectbox("سن", options=["R1", "R2", "P"])
71
 
72
- with col3:
73
- reading_date = st.date_input("تاریخ قرائت")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- # ایستگاه‌های اندازه‌گیری
76
- st.subheader("ایستگاه‌های اندازه‌گیری")
77
- col1, col2, col3, col4, col5 = st.columns(5)
78
-
79
- with col1:
80
- station1 = st.number_input("ایستگاه 1", min_value=0.0)
81
- with col2:
82
- station2 = st.number_input("ایستگاه 2", min_value=0.0)
83
- with col3:
84
- station3 = st.number_input("ایستگاه 3", min_value=0.0)
85
- with col4:
86
- station4 = st.number_input("ایستگاه 4", min_value=0.0)
87
- with col5:
88
- station5 = st.number_input("ایستگاه 5", min_value=0.0)
89
-
90
- # محاسبه خودکار ارتفاع هفته جاری
91
- current_height = np.mean([station1, station2, station3, station4, station5])
92
- st.info(f"ارتفاع هفته جاری مزرعه (محاسبه شده): {current_height:.2f}")
93
-
94
- # ادامه فرم...
95
- col1, col2 = st.columns(2)
96
-
97
- with col1:
98
- previous_height = st.number_input("ارتفاع هفته گذشته مزرعه", min_value=0.0)
99
- current_growth = current_height - previous_height
100
- st.info(f"رشد هفته جاری (محاسبه شده): {current_growth:.2f}")
101
- previous_growth = st.number_input("رشد هفته گذشته", min_value=0.0)
102
-
103
- # دکمه ذخیره
104
- if st.button("ذخیره اطلاعات"):
105
- save_data(locals())
106
- st.success("اطلاعات با موفقیت ذخیره شد!")
107
-
108
- # تابع ذخیره‌سازی داده‌ها
109
- def save_data(data):
110
- conn = sqlite3.connect('sugarcane_farms.db')
111
- c = conn.cursor()
112
-
113
- # ایجاد query برای ذخیره داده‌ها
114
- query = """
115
- INSERT INTO farm_data (
116
- row_number, representative, channel, department, production,
117
- cultivation_area, sub_area, variety, age, station1, station2,
118
- station3, station4, station5, current_height, previous_height,
119
- current_growth, previous_growth, reading_date
120
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
121
- """
122
-
123
- values = (
124
- data['row_number'], data['representative'], data['channel'],
125
- data['department'], data['production'], data['cultivation_area'],
126
- data['sub_area'], data['variety'], data['age'], data['station1'],
127
- data['station2'], data['station3'], data['station4'], data['station5'],
128
- data['current_height'], data['previous_height'], data['current_growth'],
129
- data['previous_growth'], data['reading_date']
130
- )
131
-
132
- c.execute(query, values)
133
- conn.commit()
134
- conn.close()
135
-
136
- # اجرای برنامه
137
- if __name__ == "__main__":
138
- init_db()
139
- data_entry_form()
 
1
  import streamlit as st
2
  import pandas as pd
3
+ import folium
4
+ from streamlit_folium import folium_static
5
+ import jdatetime
6
  import plotly.express as px
7
+ import json
8
  from pathlib import Path
9
 
10
+ # تنظیمات اولیه صفحه
11
+ st.set_page_config(
12
+ page_title="مدیریت چاهک‌های مزارع نیشکر",
13
+ page_icon="🌱",
14
+ layout="wide",
15
+ initial_sidebar_state="expanded"
16
+ )
17
+
18
+ # CSS برای راست به چپ کردن متن‌ها
19
+ st.markdown(
20
+ """
21
+ <style>
22
+ .css-1d391kg {
23
+ direction: rtl;
24
+ }
25
+ .stButton>button {
26
+ float: right;
27
+ }
28
+ .stSelectbox>div>div {
29
+ direction: rtl;
30
+ text-align: right;
31
+ }
32
+ </style>
33
+ """,
34
+ unsafe_allow_html=True
35
+ )
36
+
37
+ # تعریف داده‌های اولیه
38
+ @st.cache_data
39
+ def load_initial_data():
40
+ data = {
41
+ 'مزرعه': ['01-28', '02-19', '02-27', '03-08', '03-30', '03-32'],
42
+ 'کانال': ['01', '02', '02', '03', '03', '03'],
43
+ 'اداره': [1, 2, 2, 1, 1, 1],
44
+ 'واریته': ['CP69', 'CP69', 'CP69', 'CP69', 'IR01-412', 'IRC00-14'],
45
+ 'مساحت': [23.83, 24.53, 24.84, 23.17, 23.35, 22.97],
46
+ 'چاهک_1_نصب': [False] * 6,
47
+ 'چاهک_1_تکنسین': [''] * 6,
48
+ 'چاهک_1_تاریخ': [''] * 6,
49
+ 'چاهک_1_lat': [0.0] * 6,
50
+ 'چاهک_1_lon': [0.0] * 6,
51
+ 'چاهک_2_نصب': [False] * 6,
52
+ 'چاهک_2_تکنسین': [''] * 6,
53
+ 'چاهک_2_تاریخ': [''] * 6,
54
+ 'چاهک_2_lat': [0.0] * 6,
55
+ 'چاهک_2_lon': [0.0] * 6,
56
+ }
57
+ return pd.DataFrame(data)
58
+
59
+ # لود داده‌ها
60
+ if 'farms_data' not in st.session_state:
61
+ st.session_state.farms_data = load_initial_data()
62
+
63
+ # تعریف تکنسین‌ها
64
+ TECHNICIANS = [
65
+ 'علی دغاغله',
66
+ 'علیرضا حمیدی',
67
+ 'مسعود بن موسی',
68
+ 'امین هنری'
69
+ ]
70
+
71
+ # عنوان اصلی
72
+ st.title("🌱 مدیریت چاهک‌های مزارع نیشکر")
73
+
74
+ # ساید‌بار برای فیلتر کردن
75
+ with st.sidebar:
76
+ st.header("فیلترها")
77
+ selected_department = st.selectbox(
78
+ "انتخاب اداره",
79
+ options=[0, 1, 2, 3, 4],
80
+ format_func=lambda x: "همه ادارات" if x == 0 else f"اداره {x}",
81
+ )
82
 
83
+ search_term = st.text_input("جستجو بر اساس نام مزرعه یا کانال")
84
+
85
+ # فیلتر کردن داده‌ها
86
+ filtered_data = st.session_state.farms_data.copy()
87
+ if selected_department != 0:
88
+ filtered_data = filtered_data[filtered_data['اداره'] == selected_department]
89
+ if search_term:
90
+ mask = (filtered_data['مزرعه'].str.contains(search_term)) | (filtered_data['کانال'].str.contains(search_term))
91
+ filtered_data = filtered_data[mask]
92
+
93
+ # نمایش آمار کلی
94
+ col1, col2, col3 = st.columns(3)
95
+ with col1:
96
+ total_wells = len(filtered_data) * 2
97
+ installed_wells = filtered_data['چاهک_1_نصب'].sum() + filtered_data['چاهک_2_نصب'].sum()
98
+ st.metric("کل چاهک‌ها", total_wells)
99
+
100
+ with col2:
101
+ st.metric("چاهک‌های نصب شده", installed_wells)
102
+
103
+ with col3:
104
+ st.metric("چاهک‌های باقی‌مانده", total_wells - installed_wells)
105
+
106
+ # نمایش نقشه
107
+ st.header("🗺️ نقشه چاهک‌ها")
108
+ m = folium.Map(location=[31.3183, 48.6706], zoom_start=10)
109
+
110
+ for idx, row in filtered_data.iterrows():
111
+ if row['چاهک_1_نصب'] and row['چاهک_1_lat'] != 0:
112
+ folium.Marker(
113
+ [row['چاهک_1_lat'], row['چاهک_1_lon']],
114
+ popup=f"مزرعه: {row['مزرعه']}<br>چاهک: 1<br>تکنسین: {row['چاهک_1_تکنسین']}<br>تاریخ: {row['چاهک_1_تاریخ']}",
115
+ icon=folium.Icon(color='red')
116
+ ).add_to(m)
117
 
118
+ if row['چاهک_2_نصب'] and row['چاهک_2_lat'] != 0:
119
+ folium.Marker(
120
+ [row['چاهک_2_lat'], row['چاهک_2_lon']],
121
+ popup=f"مزرعه: {row['مزرعه']}<br>چاهک: 2<br>تکنسین: {row['چاهک_2_تکنسین']}<br>تاریخ: {row['چاهک_2_تاریخ']}",
122
+ icon=folium.Icon(color='blue')
123
+ ).add_to(m)
124
+
125
+ folium_static(m)
126
+
127
+ # لیست مزارع و ثبت چاهک
128
+ st.header("📝 لیست مزارع و ثبت چاهک")
129
+
130
+ for idx, row in filtered_data.iterrows():
131
+ with st.expander(f"مزرعه {row['مزرعه']} - کانال {row['کانال']}"):
132
+ st.write(f"واریته: {row['واریته']}")
133
+ st.write(f"مساحت: {row['مساحت']} هکتار")
134
 
135
+ col1, col2 = st.columns(2)
 
 
 
 
136
 
137
+ # چاهک 1
138
+ with col1:
139
+ st.subheader("چاهک 1")
140
+ if not row['چاهک_1_نصب']:
141
+ if st.button(f"ثبت نصب چاهک 1 - مزرعه {row['مزرعه']}", key=f"well1_{idx}"):
142
+ technician = st.selectbox(
143
+ "انتخاب تکنسین",
144
+ options=TECHNICIANS,
145
+ key=f"tech1_{idx}"
146
+ )
147
+ lat = st.number_input("عرض جغرافیایی", value=31.3183, key=f"lat1_{idx}")
148
+ lon = st.number_input("طول جغرافیایی", value=48.6706, key=f"lon1_{idx}")
149
+ if st.button("ثبت نهایی", key=f"save1_{idx}"):
150
+ st.session_state.farms_data.at[idx, 'چاهک_1_نصب'] = True
151
+ st.session_state.farms_data.at[idx, 'چاهک_1_تکنسین'] = technician
152
+ st.session_state.farms_data.at[idx, 'چاهک_1_تاریخ'] = jdatetime.datetime.now().strftime("%Y/%m/%d")
153
+ st.session_state.farms_data.at[idx, 'چاهک_1_lat'] = lat
154
+ st.session_state.farms_data.at[idx, 'چاهک_1_lon'] = lon
155
+ st.success("چاهک 1 با موفقیت ثبت شد")
156
+ st.rerun()
157
+ else:
158
+ st.info(f"نصب شده توسط {row['چاهک_1_تکنسین']} در تاریخ {row['چاهک_1_تاریخ']}")
159
 
160
+ # چاهک 2
161
+ with col2:
162
+ st.subheader("چاهک 2")
163
+ if not row['چاهک_2_نصب']:
164
+ if st.button(f"ثبت نصب چاهک 2 - مزرعه {row['مزرعه']}", key=f"well2_{idx}"):
165
+ technician = st.selectbox(
166
+ "انتخاب تکنسین",
167
+ options=TECHNICIANS,
168
+ key=f"tech2_{idx}"
169
+ )
170
+ lat = st.number_input("عرض جغرافیایی", value=31.3183, key=f"lat2_{idx}")
171
+ lon = st.number_input("طول جغرافیایی", value=48.6706, key=f"lon2_{idx}")
172
+ if st.button("ثبت نهایی", key=f"save2_{idx}"):
173
+ st.session_state.farms_data.at[idx, 'چاهک_2_نصب'] = True
174
+ st.session_state.farms_data.at[idx, 'چاهک_2_تکنسین'] = technician
175
+ st.session_state.farms_data.at[idx, 'چاهک_2_تاریخ'] = jdatetime.datetime.now().strftime("%Y/%m/%d")
176
+ st.session_state.farms_data.at[idx, 'چاهک_2_lat'] = lat
177
+ st.session_state.farms_data.at[idx, 'چاهک_2_lon'] = lon
178
+ st.success("چاهک 2 با موفقیت ثبت شد")
179
+ st.rerun()
180
+ else:
181
+ st.info(f"نصب شده توسط {row['چاهک_2_تکنسین']} در تاریخ {row['چاهک_2_تاریخ']}")
182
+
183
+ # نمودار پیشرفت نصب به تفکیک اداره
184
+ st.header("📊 گزارش پیشرفت نصب")
185
+ progress_data = []
186
+ for dept in range(1, 5):
187
+ dept_data = st.session_state.farms_data[st.session_state.farms_data['اداره'] == dept]
188
+ total = len(dept_data) * 2
189
+ installed = dept_data['چاهک_1_نصب'].sum() + dept_data['چاهک_2_نصب'].sum()
190
+ progress_data.append({
191
+ 'اداره': f'اداره {dept}',
192
+ 'درصد پیشرفت': (installed / total * 100) if total > 0 else 0
193
+ })
194
+
195
+ progress_df = pd.DataFrame(progress_data)
196
+ fig = px.bar(progress_df, x='اداره', y='درصد پیشرفت',
197
+ title='درصد پیشرفت نصب چاهک‌ها به تفکیک اداره')
198
+ st.plotly_chart(fig)