2009-12-09 4 views
15

Ich benutze PostgreSQL mit der GIS-Erweiterung zum Speichern von Kartendaten, zusammen mit OpenLayers, GeoServer usw. Gegeben ein Polygon, z.B. einer Nachbarschaft, muss ich alle LAT/LONG-Punkte finden, die in einer Tabelle gespeichert sind (z. B. Ampeln, Restaurants), die sich innerhalb des Polygons befinden. Alternativ würde ich bei einer Menge von Polygonen die Menge der Punkte innerhalb jedes Polygons finden (wie eine GROUP BY-Abfrage, anstatt über jedes Polygon zu iterieren).Wie finde ich in PostGIS alle Punkte innerhalb eines Polygons?

Sind diese Funktionen etwas, das ich programmieren muss, oder ist die Funktionalität verfügbar (wie erweitertes SQL)? Bitte erläutern.

Auch für die einfachen 2D-Daten brauche ich eigentlich die GIS-Erweiterung (GPL-Lizenz ist eine Einschränkung) oder wird PostgreSQL ausreichen?

Danke!

Antwort

11

In PostGIS können Sie den Bounding-Box-Operator verwenden, um Kandidaten zu finden, was sehr effizient ist, da es GiST-Indizes verwendet. Wenn strikte Übereinstimmungen erforderlich sind, verwenden Sie den Operator contains.

So etwas wie

SELECT 
    points,neighborhood_name from points_table,neighborhood 
WHERE 
    neighborhood_poly && points /* Uses GiST index with the polygon's bounding box */ 
AND 
    ST_Contains(neighborhood_poly,points); /* Uses exact matching */ 

Über wenn dies erforderlich ist, hängt von Ihren Anforderungen. Damit das oben genannte funktioniert, benötigen Sie PostGIS und GEOS. Aber, wenn Bounding Box Match genug ist, können Sie es einfach in SQL codieren, ohne PostGIS zu benötigen.

Wenn genaue Übereinstimmungen erforderlich sind, enthält Algorithmen sind öffentlich verfügbar, aber um sie effizient zu implementieren, erfordert einige Mühe, es in einer Bibliothek zu implementieren, die dann von SQL aufgerufen würde (genau wie GEOS).

+1

Siehe auch [ST_DWithin] (http://www.postgis.org/docs/ST_DWithin.html). –

4

Ich glaube ST_Contains automatisch die Abfrage schreibtden die GiST indizierten Begrenzungsrahmen zu verwenden, da es Hinweise:

„Mit dieser Funktion Anruf wird automatisch umfasst einen Begrenzungsrahmen Vergleich, dass Verwendung irgend machen Indizes, die in den Geometrien verfügbar sind. Um Index zu vermeiden, verwenden Sie die Funktion _ST_Contains. "

http://postgis.refractions.net/docs/ST_Contains.html

+0

Dies ist mehr ein Kommentar als eine Antwort. – RickyA

+0

Es ist eine Antwort gemäß der SO FAQ. – IamIC

2

ST_Contains würde Ihr Problem lösen.

SELECT 
polygon.gid, points.x, points.y 
FROM 
    polygons LEFT JOIN points 
ON st_contains(polygon.geom, points.geom) 
WHERE 
    polygon.gid=your_id