Instalando GDAL en Python

GDAL (Geospatial Data Abstraction Library) es la biblioteca de facto del mundo geoespacial: lee y escribe rásters y vectores en decenas de formatos, reproyecta, recorta y transforma datos en cualquier flujo GIS. En este artículo te cuento qué es, para qué sirve, cómo instalarlo en Python (que es lo que quedaba pendiente) y cómo dar tus primeros pasos con datos reales, con la misma estructura de las guías de hoy.

· · ·

01 Qué es GDAL

GDAL es una biblioteca en C++ con dos mitades inseparables: GDAL para datos ráster (GeoTIFF, Sentinel/Landsat, DEM, PNG georreferenciado…) y OGR para datos vectoriales (Shapefile, GeoJSON, GeoPackage, PostGIS…). Sobre ella se construyen casi todas las herramientas que usas a diario: QGIS, PostGIS, GeoServer, MapServer, y las bibliotecas Python rasterio, fiona, pyogrio o rioxarray.

Incluye también un conjunto de programas de línea de comandos (gdalinfo, gdal_translate, gdalwarp, ogr2ogr…) y bindings oficiales para Python (osgeo). Es software libre, con una comunidad enorme y documentación muy buena.

Ráster o vector

Si hablamos de píxeles (imágenes, DEM, ortofotos), es GDAL. Si hablamos de geometrías (puntos, líneas, polígonos, capas de SIG), es OGR. El paquete y la instalación son los mismos; solo cambian los comandos y módulos que usas.

· · ·

02 Qué utilidad tiene

  • Leer casi cualquier formato y convertirlo (GeoTIFF ↔ PNG/JPEG ↔ Sentinel SAFE, Shapefile ↔ GeoJSON ↔ GeoPackage…).
  • Reproyectar entre sistemas de referencia (p. ej. de EPSG:3857 a EPSG:25830) con remuestreo de calidad.
  • Recortar (por coordenadas o por una capa vectorial), unir en mosaicos y crear VRT para tratar conjuntos enormes sin duplicarlos.
  • Procesar DEM: pendientes, orientación, sombreado (hillshade), mapas de relieve con color.
  • Publicar y servir en la web (Cloud Optimized GeoTIFF / COG, tiles), y automatizar todo ello desde Python en scripts o pipelines.

Regla práctica: si un dato geoespacial «no se abre», la culpa suele ser de GDAL… hasta que aprendes a usarlo. Con GDAL (o sus envoltorios) acaba abriéndose.

· · ·

03 Cómo se instala (lo pendiente)

Opción A — Paquetes Python con GDAL incluido (la recomendada). Las ruedas de rasterio, fiona, pyogrio o rioxarray ya llevan la librería compilada; no necesitas tocar el sistema:

pip install rasterio fiona pyogrio geopandas

Opción B — Bindings oficiales (osgeo) contra el GDAL del sistema. En Ubuntu/Debian primero instalas la librería y luego el paquete Python de la misma versión:

sudo apt install gdal-bin libgdal-dev
pip install GDAL==$(gdal-config --version)

En Windows lo más simple es OSGeo4W o las ruedas de GDAL (pypi). En macOS: brew install gdal. Si usas conda, el camino sin fricción es conda-forge:

conda install -c conda-forge gdal rasterio

Para comprobar que todo está bien instalado:

python -c "from osgeo import gdal, ogr, osr; print('GDAL', gdal.VersionInfo())"
El error típico

Si mezclas el pip install GDAL con una versión distinta de libgdal del sistema, verás un error de importación («libgdal.so… undefined symbol» o similar). Solución: instala primero libgdal-dev y usa GDAL==$(gdal-config --version), o elige la opción A y no toques el GDAL del sistema.

· · ·

04 Primeros pasos: abrir y leer un ráster

Con la API oficial (osgeo) o con rasterio. Ejemplo con rasterio (más Pythonic):

import rasterio

with rasterio.open("dem.tif") as ds:
    print("CRS   :", ds.crs)          # EPSG:25830, EPSG:3857...
    print("Tamaño:", ds.width, "x", ds.height)
    print("Bounds:", ds.bounds)       # minx, miny, maxx, maxy
    print("Bands :", ds.count)
    banda = ds.read(1)                # primera banda como array numpy

Con los bindings oficiales sería equivalente: gdal.Open("dem.tif"), y luego banda.ReadAsArray() o gdal.Info(ds) para volcar los metadatos por pantalla.

· · ·

05 Comandos CLI que te salvarán la vida

Aunque el artículo hable de Python, estos cuatro comandos (ya instalados con la opción A en Ubuntu/Debian o con conda-forge) hacen el 90% del trabajo rápido:

gdalinfo dem.tif                          # metadatos del ráster
gdal_translate -of COG -co COMPRESS=DEFLATE entrada.tif salida_cog.tif
gdalwarp -t_srs EPSG:25830 -r bilinear entrada.tif reproyectado.tif
ogr2ogr -t_srs EPSG:25830 salida.gpkg entrada.shp

También útiles: gdalbuildvrt (mosaico virtual de muchos ficheros), gdaldem (pendiente, orientación, hillshade) y gdal_calc.py (álgebra de bandas).

· · ·

06 Reproyectar y recortar desde Python

Reproyectar un ráster con osgeo (vía gdal.Warp):

from osgeo import gdal
gdal.Warp("dem_25830.tif", "dem_3857.tif",
          dstSRS="EPSG:25830", resampleAlg="bilinear")

Recortar a una capa vectorial (cutline) dejando fuera lo que no toca el polígono:

gdal.Warp("recorte.tif", "dem_25830.tif",
          cutlineDSName="zona.gpkg", cropToCutline=True,
          dstNodata=0)

Con rasterio, recortar con máscara es igual de directo (función mask de rasterio.mask), y para vectores puedes usar geopandas.read_file() + fiona/pyogrio de forma transparente.

· · ·

07 Caso práctico: de un DEM a un GeoTIFF útil

Objetivo: coger un modelo digital del terreno (DEM) mundial, recortarlo a nuestra zona de interés (provincia/municipio) y reproyectarlo a EPSG:25830, listo para QGIS o para calcular pendientes.

1. Descarga del DEM (p. ej. Copernicus 30m en dem_original.tif) y miramos qué es:

gdalinfo dem_original.tif   # mira CRS, extensión y nodata

2. Preparamos la zona de interés como vector (zona.gpkg) y recortamos con la CLI:

gdalwarp -cutline zona.gpkg -crop_to_cutline \
         -t_srs EPSG:25830 -r bilinear -dstnodata -9999 \
         dem_original.tif dem_zona_25830.tif

3. Lo mismo en Python, en un script reproducible:

from osgeo import gdal

gdal.Warp(
    "dem_zona_25830.tif", "dem_original.tif",
    cutlineDSName="zona.gpkg", cropToCutline=True,
    dstSRS="EPSG:25830", resampleAlg="bilinear",
    dstNodata=-9999)

info = gdal.Info("dem_zona_25830.tif")
print(info)   # comprueba CRS, extensión y tamaño

4. (Opcional) Genera productos derivados con gdaldem: gdaldem hillshade, gdaldem slope o gdaldem color-relief, y cárgalos en QGIS como capas apiladas.

Resultado

Con GDAL (vía CLI o Python) pasas de un DEM global sin tratar a un GeoTIFF recortado, reproyectado y con nodata definido, listo para análisis y visualización. El mismo patrón sirve para ortofotos, Sentinel o cualquier capa ráster: info → recorte → reproyección → formato de salida.

¿Qué formato tienes que manejar tú: ráster (imágenes/DEM) o vector (capas SIG)? Cuéntame tu caso y te ayudo con el comando exacto.

· · ·

08 Errores y buenas prácticas

  • Confundir CRS: reproyecta siempre con -t_srs/dstSRS; si «no encaja» con otra capa, casi siempre es un problema de proyección, no de datos.
  • Nodata: define -dstnodata o el recorte te dejará bordes negros/ceros que ensucian análisis y estadísticas.
  • Versiones incompatibles: mantén el GDAL del sistema y la rueda de Python en la misma versión (o usa rasterio/pyogrio que lo encapsulan).
  • Ficheros enormes: para conjuntos que no caben en memoria usa VRT (gdalbuildvrt), ventanas (ReadAsArray(xoff,yoff,…)) y salida COG.
  • Sobrescribir: en CLI añade -overwrite (u borra antes el fichero) o te avisará de que ya existe.
  • Hazlo reproducible: deja el flujo en un script .py con las rutas al principio; el día que cambie la zona o la fuente solo tocas dos variables.
· · ·

09 Conclusión

GDAL es el traductor universal del mundo geoespacial: instalarlo en Python es hoy casi trivial (una línea de pip con rasterio/pyogrio, o osgeo contra el GDAL del sistema), y con un puñado de funciones (gdal.Warp, read/mask) y comandos (gdalinfo, gdal_translate, gdalwarp, ogr2ogr) puedes recortar, reproyectar y convertir cualquier dato geoespacial. Con el patrón info → recorte → reproyección → salida tienes resuelto el 80% de los trabajos con rásters.

· · ·

10 Notas y referencias