¿Cuál es la forma correcta de insertar un punto en una base de datos PostGIS usando Python?
Excelente, ¡gracias! Me pregunto si hay una diferencia de rendimiento entre estos dos enfoques.
¿Cuál es la forma correcta de insertar un punto en una base de datos PostGIS usando Python?
En primer lugar, instale el psycopg2 una interfaz pitónica para PostgreSQL.
A continuación, utilice 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
puede utilizarse para validar los valores:
>>> cur.execute("SELECT ST_AsText(ST_SetSRID(ST_MakePoint(%s, %s, %s),4326));", (x, y, z))
>>> cur.fetchall()
[('POINT Z (32 34 0)',)]
Notas
(lat, lon)
es (y, x)
no (x, y)
.(x, y, z)
al final para que psycopg2
puede manejar la sustitución.Para geometrías más complicadas, como LineString y Polygon, puede manejarlas con Shapely, y luego pasarlas a través de psycopg2 como WKB codificado en hexadecimal. Tenga en cuenta que se requiere Shapely 1.3 o posterior para manejar la exportación de geometrías 3D con la función wkb_hex
propiedad.
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)
Además, hay que tener en cuenta que se puede conseguir algo similar enviando el WKT de la geometría, pero como se convierte en texto, tiene pérdidas y puede reducir los angstroms de precisión. La transferencia de geometrías como WKB codificado en hexadecimal no tiene pérdidas y preserva la precisión exacta de cada coordenada.
Excelente, ¡gracias! Me pregunto si hay una diferencia de rendimiento entre estos dos enfoques.
I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.