Librerías y Entorno de Trabajo

Para el desarrollo de esta sesión utilizaremos GeoPandas, una librería de código abierto fundamental en el ecosistema de Python geoespacial. GeoPandas extiende las capacidades de pandas para permitir operaciones espaciales en tipos geométricos. Funciona integrando otras librerías esenciales: utiliza pandas para el manejo de datos tabulares, shapely para realizar las operaciones geométricas y fiona para el acceso y lectura de archivos.

Para comenzar, importamos la librería utilizando el alias estándar que nos permitirá acceder a sus funciones de manera abreviada.

Python
import geopandas as gpd

Lectura de Fuentes de Datos Espaciales

En el análisis geográfico es común trabajar con diversos formatos de archivos. GeoPandas simplifica este proceso mediante el comando unificado read_file, el cual detecta automáticamente el formato del archivo de entrada. Trabajaremos con los formatos más estandarizados en la industria.

El formato Shapefile (.shp) es el estándar más antiguo y común. Aunque lo vemos como un solo archivo, en realidad es un conjunto de archivos que contienen la geometría (.shp), los atributos (.dbf) y la proyección (.prj). También es posible leer archivos comprimidos en formato .zip directamente sin necesidad de descomprimirlos previamente, lo cual optimiza el flujo de trabajo cuando descargamos datos de internet.

Adicionalmente, manejamos formatos modernos como GML o GeoJSON, muy utilizados en aplicaciones web y servicios de mapas.

Python
# Lectura de un Shapefile tradicional
localidades = gpd.read_file(r'ruta/a/tu/archivo/localidades.shp')

# Lectura directa de un archivo comprimido
barrios = gpd.read_file(r'ruta/a/tu/archivo/barrios.zip')

# Lectura de formatos web (GML y GeoJSON)
centroides = gpd.read_file('ruta/archivo.gml')
datos_json = gpd.read_file('ruta/archivo.geojson')

Estructura del GeoDataFrame y Manejo de Índices

Una vez cargados los datos, obtenemos un GeoDataFrame. Estructuralmente es idéntico a un DataFrame de pandas, pero incluye una columna especial llamada geometry. Esta columna es vital porque almacena la información espacial (puntos, líneas o polígonos) y es sobre la cual se ejecutarán los cálculos geográficos.

Para facilitar el análisis, es una buena práctica redefinir el índice de la tabla. En lugar de usar números consecutivos autogenerados (0, 1, 2...), asignamos una columna con valor semántico, como el nombre de la localidad, para poder realizar búsquedas y filtros de manera más intuitiva.

Python
# Asignar una columna de texto como índice principal
localidades_shp = localidades.set_index('Nombre')

# Exploración rápida de los primeros y últimos registros
localidades_shp.head(3)
localidades_shp.tail(4)

Atributos Geométricos Básicos: Área y Perímetro

Los objetos espaciales tienen propiedades intrínsecas. Como estamos trabajando con un sistema proyectado, podemos calcular métricas euclidianas directamente. La propiedad .area nos devuelve la superficie de cada polígono en las unidades del sistema de referencia (usualmente metros cuadrados), mientras que .boundary extrae el límite del polígono, convirtiéndolo en una línea (LineString), lo que nos sirve para calcular perímetros.

Es importante notar que estas operaciones se realizan 'fila por fila' de manera vectorizada, lo que hace el procesamiento muy eficiente.

Python
# Cálculo del área
localidades_shp['area'] = localidades_shp.area

# Extracción del límite (perímetro)
localidades_shp['perimetro'] = localidades_shp.boundary

Geometría Constructiva: Centroides y Envolventes

Más allá de medir, podemos construir nuevas geometrías derivadas de las originales. Un concepto clave es el Centroide, que representa el centro geométrico o punto de equilibrio de un polígono. Esto es útil cuando queremos simplificar un mapa de polígonos a puntos para análisis de distribución.

Otro concepto teórico relevante es el Convex Hull (envolvente convexa). Imagina que colocas una banda elástica alrededor de los puntos que forman tu geometría; la forma resultante es el polígono convexo más pequeño que contiene a todos los puntos. Esto se usa para simplificar formas complejas o analizar dispersión.

Python
# Generación de centroides (Puntos)
localidades_shp['centroide'] = localidades_shp.centroid

# Generación de la envolvente convexa (Polígono simplificado)
localidades_shp['envolvente'] = localidades_shp.convex_hull

Análisis de Proximidad: Distancias y Buffers

El análisis espacial muchas veces se trata de entender la relación entre objetos. Para calcular distancias, necesitamos un punto de referencia. La función .distance() calcula la distancia euclidiana más corta entre geometrías.

El concepto de Buffer (área de influencia) es fundamental en SIG. Consiste en crear un polígono que abarca toda el área dentro de una distancia específica desde una geometría dada. Esto es esencial para estudios de impacto ambiental o cobertura de servicios.

Python
# Cálculo de distancia desde un punto fijo a todas las localidades
punto_inicial = localidades_shp['centroide'].iloc[0]
localidades_shp['distancia'] = localidades_shp['centroide'].distance(punto_inicial)

# Promedio de distancias calculadas
promedio_dist = localidades_shp['distancia'].mean()

# Creación de un buffer de 10,000 unidades
localidades_shp['buffer_10k'] = localidades_shp.buffer(10000)

Visualización y Cartografía

La visualización es la herramienta principal para la exploración de datos. GeoPandas utiliza matplotlib como motor gráfico. Podemos crear mapas de coropletas, donde el color de cada polígono representa el valor de una variable (como el área), permitiendo identificar patrones visuales rápidamente.

Para mapas más complejos que requieren superponer varias capas (por ejemplo, mostrar los polígonos de las localidades y encima sus centroides), utilizamos el concepto de axis (ejes). Primero dibujamos la capa base y guardamos su referencia en una variable ax, y luego pasamos esa referencia a las siguientes capas para que se dibujen en el mismo lienzo.

Python
# Mapa básico coloreado por área con leyenda
localidades_shp.plot(column='area', legend=True)

# Mapa cambiando la geometría activa a centroides
localidades_shp.set_geometry('centroide').plot()

# Superposición de capas (Polígonos + Centroides)
ax = localidades_shp.plot(color='black')
localidades_shp['centroide'].plot(ax=ax, color='red')

# Mapa personalizado con tamaño de figura
localidades_shp.plot(
    column='Codigo',
    legend=True,
    figsize=(12, 20),
    legend_kwds={'loc': 'upper left'}
)

Operaciones de Conjuntos y Consultas Espaciales

Al igual que en SQL o pandas, podemos filtrar datos, pero también podemos realizar preguntas espaciales. La función .intersects() es una operación booleana que verifica si dos geometrías comparten algún espacio en común (se tocan o se solapan). Esto permite responder preguntas como '¿Qué áreas de influencia tocan una localidad específica?'.

También utilizamos .loc para selecciones por etiqueta y .query para consultas basadas en cadenas de texto, lo cual hace el código más legible.

Python
# Selección de una localidad específica
engativa = localidades_shp.loc['Engativá']

# Selección mediante consulta SQL-like
localidad_12 = localidades_shp.query("Codigo_Loc == '12'")

# Verificación de intersección espacial
intersecciones = localidades_shp['buffer_10k'].intersects(engativa.geometry)

Sistemas de Referencia de Coordenadas (CRS)

Finalmente, un concepto crítico en cualquier análisis SIG es el CRS (Coordinate Reference System). Los datos geográficos están definidos sobre la superficie curva de la Tierra, pero para medirlos y dibujarlos en una pantalla plana, necesitamos proyectarlos.

Cada proyección tiene un código único llamado EPSG. Es vital verificar en qué sistema están nuestros datos con .crs. Si necesitamos integrar datos de diferentes fuentes o realizar cálculos en diferentes unidades (grados vs metros), debemos reproyectar los datos usando .to_crs.

Python
# Consultar el sistema de referencia actual
print(localidades_shp.crs)

# Reproyectar a coordenadas geográficas mundiales (WGS84 - EPSG:4326)
localidades_wgs84 = localidades_shp.to_crs(epsg=4326)