Optimisation des requêtes de base de données Postgis

10

J'ai un ensemble de rasters au format DTED que je charge dans la base de données PostGIS à l'aide de l'outil de ligne de commande raster2pgsql.

Chacun des rasters est simplement stocké dans une rangée et décrit par rid et une valeur de format raster.

Maintenant, je veux créer une fonction de base de données qui prend la longitude et la latitude d'un point et renvoie une valeur de pixel correspondant à ce point.

Le problème que j'ai, c'est que cela prend beaucoup de temps (3-4 secondes) car la base de données fonctionne sur la carte Odroid.

Je sais que l'ensemble de données que je traite est assez volumineux (les rasters couvrent toute la zone du Royaume-Uni) mais comme je ne suis pas très familier avec PostgreSQL et PostGIS, je pense que cela peut être fait plus rapidement.

Voici ce que j'ai fait jusqu'à présent:

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;

$1et $2sont respectivement long et lat.

zedsdead
la source
2
Avez-vous découpé le raster en mosaïques lors de l'importation dans des postgis? (paramètre -t largeur x hauteur)?
mutolisp
Oui je l'ai fait. Cela a amélioré un peu les performances. Je devrais probablement également ajouter que la base de données se trouve sur la carte Odroid, elle fonctionne donc beaucoup plus lentement que sur un PC de bureau. Je me demandais simplement si je pouvais changer d'une manière ou d'une autre l'approche du traitement des rasters pour qu'il fasse moins de calculs inutiles. Par exemple, au départ, j'appelais la fonction ST_Value sur tous les rasters, puis je cherchais la ligne qui contient en fait une certaine valeur. C'était l'approche la plus simple mais fonctionnait beaucoup plus lentement.
zedsdead
2
Utiliser ST_SetSRID(ST_MakePoint($1, $2),4326)à la place des chaînes de caractères peut vous faire gagner du temps s'il y a suffisamment d'itérations.
Scro
1
Cela ne semble pas beaucoup aider mais merci. Je pensais à ajouter une autre colonne lors de la création de la table qui contiendrait simplement une boîte englobante pour un seul raster. Peut-être que de cette façon, un raster droit pourrait être trouvé plus rapidement ... De plus, je me demandais si un pré-calcul de la position des pixels dans le raster basé sur les coordonnées des coins et le pas des pixels en lon / lat pourrait aider ... Si quelqu'un a un pensées à ce sujet, je serai reconnaissant de les partager :)
zedsdead
2
Vous pourriez peut-être essayer d'utiliser «expliquer» pour vérifier où se trouve le goulot de la bouteille.
mutolisp

Réponses:

1

Vous pouvez essayer ceci:

--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;

Mais le vrai problème est la recherche raster; la mise en mosaïque de l'ensemble de données devrait accélérer les requêtes. Vous pouvez essayer d'utiliser PostGIS WKT Raster et suivre ce didacticiel .

J'espère que ce sera utile,

Benno
la source