使用ArcGIS 10,我有一个栅格,我想在其中找到栅格中最大值的像素,并以十进制度返回其位置(像素中心)。我想遍历此过程,返回栅格的第二个最高值的位置,然后返回第三个值,依此类推,如此一来,最后我得到了N个位置的列表,这些N个位置的栅格值最高。
我认为使用Python脚本最容易做到这一点,但是如果有更好的方法,我愿意接受其他想法。
使用ArcGIS 10,我有一个栅格,我想在其中找到栅格中最大值的像素,并以十进制度返回其位置(像素中心)。我想遍历此过程,返回栅格的第二个最高值的位置,然后返回第三个值,依此类推,如此一来,最后我得到了N个位置的列表,这些N个位置的栅格值最高。
我认为使用Python脚本最容易做到这一点,但是如果有更好的方法,我愿意接受其他想法。
Answers:
如果您乐于使用R,则有一个名为raster的软件包。您可以使用以下命令读取栅格:
install.packages('raster')
library(raster)
test <- raster('F:/myraster')
然后,当您去查看它时(通过键入test
),您可以看到以下信息:
class : RasterLayer
dimensions : 494, 427, 210938 (nrow, ncol, ncell)
resolution : 200, 200 (x, y)
extent : 1022155, 1107555, 1220237, 1319037 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs +towgs84=0,0,0
values : F:/myraster
min value : 0
max value : 1
可能有更好的处理栅格的方法,但是查找所需信息的一种方法可能是找到最大值,获取其矩阵位置,然后将其添加到较低的范围。
R
,就可以使用标准R
函数或getValues
方法来访问像元值。从那里可以直接确定最高值及其位置。
可以通过将值的前1%的指标网格与经度和纬度网格相结合来获得答案。诀窍在于创建该指标网格,因为ArcGIS(40年后仍是!)没有用于对栅格数据进行排名的过程。
浮点栅格的一种解决方案是迭代,但要快得多。令n为数据单元的数量。值的经验累积分布由所有对(z,n(z))组成,其中z是网格中的值,n(z)是网格中值小于或等于z的像元数。我们得到了一条曲线,该曲线将(-infinity,0)链接到(+ infinity,n),而这是由z排序的这些顶点的序列之外的。因此,它定义了一个函数f,其中(z,f(z))始终位于曲线上。您想在该曲线上找到一个点(z0,0.99 * n)。
换句话说,任务是找到f(z)-(1-0.01)* n的零。使用任何零查找例程(可以处理任意函数:这是不可微的)执行此操作。最简单且通常有效的方法是猜测并检查:最初,您知道z0介于最小值zMin和最大值zMax之间。严格猜测这两者之间的任何合理值。如果猜测太低,则设置zMin = z0; 否则设置zMax = z0。现在重复。您将迅速收敛到解决方案。当zMax和zMin足够接近时,您就足够接近了。保守起见,请选择zMin的最终值作为解决方案:它可能会吸收一些额外的点,以后可以丢弃。有关更复杂的方法,请参见数字食谱的第9章 (链接指向较早的免费版本)。
回顾此算法,您只需要执行两种栅格操作:(1)选择所有小于或等于某个目标值的像元,以及(2)对所选像元进行计数。这些都是最简单,最快的操作。(2)可以作为区域计数或通过从选择网格的属性表中读取一条记录来获得。
尽管我的解决方案使用的是GDAL,但我还是这样做的(因此,这不仅适用于ArcGIS)。我认为您可以从ArcGIS 10中的栅格中获取NumPy数组,但我不确定。NumPy提供了简单而强大的数组索引,argsort
以及其他。此示例不处理NODATA也不将坐标从投影坐标转换为经度/经度(但是使用GDAL随附的osgeo.osr并不困难)
import numpy as np
from osgeo import gdal
# Open raster file, and get GeoTransform
rast_src = gdal.Open(rast_fname)
rast_gt = rast_src.GetGeoTransform()
def get_xy(r, c):
'''Get (x, y) raster centre coordinate at row, column'''
x0, dx, rx, y0, ry, dy = rast_gt
return(x0 + r*dx + dx/2.0, y0 + c*dy + dy/2.0)
# Get first raster band
rast_band = rast_src.GetRasterBand(1)
# Retrieve as NumPy array to do the serious work
rast = rast_band.ReadAsArray()
# Sort raster pixels from highest to lowest
sorted_ind = rast.argsort(axis=None)[::-1]
# Show highest top 10 values
for ind in sorted_ind[:10]:
# Get row, column for index
r, c = np.unravel_index(ind, rast.shape)
# Get [projected] X and Y coordinates
x, y = get_xy(r, c)
print('[%3i, %3i] (%.3f, %.3f) = %.3f'%
(r, c, x, y, rast[r, c]))
为我的测试栅格文件显示以下内容:
[467, 169] (2813700.000, 6353100.000) = 844.538
[467, 168] (2813700.000, 6353200.000) = 841.067
[469, 168] (2813900.000, 6353200.000) = 840.705
[468, 168] (2813800.000, 6353200.000) = 840.192
[470, 167] (2814000.000, 6353300.000) = 837.063
[468, 169] (2813800.000, 6353100.000) = 837.063
[482, 166] (2815200.000, 6353400.000) = 833.038
[469, 167] (2813900.000, 6353300.000) = 832.825
[451, 181] (2812100.000, 6351900.000) = 828.064
[469, 169] (2813900.000, 6353100.000) = 827.514