Bounding-Box-Abfrage in PostGIS durchführen? [geschlossen]

22

Ich habe eine PostgreSQL-Tabelle mit fast 2 Millionen Zeilen und einem langen coordinatesFeld in der Form POINT(-73.4938 33.2405).

Angenommen, es gibt einen Geodatenindex für dieses Feld. Was ist der effizienteste und schnellste Weg, um alle Zeilen innerhalb eines beliebigen Begrenzungsrahmens auszuwählen?

Die Box ist wie SW long-lat: -74.0042 40.7688, NE long-lat: -73.8809 40.7984.

Avishai
quelle
Sind Ihre gespeicherten Koordinaten bereits lang oder haben sie ein Gitter (X, Y)?
Martin F
1
Einfache Mathematik würde hier reichen ... Wenn point.x größer als SW.x und kleiner als NE.x ist und point.y gleichzeitig größer als SW.y und kleiner als NE.y ist, liegt der Punkt innerhalb der MBR. Ich weiß jedoch nicht, ob es schneller ist als die Verwendung von räumlichen Abfragen. Hast du etwas dagegen, es zu versuchen?
Michal Zimmermann
@zimmi: Er tut nicht wirklich fest , dass die Einzelteile sind nur Punkte; es können komplexe geometrien sein.
Martin F
Das sind aber nur Punkte ;-). Sie haben die Form POINT (-73.4938 33.24059) und sind als WKB gespeichert.
Avishai
Ich habe das Q (und mein A) bearbeitet, um diese Informationen wiederzugeben. :-)
Martin F

Antworten:

24

Angenommen, die angegebenen Begrenzungsrahmengrenzen befinden sich im selben räumlichen Bezugssystem wie die gespeicherten Koordinaten, und Sie wissen, welchen räumlichen Operator Sie benötigen (überschneiden oder enthalten durch):

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)

Wenn Sie alternativ den Sound von "contain" (anstelle von "contain by") bevorzugen WHERE, sollte die Klausel umgedreht werden:

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

PS: Angesichts der Tatsache, dass es sich bei den Aufzeichnungen (nach der Veröffentlichung von OP) um einfache Punkte handelt, denke ich, dass der Unterschied zwischen "Schnittpunkten" und "Eindämmung" sehr subtil wird und nur die Punkte an den Rändern des Begrenzungsrahmens betrifft .

Martin F
quelle
das ist ein guter Punkt. Enthält sollte in Ordnung sein, da Sie einen Kartenmarker nicht wirklich sehen können, wenn er sich an der Grenze befindet (dh wahrscheinlich das Browser-Chrom).
Avishai
What's the fastest ...?: OP
Magno C
Seien Sie sich bewusst: &&und @scheinen nicht zu funktionieren, wenn Sie sich mit Polygongeometrie schneiden. In diesem Fall verwenden Sie ST_Intersects(latlng_column,ST_GeomFromText('Polygon ((...))',4326))oder alternativST_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
quelle
1
Nicht unbedingt 4326 zu sagen ist die SRID.
Magno C
2

Anscheinend habe ich nicht genug Punkte, um einen Kommentar hinzuzufügen, daher benutze ich diese Antwort nur, um zu sagen, dass ich versucht habe, ST_MakeEnvelope mit dem mathematischen Vergleich von "x> min_x und x <max_x und y> min_y und y <max_y" zu vergleichen. ..im Durchschnitt hat ST_MakeEnvelope 60 ms gedauert und das Vergleichen mit Mathematik hat 155 ms gedauert bei meiner speziellen Bbox-Abfrage.

Die räumliche Suche ST_MakeEnvelope sollte also schneller sein als der mathematische Vergleich!

Jason
quelle
1
Wenn Sie die richtigen Indizes erstellen, sind min_x, max_x, min_y und max_y tatsächlich viel schneller. Ich habe einen sehr großen Datensatz (über 3 Millionen Polygone) und habe beide INDEXüber ST_MakeEnvelope und (ST_XMax, ST_XMin, ST_YMax, ST_YMin) durchgeführt, und der Unterschied ist immens günstig für Mathe. Die Berechnung dauerte weniger als 20 Sekunden (INDEX + Abfrage), während die Umschlagkreuzung mehr als 2 Minuten dauerte (ich gab auf, als sie 2 Minuten, 40
Sekunden