import streamlit as st import warnings warnings.filterwarnings('ignore') import pandas as pd import geopandas as gpd from difflib import get_close_matches import tempfile import datetime from io import BytesIO st.set_page_config(page_title="Terradot CREA project", page_icon=":terradot:", layout='wide') def convert_to_gdf(uploaded_file): # Read the file using BytesIO file_buffer = BytesIO(uploaded_file.read()) # Detect file type and load accordingly if uploaded_file.name.endswith('.shp'): gdf = gpd.read_file(file_buffer) elif uploaded_file.name.endswith(('.geojson', '.json')): gdf = gpd.read_file(file_buffer, driver='GeoJSON') else: raise ValueError("Unsupported file format") return gdf # add logo D:\Terradot\repos\crea-carbon-model\app\logo.jpg st.sidebar.image('logo.jpg', width=300) st.sidebar.markdown("""Terradot""", unsafe_allow_html=True) st.sidebar.title('Proyecto Crea') st.sidebar.write('Solo uso interno') # add sidebar with 2 upload buttons st.sidebar.header('Upload Files') uploaded_file = st.sidebar.file_uploader('Upload your shapefile', type=['shp', 'geojson', 'json'], disabled = True) uploaded_file2 = st.sidebar.file_uploader('Upload your csv file', type=['csv'], disabled = True) if uploaded_file is not None: lotes_gdf = convert_to_gdf(uploaded_file) st.write(lotes_gdf) if uploaded_file2 is not None: # read csv and create dataframe obs_df_2023 = pd.read_csv(uploaded_file2) # add Test button test = True #st.sidebar.button('Test') if 'key' not in st.session_state: st.session_state['key'] = None if 'lote_gdf' not in st.session_state: gdf = gpd.read_file('data/lotes espacio crea_empresa.shp', encoding='utf-8') gdf['campo_obs'] = None gdf['lote_obs'] = None st.session_state['lote_gdf'] = gdf if 'show_field' not in st.session_state: st.session_state['show_field'] = None if 'selected_company' not in st.session_state: st.session_state['selected_company'] = None if 'selected_farm' not in st.session_state: st.session_state['selected_farm'] = None if 'estado_farm' not in st.session_state: st.session_state['estado_farm'] = [] if 'estado_field' not in st.session_state: st.session_state['estado_field'] = [] if 'field_similar_dict_df' not in st.session_state: st.session_state['field_similar_dict_df'] = None def show_text(): def inner_func(): st.write('recuerde guardar') return inner_func if test: gdf = st.session_state['lote_gdf'] obs_df = pd.read_csv('data/obs_df_2023_12_1.csv') obs_df.fillna('-', inplace=True) obs_df.Campo = obs_df.Campo.astype('str') ##### Columns Section ##### col1, col2,col3 = st.columns(3) with col1: st.header('EMPRESA') # comp_list = obs_df.EMPRESA.unique().tolist() comp_list = gdf.empresa.unique().tolist() selected_company = st.selectbox(f'Seleccione empresa', comp_list, index= 0) st.session_state['selected_company'] = selected_company with col2: st.header('CAMPO') selected_company = st.session_state['selected_company'] obs_df_comp = obs_df[obs_df['EMPRESA'] == selected_company] farm_obs_names = obs_df_comp.Campo.unique().tolist() farm_obs_names.insert(0, 'no match') farm_gdf = gdf[gdf['empresa'] == selected_company] farm_gdf_names = farm_gdf.campo.unique().tolist() similar_dict = {} for item in farm_gdf_names: # normalize the stings to lowercase and remove punctuation in campo_obs farm_obs_norm = [str(c).lower() for c in farm_obs_names] farm_obs_norm = [c.replace('.', ' ') for c in farm_obs_norm] # Find the most similar item in df_columns list similar_items = get_close_matches(item, farm_obs_norm, 3, 0.72) # get the index of the most similar item similar_items_idx = [farm_obs_norm.index(i) for i in similar_items] # get the most similar item in the original list similar_items = [farm_obs_names[i] for i in similar_items_idx] # If a similar item is found, add to the dictionary if similar_items: similar_dict[item] = similar_items[0] else: # If no similar item is found, set value as "no match" similar_dict[item] = "no match" similar_dict_df = pd.DataFrame.from_dict(similar_dict, orient='index').reset_index() similar_dict_df.columns = ['gdf','obs'] with st.form(key='farm_name'): sel_farm_name = {} for i, farm in enumerate(farm_gdf_names): cll_val = farm_gdf[farm_gdf['campo'] == farm]['campo_obs'].unique()[0] if cll_val == None: index=farm_obs_names.index(similar_dict_df[similar_dict_df['gdf'] == farm]['obs'].values[0]) else: index=farm_obs_names.index(cll_val) selected_value = st.selectbox(f'{farm}:', \ farm_obs_names, index=index) sel_farm_name[farm] = selected_value submitted = st.form_submit_button(label='Guardar') if selected_company not in st.session_state['estado_farm']: st.write('sin guardar') st.session_state['show_field'] = False else: st.write('guardado') if submitted: st.session_state['estado_farm'].append(selected_company) st.write('guardado') for key, value in sel_farm_name.items(): similar_dict_df.loc[similar_dict_df['gdf'] == key, 'obs'] = value # farm_gdf.loc[farm_gdf['campo'] == key, 'campo_obs'] = value gdf.loc[(gdf['campo'] == key) & (gdf['empresa']), 'campo_obs'] = value st.session_state['lote_gdf'] = gdf st.session_state['show_field'] = True with col3: if st.session_state['show_field']: st.header('LOTE') gdf = st.session_state['lote_gdf'] selected_company = st.session_state['selected_company'] farm_gdf = gdf[gdf['empresa'] == selected_company] farm_list = gdf[gdf['empresa'] == selected_company]['campo'].unique().tolist() selected_farm = st.selectbox(f'Seleccione campo', farm_list, index=0) selected_obs_farm = gdf[(gdf['empresa'] == selected_company)&(gdf['campo'] == selected_farm)]['campo_obs'].unique()[0] field_gdf_names = gdf[(gdf['empresa'] == selected_company)&(gdf['campo'] == selected_farm)]['lote'].unique().tolist() field_obs_names = obs_df[(obs_df['EMPRESA'] == selected_company)&(obs_df['Campo'] == selected_obs_farm)]['Lote'].unique().tolist() field_obs_names.insert(0, 'no match') if selected_farm not in st.session_state['estado_field']: st.write('sin guardar') else: st.write('guardado') similar_dict = {} for item in field_gdf_names: # normalize the stings to lowercase and remove punctuation in campo_obs field_obs_norm = [str(c).lower() for c in field_obs_names] field_obs_norm = [c.replace('.', ' ') for c in field_obs_norm] # Find the most similar item in df_columns list similar_items = get_close_matches(item.lower(), field_obs_norm, 3, 0.50) # get the index of the most similar item similar_items_idx = [field_obs_norm.index(i) for i in similar_items] # get the most similar item in the original list similar_items = [field_obs_names[i] for i in similar_items_idx] # If a similar item is found, add to the dictionary if similar_items: similar_dict[item] = similar_items[0] else: # If no similar item is found, set value as "no match" similar_dict[item] = "no match" field_similar_dict_df = pd.DataFrame.from_dict(similar_dict, orient='index').reset_index() field_similar_dict_df.columns = ['gdf','obs'] with st.form(key='field_name'): cll_val = farm_gdf[farm_gdf['campo'] == selected_farm]['campo_obs'].unique()[0] if cll_val == None: index=farm_obs_names.index(similar_dict_df[similar_dict_df['gdf'] == farm]['obs'].values[0]) else: index=farm_obs_names.index(cll_val) sel_field_name = {} for i, field in enumerate(field_gdf_names): # selected_field = st.selectbox(f'{field}:', \ # field_obs_names, index=field_obs_names.index(field_similar_dict_df[field_similar_dict_df['gdf'] == field]['obs'].values[0])) selected_field = st.multiselect(f'{field}:', \ field_obs_names, default=field_similar_dict_df[field_similar_dict_df['gdf'] == field]['obs'].values) sel_field_name[field] = selected_field submitted = st.form_submit_button(label='Guardar') if submitted: st.session_state['estado_field'].append(selected_farm) st.write('guardado') for key, value in sel_field_name.items(): field_similar_dict_df.loc[field_similar_dict_df['gdf'] == key, 'obs'] = [value] gdf.loc[(gdf['empresa'] == selected_company) & (gdf['campo'] == selected_farm) & (gdf['lote'] == key), 'lote_obs'] = str(value) st.session_state['lote_gdf'] = gdf st.session_state['show_field'] = True ##### Download Section ##### # get today and hour minute today = datetime.date.today() now = datetime.datetime.now() hour = now.hour minute = now.minute st.sidebar.download_button( label="Download GeoJSON", data=gdf.to_json().encode('utf-8'), file_name=f'TODO_{today}_{hour}_{minute}.geojson', # mime='text/csv', mime = 'application/json', )