Analysiszaliai / app.py
Esmaeilkianii's picture
Update app.py
8586092 verified
raw
history blame
13.7 kB
import streamlit as st
import ee
import geemap.foliumap as geemap
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import plotly.express as px
# Initialize Earth Engine
@st.cache_resource
def initialize_ee():
service_account = "esmaeil-kiani1387-gmail-com@ee-esmaeilkiani13877.iam.gserviceaccount.com"
credentials = ee.ServiceAccountCredentials(service_account, 'ee-esmaeilkiani13877-9a054809a4bb.json')
ee.Initialize(credentials)
initialize_ee()
# Cache farm data loading
@st.cache_data
def load_farm_data():
return pd.read_csv('tableConvert.com_wftamx (1).csv')
# Calculate vegetation indices
def calculate_indices(image):
nir = image.select('B8')
red = image.select('B4')
red_edge = image.select('B5')
blue = image.select('B2')
ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
ndre = image.normalizedDifference(['B8', 'B5']).rename('NDRE')
savi = nir.subtract(red).divide(nir.add(red).add(0.5)).multiply(1.5).rename('SAVI')
# Simplified LAI calculation
lai = ndvi.expression(
'-(1/0.68) * log((0.89 - NDVI) / 0.89)',
{'NDVI': ndvi}
).rename('LAI')
return image.addBands([ndvi, ndre, savi, lai])
# Get image collection with all indices
@st.cache_data
def get_analyzed_collection(_start_date, _end_date, _region):
collection = (ee.ImageCollection("COPERNICUS/S2")
.filterDate(_start_date, _end_date)
.filterBounds(_region)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)))
return collection.map(lambda img: calculate_indices(img))
def main():
st.title("سیستم پایش پیشرفته مزارع نیشکر")
# Sidebar controls
st.sidebar.header("تنظیمات")
# Advanced farm search
farm_data = load_farm_data()
farm_search = st.sidebar.text_input("جستجوی مزرعه")
filtered_farms = farm_data[farm_data['name'].str.contains(farm_search, case=False, na=False)]
selected_farm = st.sidebar.selectbox("انتخاب مزرعه", filtered_farms['name'].tolist())
# Vegetation index selection
selected_indices = st.sidebar.multiselect(
"انتخاب شاخص‌های گیاهی",
["NDVI", "NDRE", "SAVI", "LAI"],
default=["NDVI"]
)
# Time range selection
time_range = st.sidebar.selectbox("بازه زمانی", ["هفتگی", "ماهانه"])
end_date = datetime.now()
if time_range == "هفتگی":
start_date = end_date - timedelta(weeks=7)
else:
start_date = end_date - timedelta(days=30)
# Define region
region_coords = [[48.79252390796415, 31.596953010376705],
[48.69124369556181, 31.607041188679787],
[48.69861903787225, 31.535914109610033],
[48.680600690190715, 31.417962552059578],
[48.72248606616728, 31.412981635420792],
[48.72660262384833, 31.424334080147833],
[48.7290033771076, 31.436272376332106],
[48.7362085123954, 31.429095544978416],
[48.75697875392245, 31.45721532135626],
[48.77106623584501, 31.475956095783822],
[48.77809194907528, 31.534990441425453],
[48.78495933248562, 31.539603784644903]]
region = ee.Geometry.Polygon(region_coords)
if st.sidebar.button("نمایش نقشه و تحلیل"):
try:
with st.spinner('در حال پردازش داده‌ها...'):
# Create map
map_ = geemap.Map(center=[31.5, 48.7], zoom=11)
# Get analyzed collection
collection = get_analyzed_collection(
start_date.isoformat(),
end_date.isoformat(),
region
)
# Calculate median values
median_image = collection.median().clip(region)
# Visualization parameters for different indices
vis_params = {
"NDVI": {"min": 0, "max": 1, "palette": ["red", "yellow", "green"]},
"NDRE": {"min": 0, "max": 1, "palette": ["red", "yellow", "green"]},
"SAVI": {"min": -1, "max": 1, "palette": ["red", "yellow", "green"]},
"LAI": {"min": 0, "max": 5, "palette": ["red", "yellow", "green"]}
}
# Add layers for selected indices
for index in selected_indices:
map_.addLayer(
median_image.select(index),
vis_params[index],
index
)
# Add markers for all farms
for _, farm in filtered_farms.iterrows():
map_.add_marker(
location=[farm['latitude'], farm['longitude']],
popup=f"مزرعه: {farm['name']}<br>سن: {farm['age']}<br>واریته: {farm['variety']}"
)
# Center map on selected farm
if selected_farm:
farm_info = farm_data[farm_data['name'] == selected_farm].iloc[0]
map_.center_object(ee.Geometry.Point([farm_info['longitude'], farm_info['latitude']]), 15)
# Display map
map_.add_layer_control()
map_.to_streamlit(height=500)
# Time series analysis
if selected_farm:
farm_info = farm_data[farm_data['name'] == selected_farm].iloc[0]
farm_point = ee.Geometry.Point([farm_info['longitude'], farm_info['latitude']])
# Get time series data for selected indices
series = collection.getRegion(farm_point, 30).getInfo()
# Process time series data
dates = []
values = {index: [] for index in selected_indices}
for row in series[1:]:
if all(row[4:]):
dates.append(datetime.fromtimestamp(row[3]/1000))
for i, index in enumerate(selected_indices):
values[index].append(row[4+i])
# Create time series plot
fig = go.Figure()
for index in selected_indices:
fig.add_trace(go.Scatter(x=dates, y=values[index], name=index))
fig.update_layout(
title=f"روند تغییرات شاخص‌های گیاهی برای مزرعه {selected_farm}",
xaxis_title="تاریخ",
yaxis_title="مقدار شاخص"
)
st.plotly_chart(fig)
# Growth prediction
st.subheader("پیش‌بینی روند رشد")
selected_index_for_prediction = st.selectbox("انتخاب شاخص برای پیش‌بینی", selected_indices)
X = np.array(range(len(dates))).reshape(-1, 1)
y = np.array(values[selected_index_for_prediction])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(X_train, y_train)
future_dates = pd.date_range(start=dates[-1], periods=30)
future_X = np.array(range(len(dates), len(dates) + 30)).reshape(-1, 1)
future_y = model.predict(future_X)
fig_prediction = go.Figure()
fig_prediction.add_trace(go.Scatter(x=dates, y=y, name="داده‌های واقعی"))
fig_prediction.add_trace(go.Scatter(x=future_dates, y=future_y, name="پیش‌بینی"))
fig_prediction.update_layout(
title=f"پیش‌بینی روند {selected_index_for_prediction} برای 30 روز آینده",
xaxis_title="تاریخ",
yaxis_title=selected_index_for_prediction
)
st.plotly_chart(fig_prediction)
# Weekly report
st.subheader("گزارش هفتگی")
weekly_growth = np.diff(values[selected_index_for_prediction])
max_growth = np.max(weekly_growth)
min_growth = np.min(weekly_growth)
avg_growth = np.mean(weekly_growth)
col1, col2, col3 = st.columns(3)
col1.metric("بیشترین رشد هفتگی", f"{max_growth:.4f}")
col2.metric("کمترین رشد هفتگی", f"{min_growth:.4f}")
col3.metric("میانگین رشد هفتگی", f"{avg_growth:.4f}")
if min_growth < 0:
st.warning("هشدار: افت رشد در هفته گذشته مشاهده شده است.")
# Management recommendations
st.subheader("پیشنهادات مدیریتی")
last_index_value = values[selected_index_for_prediction][-1]
if last_index_value < 0.3:
st.error("وضعیت رشد ضعیف است. پیشنهاد می‌شود:")
st.write("- برنامه آبیاری را بررسی و در صورت نیاز افزایش دهید.")
st.write("- کوددهی را طبق توصیه کارشناسان انجام دهید.")
elif 0.3 <= last_index_value < 0.6:
st.warning("وضعیت رشد متوسط است. پیشنهاد می‌شود:")
st.write("- برنامه آبیاری را بهینه کنید.")
st.write("- وضعیت تغذیه گیاه را بررسی کنید.")
else:
st.success("وضعیت رشد مناسب است. ادامه مراقبت‌های معمول توصیه می‌شود.")
# Advanced graphical analysis
st.subheader("تحلیل‌های گرافیکی پیشرفته")
# Interactive heatmap
fig_heatmap = px.imshow(
np.array([values[index] for index in selected_indices]),
x=dates,
y=selected_indices,
labels=dict(x="تاریخ", y="شاخص", color="مقدار"),
title="نقشه حرارتی شاخص‌های گیاهی"
)
st.plotly_chart(fig_heatmap)
# Animated growth visualization
fig_animation = px.scatter(
x=dates,
y=values[selected_indices[0]],
animation_frame=range(len(dates)),
range_y=[0, 1],
title=f"انیمیشن تغییرات {selected_indices[0]} در طول زمان"
)
st.plotly_chart(fig_animation)
# Analytical dashboard
st.subheader("داشبورد تحلیلی")
dashboard_index = st.selectbox("انتخاب شاخص برای داشبورد", selected_indices)
threshold = st.slider("آستانه هشدار", 0.0, 1.0, 0.5)
fig_dashboard = go.Figure()
fig_dashboard.add_trace(go.Scatter(x=dates, y=values[dashboard_index], name=dashboard_index))
fig_dashboard.add_hline(y=threshold, line_dash="dash", line_color="red", annotation_text="آستانه هشدار")
fig_dashboard.update_layout(
title=f"داشبورد تحلیلی {dashboard_index}",
xaxis_title="تاریخ",
yaxis_title="مقدار شاخص"
)
st.plotly_chart(fig_dashboard)
below_threshold = [date for date, value in zip(dates, values[dashboard_index]) if value < threshold]
if below_threshold:
st.warning(f"تاریخ‌هایی که مقدار شاخص زیر آستانه بوده است: {', '.join(map(str, below_threshold))}")
else:
st.success("مقدار شاخص در تمام تاریخ‌ها بالای آستانه بوده است.")
except Exception as e:
st.error(f"خطا در پردازش نقشه: {str(e)}")
if __name__ == "__main__":
main()