Risposte:
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 pick
inizia l'indicizzazione da 1, non da 0.
(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.
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?
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 = NoData
quindi prima imposta questi riclassificano i valori con NoData
0:
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 NoData
valori in modo che quel pezzo possa essere lasciato fuori.
Con(IsNull(ras1), 0, ras2)
NoData
? È solo per assicurarsi che non vengano scelti quando si sceglie casualmente?
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 :)