Apa cara yang tepat untuk memasukkan Point ke database PostGIS menggunakan Python?
Apa cara yang tepat untuk memasukkan Point ke database PostGIS menggunakan Python?
Jawaban:
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
(lat, lon)
ini (y, x)
, tidak (x, y)
.(x, y, z)
di bagian akhir sehingga psycopg2
bisa menangani subtitusi.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_hex
properti.
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.
ST_MakePoint
, yang sangat bagus untuk geometri titik. Namun, membangun tipe geometri yang lebih kompleks umumnya akan lebih sederhana dengan Shapely.