Masukkan Point ke PostGIS menggunakan Python


Jawaban:


21

Pertama, instal paket psycopg2 , antarmuka Pythonic untuk PostgreSQL.

Kemudian, gunakan ST_MakePoint:

>>> import psycopg2
>>> conn = psycopg2.connect(dbname=..., port=..., user=...,
                            password=..., host=...)
>>> cur = conn.cursor()
>>> x, y, z, = 32, 34, 0
>>> cur.execute("SELECT ST_SetSRID(ST_MakePoint(%s, %s, %s),4326);", (x, y, z))
>>> cur.fetchall()
[('01010000A0E6100000000000000000404000000000000041400000000000000000',)]

ST_AsText dapat digunakan untuk memvalidasi nilai:

>>> cur.execute("SELECT ST_AsText(ST_SetSRID(ST_MakePoint(%s, %s, %s),4326));", (x, y, z))
>>> cur.fetchall()
[('POINT Z (32 34 0)',)]

Catatan

  • Ingat bahwa (lat, lon)ini (y, x), tidak (x, y).
  • Selalu gunakan parameter, alih-alih manipulasi string, untuk mencegah injeksi SQL . Dalam contoh ini kita tupled (x, y, z)di bagian akhir sehingga psycopg2bisa menangani subtitusi.

20

Untuk geometri yang lebih rumit, seperti geometri LineString dan Polygon, Anda dapat menanganinya dengan Shapely, lalu meneruskannya melalui psycopg2 sebagai WKB yang dikodekan-hex. Perhatikan bahwa Shapely 1.3 atau yang lebih baru diperlukan untuk menangani ekspor geometri 3D dengan wkb_hexproperti.

import psycopg2
from shapely.geometry import LineString
from shapely import wkb

conn = psycopg2.connect('...')
curs = conn.cursor()

# Make a Shapely geometry
ls = LineString([(2.2, 4.4, 10.2), (3.3, 5.5, 8.4)])
ls.wkt  # LINESTRING Z (2.2 4.4 10.2, 3.3 5.5 8.4)
ls.wkb_hex  # 0102000080020000009A999999999901409A999999999911406666666666662440666666...

# Send it to PostGIS
curs.execute('CREATE TEMP TABLE my_lines(geom geometry, name text)')
curs.execute(
    'INSERT INTO my_lines(geom, name)'
    'VALUES (ST_SetSRID(%(geom)s::geometry, %(srid)s), %(name)s)',
    {'geom': ls.wkb_hex, 'srid': 4326, 'name': 'First Line'})

conn.commit()  # save data

# Fetch the data from PostGIS, reading hex-encoded WKB into a Shapely geometry
curs.execute('SELECT name, geom FROM my_lines')
for name, geom_wkb in curs:
    geom = wkb.loads(geom_wkb, hex=True)
    print('{0}: {1}'.format(name, geom.wkt))
# First Line: LINESTRING Z (2.2 4.4 10.2, 3.3 5.5 8.4)

Catatan lebih lanjut bahwa hal serupa dapat dilakukan dengan mengirimkan WKT geometri, namun karena dikonversi ke teks, maka lossy dan dapat mengurangi angstrom presisi. Mentransfer geometri sebagai hex-encode WKB adalah lossless, dan mempertahankan presisi yang tepat dari setiap koordinat.


Luar biasa terima kasih! Saya ingin tahu apakah ada perbedaan kinerja antara kedua pendekatan ini.
Adam Matan

Ada 10% keunggulan poin kinerja dengan kinerja ST_MakePoint, yang sangat bagus untuk geometri titik. Namun, membangun tipe geometri yang lebih kompleks umumnya akan lebih sederhana dengan Shapely.
Mike T
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.