Esecuzione di query con riquadro di delimitazione in PostGIS? [chiuso]


22

Ho una tabella PostgreSQL, con quasi 2 milioni di righe, con un coordinatescampo long-lat nel modulo POINT(-73.4938 33.2405).

Supponendo che ci sia un indice geospaziale su quel campo, qual è il modo più efficiente e veloce per selezionare tutte le righe all'interno di un riquadro di delimitazione arbitrario?

La scatola è come SW long-lat: -74.0042 40.7688, NE long-lat: -73.8809 40.7984.


Le coordinate memorizzate sono già long-lat o sono grid (X, Y)?
Martin F,

1
La matematica semplice farebbe qui ... Se point.x è più grande di SW.xe più piccolo di NE.xe point.y è più grande di SW.y e più piccolo di NE.y allo stesso tempo, il punto si trova all'interno del MBR. Non so se sia più veloce dell'uso della query spaziale. Ti dispiace provare?
Michal Zimmermann,

@zimmi: in realtà non afferma che gli oggetti sono solo punti; potrebbero essere geometrie complesse.
Martin F,

Essi sono solo punti, però ;-). Sono long-lat nella forma POINT (-73.4938 33.24059) memorizzati come WKB.
Avishai,

Ho modificato la Q (e la mia A) per riflettere tali informazioni. :-)
Martin F

Risposte:


24

Supponendo che i limiti del riquadro di delimitazione indicati si trovino nello stesso sistema di riferimento spaziale delle coordinate memorizzate e si sappia quale operatore spaziale (interseca o contenuto da) è necessario:

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)

In alternativa, se si preferisce il suono di "contiene" (anziché "contenuto da") WHERE, è necessario invertire la clausola:

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

PS: Dato (da OP dopo che è stato pubblicato quanto sopra) che i record sono punti semplici, penso che la differenza tra "interseca" e "contenimento" diventi molto sottile, influenzando solo i punti ai bordi del rettangolo di selezione.


è un buon punto. Il contenuto dovrebbe andare bene, dal momento che non sarai davvero in grado di vedere un indicatore di mappa se è sul confine (cioè, probabilmente il browser Chrome).
Avishai,

What's the fastest ...?: OP
Magno C

Attenzione: &&e @non sembra funzionare quando si interseca con la geometria poligonale. In questo caso, utilizzare ST_Intersects(latlng_column,ST_GeomFromText('Polygon ((...))',4326))o in alternativaST_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)

1
Non è necessario dire che 4326 è SRID.
Magno C,

2

Apparentemente, non ho abbastanza punti per aggiungere un commento, quindi sto usando questa risposta solo per dire che ho provato sia ST_MakeEnvelope contro il confronto matematico di "x> min_x e x <max_x e y> min_y e y <max_y". ..sulla media di ST_MakeEnvelope ha richiesto 60ms e il confronto matematico ha richiesto 155ms sulla mia particolare query bbox.

Quindi la ricerca spaziale ST_MakeEnvelope dovrebbe essere più veloce del confronto matematico!


1
In realtà, se crei gli indici giusti min_x, max_x, min_y e max_y saranno molto più veloci. Ho un set di dati molto grande (oltre 3 milioni di poligoni) e ho fatto entrambi INDEXsu ST_MakeEnvelope e (ST_XMax, ST_XMin, ST_YMax, ST_YMin) e la differenza è enormemente a favore della matematica. La matematica mi ha impiegato meno di 20 secondi (INDICE + Query) mentre l'intersezione di Envelope ha richiesto oltre 2 minuti (ho rinunciato quando ha raggiunto i 2 minuti, 40
secondi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.