Spaces:
Sleeping
Sleeping
| import mysql.connector | |
| import streamlit as st | |
| import streamlit.components.v1 as components | |
| import pandas as pd | |
| import ifcopenshell | |
| import ifcopenshell.util.element as Element | |
| import tempfile | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| import plotly.io as pio | |
| import os | |
| import json | |
| import re | |
| import matplotlib.pyplot as plt | |
| import base64 | |
| hide_st_style = """ | |
| <style> | |
| #MainMenu {visibility: hidden;} | |
| footer {visibility: hidden;} | |
| header {visibility: hidden;} | |
| </style> | |
| """ | |
| st.markdown(hide_st_style, unsafe_allow_html=True) | |
| connection = mysql.connector.connect( | |
| host="srv1885.hstgr.io", | |
| user="u539776097_HQQNV", | |
| password="Nekoryu1234.", | |
| database="u539776097_zCV5L" | |
| ) | |
| if "button_clicked" not in st.session_state: | |
| st.session_state.button_clicked = False | |
| def callback(): | |
| st.session_state.button_clicked = True | |
| licenceifc=st.text_input("Ingrese su licencia","") | |
| if st.button("Acceso",on_click=callback) or st.session_state.button_clicked : | |
| cursor = connection.cursor() | |
| cursor2 = connection.cursor() | |
| select_patient_query = "select licencia_ifc from wp_lmfwc_licenses where licencia_ifc = %s" | |
| data=[(licenceifc)] | |
| cursor.execute(select_patient_query,data) | |
| licen = cursor.fetchone() | |
| if licen=="": | |
| st.write("La licencia esta correcto") | |
| else: | |
| cursor = connection.cursor() | |
| cursor2 = connection.cursor() | |
| select_patient_query = "select creditos from wp_lmfwc_licenses where licencia_ifc = %s" | |
| data=[(licenceifc)] | |
| cursor.execute(select_patient_query,data) | |
| patient = cursor.fetchone() | |
| final=re.sub(r'[,\(\)\"\']','',str(patient)) | |
| final=int(float(final)) | |
| if final > 0: | |
| # Crear la aplicaci贸n Streamlit | |
| st.title("Estandarizaci贸n del modelo Ifc") | |
| def cargar_datos_desde_json(tipo_modelo, nivel_avance): | |
| # Genera la ruta completa del archivo JSON basado en la selecci贸n del usuario | |
| nombre_archivo = f"{tipo_modelo}_{nivel_avance}.json" | |
| ruta_archivo = os.path.join( nombre_archivo) | |
| try: | |
| # Intenta abrir y cargar el archivo JSON correspondiente | |
| with open(ruta_archivo, 'r') as file: | |
| data = json.load(file) | |
| return data | |
| except FileNotFoundError: | |
| st.error(f"El archivo JSON '{nombre_archivo}' no se encontr贸 en la ubicaci贸n '{ruta_archivo}'.") | |
| return None | |
| except Exception as e: | |
| st.error(f"Error al cargar datos desde el archivo JSON: {str(e)}") | |
| return None | |
| def obtener_informacion(data, tipo_modelo, nivel_avance): | |
| if data and tipo_modelo in data and nivel_avance in data[tipo_modelo]: | |
| info_seleccionada = data[tipo_modelo][nivel_avance] | |
| rows = [] | |
| for entidad, ndi_info in info_seleccionada.items(): | |
| for ndi, ndi_data in ndi_info.items(): | |
| atributos = ndi_data.get('Atributos', None) | |
| Propiedades = ndi_data.get('Propiedades', None) | |
| # Utiliza apply con una funci贸n lambda para formatear la columna 'Atributos' | |
| atributos_str = ', '.join(atributos) if atributos else '' | |
| rows.append([entidad, ndi, atributos_str, Propiedades]) | |
| df = pd.DataFrame(rows, columns=['Entidad', 'NDI', 'Atributos', 'Propiedades']) | |
| return df | |
| else: | |
| return pd.DataFrame({'Mensaje': ['No se encontr贸 informaci贸n para la selecci贸n']}) | |
| # Crear la aplicaci贸n de Streamlit con el tama帽o de t铆tulo personalizado | |
| #st.markdown("<h1 style='text-left: center; font-size: 35px;'>Revisor de Modelos IFC</h1>", unsafe_allow_html=True) | |
| # Definir las listas de tipos de modelo y niveles de avance | |
| tipos_modelo = ["Sitio", "Volum茅trico", "Arquitectura", "Dise帽o de Infraestructura", "Estructura", | |
| "MEP", "Coordinaci贸n", "Construcci贸n", "As-Built", "Operaci贸n"] | |
| nivel_avance = ["DC", "DA", "DB", "DD", "CC", "CM","AB","PM","GM"] | |
| # Etiqueta para el tipo de modelo | |
| st.write("Seleccione el tipo de modelo:") | |
| tipo_modelo = st.selectbox("Tipo de Modelo:", tipos_modelo) | |
| # Etiqueta para el nivel de avance | |
| st.write("Seleccione el EAIM:") | |
| nivel_avance = st.selectbox("EAIM:", nivel_avance) | |
| data = cargar_datos_desde_json(tipo_modelo, nivel_avance) | |
| # Agrega un bot贸n de "Aceptar" | |
| if st.button("Aceptar"): | |
| st.write("Entidades, atributos y propiedades minimas de EBPP") | |
| # C贸digo que se ejecutar谩 cuando se presione el bot贸n | |
| resultado_df = obtener_informacion(data, tipo_modelo, nivel_avance) | |
| #st.write(resultado_df) # Muestra el resultado en la aplicaci贸n | |
| resultado_df = obtener_informacion(data, tipo_modelo, nivel_avance) | |
| def get_objects_data_by_class(entity): | |
| psets = Element.get_psets(entity) | |
| attribute_names = [attribute for attribute in dir(entity) if not attribute.startswith("_")] | |
| # Initialize a dictionary to store properties grouped by Pset name | |
| propiedades_dict = {} | |
| for pset_name, properties in psets.items(): | |
| propiedades = [] | |
| for property_name, property_value in properties.items(): | |
| if isinstance(property_value, ifcopenshell.entity_instance): | |
| property_value = property_value.Name | |
| propiedades.append(property_name) | |
| propiedades_dict[pset_name] = propiedades | |
| object_data = { | |
| 'Entidad': entity.is_a(), | |
| 'Atributos': ', '.join(attribute_names), | |
| 'Propiedades': propiedades_dict, | |
| } | |
| return object_data | |
| #cargar dataframe | |
| df1 = resultado_df[['Entidad', 'Propiedades']] | |
| def transformar_dataframe(df1): | |
| # Lista para almacenar los nuevos datos | |
| nuevas_filas = [] | |
| # Itera sobre cada fila del dataframe original | |
| for index, row in df1.iterrows(): | |
| element = row['Entidad'] | |
| properties = row['Propiedades'] | |
| # Verifica si properties es una cadena, de lo contrario ya es un diccionario | |
| if isinstance(properties, str): | |
| properties_dict = json.loads(properties) | |
| else: | |
| properties_dict = properties | |
| # Itera sobre cada grupo de propiedades y sus propiedades | |
| for grupo, propiedades in properties_dict.items(): | |
| for propiedad in propiedades: | |
| nuevas_filas.append({ | |
| 'Entidad': element, | |
| 'Grupo': grupo, | |
| 'Propiedades': propiedad | |
| }) | |
| # Crea un nuevo dataframe con las filas nuevas | |
| nuevo_df = pd.DataFrame(nuevas_filas) | |
| return nuevo_df | |
| # Transformar el dataframe | |
| nuevo_df = transformar_dataframe(df1) | |
| st.write("Propiedades a cargar en el modelo") | |
| # Mostrar el nuevo dataframe con Streamlit | |
| st.write(nuevo_df) | |
| ifcfile = None # Definir ifcfile en el 谩mbito global | |
| ifc_path = None # Definir ifc_path en el 谩mbito global | |
| save_path = None # Definir save_path en el 谩mbito global | |
| # Funci贸n para cargar el archivo IFC | |
| def cargar_archivo_ifc(ifc_file): | |
| global ifcfile, ifc_path # Usar las variables ifcfile e ifc_path globales | |
| if ifc_file is not None: | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".ifc") as temp_file: | |
| temp_file.write(ifc_file.read()) | |
| ifc_path = temp_file.name | |
| ifcfile = ifcopenshell.open(ifc_path) | |
| return ifcfile | |
| # Funci贸n para procesar los archivos cargados | |
| def procesar_archivos(ifcfile, json_data): | |
| if ifcfile is not None and json_data is not None: | |
| owner_history = ifcfile.by_type("IfcProduct")[0] | |
| for entity_type, entity_info in json_data.get(f"{tipo_modelo}", {}).get(f"{nivel_avance}", {}).items(): | |
| for _, data in entity_info.items(): | |
| propiedades = data.get("Propiedades", {}) | |
| try: | |
| # Filtrar entidades por tipo | |
| entities = set([entity for entity in ifcfile.by_type(entity_type) if entity.is_a(entity_type)]) | |
| for entity in entities: | |
| for pset_name, properties in propiedades.items(): | |
| property_set = None | |
| existing_property_sets = entity.IsDefinedBy | |
| for existing_pset in existing_property_sets: | |
| if hasattr(existing_pset, "RelatingPropertyDefinition") and hasattr(existing_pset.RelatingPropertyDefinition, "HasProperties") and hasattr(existing_pset.RelatingPropertyDefinition, "Name"): | |
| if existing_pset.RelatingPropertyDefinition.Name == pset_name: | |
| property_set = existing_pset | |
| break | |
| if property_set is None: | |
| property_values = [] | |
| for property_name in set(properties): # Utiliza un conjunto para obtener propiedades 煤nicas | |
| # Verificar si la propiedad ya existe por su nombre | |
| if not any(p.Name == property_name for p in property_values): | |
| property_values.append( | |
| ifcfile.createIfcPropertySingleValue(property_name, "Value", ifcfile.create_entity("IfcText", "0"), None) | |
| ) | |
| #print(f"Propiedades a agregar al conjunto: {property_values}") | |
| # Crear un nuevo conjunto de propiedades y asignarlo a la entidad | |
| property_set = ifcfile.createIfcPropertySet(entity.GlobalId, owner_history, pset_name, None, property_values) | |
| ifcfile.createIfcRelDefinesByProperties(entity.GlobalId, owner_history, None, None, [entity], property_set) | |
| else: | |
| # Si se encontr贸 un conjunto de propiedades existente, verificar y crear propiedades que falten | |
| existing_properties = set(p.Name for p in property_set.RelatingPropertyDefinition.HasProperties) | |
| missing_properties = set(properties) - existing_properties | |
| if missing_properties: | |
| missing_property_values = [] | |
| for property_name in missing_properties: | |
| if not any(p.Name == property_name for p in property_values): | |
| missing_property_values.append( | |
| ifcfile.createIfcPropertySingleValue(property_name, "Value", ifcfile.create_entity("IfcText", "0"), None) | |
| ) | |
| # Actualizar el conjunto de propiedades existente con las propiedades faltantes | |
| property_set.RelatingPropertyDefinition.HasProperties = list(property_set.RelatingPropertyDefinition.HasProperties) + missing_property_values | |
| #print(f"Propiedades agregadas al conjunto existente: {missing_properties}") | |
| except Exception as e: | |
| print(f"Error al procesar entidad '{entity_type}': {str(e)}") | |
| if ifcfile is None: | |
| print("cargar archivo") | |
| # Funci贸n para obtener el enlace de descarga | |
| def get_binary_file_downloader_html(bin_file, label='Archivo'): | |
| if bin_file is not None: | |
| with open(bin_file, 'rb') as f: | |
| data = f.read() | |
| b64 = base64.b64encode(data).decode() | |
| href = f'<a href="data:application/octet-stream;base64,{b64}" download="{os.path.basename(bin_file)}">{label}</a>' | |
| return href | |
| else: | |
| return '' # Si no se ha cargado un archivo IFC, devuelve una cadena vac铆a | |
| # Funci贸n para generar un enlace de descarga para un DataFrame de Pandas en formato Excel | |
| def get_table_download_link(nuevo_df, filename="Propiedades cargadas al modelo.xlsx", link_text="Descargar reporte de propiedades cargadas al modelo"): | |
| # Crear un BytesIO buffer para escribir el archivo Excel | |
| excel_buffer = pd.ExcelWriter(filename, engine="xlsxwriter") | |
| nuevo_df.to_excel(excel_buffer, index=False) | |
| excel_buffer._save() | |
| # Leer el archivo Excel en binario y codificarlo en base64 | |
| excel_binary = open(filename, 'rb').read() | |
| excel_base64 = base64.b64encode(excel_binary).decode() | |
| # Crear el enlace de descarga | |
| href = f'<a href="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,{excel_base64}" download="{filename}">{link_text}</a>' | |
| return href | |
| st.write("**Carga un archivo IFC para crear las propiedades faltantes en las entidades existentes del archivo IFC.**") | |
| ifc_file = st.file_uploader("Seleccionar archivo IFC", type=["ifc"]) | |
| #json_file = st.file_uploader("Seleccionar archivo JSON", type=["json"]) | |
| def obtener_nombre_archivo_ifc(ifc_file): | |
| if ifc_file is not None: | |
| nombre_archivo = os.path.basename(ifc_file.name) | |
| nombre_sin_extension, _ = os.path.splitext(nombre_archivo) | |
| return nombre_sin_extension | |
| else: | |
| return None | |
| nombre_archivo = obtener_nombre_archivo_ifc(ifc_file) | |
| st.write("Cada vez que procese un archivo este consumir谩, un cr茅dito de la licencia") | |
| if st.button("Procesar Archivos"): | |
| ifcfile = cargar_archivo_ifc(ifc_file) | |
| json_data = data | |
| procesar_archivos(ifcfile, json_data) | |
| # Create a temporary directory to save the processed IFC file | |
| with tempfile.TemporaryDirectory() as temp_dir: | |
| processed_ifc_path = os.path.join(temp_dir,f"{nombre_archivo}" "_Archivo_procesado.ifc") | |
| ifcfile.write(processed_ifc_path) | |
| # Display a download link for the processed IFC file | |
| st.markdown(get_binary_file_downloader_html(processed_ifc_path, label='Descargar Archivo IFC Procesado'), unsafe_allow_html=True) | |
| # Generar y mostrar el enlace de descarga | |
| st.markdown(get_table_download_link(nuevo_df), unsafe_allow_html=True) | |
| update_credit = "UPDATE wp_lmfwc_licenses set creditos = %s where licencia_ifc = %s" | |
| final=final-1 | |
| datacredit=[(final)] | |
| cursor2.execute(update_credit,(final,licenceifc)) | |
| connection.commit() | |
| st.write("Queda actualemente ",final," creditos para esta licencia") | |
| st.write("Espere a que aparesca el link de descargas y este texto no este en color gris") | |
| else : | |
| st.write("licencia sin creditos, Porfavor comprar otra licecnia para poder utilizar la herramienta") | |