Réponses:
Pick a été créé pour des problèmes comme celui-ci. Considérez-le comme la version "switch" (ou "case") de "con", qui est l'implémentation d'algèbre de carte de "if ... else".
S'il y a 3 rasters qui se chevauchent, par exemple, la syntaxe (Python) ressemblerait à
inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])
Notez que l' pick
indexation commence à 1, pas à 0.
(voir le fil des commentaires)
Pour gérer les valeurs NoData, vous devez d'abord désactiver la gestion NoData d'ArcGIS. Pour ce faire, créez des grilles qui ont une valeur spéciale (mais valide) à la place de NoData, comme 99999 (ou autre chose: mais assurez-vous de choisir une valeur plus grande que tout nombre valide pouvant apparaître: cela sera pratique plus tard) . Cela nécessite l' utilisation de la demande IsNull, comme dans
p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)
Par exemple, considérons le cas de ces grilles à une ligne (NoData est représenté par "*"):
inRas01: 1 2 19 4 * * * *
inRas02: 9 2 * * 13 14 * *
inRas03: 17 * 3 * 21 * 23 *
Le résultat est de mettre un 99999 à la place de chaque "*".
Ensuite, imaginez tous ces rasters comme des tableaux plats de blocs de bois avec NoData correspondant aux blocs manquants (trous). Lorsque vous empilez verticalement ces rasters, les blocs tomberont dans les trous situés en dessous. Nous avons besoin de ce comportement pour éviter de choisir des valeurs NoData: nous ne voulons pas de lacunes verticales dans les piles de blocs. L'ordre des blocs dans chaque tour n'a pas vraiment d'importance. À cette fin, nous pouvons obtenir chaque tour en classant les données :
q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])
Dans l'exemple, on obtient
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
Notez que les rangs sont du plus bas au plus élevé, de sorte que q01 contient les valeurs les plus basses à chaque emplacement, q02 contient le deuxième plus bas, etc. Les codes NoData ne commencent pas à apparaître jusqu'à ce que tous les nombres valides soient collectés, car ces codes sont plus grands que tous les nombres valides.
Afin d'éviter de choisir ces codes NoData lors de la sélection aléatoire, vous devez savoir combien de blocs sont empilés à chaque emplacement: cela nous indique combien de valeurs valides se produisent. Une façon de gérer cela est de compter le nombre de codes NoData et de le soustraire du nombre total de grilles de sélection:
n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])
Cela donne
n0: 3 2 2 1 2 1 1 0
Pour gérer les cas où n = 0 (il n'y a donc rien de disponible à sélectionner), définissez-les sur NoData:
n = SetNull(n0 == 0, n0)
Maintenant
n: 3 2 2 1 2 1 1 *
Cela garantira également que vos codes NoData (temporaires) disparaissent dans le calcul final. Générez des valeurs aléatoires entre 1 et n:
inPositionRaster = 1 + int(n * CreateRandomRaster())
Par exemple, ce raster pourrait ressembler à
inPositionRaster: 3 2 1 1 2 1 1 *
Toutes ses valeurs sont comprises entre 1 et la valeur correspondante dans [n].
Sélectionnez les valeurs exactement comme avant:
selection = Pick(inPositionRaster, [q01, q02, q03])
Il en résulterait
selection: 17 2 3 4 21 14 23 *
Pour vérifier que tout va bien, essayez de sélectionner toutes les cellules de sortie qui ont le code NoData (99999 dans cet exemple): il ne devrait pas y en avoir.
Bien que cet exemple en cours d'exécution n'utilise que trois grilles pour sélectionner, je l'ai écrit d'une manière qui se généralise facilement à n'importe quel nombre de grilles. Avec beaucoup de grilles, l'écriture d'un script (pour parcourir les opérations répétées) sera inestimable.
pick
: si inPositionRaster et le raster sélectionné ont tous les deux des valeurs valides dans une cellule, alors plausiblement le résultat pour cette cellule doit être la valeur du raster sélectionné, quel que soit le contenu des autres rasters). À quel autre comportement pensez-vous?
En utilisant python et ArcGIS 10 et en utilisant la fonction con qui a la syntaxe suivante:
Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})
L'idée ici est de voir si la valeur dans le raster aléatoire est inférieure à 0,5, s'il s'agit de raster1, sinon de raster2. NoData
+ data = NoData
définissez d'abord ces valeurs de reclassification avec 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: Je viens de réaliser que vous n'ajoutez pas les NoData
valeurs de sorte que la pièce puisse être laissée de côté.
Con(IsNull(ras1), 0, ras2)
NoData
? Est-ce juste pour s'assurer qu'ils ne sont pas sélectionnés lors d'un choix aléatoire?
Je voudrais simplement créer un raster aléatoire ( aide ) de la même étendue et de la même taille de cellule. Ensuite, en utilisant CON ( aide ), définissez-le pour choisir la valeur du 1er raster si la cellule du raster randomisé a une valeur <128 (si un raster aléatoire est compris entre 0 et 255), sinon choisissez une valeur du 2ème raster.
J'espère que cela a du sens :)