Conociendo el nivel de infraestructura de ciudades utilizando imágenes satelitales.

En este blog te mostraremos algunos de los usos que podés darles a las bases de datos Open Buildings de Google. En concreto trabajaremos con las bases de datos para Nicaragua, obteniendo como resultado final una base de datos de edificaciones a nivel de departamentos y municipios (ciudades). En este blog usaremos las edificaciones como variable de aproximación (proxy) al concepto de infraestructura.

Algunos de los usos que puedes darle a la base de datos final incluye estimaciones poblacionales, identificación de centros urbanos y zonas de riesgo entre muchas otras.

Realizamos el proceso utilizando Python en un Jupyter Notebook y te lo mostraremos paso a paso. Las bases de datos que utilizamos y las resultantes te las dejamos por acá:

Descargar celdas para Nicaragua de Open Buildings

Base de datos de polígonos de departamentos y municipios de Nicaragua

Base de datos de edificación de Nicaragua a nivel de departamentos y municipios

¿Qué es Open Buildings?

Open Buildings es una iniciativa de Google que pone a disposición del público un conjunto de datos abiertos a gran escala que contienen contornos de los edificios detectados a través de imágenes satelitales de alta resolución. El dataset contiene 1.8 billones de detecciones de edificios para una superficie de 58 millones de km2. La imágenes corresponde al año 2021, en algunos casos el año de la detención puede variar.

Al descargar un dataset las variables incluidas son:

  • latitude: Latitud en grados decimales del centroide del polígono.
  • longitude: Longitud en grados decimales del centroide del polígono.
  • area_in_meters: Área en metros cuadrados del polígono.
  • confidence: Puntuación de confianza que indica la certeza de que sea una edificación, este valor varía de 0.65 a 1.
  • geometry: Representación del polígono de la edificación en formato WKT.
  • full_plus_code: Ubica un punto en el centro de la edificación.

Puedes conocer más de Open Buildings en https://sites.research.google/open-buildings/

¿Qué se entiende por “edificaciones o edificios” en el contexto de los datos?

El término edificio y edificación se usará como sinónimo, y se refiere a estructuras construidas que tienen una ubicación y huella física.

Proceso

A continuación te explicamos los código que utilizamos, pero primero, te vamos a contar de forma general los que hicimos para que tengas un poco de contexto del proceso.

Como mencionamos anteriormente el resultado de este código es una base de datos de edificaciones a nivel de departamentos y municipios de Nicaragua. Lo primero que debemos hacer es instalar todas las librerías de Python que usaremos.

Luego debemos descargar las bases de datos correspondientes a Nicaragua. Para esto debemos ir a Open Buildings y en el apartado “Download from the map” seleccionar los cuadrantes que corresponde a Nicaragua. Cada cuadrante es una base de datos, y para el caso de Nicaragua fue necesario descargar los datos de dos cuadrantes que luego debemos unir (los CSV pesan 110mb y 3gb). En la imagen 1 te mostramos cuales son estos cuadrantes. Como podés observar, en los cuadrantes donde está Nicaragua, también está Honduras, El Salvador, parte de Guatemala, Belice y Costa Rica. Esto significa que debemos limpiar la base de datos. Una vez que hemos dejado solo a Nicaragua, cruzaremos esta base de datos con los polígonos de cada municipio del país, y obtendremos una nueva base de datos con las variables de departamento y municipio. Para lograr estos hay que hacer algunas transformaciones de variables y verificaciones que ya te explicaremos en el código, pero en general ese es el sencillo proceso que hemos realizado.

Imagen 1. Descarga de bases de datos desde el mapa.

Una vez que obtengamos la base de datos GIS final, podrás conocer la cantidad de edificaciones por departamento y municipios (en metros cuadrados y en cantidades), y cruzar con otras bases de datos.

Código

El siguiente código fue escrito y ejecutado en un Jupyter Notebook, con Python versión 3.9.12.

El código mostrado a continuación está acompañado por comentarios explicando los procesos a realizar. Este código está listo para que lo copies y pegues en tu Jupyter Notebook y podás seguir el proceso.

El código lo dividiremos en tres etapas:

Etapa 1: Importación de librerías, base de datos a utilizar y transformación de variables.

Etapa 2: Importación de polígonos de los municipios y transformación de variables.

Etapa 3: Unión de DataFrames.

Etapa 1: Importación de librerías, base de datos a utilizar y transformación de variables.

# Importando las librerías a utilizar

pip install geopandas
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import Point
from shapely import wkt
from shapely import wkb
from shapely.wkt import loads
import shapely.wkt
import binascii
# Importando los dos archivo CSV correspondientes a los dos poligonos que ubican a Nicaragua y convirtiéndolos a dataframes de Python. Estos son los dos cuadrantes de la imagen 1. 

df0 = pd.read_csv('8f7_buildings.csv')

df1 = pd.read_csv('8f1_buildings.csv')
# Uniendo los dos datraframes

df = pd.concat([df0, df1]).reset_index(drop=True)
df.head()
# Convirtiendo la columna de geometría de strings a objeto Polygon

df['geometry'] = df['geometry'].apply(shapely.wkt.loads)

# Convirtiendo el dataframe "df" a un GeoDataFrame

gdf = gpd.GeoDataFrame(df, geometry='geometry')
# Obteniendo el polígono de Nicaragua

# Importando librería que permite obtener datos geográficos de OpenStreetMap (OSM), y para este caso obtener las fronteras administrativas de Nicaragua.

import osmnx as ox

# Usando osmnx para obtener el polígono de Nicaragua.

nicaragua = ox.geocode_to_gdf('Nicaragua')

# GeoDataFrame cuenta con una sola fila, entonces seleccionamos el primer polígono.

polygon = nicaragua['geometry'][0]
# Filtramos los datos para obtener solo la información de Nicaragua. Esto puede tomar entre 2 a 4 horas dependiendo de la capacidad de tu computadora. 

gdf_nic = gdf[gdf.geometry.within(polygon)]
gdf_nic
# Guardando el dataframe de Nicaragua en formato CSV.

gdf_nic.to_csv('gdf_nic.csv')
# Graficando para tener una visualización espacial de los datos. Esto lo hacemos para saber como se distribuyen espacialmente las edificaciones.

plt.figure(figsize=(10, 6))
plt.scatter(gdf_nic['longitude'], gdf_nic['latitude'])
plt.xlabel('Longitud')
plt.ylabel('Latitud')
plt.title('Visualización de datos geoespaciales')
plt.grid(True)
plt.show()

Etapa 2: Importación de polígonos de los municipios y transformación de variables.

# Importando la base de datos para extraer los polígonos de los municipios. Esta base de datos te la hemos compartido al inicio de este tutorial.

muni = pd.read_csv('municipios_nic.csv')
# Transformación de la variables "the_geom" (WKB (Well-Known Binary)) a formato shapely.geometry.

muni['the_geom'] = muni['the_geom'].apply(lambda x: wkb.loads(binascii.unhexlify(x)))

# Convirtiendo el dataframe muni a formato GeoDataFrame

gdf_muni = gpd.GeoDataFrame(muni, geometry='the_geom')
# Verificando que gdf_nic sean GeoDataFrame para poder unirlos. Esto lo podríamos omitir, pero siempre es importante verificar.

if isinstance(gdf_nic, gpd.GeoDataFrame):
    print("df es un GeoDataFrame")
else:
    print("df no es un GeoDataFrame")
# Verificando que gdf_muni sean GeoDataFrame

if isinstance(gdf_muni, gpd.GeoDataFrame):
    print("df es un GeoDataFrame")
else:
    print("df no es un GeoDataFrame")

Etapa 3: Unión de DataFrames.

# Unión de gdf_nic y gdf_muni

# Cambiando el nombre de la variable "the_geom" a "geometry" en gdf_muni.

gdf_muni = gdf_muni.rename(columns={'the_geom': 'geometry'})

# Definiendo la variables "geometry" como la columna de geometría activa.

gdf_muni = gdf_muni.set_geometry('geometry')

# Uniendo las bases de datos realizando un spatial join.

gdf_nic_muni = gpd.sjoin(gdf_nic, gdf_muni, how="left", op='intersects')

# La base de datos cuenta con 2,973,301 edificaciones identificadas para Nicaragua.

gdf_nic_muni
# Guardando el GeoDataFrame de edificaciones de Nicaragua a nivel de municipios en formato CSV. Podés descargar esta base de datos al inicio de este tutorial.

gdf_nic_muni.to_csv('gdf_nic_muni.csv')

Hasta aquí ya hemos creado la base de datos de edificación para Nicaragua a nivel de municipios. Ahora toca hacer un análisis exploratorio de los datos para identificar valores atípicos, nulos, inconsistencias entre otros. A continuación mostramos el código que nos permite identificar los valores nulos.

# Identificación de registros/edificaciones que cuentan con valores nulos.

gdf_nic_muni[gdf_nic_muni['index_right'].isna()]

Identificamos 8,018 registros con valores nulos. Estos datos corresponden a registros que no encontraron correspondencia con los polígonos de los municipios. Para corregir estos valores nulos podemos ir a cada ubicación e identificar el municipio correspondiente, este proceso puede que sea muy tardado. En nuestro caso eliminaremos los registros que contengan valores nulos y todos aquellos que tengan puntuación de confianza (confidence) menor a 0.7, luego mostraremos el ranking de los municipio con mayor “infraestructura” en Nicaragua. Para este ejemplo, entenderemos el área de las edificaciones como una variable proxy a la infraestructura del municipio.

# Eliminando registros/edificaciones que contengan valores nulos en cualquiera de las columnas

gdf_nic_muni = gdf_nic_muni.dropna()

# Obteniendo solo los registros/edificaciones con puntaje menor a 0.7.

gdf_nic_muni_07 = gdf_nic_muni[gdf_nic_muni['confidence'] >= 0.7]

# Obteniendo dataframe de los municipios por área de edificaciones en metros cuadrados.

gdf_nic_muni_07_agrupado=gdf_nic_muni_07[['municipio','area_in_meters']].groupby('municipio').sum()

gdf_nic_muni_07_sorted=gdf_nic_muni_07_agrupado.sort_values('area_in_meters', ascending=False)

gdf_nic_muni_07_sorted

Como podemos observar los tres municipios con mayor infraestructura (área de edificaciones) es Managua, León y Esteli, por otro lado los que cuentan con menor infraestructura son El Castillo, San Juan del Norte y Desembocadura del Rio Grande.

Sin embargo, para hacer un ranking más justos seria necesario comparar el área de edificaciones y el área del municipio. Esto lo hacemos en el siguiente código:

# Convirtiendo hectarias y metros cuadrados a kilometros cuadrados.

gdf_nic_muni_07_agrupado['area_in_km2_muni'] = gdf_nic_muni_07_agrupado['area_ha']/100

gdf_nic_muni_07_agrupado['area_in_km2_edi'] = gdf_nic_muni_07_agrupado['area_in_meters']/1000000

# Encontrando la relación entre el área de edificación y el área del municipio.

gdf_nic_muni_07_agrupado['relacion_edi_muni'] = gdf_nic_muni_07_agrupado['area_in_km2_edi']/gdf_nic_muni_07_agrupado['area_in_km2_muni']

gdf_nic_muni_07_agrupado['m2_de_edi_por_1km_de_muni'] = gdf_nic_muni_07_agrupado['relacion_edi_muni']*1000000

# Ordenando por la variable "m2_de_edi_por_1km_de_muni". Esta variables lo que muestra el área de edificación en metros cuadrados por cada 1 kilometros cuadrado de área en el municipio.

gdf_nic_muni_07_agrupado_sorted = gdf_nic_muni_07_agrupado.sort_values(by='m2_de_edi_por_1km_de_muni', ascending=False)
gdf_nic_muni_07_agrupado_sorted

Con este resultado el ranking cambia completamente, y podemos decir que el municipio de Dolores, cuenta con la mayor relación área de edificación y área del municipio. Para este municipio por cada kilometro cuadrado de área hay apróximadamente 30 metros cuadrados de edificación. Los municipios con menor relación son Puerto Cabezas, Prinzapolka y Waspan.

Hasta aquí llegamos con este tutorial, y como te estarás imaginando, las aplicaciones con esta base de datos son muchísimas, algunos de los posibles usos pueden ser la identificación de los centros urbanos, conteo de viviendas en zonas rurales, edificaciones cerca de zonas de riesgo, entre otros.