¿Realizando consulta de cuadro delimitador en PostGIS? [cerrado]

22

Tengo una tabla PostgreSQL, con casi 2 millones de filas, con un coordinatescampo largo en el formulario POINT(-73.4938 33.2405).

Suponiendo que haya un índice geoespacial en ese campo, ¿cuál es la forma más eficiente y rápida de seleccionar todas las filas dentro de un cuadro de límite arbitrario?

El cuadro es como SW long-lat: -74.0042 40.7688, NE long-lat: -73.8809 40.7984.

Avishai
fuente
¿Sus coordenadas almacenadas ya son de largo lat o son cuadrícula (X, Y)?
Martin F
1
Las matemáticas simples serían útiles aquí ... Si point.x es más grande que SW.x y más pequeño que NE.x y point.y es más grande que SW.y y más pequeño que NE.y al mismo tiempo, el punto se encuentra dentro del MBR. Sin embargo, no sé si es más rápido que usar una consulta espacial. ¿Te importaría intentarlo?
Michal Zimmermann
@zimmi: En realidad no dice que los artículos son solo puntos; Podrían ser geometrías complejas.
Martin F
Sin embargo, son solo puntos ;-). Son largos lat en la forma PUNTO (-73.4938 33.24059) almacenados como WKB.
Avishai
Edité la Q (y mi A) para reflejar esa información. :-)
Martin F

Respuestas:

24

Suponiendo que los límites del cuadro delimitador dados están en el mismo sistema de referencia espacial que las coordenadas almacenadas, y usted sabe qué operador espacial (interseca o contenido) necesita:

SELECT *
FROM   my_table
WHERE  coordinates 
    && -- intersects,  gets more rows  -- CHOOSE ONLY THE
    @ -- contained by, gets fewer rows -- ONE YOU NEED!
    ST_MakeEnvelope (
        xmin, ymin, -- bounding 
        xmax, ymax, -- box limits
        my_srid)

Alternativamente, si prefiere el sonido de "contiene" (en lugar de "contenido por"), la WHEREcláusula debería cambiarse:

WHERE  ST_MakeEnvelope (...)
    ~ -- contains, gets same fewer rows 
    coordinates 

PD: Dado (por OP después de que se publicó lo anterior) que los registros son puntos simples, creo que la diferencia entre "intersecciones" y "contención" se vuelve muy sutil, afectando solo los puntos en los bordes del cuadro delimitador.

Martin F
fuente
ese es un buen punto. El contenido debe estar bien, ya que realmente no podrá ver un marcador de mapa si está en el límite (es decir, probablemente el navegador Chrome).
Avishai
What's the fastest ...?: OP
Magno C
Tenga en cuenta: &&y @parece que no funciona cuando se cruza con la geometría del polígono. En este caso, use ST_Intersects(latlng_column,ST_GeomFromText('Polygon ((...))',4326))o alternativamenteST_Contains
Alex
4
SELECT ST_Y(the_geom) AS latitude, ST_X(the_geom) as longitude
from units u where the_geom && ST_MakeEnvelope(left, bottom, right, top, 4326)
Magno C
fuente
1
No es necesario decir que 4326 es el SRID.
Magno C
2

Aparentemente, no tengo suficientes puntos para agregar un comentario, así que estoy usando esta respuesta solo para decir que probé tanto ST_MakeEnvelope versus la comparación matemática de "x> min_x y x <max_x e y> min_y e y <max_y". ..en promedio ST_MakeEnvelope tardó 60 ms y la comparación matemática tardó 155 ms en mi consulta particular de bbox.

¡Entonces la búsqueda espacial ST_MakeEnvelope debería ser más rápida que la comparación matemática!

Jason
fuente
1
En realidad, si crea los índices correctos, min_x, max_x, min_y y max_y serán mucho más rápidos. Tengo un conjunto de datos muy grande (más de 3 millones de polígonos) e hice ambos INDEXsobre ST_MakeEnvelope y (ST_XMax, ST_XMin, ST_YMax, ST_YMin) y la diferencia es muy favorable a las matemáticas. Las matemáticas me tomaron menos de 20 segundos (ÍNDICE + Consulta), mientras que la intersección de la envoltura tardó más de 2 minutos (me di por vencido cuando llegó a 2 minutos, 40
segundos