15 votos

PostGIS: Insertar un punto usando Python

¿Cuál es la forma correcta de insertar un punto en una base de datos PostGIS usando Python?

25voto

skfd Puntos 463

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

  • Recuerda que (lat, lon) es (y, x) no (x, y) .
  • Utilice siempre parámetros, en lugar de manipulaciones de cadenas, para evitar la inyección SQL . En estos ejemplos, hemos copiado (x, y, z) al final para que psycopg2 puede manejar la sustitución.

24voto

hernan43 Puntos 566

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.

0 votos

Excelente, ¡gracias! Me pregunto si hay una diferencia de rendimiento entre estos dos enfoques.

0 votos

Hay una ventaja de rendimiento del 10% construyendo puntos con ST_MakePoint , lo que es ideal para las geometrías puntuales. Sin embargo, la construcción de tipos de geometría más complejos será generalmente más sencilla con Shapely.

i-Ciencias.com

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.

Powered by:

X