Antworten:
Pick wurde für solche Probleme erstellt. Stellen Sie sich das als "switch" (oder "case") Version von "con" vor, der Map-Algebra-Implementierung von "if ... else".
Wenn es zum Beispiel 3 überlappende Raster gibt, würde die (Python-) Syntax so aussehen
inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])
Beachten Sie, dass pick
die Indizierung bei 1 beginnt, nicht bei 0.
(siehe den Kommentarthread)
Um mit NoData-Werten fertig zu werden, müssen Sie zuerst die NoData-Behandlung von ArcGIS deaktivieren. Erstellen Sie dazu Raster, die anstelle von NoData einen speziellen (aber gültigen) Wert haben, z. B. 99999 (oder was auch immer: Wählen Sie jedoch einen Wert, der größer ist als eine gültige Zahl, die angezeigt werden kann. Dies ist später hilfreich.) . Dies erfordert die Verwendung der IsNull-Anforderung wie in
p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)
Betrachten Sie beispielsweise den Fall dieser einzeiligen Gitter (NoData wird als "*" angezeigt):
inRas01: 1 2 19 4 * * * *
inRas02: 9 2 * * 13 14 * *
inRas03: 17 * 3 * 21 * 23 *
Das Ergebnis ist, dass anstelle jedes "*" ein 99999 eingesetzt wird.
Stellen Sie sich als nächstes alle diese Raster als flache Anordnungen von Holzblöcken vor, wobei NoData fehlenden Blöcken (Löchern) entspricht. Wenn Sie diese Raster vertikal stapeln, fallen Blöcke in Löcher darunter. Wir brauchen dieses Verhalten, um die Auswahl von NoData-Werten zu vermeiden: Wir wollen keine vertikalen Lücken in den Blockstapeln. Die Reihenfolge der Blöcke in jedem Turm spielt keine Rolle. Zu diesem Zweck können wir jeden Turm erhalten, indem wir die Daten ordnen :
q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])
Im Beispiel erhalten wir
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
Beachten Sie, dass die Ränge vom niedrigsten zum höchsten sind, sodass q01 an jeder Stelle die niedrigsten Werte enthält, q02 die zweitniedrigsten usw. Die NoData-Codes werden erst angezeigt, wenn alle gültigen Zahlen erfasst wurden, da diese Codes vorhanden sind sind größer als alle gültigen Zahlen.
Um zu vermeiden, dass diese NoData-Codes während der zufälligen Auswahl ausgewählt werden, müssen Sie wissen, wie viele Blöcke an jedem Ort gestapelt sind. Dies gibt an, wie viele gültige Werte auftreten. Eine Möglichkeit, dies zu handhaben, besteht darin, die Anzahl der NoData-Codes zu zählen und diese von der Gesamtzahl der Auswahlgitter zu subtrahieren:
n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])
Dies ergibt
n0: 3 2 2 1 2 1 1 0
Um die Fälle zu behandeln, in denen n = 0 ist (es steht also nichts zur Auswahl zur Verfügung), setzen Sie sie auf NoData:
n = SetNull(n0 == 0, n0)
Jetzt
n: 3 2 2 1 2 1 1 *
Dies garantiert auch, dass Ihre (temporären) NoData-Codes bei der endgültigen Berechnung verschwinden. Generiere Zufallswerte zwischen 1 und n:
inPositionRaster = 1 + int(n * CreateRandomRaster())
Zum Beispiel könnte dieses Raster so aussehen
inPositionRaster: 3 2 1 1 2 1 1 *
Alle seine Werte liegen zwischen 1 und dem entsprechenden Wert in [n].
Wählen Sie die Werte genau wie zuvor aus:
selection = Pick(inPositionRaster, [q01, q02, q03])
Dies würde dazu führen
selection: 17 2 3 4 21 14 23 *
Um zu überprüfen, ob alles in Ordnung ist, wählen Sie alle Ausgabezellen aus, die den NoData-Code haben (in diesem Beispiel 99999): Es sollten keine vorhanden sein.
Obwohl in diesem Beispiel nur drei Gitter zur Auswahl verwendet werden, habe ich es so geschrieben, dass es leicht auf eine beliebige Anzahl von Gittern verallgemeinert werden kann. Bei vielen Gittern ist das Schreiben eines Skripts (um die wiederholten Operationen zu durchlaufen) von unschätzbarem Wert.
pick
wenn: inPositionRaster und das ausgewählte Raster beide gültige Werte in einer Zelle haben, dann plausibel das Ergebnis für diese Zelle sollte der Wert des ausgewählten Rasters sein, unabhängig davon, was die anderen Raster enthalten können). An welches alternative Verhalten denken Sie?
Verwenden von Python und ArcGIS 10 und Verwenden der con- Funktion mit der folgenden Syntax:
Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})
Die Idee hier ist zu sehen, ob der Wert im zufälligen Raster kleiner als 0,5 ist, wenn es Raster1 ist, andernfalls wählen Sie Raster2. NoData
+ data = NoData
also setze diese zuerst umklassifiziere alle Werte mit NoData
auf 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
BEARBEITEN: Ich habe gerade festgestellt, dass Sie die NoData
Werte nicht hinzufügen , damit das Teil weggelassen werden kann.
Con(IsNull(ras1), 0, ras2)
NoData
? Ist es nur um sicherzustellen, dass sie bei der zufälligen Auswahl nicht ausgewählt werden?
Ich würde nur ein zufälliges Raster ( Hilfe ) mit dem gleichen Umfang und der gleichen Zellengröße erstellen . Verwenden Sie dann CON ( Hilfe ), um den Wert aus dem 1. Raster auszuwählen, wenn die Zelle aus dem zufälligen Raster einen Wert <128 hat (wenn ein zufälliges Raster 0 - 255 wäre), andernfalls wählen Sie einen Wert aus dem 2. Raster.
Hoffe das macht Sinn :)