Was ist der richtige Weg, um mit Python einen Punkt in eine PostGIS-Datenbank einzufügen?
Was ist der richtige Weg, um mit Python einen Punkt in eine PostGIS-Datenbank einzufügen?
Antworten:
Installieren Sie zunächst das Paket psycopg2 , eine Pythonic-Schnittstelle für PostgreSQL.
Verwenden Sie dann 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
kann verwendet werden, um die Werte zu validieren:
>>> cur.execute("SELECT ST_AsText(ST_SetSRID(ST_MakePoint(%s, %s, %s),4326));", (x, y, z))
>>> cur.fetchall()
[('POINT Z (32 34 0)',)]
Anmerkungen
(lat, lon)
ist (y, x)
nicht (x, y)
.(x, y, z)
am Ende getupft , psycopg2
damit die Substitution durchgeführt werden kann.Bei komplizierteren Geometrien wie LineString- und Polygon-Geometrien können Sie sie mit Shapely verarbeiten und dann als hexadezimal codiertes WKB durch psycopg2 leiten. Beachten Sie, dass Shapely 1.3 oder höher erforderlich ist, um den Export von 3D-Geometrien mit der wkb_hex
Eigenschaft zu handhaben .
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)
Beachten Sie außerdem, dass Ähnliches durch Senden der WKT der Geometrie erreicht werden kann. Da diese jedoch in Text konvertiert wird, ist sie verlustbehaftet und kann die Genauigkeit verringern. Das Übertragen von Geometrien als hexadezimal codiertes WKB ist verlustfrei und behält die genaue Genauigkeit jeder Koordinate bei.
ST_MakePoint
, was sich hervorragend für Punktgeometrien eignet. Das Erstellen komplexerer Geometrietypen ist mit Shapely jedoch im Allgemeinen einfacher.