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.
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())"
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.
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
-dstnodatao 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
.pycon 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.