使用ArcGIS Spatial Analyst计算栅格集的连续像素值?


23

我正在将ArcGIS 10与Spatial Analyst结合使用。

我有一组栅格(总共8个),每个栅格的每个像元都包含1或0。每个栅格代表不同年份的数据。出于争论,从第1年到第8年。

我可以将所有栅格加在一起,这将为我提供一个最终栅格,其值的范围为0到8。8表示该栅格集(所有年份)的像元始终为1。

我想找出每个单元格中最长的连续数字1。

因此,例如,整个网格可以为单个单元格记录一个值,例如5,但在8个网格中,该单元格具有最大的连续1等于3。或者另一种表示方式是3年内该单元格为1然后它开始在零和一之间振荡。

我的栅格处理技能不如矢量处理技能那么热,我对ESRI帮助文件已有很好的了解,但是我不知道要使用现成的地理处理工具如何实现这一目标?

有任何想法吗?


1
这实际上是一个很酷的分析。和往常一样,有多种方法可以做您想做的事情。我认为您将需要进行一些编程以遍历所有组合。
Mowry 2012年

1
一般评论(受@MLowry的此评论启发):请在问题有趣或清晰表达时对问题进行投票。好的问题驱动着我们网站上的一切;请尽我们所能来奖励那些问他们的人!
ub

Answers:


14

因为这是本地操作,所以让我们弄清楚如何对单个单元进行操作:“地图代数”将负责其余的工作。

首先请注意,栅格的顺序显然很重要。因此,单次单元格统计信息(例如单元格总和)将无法执行。

如果在给定的单元格上遇到序列如01110101,我们将从头到尾进行处理,

  1. 从零开始计数。

  2. 每次遇到1时增加计数。

  3. 保存最后一个计数后,每次遇到0时重置计数

  4. 最后,获取最大已保存的计数(包括最终计数)。

步骤1用恒定的零网格实现。步骤2和3取决于我们遇到的情况:因此这是一个有条件的操作。步骤4显然是局部最大值。然后,我们将其正式编码为:

count = 0
result = 0
For each value:
    If (value==1):
        count=count+1
    else
        result = max(result, count)
        count=0
result = max(result, count)

当您有许多网格时,最好用Python脚本来完成,但是有八个网格时,展开循环并手动写出步骤并不繁琐。这揭示了一个小问题:这result=max(longest,count)是一种“副作用”,很难使用栅格操作进行编码。(但是可以这样做,如下面的第二个解决方案所示。)它的效率也不高,因为它在每个步骤都增加了额外的计算量。因此,我们对方法进行了一些修改,目的是将max操作推迟到最后。这将需要在每个阶段保存单独的计数。

通过这一过程,我还找到了第一步的捷径。这将导致以下解决方案,尽管该解决方案比较长且占用大量RAM,但它很简单,并且包含快速执行的步骤:

result1 = "grid1"
result2 = con("grid2"==1, "result1"+1, 0)
result3 = con("grid3"==1, "result2"+1, 0)
result4 = con("grid4"==1, "result3"+1, 0)
result5 = con("grid5"==1, "result4"+1, 0)
result6 = con("grid6"==1, "result5"+1, 0)
result7 = con("grid7"==1, "result6"+1, 0)
result8 = con("grid8"==1, "result7"+1, 0)
CellStatistics(["result1", "result2", "result3", "result4", "result5", "result6", "result7" "result8"], "max")

实际语法因您的ArcMap版本而异。(例如CellStatistics,我相信它是版本10的新功能,但是始终可以使用本地最大操作。)

在具有输入01110101的示例中,“结果*”网格的序列将包含值0、1、2、3、0、1、0、1,因此最后CellStatistics将返回3,即最长字符串的长度。 1。

如果RAM不足,则可以修改解决方案以重新使用中间结果,但执行时间大约要加倍:

result = "grid1"
temp = con("grid2"==1, "result"+1, 0)
result = CellStatistics[["temp", "result"], "max"]
temp = con("grid3"==1, "temp"+1, 0)
result = CellStatistics[["temp", "result"], "max"]
...
temp = con("grid8"==1, "temp"+1, 0)
CellStatistics[["temp", "result"], "max"]

在具有输入01110101的示例中,第一行之后的(“ temp”,“ result”)值将为(NoData,0),每对(“ Con”,“ CellStatistics”)操作对之后的值将为(1 ,1),(2、2),(3、3),(0、3),(1、3),(0、3),(1、3)。最终值再次是3。

两种解决方案中的Map Algebra表达式的规则模式都指示如何在脚本中将算法编码为循环,并在每次迭代时适当地更改索引。


类型代码块中可能有错别字:count = count = 1可能应该是count = count + 1
Mowry 2012年

1
@ML谢谢(眼睛很好!):现在已修复。很难使伪代码绝对正确。人工检查是发现错误的真正资产。另外,尽管我没有在ArcGIS中测试解决方案,但确实在R中实现了第一个解决方案,因此我可以肯定这种方法是正确的。
ub

1
“威伯”又是你认识的男人!如果您被公车撞倒,上帝会帮助我们其余的人!您最初使用Python的方法就是我一直在思考的方向,但是我知道使用栅格通常可以完成您已经证明的所有操作。如果您发现自己在英国,将很荣幸为您买一品脱最好的室温扁平啤酒!:)
Hornbydd 2012年

谢谢,邓肯:但是请查看Andy Harfoot的出色解决方案!
ub

14

只是聊一聊,想知道是否可以通过将输入网格视为二进制流来解决该问题。这将使您可以将它们组合起来以给出该序列的唯一汇总整数-即01110101 =117。然后可以将该值重新分类以给出连续1的最大数目。

以下示例显示了一种组合八个网格的方法:

2*(2*(2*(2*(2*(2*(2*"g8" + "g7") + "g6") + "g5") + "g4") + "g3") + "g2") + "g1"

按位操作也可以用于此步骤。或者,您可以使用合并,然后进行字段计算。(字段计算将具有与上一个类似的表达式。)

重新分类表必须为00000000B = 0和11111111B = 255之间的所有值最大的运行长度为,在这里,他们是:

0, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 6, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 1, 1, 1, 2, 1, 1, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 1, 1, 1, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 3, 4, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8

在ArcGIS中,此方法仅限于大约20个网格:使用更多方法可以创建笨拙的属性表。(Combine具体限于20个网格。)


+1:这是一个非常好的主意。(唯一的限制是,当涉及到31个以上的网格时,您将用尽所有的位。)我已自由地将您的想法充实了一点,以便其他人可以看到实现起来有多么容易。
ub

3

您是否考虑过将值从0和1更改为2的幂(1,2,4,8,16,32)。当您将8个网格合并在一起时,您将获得每个单元格的唯一值,这将为您提供连续的信息(即:值3表示1年和2年,其中54表示6至8年)。

只是一个想法


这正是@Andy Harfoot几个小时前建议的,Ryan。:-)
whuber

谢谢,抱歉。度假时,我在手机上阅读了此内容。
瑞安·加内特
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.