Intersection d'un raster avec un polygone à l'aide de PostGIS - erreur d'artefact

15

J'utilise PostGIS2.0 pour faire des intersections raster / polygone. J'ai de la difficulté à comprendre quelle opération je dois utiliser et quelle est la façon la plus rapide de procéder. Mon problème est le suivant:

  • J'ai un polygone et un raster
  • Je veux trouver tous les pixels qui appartiennent au polygone et obtenir la somme de la valeur des pixels
  • Et (problème mis à jour): j'obtiens des valeurs massives pour certains pixels qui n'existent pas dans le raster d'origine lorsque j'effectue la requête

J'ai du mal à comprendre si je dois utiliser ST_Intersects()ou ST_Intersection(). Je ne sais pas non plus quelle est la meilleure approche pour additionner mes pixels. Voici la première approche que j'ai essayée (# 1):

SELECT 
    r.rast 
FROM
    raster as r, 
    polygon as p
WHERE
    ST_Intersects(r.rast, p.geom)

Cela renvoie une liste de rastvaleurs, dont je ne sais pas quoi faire. J'ai essayé de calculer les statistiques récapitulatives à l'aide ST_SummaryStats()mais je ne suis pas certain s'il s'agit de la somme pondérée de tous les pixels qui se trouvent dans le polygone.

SELECT  
        (result).count,
        (result).sum    
FROM (  
         SELECT 
            ST_SummaryStats(r.rast) As result
         FROM
            raster As r, 
            polygon As p
         WHERE
            ST_Intersects(r.rast, p.geom)    
    ) As tmp

L'autre approche que j'ai essayée (# 2) utilise ST_Intersection():

 SELECT
        (gv).geom,         
        (gv).val
 FROM 
 (
    SELECT 
        ST_Intersection(r.rast, p.geom) AS gv
    FROM 
        raster as r, 
        polygon as p           
    WHERE 
        ST_Intersects(r.rast, p.geom)

      ) as foo;

Cela renvoie une liste de géométries que j'analyse plus en détail, mais je suppose que cela est moins efficace.

Je ne sais pas non plus quel est l'ordre de fonctionnement le plus rapide. Dois-je toujours choisir raster, polygonou polygon, raster, ou convertir le polygone en raster pour qu'il soit raster, raster?

EDIT: J'ai mis à jour l'approche # 2 avec quelques détails du R.K.lien de.

En utilisant l'approche # 2, j'ai remarqué l'erreur suivante dans les résultats qui fait partie de la raison pour laquelle je n'ai pas compris la sortie. Voici l'image de mon raster original, et un contour du polygone qui est utilisé pour l'intersecter, superposé en haut:

entrez la description de l'image ici

Et voici le résultat de l'intersection avec PostGIS:

entrez la description de l'image ici

Le problème avec le résultat est qu'il y a des valeurs de 21474836 renvoyées, qui ne sont pas dans le raster d'origine. Je ne sais pas pourquoi cela se produit. Je soupçonne que cela est lié à de petits nombres quelque part (divisant par près de 0), mais cela renvoie le mauvais résultat.

djq
la source
Concernant le point deux, vous voulez obtenir la somme des valeurs des pixels qui coupent le polygone?
RK
Oui, je l'ai utilisé ST_SummaryStats()pour le n ° 1, mais je ne sais pas comment le faire pour le n ° 2.
djq
Publié un lien vers une référence. J'espère que ça aide.
RK
2
La valeur maximale de l'échelle dans votre carte est le maximum d'un entier signé 32 bits. Je ne sais pas ce que cela signifie dans votre cas, mais cela pourrait avoir à voir avec les valeurs NA. La plage de votre requête peut avoir des valeurs nulles qui ne sont pas gérées correctement. en.wikipedia.org/wiki/2147483647#2147483647_in_computing
yellowcap
6
FWIW, 21474836 n'est pas la valeur maximale d'un entier signé 32 bits. Cependant, 2 ^ 31-1 = 2147483647 est le maximum, et notez que 21474836 = 2147483647/100 (division entière). Cela indique que certains NA sont générés en interne (peut-être le long des cellules de bordure), ils sont représentés comme 2 ^ 31-1, puis le code "oublie" que ce sont NA et (peut-être dans un processus de rééchantillonnage?) Il les divise par 100.
whuber

Réponses:

6

J'ai trouvé un didacticiel sur l' intersection de polygones vectoriels avec une grande couverture raster à l'aide de PostGIS WKT Raster . Pourrait avoir les réponses que vous cherchez.

Le didacticiel a utilisé deux jeux de données, un fichier de forme de point qui a été mis en mémoire tampon pour produire des polygones et une série de 13 rasters d'altitude SRTM. Il y avait beaucoup d'étapes entre les deux, mais la requête utilisée pour couper le raster et le vecteur ressemblait à ceci:

 CREATE TABLE caribou_srtm_inter AS
 SELECT id, 
        (gv).geom AS the_geom, 
        (gv).val
 FROM (SELECT id, 
              ST_Intersection(rast, the_geom) AS gv
       FROM srtm_tiled,
            cariboupoint_buffers_wgs
       WHERE ST_Intersects(rast, the_geom)
      ) foo;

Les valeurs ont ensuite été résumées à l'aide des éléments suivants:

 CREATE TABLE result01 AS
 SELECT id, 
        sum(ST_Area(ST_Transform(the_geom, 32198)) * val) / 
        sum(ST_Area(ST_Transform(the_geom, 32198))) AS meanelev
 FROM caribou_srtm_inter
 GROUP BY id
 ORDER BY id;

Je ne connais pas suffisamment PostGIS pour expliquer cela, mais cela ressemble à ce que vous essayez d'accomplir. Le didacticiel doit faire la lumière sur les étapes intermédiaires. Bonne chance :)

RK
la source
Merci @RK J'ai lu ce tutoriel. Je pense que mon calcul est plus basique, mais je suis toujours en train de comprendre cette étape de base!
djq
2

En ce qui concerne le point 2 de la question d'origine - plusieurs des versions de développement de postgis 2.0 ont utilisé une version de la bibliothèque GDAL qui transforme les flottants en entiers. Si votre raster contient des valeurs flottantes et que vous utilisiez une version de GDAL inférieure à 1.9.0, ou une version préliminaire de PostGIS 2.0 qui n'appelait pas correctement GDALFPolygonize (), alors vous pourriez rencontrer ce bogue. Les tickets dans les suiveurs de bogues PostGIS et GDAL ont été classés et fermés. Ce bogue était actif au moment de la question d'origine.

En termes de performances, vous constaterez que l'utilisation ST_Intersects(raster, geom)est beaucoup plus rapide que l'utilisation ST_Intersects(geom, raster). La première version pixellise la géométrie et fait une intersection raster-espace. La deuxième version vectorise la géométrie et fait une intersection espace-vecteur, ce qui peut être un processus beaucoup plus coûteux.

Pete Clark
la source
0

J'avais aussi des problèmes étranges ST_SummaryStatsavec ST_Clip. Interroger les données différemment m'a dit que la valeur min de mon raster était de 32, puis max 300, mais ST_SummaryStatsrenvoyait -32700 pour les valeurs de pixels dans mon polygone cible.

J'ai fini par pirater la question comme suit:

WITH first AS (
   SELECT id, (ST_Intersection(geom, rast)).val
   FROM raster_table
   INNER JOIN vector_table ON ST_Intersects(rast, geom)
)
SELECT id, COUNT(val), SUM(val), AVG(val), stddev(val), MIN(val), MAX(val)
FROM first
GROUP BY id
jczaplew
la source