import pydeck as pdk import pandas as pd import psycopg2 from shapely.wkt import loads import geopandas as gpd # Función para conectarse a la base de datos y obtener los datos def get_data_from_db(): # Parámetros de conexión a PostgreSQL conn_params = { 'host': '146.59.69.180', 'port': '30038', 'dbname': 'ar', 'user': 'postgres', 'password': 'pg' } # Conectar a la base de datos conn = psycopg2.connect(**conn_params) cursor = conn.cursor() # Consulta SQL para obtener latitud, longitud y altura query = """ SELECT id, ST_AsText(geom), zz FROM cordoba.edificios_lidar_4326; """ # Ejecutar la consulta cursor.execute(query) data = cursor.fetchall() # Cerrar la conexión cursor.close() conn.close() # Crear el DataFrame df = pd.DataFrame(data, columns=['id', 'geometry_wkt', 'altura']) # Convertir las geometrías de WKT a objetos Shapely df['geometry'] = df['geometry_wkt'].apply(loads) df = df.drop(columns=['geometry_wkt']) return df def hexagon_map_from_db(path_save): # Convertir el DataFrame a un GeoDataFrame df = get_data_from_db() gdf = gpd.GeoDataFrame(df, geometry='geometry', crs='EPSG:4326') # Obtener el bounding box para centrar el mapa bounds = gdf.total_bounds # [x_min, y_min, x_max, y_max] x_min, y_min, x_max, y_max = bounds # Calcular la altura mínima para ajustar el nivel base altura_min = gdf['altura'].min() # Crear una lista de geometrías y sus propiedades para PyDeck polygons = [ { "polygon": list(geom.exterior.coords), # Coordenadas del polígono "altura": altura / 10 - altura_min / 10, # Ajustar altura relativa al suelo } for geom, altura in zip(gdf.geometry, gdf.altura) ] # Cargar tu estilo personalizado de Mapbox GL JSON custom_style = "https://tileserver.ipsilum.com/styles/osm/style.json" # Crear la capa de polígonos 3D polygon_layer = pdk.Layer( "PolygonLayer", data=polygons, pickable=True, stroked=True, filled=True, extruded=True, get_polygon="polygon", get_elevation="altura", # Usar solo la altura ajustada get_fill_color="[0, altura * 300, altura * 100, 140]", # Color basado en la altura get_line_color=[255, 255, 255], line_width_min_pixels=1, ) # Crear el estado de vista centrado en los datos view_state = pdk.ViewState( latitude=(y_min + y_max) / 2, longitude=(x_min + x_max) / 2, zoom=14, pitch=30, # Reducido para minimizar el efecto visual del desfase ) # Crear el mapa interactivo r = pdk.Deck( layers=[polygon_layer], initial_view_state=view_state, map_style=custom_style, tooltip={"text": "Altura: {altura}"}, # Tooltip para mostrar la altura ) # Guardar el resultado en un archivo HTML r.to_html(path_save) return path_save # Generar el mapa path_save = hexagon_map_from_db('/home/data3/master_folder/htmls/edificios_lidar_2.html')