Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,56 +1,169 @@
|
|
1 |
-
import pandas as pd
|
2 |
import streamlit as st
|
|
|
3 |
import folium
|
4 |
from streamlit_folium import folium_static
|
|
|
|
|
5 |
|
6 |
-
#
|
7 |
-
|
8 |
-
df_coordinates = pd.read_csv('مختصات و مشخصات کامل مزارع (4).csv')
|
9 |
|
10 |
-
#
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
#
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
#
|
17 |
-
|
18 |
-
selected_representative = st.selectbox('انتخاب مزرعه نماینده', representatives)
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
st.write('**زیرمجموعههای مزرعه انتخاب شده:**', sub_farms)
|
24 |
-
|
25 |
-
# استخراج مختصات مزرعه نماینده
|
26 |
-
rep_coords = df_coordinates[df_coordinates['مزرعه'] == selected_representative][['عرض جغرافیایی', 'طول جغرافیایی']].values
|
27 |
-
if len(rep_coords) > 0:
|
28 |
-
rep_lat, rep_lon = rep_coords[0]
|
29 |
-
else:
|
30 |
-
st.error('مختصات مزرعه نماینده یافت نشد!')
|
31 |
-
st.stop()
|
32 |
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
folium.Marker(
|
49 |
-
[
|
50 |
-
popup=
|
51 |
-
icon=folium.Icon(color=
|
52 |
).add_to(m)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
import folium
|
4 |
from streamlit_folium import folium_static
|
5 |
+
import base64
|
6 |
+
from folium.plugins import MarkerCluster
|
7 |
|
8 |
+
# Set page title and layout
|
9 |
+
st.set_page_config(page_title="Farm Monitoring Dashboard", layout="wide")
|
|
|
10 |
|
11 |
+
# Add custom CSS for blinking effect
|
12 |
+
st.markdown("""
|
13 |
+
<style>
|
14 |
+
@keyframes blink {
|
15 |
+
0% { opacity: 1; }
|
16 |
+
50% { opacity: 0.3; }
|
17 |
+
100% { opacity: 1; }
|
18 |
+
}
|
19 |
+
.blinking {
|
20 |
+
animation: blink 1.5s infinite;
|
21 |
+
}
|
22 |
+
</style>
|
23 |
+
""", unsafe_allow_html=True)
|
24 |
|
25 |
+
# Function to load data
|
26 |
+
@st.cache_data
|
27 |
+
def load_data():
|
28 |
+
In a real app, you would load from actual CSV files
|
29 |
+
representative_farms = pd.read_csv("مزارع نماینده راتون.csv")
|
30 |
+
farm_coordinates = pd.read_csv("مختصات و مشخصات کامل مزارع (4).csv")
|
31 |
+
|
32 |
+
# For this example, we'll create sample dataframes
|
33 |
+
representative_farms = pd.DataFrame({
|
34 |
+
"مزرعه نماینده": ["Farm A", "Farm A", "Farm B", "Farm B", "Farm C"],
|
35 |
+
"زیر مجموعه": ["Subset A1", "Subset A2", "Subset B1", "Subset B2", "Subset C1"],
|
36 |
+
"کانال": ["Channel 1", "Channel 1", "Channel 2", "Channel 2", "Channel 3"],
|
37 |
+
"اداره": ["Dept 1", "Dept 1", "Dept 2", "Dept 2", "Dept 3"],
|
38 |
+
"سن": [3, 3, 5, 5, 2],
|
39 |
+
"واریته": ["Variety X", "Variety X", "Variety Y", "Variety Y", "Variety Z"],
|
40 |
+
"تهیه قلمه": ["Method 1", "Method 1", "Method 2", "Method 2", "Method 3"],
|
41 |
+
"مساحت کلی": [150, 120, 200, 180, 250]
|
42 |
+
})
|
43 |
+
|
44 |
+
farm_coordinates = pd.DataFrame({
|
45 |
+
"مزرعه": ["Farm A", "Subset A1", "Subset A2", "Farm B", "Subset B1",
|
46 |
+
"Subset B2", "Farm C", "Subset C1"],
|
47 |
+
"طول جغرافیایی": [51.4, 51.41, 51.39, 51.5, 51.51, 51.49, 51.3, 51.31],
|
48 |
+
"عرض جغرافیایی": [35.7, 35.71, 35.69, 35.8, 35.81, 35.79, 35.6, 35.61]
|
49 |
+
})
|
50 |
+
|
51 |
+
return representative_farms, farm_coordinates
|
52 |
|
53 |
+
# Load data
|
54 |
+
representative_farms, farm_coordinates = load_data()
|
|
|
55 |
|
56 |
+
# Title
|
57 |
+
st.title("Farm Monitoring Dashboard")
|
58 |
+
st.markdown("---")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
+
# Sidebar for farm selection
|
61 |
+
with st.sidebar:
|
62 |
+
st.header("Farm Selection")
|
63 |
+
|
64 |
+
# Get unique representative farms
|
65 |
+
unique_farms = representative_farms["مزرعه نماینده"].unique()
|
66 |
+
|
67 |
+
# Create dropdown for farm selection
|
68 |
+
selected_farm = st.selectbox(
|
69 |
+
"Select a representative farm:",
|
70 |
+
options=unique_farms
|
71 |
+
)
|
72 |
+
|
73 |
+
# Get subsets for the selected farm
|
74 |
+
if selected_farm:
|
75 |
+
subsets = representative_farms[representative_farms["مزرعه نماینده"] == selected_farm]["زیر مجموعه"].tolist()
|
76 |
+
|
77 |
+
st.subheader("Subsets:")
|
78 |
+
for subset in subsets:
|
79 |
+
st.markdown(f"- {subset}")
|
80 |
+
|
81 |
+
# Display farm details
|
82 |
+
st.subheader("Farm Details:")
|
83 |
+
farm_details = representative_farms[representative_farms["مزرعه نماینده"] == selected_farm].iloc[0]
|
84 |
+
|
85 |
+
st.markdown(f"**Age:** {farm_details['سن']} years")
|
86 |
+
st.markdown(f"**Variety:** {farm_details['واریته']}")
|
87 |
+
st.markdown(f"**Channel:** {farm_details['کانال']}")
|
88 |
+
st.markdown(f"**Department:** {farm_details['اداره']}")
|
89 |
+
st.markdown(f"**Cutting Method:** {farm_details['تهیه قلمه']}")
|
90 |
+
st.markdown(f"**Total Area:** {farm_details['مساحت کلی']} hectares")
|
91 |
|
92 |
+
# Main content - Map
|
93 |
+
if selected_farm:
|
94 |
+
# Get coordinates for the selected farm
|
95 |
+
main_farm_coords = farm_coordinates[farm_coordinates["مزرعه"] == selected_farm]
|
96 |
+
|
97 |
+
if not main_farm_coords.empty:
|
98 |
+
main_lat = main_farm_coords.iloc[0]["عرض جغرافیایی"]
|
99 |
+
main_lon = main_farm_coords.iloc[0]["طول جغرافیایی"]
|
100 |
+
|
101 |
+
# Get coordinates for subsets
|
102 |
+
subset_coords = farm_coordinates[farm_coordinates["مزرعه"].isin(subsets)]
|
103 |
+
|
104 |
+
# Create map centered on the main farm
|
105 |
+
m = folium.Map(location=[main_lat, main_lon], zoom_start=12,
|
106 |
+
tiles="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
107 |
+
attr="Esri World Imagery")
|
108 |
+
|
109 |
+
# Add layer control
|
110 |
+
folium.TileLayer('OpenStreetMap').add_to(m)
|
111 |
+
folium.TileLayer('Stamen Terrain').add_to(m)
|
112 |
+
folium.LayerControl().add_to(m)
|
113 |
+
|
114 |
+
# Add marker for the main farm
|
115 |
folium.Marker(
|
116 |
+
location=[main_lat, main_lon],
|
117 |
+
popup=f"<b>{selected_farm}</b><br>Representative Farm",
|
118 |
+
icon=folium.Icon(color="red", icon="star")
|
119 |
).add_to(m)
|
120 |
+
|
121 |
+
# Add markers for subsets with blinking effect
|
122 |
+
for _, row in subset_coords.iterrows():
|
123 |
+
iframe = folium.IFrame(f"""
|
124 |
+
<div>
|
125 |
+
<h4>{row['مزرعه']}</h4>
|
126 |
+
<p>Subset Farm</p>
|
127 |
+
<p>Coordinates: {row['عرض جغرافیایی']:.6f}, {row['طول جغرافیایی']:.6f}</p>
|
128 |
+
</div>
|
129 |
+
""")
|
130 |
+
|
131 |
+
popup = folium.Popup(iframe, min_width=200, max_width=300)
|
132 |
+
|
133 |
+
# Create a custom icon with blinking class
|
134 |
+
icon_html = """
|
135 |
+
<div class="blinking">
|
136 |
+
<i class="fa fa-map-marker fa-3x" style="color:green"></i>
|
137 |
+
</div>
|
138 |
+
"""
|
139 |
+
|
140 |
+
icon = folium.DivIcon(
|
141 |
+
icon_size=(30, 30),
|
142 |
+
icon_anchor=(15, 30),
|
143 |
+
html=icon_html
|
144 |
+
)
|
145 |
+
|
146 |
+
folium.Marker(
|
147 |
+
location=[row["عرض جغرافیایی"], row["طول جغرافیایی"]],
|
148 |
+
popup=popup,
|
149 |
+
icon=icon
|
150 |
+
).add_to(m)
|
151 |
+
|
152 |
+
# Display the map
|
153 |
+
st.subheader(f"Map for {selected_farm} and its Subsets")
|
154 |
+
folium_static(m, width=1000, height=600)
|
155 |
+
|
156 |
+
else:
|
157 |
+
st.error("No coordinates found for the selected farm.")
|
158 |
+
else:
|
159 |
+
st.info("Please select a farm from the sidebar to view on the map.")
|
160 |
|
161 |
+
# Add some information at the bottom
|
162 |
+
st.markdown("---")
|
163 |
+
st.markdown("### How to use this dashboard:")
|
164 |
+
st.markdown("""
|
165 |
+
1. Select a representative farm from the dropdown in the sidebar
|
166 |
+
2. View the farm's subsets and details in the sidebar
|
167 |
+
3. Explore the farm and its subsets on the satellite map
|
168 |
+
4. The main farm is marked with a red star
|
169 |
+
5. Subset farms are marked with blinking green markers
|