Obter valores de varredura de uma sobreposição de polígono em soluções Opensource GIS

16

Eu tenho duas camadas. Uma camada em forma de polígono com muitos ladrilhos e uma camada de varredura contendo a cobertura do solo CORINE 2006 com muitas categorias em um mapa de cores. Desejo obter para cada polígono no shapelayer uma soma de cada categoria de cobertura de terra da camada raster.

Por exemplo, há um polígono com o ID '2' e eu quero Atributos como este para este polígono (em porcentagem ou metros quadrados):

  • Terra arável: 15%
  • Floresta: 11%
  • Ruas: 2% (... e mais uma)

Eu tentei fazê-lo na grama, qgis (sem função), saga (apenas resume todo o valor total) r (soma total), mas ainda não encontrei solução. A maioria dos plugins (estatísticas zonais no qgis) suporta apenas 0-1 camadas raster. O v.rast.stats também não ajudou. Estou aberto a qualquer solução boa e inteligente! Talvez eu tenha usado uma abordagem errada ou cometido erros.

No Arcgis, essa tarefa é bastante fácil, se bem me lembro, mas ainda estou perdendo uma boa solução para o seu usuário linux cotidiano.

Estou executando um sistema debian linux e é por isso que só posso usar programas para este sistema operacional.


EDIT: Como essa pergunta ainda tem muitas visualizações e visitantes: eu escrevi um QGIS-plugin, que também é capaz de calcular a cobertura da camada raster. Ainda não codifiquei uma sobreposição de polígono, mas ela definitivamente foi planejada. Encontre o plug-in aqui e instale a biblioteca Scipy primeiro.

Maçarico
fonte
Definitivamente, isso pode ser feito em R, é apenas uma questão de descobrir quais funções. Você precisa sobrepor cada polígono com a varredura e, em seguida, usar table () para obter um resumo dos pixels "cortados por cookies". Pacotes raster, rgdal e rgeos podem ser úteis. Leia o "R Spatial Task View" (o Google o encontrará)
Spacedman
claro, mas como posso obter um resumo desse tipo? Você pode sobrepor facilmente uma camada de polígono com uma camada de varredura com! Is.na (sobreposição (Poly, Raster)), mas com comandos como extrair só posso calcular a área total no pixel cortado e não categorias diferentes de um mapa de cores . Eu não conhecia rgeos, mas olhei pela API e não encontrei nenhuma função para fazer isso.
quer
Verifique r.univar no GRASS, como ver grasswiki.osgeo.org/wiki/Zonal_statistics
markusN
Oi! Obrigado por criar um plugin QGIS! Eu só queria mencionar que o plugin trava (> 13000 polígonos). Seria ótimo se dividisse a tarefa para não falhar. E seria maravilhoso ter uma opção para adicionar todas as classes de uma vez (por exemplo, de modo a tabela de atributos recebe 2 novos campos LandcoverID e Landcover% onde ambos espera uma lista CSV com os valores) :)
Mfbaer
@ Jordan: Se você acha que isso é um bug, crie um relatório de bug em vez de escrever isso em um comentário ( github.com/Martin-Jung/LecoS/issues ). Além disso, 1) não é o trabalho dos plug-ins serializar ou processar em lote suas tarefas. Execute-o em subconjuntos menores então. 2) Claro. Haveria muitas coisas maravilhosas a acrescentar. Código é open source, não hesite em código-lo :)
Curlew

Respostas:

13

Use 'extract' para sobrepor recursos de polígono de um SpatialPolygonsDataFrame (que pode ser lido de um shapefile usando maptools: readShapeSpatial) em uma varredura e use 'table' para resumir. Exemplo:

> c=raster("cumbria.tif") # this is my CORINE land use raster
> summary(spd)
Object of class SpatialPolygonsDataFrame
[...]
> nrow(spd)  # how many polygons:
[1] 2
> ovR = extract(c,spd)
> str(ovR)
List of 2
 $ : num [1:542] 26 26 26 26 26 26 26 26 26 26 ...
 $ : num [1:958] 18 18 18 18 18 18 18 18 18 18 ...

Portanto, meu primeiro polígono cobre 542 pixels e meu segundo, 958. Posso resumir cada um deles:

> lapply(ovR,table)
[[1]]

 26  27 
287 255 

[[2]]

  2  11  18 
 67  99 792 

Portanto, meu primeiro polígono é 287 pixels da classe 26 e 255 pixels da classe 27. Fácil o suficiente para somar, dividir e multiplicar por 100 para obter porcentagens.

Spacedman
fonte
Ótimo, muito obrigado pelo esforço. Vou tentar isso e relatório de volta :-)
Curlew
6

Eu queria relatar e aqui estou eu. A solução de Spacedman funcionou muito bem e eu pude exportar todas as informações para cada polígono na minha forma. Apenas no caso de alguém ter o mesmo problema, eis como eu precedi:

...
tab <- apply(ovR,table)
# Calculate percentage of landcover types for each polygon-field.
# landcover is a datastream with the names of every polygon
for(i in 1:length(tab)){
 s <- sum(tab[[i]])
 mat <- as.matrix(tab[[i]])
 landcover[i,paste("X",row.names(mat),sep="")] <- as.numeric(tab[[i]]/s)
}
Maçarico
fonte
3

se eu entendi corretamente o que você quer, e supondo que você tenha a camada vetorial 'mypolygonlayer' e a camada raster 'corina' já no seu banco de dados GRASS GIS:

Primeiro eu converteria vetor para varredura. O gato garantirá que você tenha um identificador exclusivo por polígono. Se você tiver uma coluna com um identificador numérico exclusivo, poderá usar essa coluna. A labelcolumn é opcional:

v.to.rast input = camada mypolygonlayer = 1 saída = mypolygons use = cat labelcolumn = NameMappingUnit

Em seguida, execute r.stats para obter suas estatísticas:

r.stats -a -l input = mypolygons, separador de corina =; saída = / home / paulo / corinastats.csv

O último passo é abrir o corinastats.csv no, por exemplo, LibreOffice e criar tabela dinâmica ou usar R para criar sua tabela cruzada

Ecodiv
fonte
3

Sei que este post é bastante antigo, mas recentemente pretendo realizar o mesmo tipo de análise, mas o download de programas como o R é um pouco problemático no meu computador de trabalho e precisa de aprovação. Depois de muitas horas pesquisando um método que eu poderia usar apenas com QGis e Excel, achei que esse método funcionou melhor para mim e queria oferecê-lo às pessoas no mesmo tipo de situação.

  1. Cortar polígono para camada raster (Raster → extração → clipper: arquivo de entrada = camada raster, escolha o nome e o local da saída, clique na camada de máscara, escolha o polígono → ok)

  2. Poligonalizar a camada do cortador (Raster → Conversão → poligonalizar: arquivo de entrada = sua camada de clipe, salvar saída → ok)

  3. Cálculo do número de pixels (Clique no arquivo de forma que você acabou de criar → abrir calculadora de campo: marque "criar novo campo" e adicione o nome do campo, Função = geometria → área → ok). Agora você deve ter uma nova coluna em sua tabela de atributos mostrando o número de número de pixels.

  4. Salvar camada poligonalizada (clique com o botão direito do mouse na camada poligonalizada, salve como: format = arquivo DBF, salve como → ok)

  5. Resumindo o número de pixels para cada habitat (inicie o Excel, abra o arquivo, se você não tiver títulos, adicione um agora para cada coluna, clique em uma célula vazia, acesse a guia DADOS, consolide, verifique se está em ordem, clique no botão seta vermelha ao lado de “procurar…” e selecione duas colunas (títulos incluídos), clique em “adicionar” e marque as caixas “Linha superior” e “coluna esquerda” → ok)

  6. Se, como eu, você tiver muitos polígonos para analisar e precisar compará-los na mesma tabela, esta etapa será útil. Em uma nova pasta de trabalho do Excel, liste os números dos habitats na coluna A (de 1 a 48) e coloque as duas colunas que você acabou de consolidar na coluna B e C (habitat em B e número de pixels em C). Na célula D1, escreva a seguinte fórmula: = IFNA (INDEX (C: C; MATCH (A2; B: B; 0)); "") e arraste (ou clique duas vezes no canto inferior direito) até o último valor (por isso, se você tem 48 habitats até a célula D48). O número de pixels está agora nas células correspondentes ao seu habitat e você pode repetir esse processo para todos os seus polígonos.

Emily
fonte
2

Que tal converter os dados CORINE em um conjunto de dados de polígonos vetoriais usando QGIS ( Raster> Conversão> Poligonizar ) e depois usar a função União ( Vetor> Ferramentas de Geoprocessamento> União ) para combinar com os polígonos. O conjunto de dados vetorial resultante conteria as áreas de cada classe CORINE em cada polígono.

Andy Harfoot
fonte
obrigado por esta sugestão. Ainda não pensou em união de vetores. Talvez eu tente isso, se o processamento R falhar de alguma forma.
Curlew
0

QGIS.

No tronco do QGIS, existe outra versão do ZonalStats, denominada Estatísticas Zonais.

Isso executa a função que você precisa.

Quanto ao fluxo de trabalho, não sei ao certo quantas rasters você tem ou são apenas faixas em uma varredura?

Willy
fonte
obrigado pelo comentário, mas as Estatísticas Zonais só comem varredura sem categorias. Estou usando o QGIS Trunk 1.9
Curlew
0

Ao contrário da maioria das respostas acima, eu argumentaria que a melhor opção é rasterizar seus polígonos e trabalhar com dois conjuntos de dados rasterizados em vez de dois conjuntos de dados poligonais. Isso requer muito menos processamento e, consequentemente, é a única solução fácil de implementar para processar rasters e arquivos de polígono grandes em R.

Depois de rasterizar seus polígonos exatamente na mesma extensão e resolução dos dados da varredura, é possível tabular estatísticas resumidas, conforme explicado aqui , o que é apropriado se a sua varredura se encaixar na memória (camadas de varredura pequenas / médias) ou se pode binarizar cada categoria com a reclassfunção e depois calcular zonalestatísticas para cada classe. Aqui está uma solução que incorpora as estatísticas de rasterização e zonal em uma função e funciona bem com conjuntos de dados muito grandes.

joaoal
fonte