PostGIS-GROUP BY für kontinuierliche Datenwerte?

8

Im Beispielcode für die Funktion PostGIS ST_ConvexHull würden mehrere Polygone basierend auf verschiedenen diskreten Werten im Feld "Krankheitstyp" erstellt.

--Get estimate of infected area based on point observations
SELECT d.disease_type,
    ST_ConvexHull(ST_Collect(d.the_geom)) As the_geom
    FROM disease_obs As d
    GROUP BY d.disease_type;

Nehmen wir an, es gab ein numerisches Feld (nennen wir es "mein Feld") mit kontinuierlichen Werten von 0 bis 5. Wie würden Sie ähnliche Ergebnisse wie GROUP BY erzielen, aber Ihre eigenen Haltepunkte definieren (zum Beispiel: 0-1,25, 1,25-3,5, 3,5-5)?

RyanKDalton
quelle
Nicht wirklich eine GIS-Frage, aber da sie bereits beantwortet wurde.
Underdark

Antworten:

9

Mit CASE können Sie Klassen erstellen. So ähnlich:

SELECT 
d.disease_type,
ST_ConvexHull(ST_Collect(d.the_geom)) As the_geom
FROM 
    (
    SELECT
    diseaseobs.the_geom,
    (CASE diseaseobs.number WHEN number BETWEEN 0 AND 1.5 THEN 'type one'
         WHEN number BETWEEN 1.6 AND 3 THEN 'type two'       
         ELSE 'other'
    END ) as disease_type
    FROM schema.diseaseobs

    ) AS d

GROUP BY d.disease_type;
Pablo
quelle
Danke, Pablo. Das ist großartig ... Ich muss es selbst testen, aber ich hoffe, dass dies die Antwort ist, nach der ich gesucht habe.
RyanKDalton
2

Hallo

In diesen Fällen erstelle ich eine Tabelle mit den Klassen und verbinde sie mit ihnen oder verwende eine Unterabfrage, um eine Liste von Klassen zu erstellen.

Ich denke, das bietet einen intuitiveren Ansatz und ich denke, es ist flexibler, da Sie die Klassen aktualisieren können, indem Sie einfach eine Tabelle aktualisieren.

Ein weiterer Vorteil ist, dass Sie auch die leeren Klassen erhalten können.

Der Unterabfrage-Ansatz könnte ungefähr so ​​aussehen:

SELECT
d.disease_type,
ST_ConvexHull(ST_Collect(d.the_geom)) AS the_geom FROM disease_obs
RIGHT JOIN
(SELECT 0::float AS classbottom, 1.25::float AS classtop, 1::int AS classid
UNION ALL    
SELECT 1.25::float AS classbottom, 3.5::float AS classtop, 2::int AS classid
UNION ALL    
SELECT 3.5::float AS classbottom, 5::float AS classtop, 3::int AS classid) AS classes
ON disease_obs.continuous_value>=classes.classbottom AND disease_obs.continuous_value<classes.classbottom
GROUP BY classes.id;

Hier habe ich einen rechten Join verwendet, um auch die leeren Klassen zu erhalten, was manchmal nützlich sein kann. Wenn Sie nicht möchten, dass die leeren einfach zu einem inneren Join wechseln.

Wenn Sie die Klassen in eine Tabelle verschieben und den Rest der Abfrage in einer Ansicht platzieren, können Sie die Klassen ändern, ohne die Abfrage zu berühren.

HTH / Nicklas

Nicklas Avén
quelle
Danke für den Vorschlag. Ich habe überlegt, diesen Weg zu gehen, aber ich möchte dies letztendlich in eine App integrieren, in der der Benutzer seine eigenen Haltepunkte auswählen kann, was diese Lösung nicht ganz so förderlich macht.
RyanKDalton