Optimierung der Postgis-Datenbankabfrage

10

Ich habe eine Reihe von Rastern im DTED-Format, die ich mit dem Befehlszeilentool raster2pgsql in die PostGIS-Datenbank lade.

Jedes der Raster wird einfach in einer Reihe gespeichert und durch rid und einen Wert im Rasterformat beschrieben.

Jetzt möchte ich eine Datenbankfunktion erstellen, die Längen- und Breitengrade eines Punkts verwendet und einen diesem Punkt entsprechenden Pixelwert zurückgibt.

Das Problem, das ich habe, ist, dass es ziemlich viel Zeit braucht (3-4 Sekunden), weil die Datenbank auf Odroid Board funktioniert.

Ich weiß, dass der Datensatz, den ich verarbeite, ziemlich groß ist (die Raster decken den gesamten britischen Bereich ab), aber da ich mit PostgreSQL und PostGIS nicht sehr vertraut bin, vermute ich, dass dies schneller möglich ist.

Folgendes habe ich bisher getan:

SELECT ST_Value(rast, ST_GeomFromText(CONCAT('POINT(', $1, ' ', $2, ')'), 4326))
FROM (
    SELECT * FROM rasters
    WHERE rast && ST_GeomFromText(CONCAT('POINT(', $1, ' ', $2, ')'), 4326)
) x;

$1und $2sind lang bzw. lat.

zedsdead
quelle
2
Haben Sie das Raster beim Import in Postgis in Kacheln geschnitten? (Parameter -t Breite x Höhe)?
Mutolisp
Ja, habe ich. Es hat die Leistung ein wenig verbessert. Ich sollte wahrscheinlich auch hinzufügen, dass sich die Datenbank auf einem Odroid-Board befindet, daher arbeitet sie erheblich langsamer als auf einem Desktop-PC. Ich habe mich nur gefragt, ob ich den Ansatz für die Rasterverarbeitung irgendwie ändern kann, damit weniger unnötige Berechnungen durchgeführt werden. Zum Beispiel habe ich anfangs die ST_Value-Funktion für alle Raster aufgerufen und dann nach der Zeile gesucht, die tatsächlich einen Wert enthält. Es war der einfachste Ansatz, arbeitete aber viel langsamer.
Zedsdead
2
Die Verwendung ST_SetSRID(ST_MakePoint($1, $2),4326)anstelle von String-Concats kann Ihnen Zeit sparen, wenn genügend Iterationen vorhanden sind.
Scro
1
Es scheint nicht viel zu helfen, aber danke. Ich habe darüber nachgedacht, beim Erstellen einer Tabelle eine weitere Spalte hinzuzufügen, die lediglich einen Begrenzungsrahmen für ein einzelnes Raster enthält. Vielleicht könnte auf diese Weise ein richtiges Raster schneller gefunden werden ... Außerdem habe ich mich gefragt, ob eine Vorberechnung der Pixelposition im Raster basierend auf den Eckkoordinaten und dem Pixelschritt in lon / lat hilfreich sein könnte ... Wenn jemand welche hat Gedanken dazu, dass ich dankbar sein werde, sie zu teilen :)
Zedsdead
2
Vielleicht könnten Sie versuchen, mit „EXPLAIN“ zu überprüfen, wo sich der Flaschenhals befindet.
Mutolisp

Antworten:

1

Sie könnten dies versuchen:

--calculate and store geom point just One time
WITH point_geom AS 
(
    SELECT ST_setsrid(ST_GeomFromText('POINT('|| $1 || ' '|| $2 || ')'), 4326) as geom
)
-- Your subquery is maybe useless , alias "x" isn't used
SELECT ST_Value( rast, point_geom.geom )
FROM rasters
WHERE rast && point_geom.geom;

Das eigentliche Problem ist jedoch die Rasterabfrage. Durch Kacheln des Datasets sollten Abfragen beschleunigt werden. Sie können versuchen, PostGIS WKT Raster zu verwenden, und diesem Tutorial folgen .

Ich hoffe, es wird nützlich sein,

Benno
quelle