我正在使用PyGRASS自动化一些GIS栅格分析(栅格是一个值网格)。我想使用python迭代网格的子部分,并将每个单元格与其最近的邻居进行比较。使用PyGRASS我可以将栅格作为嵌套列表,例如一个行列表,其中每一行都是值列表。
使用numpy我能够获得一个单元格的最近邻居,但我想确保最近邻居只能在栅格/网格范围内。也就是说,如果我想要一个不在网格边缘的单元的邻居,它将有8个邻居。这是相邻单元的最大数量:
+-+-+-+-+-+
|0|0|0|0|0|
+-+-+-+-+-+
|0|1|1|1|0|
+-+-+-+-+-+
|0|1|X|1|0|
+-+-+-+-+-+
|0|1|1|1|0|
+-+-+-+-+-+
|0|0|0|0|0|
+-+-+-+-+-+
但是,如果它位于网格的边缘或角落,则它可能只有5个或3个邻居:
+-+-+-+-+-+ +-+-+-+-+-+
|1|1|0|0|0| |X|1|0|0|0|
+-+-+-+-+-+ +-+-+-+-+-+
|X|1|0|0|0| |1|1|0|0|0|
+-+-+-+-+-+ +-+-+-+-+-+
|1|1|0|0|0| - OR - |0|0|0|0|0|
+-+-+-+-+-+ +-+-+-+-+-+
|0|0|0|0|0| |0|0|0|0|0|
+-+-+-+-+-+ +-+-+-+-+-+
|0|0|0|0|0| |0|0|0|0|0|
+-+-+-+-+-+ +-+-+-+-+-+
我已经开发了一些代码来检查8个潜在的相邻单元中是否有任何一个落在网格之外。但是当我运行我的代码时,只检查了大约一半的邻居单元。
我正在使用 enumerate()检查8个潜在的相邻单元格中的每一个,这些单元格已作为元组存储在列表中,例如(0,1)的理论邻居包含在列表[(-1,0),(-1,1),( - 1,2),(0,0),(0,2),(1)中,0),(1,1),(1,2)]。但是我想摆脱任何具有负值或超出网格尺寸的值的坐标对。
我的代码:
import sys
import os
import numpy
from numpy import *
''' define nearest neighbors matrix with numpy '''
k = 1
X_index, Y_index = mgrid[-k:k+1,-k:k+1]
## discount the center (0,0) index
center = (X_index==0) & (Y_index==0)
X_index = X_index[~center]
Y_index = Y_index[~center]
## credit for this clever solution goes to user Hooked on stackoverflow
## http://stackoverflow.com/questions/9245898/listing-adjacent-cells
def get_neighbors(raster,row,col):
## pass neighbor cell coordinates to list object as tuples
neighbor_coords = zip(X_index+col,Y_index+row)
print neighbor_coords,"\n"
for pos,cell in enumerate(neighbor_coords):
print "\n",cell
x = neighbor_coords[pos][0]
y = neighbor_coords[pos][1]
if (x < 0 or x+1 > len(raster)) or (y < 0 or y+1 > len(raster[0])):
print "Point ({},{}) is out of range.".format(x,y)
del neighbor_coords[pos]
print "\n",neighbor_coords,"\n"
# neighbor_values = raster[X_index+row,Y_index+col]
## pass neighbor cell values to list object
neighbor_values = raster[[i[0] for i in neighbor_coords],[i[1] for i in neighbor_coords]]
return neighbor_values
print "\n\n\n"
A = random.random((5,5))
get_neighbors(A,0,0)
print "\n\n\n"
get_neighbors(A,1,1)
请注意,只有在输入位于网格边缘某处的点时才会跳过单元格。