Conteggio dei valori di pixel consecutivi per set di raster usando ArcGIS Spatial Analyst?


23

Sto usando ArcGIS 10 con Analista spaziale.

Ho un set di raster (8 in totale) che contengono solo 1 o 0 per ogni cella. Ogni raster rappresenta dati diversi per un valore di anni. Per ragioni dal 1o all'anno 8.

Posso sommare tutti i raster che mi daranno una griglia finale con valori compresi tra 0 e 8. Un 8 che indica che la cella era costantemente 1 per l'insieme di raster (tutti gli anni).

Vorrei scoprire per ogni cella il numero progressivo più lungo di 1.

Quindi, ad esempio, la griglia totale può registrare per una singola cella un valore di dire 5 ma oltre le 8 griglie quella cella ha il maggior numero consecutivo di 1 uguale a 3. Oppure un altro modo di esprimere questo è per 3 anni che la cella era un 1 poi ha iniziato a oscillare tra zero e uno.

Le mie capacità di elaborazione raster non sono così calde come le mie abilità di elaborazione vettoriale e ho dato una buona occhiata al file della guida ESRI ma non riesco a capire come si possa ottenere questo risultato utilizzando gli strumenti di geo-elaborazione standard?

Qualche idea?


1
Questa è in realtà un'analisi piuttosto interessante. Come al solito, c'è più di un modo per fare ciò che stai cercando di fare. Penso che dovrai fare un po 'di programmazione per scorrere tutte le combinazioni.
MLowry

1
Un commento generale (ispirato a questa osservazione di @MLowry): per favore vota le domande ogni volta che sembrano interessanti o sono chiaramente articolate. Le buone domande guidano tutto sul nostro sito; per favore facciamo quello che possiamo per premiare chi lo chiede!
whuber

Risposte:


14

Poiché si tratta di un'operazione locale, scopriamo come farlo per una singola cella: Map Algebra si occuperà del resto.

Prima nota che l' ordine dei raster è ovviamente importante. Pertanto le statistiche sulle celle a colpo singolo, come la somma di una cella, non lo faranno.

Se dovessimo incontrare una sequenza come 01110101 in una data cella, la elaboreremmo dall'inizio alla fine e

  1. Inizia con un conteggio a zero.

  2. Aumenta il conteggio ogni volta che incontriamo un 1.

  3. Ripristina il conteggio ogni volta che incontriamo uno 0, dopo aver salvato l'ultimo conteggio .

  4. Alla fine, prendi il conteggio massimo salvato (incluso il conteggio finale).

Il passaggio 1 viene implementato con una griglia zero costante. I passaggi 2 e 3 dipendono da ciò che incontriamo: è quindi un'operazione condizionale . Il passaggio 4 è chiaramente un massimo locale. Vorremmo codificare questo, quindi, un po 'più formalmente come:

count = 0
result = 0
For each value:
    If (value==1):
        count=count+1
    else
        result = max(result, count)
        count=0
result = max(result, count)

È meglio farlo con uno script Python quando hai molte griglie, ma con otto non è oneroso srotolare il ciclo e scrivere i passaggi a mano. Ciò rivela un leggero problema: result=max(longest,count)è una sorta di "effetto collaterale" che è difficile da codificare con operazioni raster. (Ma può essere fatto, come mostrato nella seconda soluzione di seguito.) È anche inefficiente, perché aggiunge un calcolo extra ad ogni passaggio. Modifichiamo quindi un po 'l'approccio, con l'obiettivo di rimandare l' maxoperazione fino alla fine. Ciò richiederà il salvataggio di un conteggio separato in ogni fase.

Durante questo processo ho anche trovato una scorciatoia per il primo passo. Ciò porta alla seguente soluzione, che sebbene un po 'lunga e intensa di RAM, è semplice e prevede passaggi eseguiti rapidamente:

result1 = "grid1"
result2 = con("grid2"==1, "result1"+1, 0)
result3 = con("grid3"==1, "result2"+1, 0)
result4 = con("grid4"==1, "result3"+1, 0)
result5 = con("grid5"==1, "result4"+1, 0)
result6 = con("grid6"==1, "result5"+1, 0)
result7 = con("grid7"==1, "result6"+1, 0)
result8 = con("grid8"==1, "result7"+1, 0)
CellStatistics(["result1", "result2", "result3", "result4", "result5", "result6", "result7" "result8"], "max")

La sintassi effettiva varia in base alla versione di ArcMap. (Ad esempio, CellStatisticsè una novità della versione 10, credo, ma un'operazione massima locale è sempre stata disponibile.)

Nell'esempio con input 01110101, la sequenza di griglie "risultato *" conterrebbe i valori 0, 1, 2, 3, 0, 1, 0, 1, quindi alla fine CellStatisticsrestituirà 3, la lunghezza della stringa più lunga di 1 di.

Se la RAM è scarsa, la soluzione può essere modificata per riutilizzare i risultati intermedi, con un costo di circa il doppio del tempo di esecuzione:

result = "grid1"
temp = con("grid2"==1, "result"+1, 0)
result = CellStatistics[["temp", "result"], "max"]
temp = con("grid3"==1, "temp"+1, 0)
result = CellStatistics[["temp", "result"], "max"]
...
temp = con("grid8"==1, "temp"+1, 0)
CellStatistics[["temp", "result"], "max"]

Nell'esempio con input 01110101, i valori ("temp", "risultato") sarebbero (NoData, 0) dopo la prima riga e dopo ogni coppia di operazioni ("Con", "CellStatistics") i valori sarebbero (1 , 1), (2, 2), (3, 3), (0, 3), (1, 3), (0, 3), (1, 3). Ancora una volta il valore finale è 3.

Il modello regolare di espressioni Map Algebra in entrambe le soluzioni indica come codificare l'algoritmo come un ciclo in uno script, modificando gli indici come appropriato con ogni iterazione.


Potrebbe esserci un errore di battitura nel blocco del codice del tipo: count = count = 1 dovrebbe probabilmente essere count = count + 1
MLowry

1
@ML Grazie (buoni occhi!): È stato risolto ora. È difficile rendere lo pseudocodice assolutamente corretto; la revisione umana è una vera risorsa nella ricerca di errori. Inoltre, anche se non ho testato le soluzioni in ArcGIS, ho implementato la prima soluzione in R, quindi ho la certezza che l'approccio è corretto.
whuber

1
"whuber" ancora una volta sei l'uomo che lo sa! Dio aiuti il ​​resto di noi se vieni mai investito da un autobus! Il tuo approccio iniziale a Python era la direzione che stavo pensando, ma so che con i raster si può fare spesso tutto quello che hai provato. Se ti trovi in ​​Gran Bretagna, sarebbe un onore offrirti una pinta della nostra migliore birra a temperatura ambiente! :)
Hornbydd,

Grazie, Duncan: ma dai un'occhiata all'ottima soluzione di Andy Harfoot!
whuber

14

Parla solo di questo e ti chiedi se potresti affrontare il problema trattando le griglie di input come un flusso binario. Ciò consentirebbe di combinarli per fornire un numero intero di riepilogo univoco per la sequenza, ovvero 01110101 = 117. Questo valore potrebbe quindi essere riclassificato per fornire il numero massimo di 1 consecutivi.

Ecco un esempio che mostra un modo per combinare otto griglie:

2*(2*(2*(2*(2*(2*(2*"g8" + "g7") + "g6") + "g5") + "g4") + "g3") + "g2") + "g1"

Le operazioni bit a bit potrebbero anche essere messe in servizio per questo passaggio. In alternativa, è possibile utilizzare la combinazione seguita da un calcolo del campo. (Il calcolo del campo avrà un'espressione simile alla precedente.)

La tabella di riclassificazione deve fornire lunghezze massime di esecuzione per tutti i valori compresi tra 00000000B = 0 e 11111111B = 255. Al fine, qui sono:

0, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 6, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8

Questo approccio è limitato a circa 20 griglie in ArcGIS: l'utilizzo di più di questo può creare una tabella di attributi ingombrante. ( Combineè specificamente limitato a 20 griglie.)


Un enorme +1: questa è un'ottima idea. (L'unico limite è che quando sono coinvolte più di 31 griglie, rimarrai senza bit da usare.) Mi sono preso la libertà di dare un tocco in più alla tua idea in modo che gli altri possano vedere quanto sia facile da implementare.
whuber

3

Hai pensato di cambiare i valori da 0 e 1 a valori con la potenza di 2 (1,2,4,8,16,32). Quando combini le 8 griglie otterrai valori univoci per ogni cella che ti darà informazioni consecutive (cioè: un valore di 3 significa anni 1 e 2, dove un valore di 54 sarebbe anni da 6 a 8).

Solo un pensiero


Questo è esattamente ciò che @Andy Harfoot ha suggerito poche ore prima, Ryan. :-)
whuber

Grazie e scusa L'ho letto sul mio telefono in vacanza.
Ryan Garnett,
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.