Ich versuche, Raster-Statistiken (min, max, mean) für jedes Polygon in einer Vektorebene mit PostgreSQL / PostGIS zu berechnen.
In dieser GIS.SE-Antwort wird beschrieben, wie Sie dies tun, indem Sie den Schnittpunkt zwischen dem Polygon und dem Raster berechnen und anschließend einen gewichteten Durchschnitt berechnen: https://gis.stackexchange.com/a/19858/12420
Ich verwende die folgende Abfrage (wo dem
ist mein Raster, topo_area_su_region
ist mein Vektor und toid
ist eine eindeutige ID:
SELECT toid, Min((gv).val) As MinElevation, Max((gv).val) As MaxElevation, Sum(ST_Area((gv).geom) * (gv).val) / Sum(ST_Area((gv).geom)) as MeanElevation FROM (SELECT toid, ST_Intersection(rast, geom) AS gv FROM topo_area_su_region,dem WHERE ST_Intersects(rast, geom)) foo GROUP BY toid ORDER BY toid;
Das funktioniert, ist aber zu langsam. Meine Vektorebene verfügt über 2489.000 Features, deren Verarbeitung jeweils etwa 90 ms dauert. Die Verarbeitung der gesamten Ebene würde Tage dauern . Die Geschwindigkeit der Berechnung scheint sich nicht wesentlich zu verbessern, wenn ich nur die Min- und Max-Werte berechne (wodurch die Aufrufe von ST_Area vermieden werden).
Wenn ich eine ähnliche Berechnung mit Python (GDAL, NumPy und PIL) durchführe, kann ich den Zeitaufwand für die Verarbeitung der Daten erheblich reduzieren, wenn ich anstelle der Vektorisierung des Rasters (mit ST_Intersection) den Vektor rastern möchte. Siehe Code hier: https://gist.github.com/snorfalorpagus/7320167
Ich brauche keinen gewichteten Durchschnitt - ein Ansatz "Wenn es berührt, ist es in" ist gut genug - und ich bin mir ziemlich sicher, dass dies die Dinge verlangsamt.
Frage : Gibt es eine Möglichkeit, PostGIS dazu zu bringen, sich so zu verhalten? dh, um die Werte aller Zellen aus dem Raster zurückzugeben, die ein Polygon berührt, und nicht den genauen Schnittpunkt.
Ich bin sehr neu in PostgreSQL / PostGIS. Vielleicht gibt es noch etwas, das ich nicht richtig mache. Ich verwende PostgreSQL 9.3.1 und PostGIS 2.1 unter Windows 7 (2,9 GHz i7, 8 GB RAM) und habe die Datenbankkonfiguration wie hier vorgeschlagen angepasst: http://postgis.net/workshops/postgis-intro/tuning.html
quelle
Antworten:
Sie haben Recht,
ST_Intersection
wenn Sie Ihre Abfrage verlangsamen, macht sich dies bemerkbar.Anstatt es zu verwenden
ST_Intersection
, ist es besser,ST_Clip
Ihr Raster mit den Polygonen (Ihren Feldern) zu beschneiden () und das Ergebnis als Polygone (ST_DumpAsPolygons
) auszugeben . So wird jede Rasterzelle in ein kleines Polygonrechteck mit unterschiedlichen Werten konvertiert.Für den Empfang von min, max oder mean aus den Dumps können Sie dieselben Anweisungen verwenden.
Diese Abfrage sollte den Trick machen:
In der Anweisung
ST_Clip
definieren Sie das Raster, das Rasterband (= 1), das Polygon und ob der Zuschnitt WAHR oder FALSCH sein soll.Außerdem können Sie damit
avg((gv).val)
den Mittelwert berechnen.BEARBEITEN
Das Ergebnis Ihres Ansatzes ist das genauere, aber das langsamere. Die Ergebnisse der Kombination von
ST_Clip
undST_DumpAsPolygons
ignorieren die Rasterzellen, die sich mit weniger als 50% (oder 51%) ihrer Größe schneiden.Diese beiden Screenshots von einer CORINE Land Use-Kreuzung zeigen den Unterschied. Erstes Bild mit
ST_Intersection
, zweites mitST_Clip
undST_DumpAsPolygons
.quelle