Creare un raster scegliendo casualmente il valore della cella da più raster sovrapposti?


10

Sto usando ArcGIS Desktop 10 con la sua estensione Analista spaziale.

Come posso combinare più raster in uno, scegliendo sempre casualmente dai valori delle celle sovrapposte?

Ho un'immagine che può spiegarlo meglio:

esempio

Risposte:


7

Pick è stato creato per problemi come questo. Pensala come la versione "switch" (o "case") di "con", che è l'implementazione algebrica della mappa di "if ... else".

Se ci sono 3 raster sovrapposti, ad esempio, la sintassi (Python) sarebbe simile

inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])

Si noti che pickinizia l'indicizzazione da 1, non da 0.


modificare

(vedi il thread dei commenti)

Per far fronte ai valori NoData, è innanzitutto necessario disattivare la gestione NoData di ArcGIS. Fallo creando griglie con un valore speciale (ma valido) al posto di NoData, come 99999 (o qualsiasi altra cosa: ma assicurati di scegliere un valore maggiore di qualsiasi numero valido che può apparire: questo sarà utile in seguito) . Ciò richiede l' uso della richiesta IsNull, come in

p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)

Ad esempio, considera il caso di queste griglie a una riga (NoData è mostrato come "*"):

inRas01:  1  2 19  4  *  *  *  *
inRas02:  9  2  *  * 13 14  *  *
inRas03: 17  *  3  * 21  * 23  *

Il risultato è di mettere un 99999 al posto di ogni "*".

Quindi, immagina tutti questi raster come matrici piane di blocchi di legno con NoData corrispondenti a blocchi mancanti (fori). Quando impili verticalmente questi raster, i blocchi cadranno in tutti i buchi sotto di essi. Abbiamo bisogno di questo comportamento per evitare di selezionare i valori NoData: non vogliamo spazi vuoti verticali nelle pile di blocchi. L'ordine dei blocchi in ogni torre non ha molta importanza. A tal fine, possiamo ottenere ogni torre classificando i dati :

q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])

Nell'esempio, otteniamo

q01:      1     2     3     4    13    14    23 99999
q02:      9     2    19 99999    21 99999 99999 99999
q03:     17 99999 99999 99999 99999 99999 99999 99999

Si noti che le classifiche vanno dal più basso al più alto, quindi q01 contiene i valori più bassi in ciascuna posizione, q02 contiene il secondo più basso, ecc. I codici NoData non iniziano a essere visualizzati fino a quando non vengono raccolti tutti i numeri validi, poiché tali codici sono più grandi di qualsiasi numero valido.

Per evitare di selezionare questi codici NoData durante la selezione casuale, devi sapere quanti blocchi sono impilati in ogni posizione: questo ci dice quanti valori validi si verificano. Un modo per gestirlo è contare il numero di codici NoData e sottrarlo dal numero totale di griglie di selezione:

n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])

Questo cede

n0:       3 2 2 1 2 1 1 0

Per gestire i casi in cui n = 0 (quindi non è disponibile nulla da selezionare), impostali su NoData:

n = SetNull(n0 == 0, n0)

Adesso

n:        3 2 2 1 2 1 1 *

Ciò garantirà inoltre che i tuoi codici (temporanei) NoData scompaiano nel calcolo finale. Genera valori casuali tra 1 e n:

inPositionRaster = 1 + int(n * CreateRandomRaster())

Ad esempio, questo raster potrebbe apparire come

inPositionRaster: 3 2 1 1 2 1 1 *

Tutti i suoi valori si trovano tra 1 e il valore corrispondente in [n].

Seleziona i valori esattamente come prima:

selection = Pick(inPositionRaster, [q01, q02, q03])

Ciò comporterebbe

selection:       17  2  3  4 21 14 23  *

Per verificare che tutto sia a posto, prova a selezionare tutte le celle di output che hanno il codice NoData (99999 in questo esempio): non dovrebbero essercene.

Sebbene questo esempio corrente utilizzi solo tre griglie tra cui scegliere, l'ho scritto in un modo che si generalizza facilmente a qualsiasi numero di griglie. Con molte griglie, scrivere una sceneggiatura (per ripetere le ripetute operazioni) sarà prezioso.


Sai come potrei ignorare i valori NoData dai calcoli (con Raster Calculator e Python)?
Sam,

Sam, "Ignora" come, precisamente? Credo che il comportamento predefinito sia l'output di NoData ovunque uno o più raster di input siano NoData (ma non ne sono completamente sicuro nel caso di pick: se inPositionRaster e il raster selezionato hanno entrambi valori validi in una cella, quindi plausibilmente il risultato per quella cella dovrebbe essere il valore del raster selezionato, indipendentemente dal contenuto degli altri raster). A quale comportamento alternativo stai pensando?
whuber

Ne ho bisogno per selezionare solo tra i valori di numero intero. Diciamo che ho tre raster. Per una cella, i loro valori sono i seguenti: 4,5, NoData. Voglio che l'outraster abbia un 4 o un 5 in quella cella ma mai il NoData.
Sam,

Ho problemi a far funzionare questo 1 + Int (n * CreateRandomRaster ()).
Sam,

"Problemi" in che senso? Sii specifico!
whuber

4

Usando python e ArcGIS 10 e usando la funzione con che ha la seguente sintassi:

Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})

L'idea qui è di vedere se il valore nel raster casuale è inferiore a 0,5, se si sceglie raster1, altrimenti scegliere raster2. NoData+ data = NoDataquindi prima imposta questi riclassificano i valori con NoData0:

import arcpy
from arcpy import env
from arcpy.sa import *
env.workspace = "C:/sapyexamples/data"

ras1_NoNull = Con(IsNull("elevation1"),0, "elevation1")  # remove NoData
ras2_NoNull = Con(IsNull("elevation2"),0, "elevation2")  # remove NoData
randRaster = CreateRandomRaster(100, 2, Extent(0, 0, 150, 150)) # raster generated between 0 and 1; 100 is seed value

outCon = Con(randRaster < 0.5, ras1_NoNull,  ras2_NoNull)  

outCon.save("C:/outcon.img")   # save raster

EDIT: Ho appena realizzato che non stai aggiungendo i NoDatavalori in modo che quel pezzo possa essere lasciato fuori.


Sto ancora lavorando sulle mie abilità in Python. C'è un modo per inserirlo in Raster Calculator che escluderebbe anche i valori NoData dal processo? Ho 10 raster e alcuni hanno NoData dove altri hanno valori.
Sam,

Penso che puoi creare condizioni usando qualcosa del genere nel calcolatore rasterCon(IsNull(ras1), 0, ras2)
djq

Sfortunatamente, questo in realtà non esclude i valori NoData: li sostituisce semplicemente con zeri. In alcuni casi potrebbe essere appropriato, ma probabilmente non qui!
whuber

hmm, buon punto @whuber. Quindi cosa significa escludere NoData? È solo per assicurarsi che non vengano scelti quando si sceglie casualmente?
djq

È così che l'ho interpretato (vedi la mia risposta modificata in questo thread), ma rimane una buona domanda. Ignorando i valori ND in questo modo, le griglie rimanenti verranno selezionate con maggiore probabilità, il che potrebbe essere un effetto indesiderato. Tutto dipende dallo scopo del calcolo.
whuber

1

Vorrei solo creare un raster casuale ( aiuto ) della stessa estensione e dimensione della cella. Quindi, usando CON ( aiuto ) impostarlo per selezionare il valore dal 1 ° raster se la cella dal raster randomizzato ha un valore <128 (se un raster casuale sarebbe 0 - 255), altrimenti selezionare un valore dal 2 ° raster.

Spero che abbia un senso :)


Sai come selezionare solo i raster con valori? Ad esempio nella mia figura ci sono quattro 2 e due 3 che si sovrappongono a NoData. Voglio assicurarmi che selezioni solo da quei raster con valori in una cella e non NoData.
Sam,

Ci scusiamo per non aver risposto. Hai ancora problemi con NoData?
jareks,
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.