miércoles, 21 de enero de 2026

Análisis geoespacial con Python - Parte 4 - Herramientas para análisis geoespacial

Geospatial Python Toolbox - Caja de Herramientas Geoespaciales
Python // Geospatial Analysis

Geospatial Python Toolbox

Tu arsenal completo de herramientas para análisis geoespacial con Python

Este capítulo presenta las bibliotecas Python esenciales para el análisis geoespacial. Desde la lectura de archivos shapefile hasta el procesamiento de imágenes satelitales, Python ofrece un ecosistema completo de herramientas que te permiten conquistar cualquier desafío en el campo geoespacial.

Exploraremos soluciones pure Python siempre que sea posible, y cuando la eficiencia lo requiera, utilizaremos bindings a bibliotecas de alto rendimiento escritas en C/C++. La portabilidad de Python lo convierte en la herramienta ideal para cualquier analista geoespacial.

MÓDULO_01

Instalación de Módulos

Antes de comenzar a trabajar con herramientas geoespaciales, necesitas configurar tu entorno Python correctamente. Existen varias formas de instalar módulos de terceros en Python.

Requisitos Técnicos

PYTHON
Versión 3.6 o superior
RAM
Mínimo 6GB, recomendado 8GB
STORAGE
SSD con 40GB disponibles

pip install

terminal
# Instalación básica con pip
pip install shapefile
pip install numpy
pip install gdal

# Para PIL en Python 3, usa Pillow
pip install Pillow

# Instalar desde GitHub
pip install https://github.com/GeospatialPython/dbfpy3/archive/master.zip

Conda Environment

Conda facilita la instalación de bibliotecas geoespaciales complejas con múltiples dependencias:

terminal
# Crear entorno virtual con Conda
conda create -n geospatial python=3.9
conda activate geospatial

# Instalar bibliotecas geoespaciales
conda install -c conda-forge gdal
conda install -c conda-forge geopandas
conda install -c conda-forge osmnx
Conda es especialmente útil para bibliotecas como osmnx que tienen docenas de dependencias complejas. Simplifica enormemente el proceso de instalación.
MÓDULO_02

Adquisición de Datos

Python proporciona bibliotecas robustas para descargar datos geoespaciales de internet. Las dos principales son urllib (biblioteca estándar) y requests (terceros).

Flujo de Adquisición de Datos
Internet
——→
urllib/requests
——→
Local Files

urllib Module

urllib_download.py
import urllib.request

# URL de un archivo shapefile comprimido
url = "https://github.com/GeospatialPython/Learn/raw/master/point.zip"

# Descargar el archivo
urllib.request.urlretrieve(url, "point.zip")

print("Descarga completada!")

requests Module

requests_download.py
import requests

url = "https://github.com/GeospatialPython/Learn/raw/master/hancock.zip"

# Realizar la petición HTTP
response = requests.get(url)

# Guardar el contenido binario
with open("hancock.zip", "wb") as f:
    f.write(response.content)

print(f"Status: {response.status_code}")

FTP Protocol

ftp_download.py
import ftplib

server = "ftp.ngdc.noaa.gov"
directory = "hazards/DART/20070815_peru"
filename = "21415_from_20070727_08_55_15_tides.txt"

# Conectar al servidor FTP
ftp = ftplib.FTP(server)
ftp.login()  # Acceso anónimo
ftp.cwd(directory)

# Descargar el archivo
with open(filename, "wb") as out:
    ftp.retrbinary("RETR " + filename, out.write)

# Verificar los datos
with open(filename) as dart:
    for line in dart:
        if "LAT, " in line:
            print(line)
            break
python ftp_download.py
LAT, LON 50.1663 171.8360
MÓDULO_03

Parsers de Datos

Los formatos de intercambio de datos geoespaciales incluyen XML (KML, GML) y JSON (GeoJSON). Python ofrece bibliotecas robustas para trabajar con ambos formatos.

ElementTree para XML/KML

parse_kml.py
import xml.etree.ElementTree as ET

# Parsear documento KML
tree = ET.ElementTree(file="time-stamp-point.kml")

# Definir namespace KML
ns = "{http://www.opengis.net/kml/2.2}"

# Buscar elemento Placemark
placemark = tree.find(f".//{ns}Placemark")

# Extraer coordenadas
coordinates = placemark.find(f"./{ns}Point/{ns}coordinates")
print(coordinates.text)
python parse_kml.py
-122.536226,37.86047,0

JSON/GeoJSON

parse_geojson.py
import json

# Documento GeoJSON de ejemplo
geojson_data = """
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [97.03125, 39.7265625]
  },
  "properties": {"name": "Sample Point"},
  "crs": {
    "type": "name",
    "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}
  }
}
"""

# Parsear GeoJSON
point = json.loads(geojson_data)

# Acceder a la geometría
print("Tipo:", point["geometry"]["type"])
print("Coordenadas:", point["geometry"]["coordinates"])
python parse_geojson.py
Tipo: Point
Coordenadas: [97.03125, 39.7265625]
GeoJSON es muy similar a los diccionarios de Python. Incluso eval() podría parsear JSON simple, aunque json.loads() es más seguro y robusto.
MÓDULO_04

Bibliotecas para Datos Vectoriales

Los datos vectoriales representan features geográficos como puntos, líneas y polígonos. Python ofrece múltiples bibliotecas para trabajar con estos formatos.

Ecosistema de Bibliotecas Vectoriales
Alto Nivel
GeoPandas
Fiona
Nivel Medio
PyShp
Shapely
geojson
Bajo Nivel
OGR (GDAL)
GEOS

OGR - Open Geospatial Library

OGR es parte de GDAL y soporta docenas de formatos vectoriales. Es el estándar de la industria:

ogr_example.py
from osgeo import ogr

# Abrir shapefile con OGR
shp = ogr.Open("point.shp")
layer = shp.GetLayer()

# Iterar sobre features
for feature in layer:
    geometry = feature.GetGeometryRef()
    print(geometry.GetX(), geometry.GetY(), 
          feature.GetField("FIRST_FLD"))
python ogr_example.py
1.0 1.0 First
3.0 1.0 Second
4.0 3.0 Third
2.0 2.0 Fourth
0.0 0.0 Appended

PyShp - Pure Python Shapefile

PyShp es una biblioteca simple y pura Python para leer y escribir shapefiles. Es portátil y fácil de usar:

pyshp_example.py
import shapefile

# Leer shapefile con PyShp
shp = shapefile.Reader("point.shp")

# Iterar sobre features
for feature in shp.shapeRecords():
    point = feature.shape.points[0]
    rec = feature.record[0]
    print(point[0], point[1], rec)
python pyshp_example.py
1.0 1.0 First
3.0 1.0 Second
4.0 3.0 Third
2.0 2.0 Fourth
0.0 0.0 Appended

Shapely - Computational Geometry

Shapely proporciona una API Pythonic sobre la biblioteca GEOS para operaciones geométricas avanzadas:

shapely_example.py
from shapely import wkt, geometry

# Crear polígono desde WKT
wkt_poly = "POLYGON((0 0,4 0,4 4,0 4,0 0))"
poly = wkt.loads(wkt_poly)

# Calcular área
print("Área original:", poly.area)

# Crear buffer de 5 unidades
buffered = poly.buffer(5.0)
print("Área con buffer:", buffered.area)

# Diferencia entre áreas
print("Área del buffer:", buffered.difference(poly).area)
python shapely_example.py
Área original: 16.0
Área con buffer: 174.41371226364848
Área del buffer: 158.413712264

Fiona - Simplified OGR

Fiona simplifica OGR con una API más Pythonic, exportando a GeoJSON por defecto:

fiona_example.py
import fiona
from pprint import pprint

# Abrir shapefile con Fiona
f = fiona.open("GIS_CensusTract_poly.shp")

# Información del archivo
print("Driver:", f.driver)
print("CRS:", f.crs)
print("Bounds:", f.bounds)
print("Features:", len(f))

# Ver esquema de datos
pprint(f.schema)
python fiona_example.py
Driver: ESRI Shapefile
CRS: {'init': 'epsg:4269'}
Bounds: (-89.87, 30.16, -89.13, 30.66)
Features: 45

GeoPandas - High-Level Analysis

GeoPandas extiende Pandas para datos geoespaciales, combinando la potencia de Shapely, Fiona y matplotlib:

geopandas_example.py
import geopandas
import matplotlib.pyplot as plt

# Cargar shapefile como GeoDataFrame
gdf = geopandas.GeoDataFrame
census = gdf.from_file("GIS_CensusTract_poly.shp")

# Visualizar mapa
census.plot()
plt.show()

# Exportar a GeoJSON
census.to_file("census.geojson", driver="GeoJSON")
GeoPandas permite realizar operaciones espaciales complejas que normalmente requerirían una base de datos como PostGIS, todo desde Python.
MÓDULO_05

Bibliotecas para Datos Raster

Los datos raster son imágenes georreferenciadas compuestas por píxeles. Python ofrece herramientas poderosas para procesamiento de imágenes satelitales y teledetección.

Pipeline de Procesamiento Raster
GDAL
——→
NumPy
——→
PIL/Rasterio

GDAL - Raster I/O

GDAL es la biblioteca dominante para datos raster, presente en casi todas las herramientas geoespaciales:

gdal_example.py
from osgeo import gdal

# Abrir imagen satelital
raster = gdal.Open("SatImage.tif")

# Obtener información del raster
print("Bandas:", raster.RasterCount)
print("Ancho (px):", raster.RasterXSize)
print("Alto (px):", raster.RasterYSize)

# Obtener geotransform
gt = raster.GetGeoTransform()
print("Origen X:", gt[0])
print("Origen Y:", gt[3])
python gdal_example.py
Bandas: 3
Ancho (px): 2592
Alto (px): 2693

NumPy - Array Processing

NumPy es el procesador de arrays multidimensional esencial para análisis raster. Su integración con GDAL es perfecta:

numpy_gdal.py
from osgeo import gdal_array

# Cargar imagen como array NumPy
src_array = gdal_array.LoadFile("SatImage.tif")

# Extraer primera banda
band1 = src_array[0]

# Guardar banda como JPEG
gdal_array.SaveArray(band1, "band1.jpg", format="JPEG")

# Información del array
print("Shape:", src_array.shape)
print("Dtype:", src_array.dtype)
python numpy_gdal.py
Shape: (3, 2693, 2592)
Dtype: uint8

PIL/Pillow - Image Processing

PIL (Pillow en Python 3) fue desarrollada originalmente para teledetección y es excelente para procesamiento de imágenes:

pil_example.py
from PIL import Image, ImageDraw

# Crear imagen nueva
img = Image.new("RGB", (400, 300), "black")
draw = ImageDraw.Draw(img)

# Dibujar polígono
polygon = [(50, 50), (200, 50), (200, 200), (50, 200)]
draw.polygon(polygon, fill="cyan", outline="white")

# Guardar imagen
img.save("polygon.png")

Rasterio - Pythonic GDAL

Rasterio envuelve GDAL en una API Python limpia y simple:

rasterio_example.py
import rasterio

# Abrir imagen con Rasterio
ds = rasterio.open("SatImage.tif")

# Información del dataset
print("Nombre:", ds.name)
print("Bandas:", ds.count)
print("Dimensiones:", ds.width, "x", ds.height)

# Leer banda como array
band1 = ds.read(1)
print("Array shape:", band1.shape)
python rasterio_example.py
Nombre: SatImage.tif
Bandas: 3
Dimensiones: 2592 x 2693

PNGCanvas - Pure Python PNG

PNGCanvas crea imágenes PNG sin dependencias externas, ideal para visualización simple:

pngcanvas_example.py
import shapefile
import pngcanvas

# Leer shapefile
r = shapefile.Reader("hancock.shp")

# Calcular dimensiones
xdist = r.bbox[2] - r.bbox[0]
ydist = r.bbox[3] - r.bbox[1]
iwidth, iheight = 400, 600
xratio = iwidth / xdist
yratio = iheight / ydist

# Convertir coordenadas a píxeles
pixels = []
for x, y in r.shapes()[0].points:
    px = int(iwidth - ((r.bbox[2] - x) * xratio))
    py = int((r.bbox[3] - y) * yratio)
    pixels.append([px, py])

# Crear imagen y dibujar polilínea
c = pngcanvas.PNGCanvas(iwidth, iheight)
c.polyline(pixels)

# Guardar PNG
with open("hancock.png", "wb") as f:
    f.write(c.dump())
MÓDULO_06

Bases de Datos Espaciales

Las bases de datos espaciales permiten almacenar y consultar datos geográficos de forma eficiente. Python puede conectarse a todas las principales bases de datos espaciales.

PyMySQL con Funciones Espaciales

mysql_spatial.py
import pymysql

# Conectar a MySQL
conn = pymysql.connect(
    host="localhost",
    user="root",
    password="password",
    database="spatial_db"
)

cursor = conn.cursor()

# Crear tabla con geometría
cursor.execute("""
    CREATE TABLE IF NOT EXISTS PLACES (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(100),
        location POINT NOT NULL,
        SPATIAL INDEX(location)
    )
""")

# Insertar ciudades como puntos
cursor.execute("""
    INSERT INTO PLACES (name, location) VALUES
    ('New York', ST_GeomFromText('POINT(-74.006 40.7128)')),
    ('Los Angeles', ST_GeomFromText('POINT(-118.2437 34.0522)'))
""")

# Calcular distancia entre ciudades
cursor.execute("""
    SELECT ST_Distance(
        (SELECT location FROM PLACES WHERE name='New York'),
        (SELECT location FROM PLACES WHERE name='Los Angeles')
    ) AS distance_degrees
""")

result = cursor.fetchone()
print(f"Distancia: {result[0]} grados")

conn.commit()
conn.close()
MySQL usa geometría planar y rectángulos de bounding box. Para cálculos más precisos en la superficie esférica de la Tierra, considera PostGIS o realiza las conversiones manualmente.
MÓDULO_07

Redes Viales con OSMnx

OSMnx combina OpenStreetMap con NetworkX para descargar, analizar y visualizar redes de calles. Es una herramienta poderosa para análisis de routing y movilidad urbana.

osmnx_example.py
import osmnx as ox

# Descargar red de calles de una ciudad
G = ox.graph_from_place(
    'Bay Saint Louis, MS, USA',
    network_type='drive'
)

# Calcular estadísticas básicas
stats = ox.basic_stats(G)
print("Longitud promedio de calle:", 
      stats["street_length_avg"], "metros")

# Visualizar red
ox.plot_graph(G)
python osmnx_example.py
Longitud promedio de calle: 172.15 metros
OSMnx tiene docenas de dependencias. Se recomienda instalarlo con Conda: conda install -c conda-forge osmnx
MÓDULO_08

PDF Geoespacial

Los PDFs geoespaciales contienen información de georreferenciación que permite conocer las coordenadas de cualquier punto en el documento. Python puede crear estos documentos usando la biblioteca geopdf.

geopdf_example.py
from geopdf import GeoCanvas
from reportlab.pdfbase.pdfdoc import PDFString, PDFArray

# Crear canvas PDF
canvas = GeoCanvas("map.pdf")

# Dibujar el estado de Colorado (rectángulo)
canvas.rect(100, 150, 400, 250, stroke=1, fill=0)

# Definir coordenadas del mapa
minx, miny = -109.05, 37.0
maxx, maxy = -102.05, 41.0

# Registrar georreferenciación
registration = PDFArray([
    PDFArray([PDFString('100'), PDFString('400'), 
               PDFString(str(minx)), PDFString(str(maxy))]),
    PDFArray([PDFString('500'), PDFString('400'), 
               PDFString(str(maxx)), PDFString(str(maxy))]),
    PDFArray([PDFString('100'), PDFString('150'), 
               PDFString(str(minx)), PDFString(str(miny))]),
    PDFArray([PDFString('500'), PDFString('150'), 
               PDFString(str(maxx)), PDFString(str(miny))])
])

canvas.addGeo(Registration=registration)
canvas.save()
Instala geopdf desde GitHub: pip install https://github.com/GeospatialPython/geopdf-py3/archive/master.zip
MÓDULO_09

Jupyter Notebooks

Jupyter Notebook es una aplicación web que crea documentos interactivos combinando código ejecutable, visualizaciones y texto narrativo. Es la herramienta preferida para análisis geoespacial exploratorio.

INTERACTIVO
Ejecuta código celda por celda y ve resultados inmediatamente
VISUALIZACIÓN
Muestra mapas y gráficos inline directamente en el notebook
COMPARTIBLE
Perfecto para tutoriales y documentación reproducible
terminal
# Instalar Jupyter
pip install jupyter

# Iniciar servidor de notebooks
jupyter notebook

# O usar JupyterLab (interfaz moderna)
pip install jupyterlab
jupyter lab

Catálogo de Herramientas

BIBLIOTECA TIPO USO PRINCIPAL
GDAL/OGR Raster Vector I/O de formatos geoespaciales
PyShp Vector Lectura/escritura de shapefiles
Shapely Vector Operaciones geométricas
Fiona Vector API simplificada sobre OGR
GeoPandas Vector Análisis de datos espaciales
NumPy Raster Procesamiento de arrays
PIL/Pillow Raster Edición de imágenes
Rasterio Raster API Pythonic para GDAL
OSMnx Vector Redes de calles
PyMySQL Database Conexión a MySQL espacial

01 // Datos Vectoriales

OGR, PyShp, Shapely, Fiona y GeoPandas para puntos, líneas y polígonos.

02 // Datos Raster

GDAL, NumPy, PIL y Rasterio para imágenes satelitales y teledetección.

03 // Adquisición de Datos

urllib, requests y ftplib para descargar datos geoespaciales de internet.

04 // Formatos de Intercambio

ElementTree para XML/KML y json para GeoJSON y APIs web.

Basado en "Python Geospatial Analysis" // Capítulo 4: Geospatial Python Toolbox