Sunday 6 January 2019

python - Automating batch load of multiple GPX files into PostGIS?


I've got 50+ GPX files that I would like to "batch load" into a PostGIS database. All of the track_points data would be loaded into a "track_points" table (with typical GPS fields like lat, long, elevation, time, etc) and the tracks data would be loaded into a similar, appropriately designed "tracks" line geometry table.


I'd prefer to automate this process so that when I get my next 50+, I won't have to hand enter the data into the database. I personally prefer to use Python to script these kinds of processes, but any suggestions are welcome.


My general thought process is to:



  1. Get a list of GPX files to process (easy enough through standard Python tools)


  2. Loop through each GPX file and extract/convert the necessary data to PostGIS format

  3. Insert the GPS data into PostGIS using the psycopg Python library


I think I can manage steps 1 & 3, but am wondering if there is a relatively simple method/library that would convert the data (tracks and track_points) into PostGIS format, or simply the tabular form that I could insert into the already created table.


I've already read "Is there a good GPS track analysis library?", "How to build a geographic database of GPS logs?", and "How to extract .gpx data with python", and have looked into the GDAL/OGR and FWTools Python bindings, but don't want to reinvent the wheel is someone already has a good method for this.



Answer



For pure Python, use GDAL's OGR module:


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')

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...