通过从多个重叠栅格中随机选择像元值来创建栅格?


Answers:


7

选择是针对此类问题而创建的。可以将其视为“ 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):不应有任何输出单元。

尽管此运行示例仅使用三个网格进行选择,但我以易于推广到任意数量网格的方式编写了该示例。在许多网格中,编写脚本(循环遍历重复的操作)将非常宝贵。


您知道如何忽略计算中的NoData值(使用Raster Calculator和Python)吗?
山姆

山姆,“无视”到底是怎么回事?我相信默认行为是在一个或多个输入栅格为NoData的情况下输出NoData(但在以下情况下我无法完全确定pick:如果inPositionRaster和所选栅格在一个像元中都具有有效值,则可能是结果该单元格应该是所选栅格的值,而不考虑其他任何栅格可能包含的值)。您在想什么替代行为?
ub

我只需要从整数值中进行选择即可。假设我有三个栅格。对于一个单元格,其值如下:4,5,NoData。我希望该栅格在该单元格中具有4或5,但从不包含NoData。
山姆

我在使此1 + Int(n * CreateRandomRaster())正常工作时遇到麻烦。
山姆

“麻烦”在什么意义上?请具体!
whuber

4

使用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值,以便可以忽略。


我仍在研究Python技能。有没有一种方法可以将其输入到“栅格计算器”中,该方法也可以从过程中排除NoData值?我有10个栅格,有些有NoData,而其他有值。
山姆

我认为您可以在栅格计算器中使用这样的条件来创建条件Con(IsNull(ras1), 0, ras2)
djq 2012年

不幸的是,这实际上并没有排除NoData值:它只是将它们替换为零。在某些情况下,这可能是适当的,但在这里可能不合适!
ub

嗯,好点@whuber。那么排除是什么意思NoData呢?只是为了确保在随机选择时不会选择它们吗?
djq 2012年

这就是我的解释方式(请参阅本主题的编辑答案),但这仍然是一个好问题。以这种方式忽略ND值会导致以更大的概率选择其余网格,这可能是不希望的副作用。这完全取决于计算的目的。
whuber

1

我只是创建一个具有相同范围和像元大小的随机栅格(帮助)。然后使用CON(help)将其设置为如果来自随机栅格的像元的值小于128(如果随机栅格为0-255)则从第一栅格中选择值,否则从第二栅格中选择一个值。

希望有道理:)


您知道如何仅从具有值的栅格中进行选择吗?例如,在我的图中,有四个与NoData重叠的2和两个3。我想确保它仅从那些具有像元值而不是NoData的栅格中选择。
山姆

很抱歉没有回应。您还在努力解决NoData问题吗?
jareks 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.