Spaces:
Sleeping
Sleeping
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 | |
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 | |
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 | |
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() | |