File size: 17,693 Bytes
9561110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72364e8
9561110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0cddb09
 
 
9561110
0cddb09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9561110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5325715
9561110
 
 
 
 
5325715
9561110
5325715
9561110
 
5325715
 
9561110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0cddb09
 
5325715
0cddb09
5325715
 
 
0cddb09
 
5325715
0cddb09
 
 
 
 
 
9561110
26494da
9561110
 
 
 
 
 
 
 
 
 
 
 
 
26494da
9561110
 
 
5325715
9561110
 
 
 
 
 
 
 
0cddb09
 
 
 
9561110
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
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")