Ottieni valori raster da un overlay poligonale nelle soluzioni GIS di OpenSource


16

Ho due strati. Uno strato poligonale con molte tessere e uno strato raster contenente la copertura del suolo CORINE 2006 con molte categorie in una mappa colori. Voglio ottenere per ogni poligono nello shapelayer una somma di ogni categoria di copertura del suolo dello strato raster.

Ad esempio, esiste un poligono con ID "2" e desidero Attributi come questo per questo poligono (in percentuale o metri quadrati):

  • Seminativi: 15%
  • Foresta: 11%
  • Strade: 2% (... e così uno)

Ho provato a farlo in grass, qgis (nessuna funzione), saga (riassume ogni singolo per un valore totale) r (somma totale), ma non ho ancora trovato alcuna soluzione. La maggior parte dei plugin (statistiche zonali in qgis) supporta solo 0-1 livelli raster. v.rast.stats non ha aiutato neanche. Sono aperto a qualsiasi soluzione buona e intelligente !. Forse ho anche usato un approccio sbagliato o fatto errori.

In Arcgis questo compito è abbastanza semplice, se ricordo bene, ma mi manca ancora una buona soluzione per il tuo utente Linux di tutti i giorni.

Sto eseguendo un sistema Linux debian e questo è il motivo per cui posso usare solo programmi per questo sistema operativo.


EDIT: Perché questa domanda ha ancora così tante visualizzazioni e visitatori: ho scritto un plug-in QGIS, che è anche in grado di calcolare il landcover del livello raster. Non ho ancora codificato una sovrapposizione di poligoni, ma sicuramente è stata pianificata. Trova il plug-in qui e installa prima la libreria Scipy.


Può sicuramente essere fatto in R, è solo una questione di capire quali funzioni. È necessario sovrapporre ciascun poligono con il raster, quindi utilizzare table () per ottenere un riepilogo dei pixel "tagliati dai cookie". I pacchetti raster, rgdal e rgeos possono essere utili. Leggi la "R Spatial Task View" (lo troverà google)
Spacedman,

certo, ma come posso ottenere un tale riepilogo. Puoi facilmente sovrapporre un livello poligonale con un livello raster con! Is.na (sovrapposizione (Poly, Raster)), ma con comandi come estrai posso solo calcolare l'area totale nel pixel tagliato dai cookie e non diverse categorie di una mappa colori . Non conoscevo i rgeos, ma ho guardato attraverso l'API e non ho trovato alcuna funzione per farlo.
Chiurlo,

Controlla r.univar in GRASS, come vedi grasswiki.osgeo.org/wiki/Zonal_statistics
markusN

Ciao! Grazie per aver creato un plug-in QGIS! Volevo solo ricordare che il plugin si arresta in modo anomalo (> 13000 poligoni). Sarebbe bello se suddividesse il compito in modo da non andare in crash. E sarebbe meraviglioso avere un'opzione per aggiungere tutte le classi contemporaneamente (ad esempio, quindi la tabella degli attributi ottiene 2 nuovi campi LandcoverID e Landcover% dove entrambi contengono un elenco CSV con i valori) :)
Mfbaer

@Joran: se ritieni che si tratti di un bug, solleva una segnalazione bug anziché scriverla in un commento ( github.com/Martin-Jung/LecoS/issues ). Inoltre 1) non è compito dei plugin serializzare o elaborare in batch i tuoi compiti. Quindi eseguilo su sottoinsiemi più piccoli. 2) Sicuro. Ci sarebbero molte cose meravigliose da aggiungere. Il codice è open source, sentiti libero di codificarlo :)
Chiurlo

Risposte:


13

Usa 'extract' per sovrapporre funzionalità poligonali da uno SpatialPolygonsDataFrame (che può essere letto da un file di forma usando maptools: readShapeSpatial) su un raster, quindi usa 'table' per riassumere. Esempio:

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

Quindi il mio primo poligono copre 542 pixel e il secondo copre 958. Posso riassumere ciascuno di essi:

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

 26  27 
287 255 

[[2]]

  2  11  18 
 67  99 792 

Quindi il mio primo poligono è di 287 pixel della classe 26 e 255 pixel della classe 27. Abbastanza facile da sommare, dividere e moltiplicare per 100 per ottenere percentuali.


Ottimo, grazie mille per lo sforzo. Ci proverò e riferirò :-)
Chiurlo

6

Volevo riferire ed eccomi qui. La soluzione di Spacedman ha funzionato alla grande e sono stato in grado di esportare tutte le informazioni per ogni poligono nella mia forma. Nel caso in cui qualcuno abbia lo stesso problema, ecco come ho preceduto:

...
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)
}

3

se capisco correttamente quello che vuoi, e supponendo che tu abbia il livello vettoriale 'mypolygonlayer' e il livello raster 'corina' già nel tuo database GRASS GIS:

Per prima cosa vorrei convertire il vettore in raster. Il gatto assicurerà che avrai un identificatore univoco per poligono. Se hai una colonna con un identificatore numerico univoco, puoi invece usare quella colonna. L'etichettacolonna è facoltativa:

v.to.rast input = mypolygonlayer layer = 1 output = mypolygons use = cat labelcolumn = NameMappingUnit

Quindi esegui r.stats per ottenere le tue statistiche:

r.stats -a -l input = mypolygons, corina separator =; output = / home / paulo / corinastats.csv

L'ultimo passo è aprire corinastats.csv ad es., LibreOffice e creare una tabella pivot o usare R per creare la tua tabella incrociata


3

So che questo post è piuttosto vecchio, ma di recente odio eseguire lo stesso tipo di analisi, ma il download di programmi come R è un po 'una seccatura sul mio computer di lavoro e necessita di approvazione. Dopo molte ore di ricerche su un metodo che avrei potuto usare solo con QGis ed Excel, ho scoperto che questo metodo funzionava meglio per me e volevo offrirlo alle persone nella stessa situazione.

  1. Aggancia il poligono al livello raster (Raster → estrazione → clipper: file di input = livello raster, scegli il nome e la posizione dell'output, fai clic sul livello maschera, scegli il poligono → ok)

  2. Poligonizza il livello del tagliatore (Raster → Conversione → poligono: file di input = livello del clip, salva output → ok)

  3. Calcolo del numero di pixel (fare clic sul file della forma appena creato → apri calcolatrice campo: selezionare “crea nuovo campo” e aggiungere il nome campo, Funzione = geometria → area → ok). Ora dovresti avere una nuova colonna nella tabella degli attributi che mostra il numero di pixel.

  4. Salva livello poligonale (fare clic con il pulsante destro del mouse sul livello poligonale, salva come: formato = file DBF, salva come → ok)

  5. Riassumendo il numero di pixel per ciascun habitat (avvia Excel, apri il file, se non hai titoli aggiungine uno ora per ogni colonna, fai clic su una cella vuota, vai alla scheda DATI, consolida, assicurati che sia sulla somma, fai clic sul freccia rossa accanto a "sfoglia ..." e seleziona due colonne (titoli inclusi), fai clic su "aggiungi" e seleziona entrambe le caselle "Riga superiore" e "Colonna sinistra" → ok)

  6. Se, come me, hai molti poligoni da analizzare e devi confrontarli nella stessa tabella, questo passaggio ti sarà utile. In una nuova cartella di lavoro Excel, elenca i tuoi numeri di habitat nella colonna A (per me da 1 a 48) e posiziona le due colonne che hai appena consolidato nelle colonne B e C (habitat in B e numero di pixel in C). Nella cella D1 scrivi la seguente formula: = IFNA (INDICE (C: C; MATCH (A2; B: B; 0)); "") e trascina (o fai doppio clic nell'angolo in basso a destra) fino all'ultimo valore (quindi se hai 48 habitat fino alla cella D48). Il numero di pixel è ora nelle celle corrispondenti al tuo habitat e puoi ripetere questo processo per tutti i tuoi poligoni.


2

Che ne dite di convertire i dati CORINE in un set di dati poligonali vettoriali usando QGIS ( Raster> Conversione> Poligonizza ) e quindi usando la funzione Unione ( Vettore> Strumenti di geoprocessing> Unione ) per combinarli con i poligoni. Il set di dati vettoriali risultante conterrebbe le aree di ciascuna classe CORINE in ciascun poligono.


grazie per questo suggerimento. Non ho ancora pensato all'unione dei vettori. Forse lo proverò, se l'elaborazione R in qualche modo fallisce.
Chiurlo,

0

QGIS.

Nel trunk QGIS è disponibile un'altra versione di ZonalStats, si chiama Zonal Statistics.

Questo svolge la funzione richiesta.

Per quanto riguarda il flusso di lavoro, non sono chiaro su quanti raster hai o sono solo bande in un raster?


grazie per il commento, ma Zonal Statistics mangia solo raster senza categorie. Iam usa QGIS Trunk 1.9
Chiurlo il

0

Contrariamente alla maggior parte delle risposte sopra, direi che l'opzione migliore è quella di rasterizzare i tuoi poligoni e di lavorare con due set di dati raster invece di due set di dati poligonali. Ciò richiede molta meno elaborazione ed è di conseguenza l'unica soluzione facile da implementare per elaborare raster di grandi dimensioni e file poligonali di grandi dimensioni in R.

Dopo aver rasterizzato i tuoi poligoni esattamente nella stessa misura e risoluzione dei dati raster, puoi tabulare le statistiche di riepilogo come spiegato qui , che è appropriato se il tuo raster si adatta alla memoria (livelli raster piccoli / medi) o puoi binarizzare ogni categoria con la reclassfunzione e che calcolare le zonalstatistiche per ogni classe. Ecco una soluzione che incorpora la rasterizzazione e le statistiche zonali in una funzione e funziona bene con set di dati molto grandi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.