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 = """ """ 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("

Revisor de Modelos IFC

", 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'{label}' 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'{link_text}' 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")