การโหลดแบตช์หลายไฟล์อัตโนมัติเป็น PostGIS?


9

ฉันมีไฟล์ GPX 50+ ที่ฉันต้องการ "batch load" ลงในฐานข้อมูล PostGIS ข้อมูล track_points ทั้งหมดจะถูกโหลดลงในตาราง "track_points" (ที่มีฟิลด์ GPS ทั่วไปเช่น lat, long, ระดับความสูง, เวลา ฯลฯ ) และข้อมูล track จะถูกโหลดลงในตารางเส้นรูปทรงเรขาคณิต "track" ที่คล้ายกันออกแบบอย่างเหมาะสม

ฉันต้องการทำให้กระบวนการนี้เป็นแบบอัตโนมัติเพื่อที่ว่าเมื่อฉันได้ 50 ปีขึ้นไปฉันจะไม่ต้องป้อนข้อมูลลงในฐานข้อมูล ฉันชอบใช้ Python ในการเขียนสคริปต์กระบวนการเหล่านี้เป็นการส่วนตัว แต่ยินดีให้คำแนะนำใด ๆ

กระบวนการคิดทั่วไปของฉันคือ:

  1. รับรายการไฟล์ GPX เพื่อดำเนินการ (ง่ายพอผ่านเครื่องมือ Python มาตรฐาน)
  2. วนรอบแต่ละไฟล์ GPX และแยก / แปลงข้อมูลที่จำเป็นในรูปแบบ PostGIS
  3. ใส่ข้อมูล GPS ลงใน PostGIS โดยใช้ psycopg Python library

ฉันคิดว่าฉันสามารถจัดการขั้นตอนที่ 1 และ 3 แต่ฉันสงสัยว่ามีวิธีการ / ไลบรารีที่ค่อนข้างง่ายที่จะแปลงข้อมูล (เพลงและ track_points) เป็นรูปแบบ PostGIS หรือเพียงแค่รูปแบบตารางที่ฉันสามารถแทรกลงในตารางที่สร้างขึ้นแล้ว .

ฉันได้อ่าน " มีห้องสมุดการติดตามการติดตาม GPS ที่ดีหรือไม่ ", " วิธีสร้างฐานข้อมูลทางภูมิศาสตร์ของบันทึก GPS " และ " วิธีการแยกข้อมูล. gpx ด้วย python " และดูใน GDAL / OGR และ FWTools Python ผูกไว้ แต่ไม่ต้องการที่จะบูรณาการล้อเป็นคนที่มีวิธีที่ดีสำหรับเรื่องนี้

คำตอบ:


10

สำหรับ Python แท้ใช้โมดูล OGR ของ 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')

ขอบคุณสำหรับการแก้ปัญหา! ฉันพยายามที่จะได้รับการผูกมัด GDAL Python เพื่อรับไดรเวอร์ OGR PostgreSQLแต่หลังจากทำตามคำแนะนำเหล่านี้เพื่อติดตั้ง GDAL & GDAL Python การผูกมัดบน Windows 7ในที่สุดฉันก็ทำงานได้
RyanKDalton

2 ประเด็นที่ฉันมีอยู่ตอนนี้: 1) มีตัวเลือก "ผนวก" เพื่อให้ไฟล์ GPX ทั้งหมดถูกผนวกเข้ากับไฟล์เดียวกัน (ปัจจุบันปรากฏขึ้นราวกับว่าเป็นแค่ไฟล์แรกที่โหลด) และ 2) มีวิธี การกำหนด schema เพื่อบันทึกตารางใหม่เป็นอย่างไร
RyanKDalton

ชื่อชั้นปลายทาง (ชื่อตาราง) CopyLayerเป็นพารามิเตอร์ที่สองใน ฉันได้เพิ่มชื่อจากไฟล์ GPX เป็นคำนำหน้าดังนั้นตารางควรไม่ซ้ำกันกับชื่อไฟล์อินพุต ตัวเลือก "ผนวก" จาก ogr2ogr เป็นตัวเลือกที่ฉันไม่แน่ใจว่าจะทำอย่างไรในขณะนี้
Mike T

5

หลังจากการวิจัยเพิ่มเติมฉันเขียนสคริปต์gpx2postgis.py Python ของฉันเองที่ทำให้กระบวนการผนวกคุณสมบัติ GPX เข้ากับตารางที่มีอยู่โดยอัตโนมัติ สคริปต์ใช้บางส่วนของงานที่มีให้โดย @Mike T ด้านบนและอื่น ๆ ฉันได้เพิ่มไว้ใน GitHub หากคุณต้องการดาวน์โหลดหรือบริจาค มันสร้างสกีมาของตารางใหม่ (ตามต้องการ) ขึ้นอยู่กับโฟลเดอร์ย่อยของ GPX และผนวกคุณสมบัติเข้ากับตารางเหล่านั้น

ในขณะที่ไม่ได้เป็นทางออกหลามผมไม่เจอคำถามที่คล้ายกันใน StackOverflowที่ทำให้ฉันรู้ฉันสามารถทำได้เพียงแค่ห่วงผ่านทั้งหมดของไฟล์ GPX ของฉันและเรียกogr2ogrบรรทัดคำสั่งในการประมวลผลโดยใช้ประเภทคุณลักษณะ GPX

ogr2ogr -append -f PostgreSQL "PG:dbname=your_db user=xxxx password=yyyy" filename.gpx

ฉันตัดสิน GPSBable เพื่อการแปลงที่รวดเร็วและสกปรก และต่อมาย้ายไปที่ R เพื่องานที่ใหญ่ขึ้น ดังนั้นหวังว่าจะได้เห็นโซลูชัน Python ด้วย!
radek
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.