¿Automatizar la carga por lotes de múltiples archivos GPX en PostGIS?

9

Tengo más de 50 archivos GPX que me gustaría "cargar por lotes" en una base de datos PostGIS. Todos los datos de track_points se cargarían en una tabla de "track_points" (con campos típicos de GPS como lat, long, elevación, tiempo, etc.) y los datos de tracks se cargarían en una tabla de geometría de línea de "tracks" similar y diseñada adecuadamente.

Prefiero automatizar este proceso para que cuando obtenga mis próximos 50+, no tenga que ingresar manualmente los datos en la base de datos. Personalmente prefiero usar Python para ejecutar este tipo de procesos, pero cualquier sugerencia es bienvenida.

Mi proceso de pensamiento general es:

  1. Obtenga una lista de archivos GPX para procesar (lo suficientemente fácil a través de las herramientas estándar de Python)
  2. Recorra cada archivo GPX y extraiga / convierta los datos necesarios al formato PostGIS
  3. Inserte los datos del GPS en PostGIS utilizando la biblioteca de Python psycopg

Creo que puedo administrar los pasos 1 y 3, pero me pregunto si existe un método / biblioteca relativamente simple que convierta los datos (tracks y track_points) en formato PostGIS, o simplemente el formulario tabular que podría insertar en la tabla ya creada .

Ya leí " ¿Hay una buena biblioteca de análisis de rastreo GPS? ", " ¿Cómo construir una base de datos geográfica de registros GPS? " Y " Cómo extraer datos .gpx con python ", y he examinado el GDAL / OGR y enlaces de Python de FWTools, pero no quiero reinventar la rueda si alguien ya tiene un buen método para esto.

RyanKDalton
fuente

Respuestas:

10

Para Python puro, use el módulo OGR de GDAL:

import os
from osgeo import ogr
from glob import glob

# Establish a connection to a PostGIS database
pg = ogr.GetDriverByName('PostgreSQL')
if pg is None:
    raise RuntimeError('PostgreSQL driver not available')
conn = pg.Open("PG:dbname='postgis' user='postgres'", True)
if conn is None:
    raise RuntimeError('Cannot open dataset connection')

# Loop through each GPX file
for gpx_file in glob('/path/to/*.gpx'):
    ds = ogr.Open(gpx_file)
    if ds is None:
        print('Skipping ' + gpx_file)
    print('Opened ' + gpx_file)
    prefix = os.path.splitext(os.path.basename(gpx_file))[0]
    # Get each layer
    for iLayer in range(ds.GetLayerCount()):
        layer = ds.GetLayer(iLayer)
        layer_name = prefix + '_' + layer.GetName()
        if layer.GetFeatureCount() == 0:
            print(' -> Skipping ' + layer_name + ' since it is empty')
        else:
            print(' -> Copying ' + layer_name)
            pg_layer = conn.CopyLayer(layer, layer_name)
            if pg_layer is None:
                print(' |-> Failed to copy')
Mike T
fuente
Gracias por la solucion! Luché para obtener los enlaces de Python GDAL para recoger el controlador PostgreSQL de OGR , pero después de seguir estas instrucciones para instalar enlaces de Python de GDAL y GDAL en Windows 7 , finalmente lo puse a funcionar.
RyanKDalton
2 problemas que tengo ahora: 1) ¿hay una opción de "agregar" para que todos los archivos GPX se agreguen al mismo archivo (actualmente, parece que es solo el primero que se carga) y 2) hay una manera? para definir el esquema para guardar las nuevas tablas?
RyanKDalton
El nombre de la capa de destino (nombre de la tabla) es el segundo parámetro en CopyLayer. He agregado el nombre del archivo GPX como prefijo, por lo que las tablas deben ser tan únicas como los nombres de los archivos de entrada. La opción "agregar" de ogr2ogr es complicada y no estoy seguro de cómo hacerlo en este momento.
Mike T
5

Después de una investigación adicional, escribí mi propio script Python gpx2postgis.py que automatiza el proceso de agregar funciones GPX a las tablas existentes. El script usa partes del trabajo proporcionado por @Mike T arriba y otros. Lo he agregado a GitHub si desea descargar o hacer contribuciones. Crea nuevos esquemas de tabla (según sea necesario) basados ​​en las subcapas GPX de entrada, y agrega características a esas tablas.

Si bien no es una solución de Python, me encontré con una pregunta similar en StackOverflow que me hizo darme cuenta de que podía recorrer todos mis archivos GPX y llamar a la línea de comando ogr2ogr para procesarlos usando los tipos de funciones GPX .

ogr2ogr -append -f PostgreSQL "PG:dbname=your_db user=xxxx password=yyyy" filename.gpx
RyanKDalton
fuente
Me decidí por GPSBable para transformaciones rápidas y sucias. Y luego se mudó a R para trabajos más grandes. ¡Espero ver también la solución Python!
radek