Answers:
选择是针对此类问题而创建的。可以将其视为“ con”的“ switch”(或“ case”)版本,这是“ if ... else”的地图代数实现。
例如,如果有3个重叠的栅格,则(Python)语法看起来像
inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])
请注意pick
从1开始索引,而不是0。
(请参阅评论线程)
要处理NoData值,首先需要关闭ArcGIS的NoData处理。通过创建具有特殊(但有效)值代替NoData的网格来完成此操作,例如99999(或其他值):但请确保选择的值大于可能出现的任何有效数字:稍后将方便使用) 。这需要使用IsNull请求,如
p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)
例如,考虑以下单行网格的情况(NoData显示为“ *”):
inRas01: 1 2 19 4 * * * *
inRas02: 9 2 * * 13 14 * *
inRas03: 17 * 3 * 21 * 23 *
结果是将99999替换为每个“ *”。
接下来,将所有这些栅格想象成木块的平面阵列,其中NoData对应于缺失的块(孔)。当垂直堆叠这些栅格时,块将掉入它们下面的任何孔中。我们需要这种行为以避免选择NoData值:我们不希望块堆栈中有任何垂直间隙。每个塔中的块顺序并不重要。为此,我们可以通过对数据进行排名来获得每个塔:
q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])
在示例中,我们获得
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
请注意,等级是从最低到最高,因此q01包含每个位置的最小值,q02包含第二低的位置,依此类推。NoData代码直到所有有效数字都收集到之后才开始显示是更大的比任何有效数字。
为了避免在随机选择期间选择这些NoData代码,您需要知道每个位置堆积了多少块:这告诉我们出现了多少个有效值。处理此问题的一种方法是计算NoData代码的数量,然后从选择网格的总数中减去:
n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])
这产生
n0: 3 2 2 1 2 1 1 0
要处理n = 0(因此没有可供选择的情况)的情况,请将它们设置为NoData:
n = SetNull(n0 == 0, n0)
现在
n: 3 2 2 1 2 1 1 *
这也将确保您的(临时)NoData代码在最终计算中消失。生成介于1和n之间的随机值:
inPositionRaster = 1 + int(n * CreateRandomRaster())
例如,此栅格可能看起来像
inPositionRaster: 3 2 1 1 2 1 1 *
它的所有值都在1和[n]中的相应值之间。
选择与之前完全相同的值:
selection = Pick(inPositionRaster, [q01, q02, q03])
这将导致
selection: 17 2 3 4 21 14 23 *
要检查一切正常,请尝试选择所有具有NoData代码的输出单元(在此示例中为99999):不应有任何输出单元。
尽管此运行示例仅使用三个网格进行选择,但我以易于推广到任意数量网格的方式编写了该示例。在许多网格中,编写脚本(循环遍历重复的操作)将非常宝贵。
pick
:如果inPositionRaster和所选栅格在一个像元中都具有有效值,则可能是结果该单元格应该是所选栅格的值,而不考虑其他任何栅格可能包含的值)。您在想什么替代行为?
使用python和ArcGIS 10并使用具有以下语法的con函数:
Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})
这里的想法是查看随机栅格中的值是否小于0.5(如果选择的是raster1,否则选择raster2)。NoData
+数据= NoData
因此首先设置这些将所有值重新分类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
编辑:刚刚意识到您没有添加NoData
值,以便可以忽略。
Con(IsNull(ras1), 0, ras2)
NoData
呢?只是为了确保在随机选择时不会选择它们吗?