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:
- Get a list of GPX files to process (easy enough through standard Python tools)
- Loop through each GPX file and extract/convert the necessary data to PostGIS format
- 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