Interseção de uma varredura com um polígono usando o PostGIS - erro de artefato

15

Estou usando o PostGIS2.0 para fazer algumas interseções de varredura / polígono. Estou tendo dificuldades para entender qual operação devo usar e qual é a maneira mais rápida de fazer isso. Meu problema é o seguinte:

  • Eu tenho um polígono e uma varredura
  • Quero encontrar todos os pixels que se enquadram no polígono e obter a soma do valor do pixel
  • E (problema atualizado): estou recebendo valores massivos para alguns pixels que não existem na varredura original quando executo a consulta

Estou tendo dificuldades para entender se devo usar ST_Intersects()ou ST_Intersection(). Também não sei qual é a melhor abordagem para somar meus pixels. Aqui está a primeira abordagem que eu tentei (# 1):

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

Isso retorna uma lista de rastvalores, com os quais não tenho certeza do que fazer. Tentei calcular as estatísticas de resumo usando, ST_SummaryStats()mas não tenho certeza se essa é a soma ponderada de todos os pixels que estão dentro do polígono.

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

A outra abordagem que tentei (nº 2) usa 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;

Isso retorna uma lista de geometrias que analiso mais adiante, mas presumo que isso seja menos eficiente.

Não sei ao certo qual é a ordem de operação mais rápida também. Devo sempre escolher raster, polygonou polygon, raster, ou converter o polígono em uma varredura para que seja raster, raster?

EDIT: Atualizei a abordagem # 2 com alguns detalhes do R.K.link de.

Usando a abordagem nº 2, notei o seguinte erro nos resultados, que é parte do motivo pelo qual não entendi a saída. Aqui está a imagem da minha varredura original e um contorno do polígono que está sendo usado para interceptá-la, sobreposto na parte superior:

insira a descrição da imagem aqui

E aqui está o resultado da interseção usando o PostGIS:

insira a descrição da imagem aqui

O problema com o resultado é que há valores de 21474836 sendo retornados, que não estão na varredura original. Eu não tenho idéia do por que isso está ocorrendo. Eu suspeito que esteja relacionado a números pequenos em algum lugar (dividindo por quase 0), mas retorna o resultado errado.

djq
fonte
Em relação ao ponto dois, você deseja obter a soma dos valores dos pixels que cruzam o polígono?
RK
Sim, usei o ST_SummaryStats()número 1, mas não sei como fazê-lo no número 2.
DJQ
Postou um link para uma referência. Espero que ajude.
RK
2
O valor máximo da escala em seu mapa é o máximo de um número inteiro assinado de 32 bits. Não sei o que isso significa no seu caso, mas poderia ter a ver com os valores de NA. O intervalo na sua consulta pode ter valores nulos que não são tratados adequadamente. en.wikipedia.org/wiki/2147483647#2147483647_in_computing
yellowcap
6
FWIW, 21474836 não é o valor máximo de um int assinado de 32 bits. No entanto, 2 ^ 31-1 = 2147483647 é o máximo e observe que 21474836 = 2147483647/100 (divisão inteira). Isso sugere que internamente alguns NAs são gerados (talvez ao longo de células de borda), eles são representados como 2 ^ 31-1 e, em seguida, o código "esquece" estes são NA e (talvez em um processo de reamostragem?) Os divide por 100.
whuber

Respostas:

6

Encontrei um tutorial sobre interseção de polígonos vetoriais com uma grande cobertura de varredura usando o PostGIS WKT Raster . Pode ter as respostas que você está procurando.

O tutorial usou dois conjuntos de dados, um arquivo de formato de ponto que foi armazenado em buffer para produzir polígonos e uma série de 13 rasters de elevação SRTM. Havia várias etapas no meio, mas a consulta usada para interceptar a varredura e o vetor era assim:

 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;

Os valores foram resumidos usando o seguinte:

 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;

Eu realmente não sei PostGIS suficiente para explicar isso, mas com certeza soa como o que você estava tentando realizar. O tutorial deve esclarecer as etapas intermediárias. Boa sorte :)

RK
fonte
Obrigado @RK, eu li esse tutorial. Acho que meu cálculo é mais básico, mas ainda estou descobrindo essa etapa básica!
6114 djq
2

No que diz respeito ao ponto 2 da pergunta original - vários dos lançamentos de desenvolvimento do postgis 2.0 usavam uma versão da biblioteca GDAL que lançava flutuadores para ints. Se a sua varredura tiver valores flutuantes e você estiver usando uma versão do GDAL menor que 1.9.0 ou uma versão do pré-lançamento do PostGIS 2.0 que não chame corretamente de GDALFPolygonize (), você poderá encontrar esse bug. Os ingressos nos rastreadores de erros PostGIS e GDAL foram arquivados e fechados. Este bug estava ativo na época da pergunta original.

Em termos de desempenho, você verá que o uso ST_Intersects(raster, geom)é muito mais rápido que o uso ST_Intersects(geom, raster). A primeira versão rasteriza a geometria e faz uma interseção raster-space. A segunda versão vetoriza a geometria e faz uma interseção de espaço vetorial, o que pode ser um processo muito mais caro.

Pete Clark
fonte
0

Eu também estava tendo problemas estranhos usando ST_SummaryStatscom ST_Clip. Consultar os dados de maneira diferente me disse que o valor mínimo da minha varredura era 32 e, no máximo, 300, mas ST_SummaryStatsretornava -32700 para os valores de pixel no polígono de destino.

Acabei cortando o problema da seguinte maneira:

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
fonte