从栅格中提取形状内的点

时间:2010-05-05 03:02:56

标签: python arcgis raster

我有一个光栅文件(基本上是2D数组),接近一百万个点。我试图从栅格中提取圆圈(以及圆圈内的所有点)。使用ArcGIS非常慢。任何人都可以建议任何图像处理库既易于学习又功能强大,而且速度足够快?

谢谢!

3 个答案:

答案 0 :(得分:2)

有效地提取点子集取决于您使用的确切格式。假设您将栅格存储为numpy整数数组,则可以提取如下所示的点:

from numpy import *

def points_in_circle(circle, arr):
    "A generator to return all points whose indices are within given circle."
    i0,j0,r = circle
    def intceil(x):
        return int(ceil(x))
    for i in xrange(intceil(i0-r),intceil(i0+r)):
        ri = sqrt(r**2-(i-i0)**2)
        for j in xrange(intceil(j0-ri),intceil(j0+ri)):
            yield arr[i][j]

points_in_circle将创建一个返回所有点的生成器。请注意,我使用的是yield而不是return。此函数实际上不返回点值,但描述了如何查找所有这些值。它在圆内的点值上创建顺序迭代器。有关yield如何运作的详细信息,请参阅Python documentation

我使用的事实是,对于圆圈,我们只能在内部点上显式循环。对于更复杂的形状,您可以循环遍历形状范围的点,然后检查点是否属于它。诀窍不是检查每个点,只检查它们的一小部分。

现在举例说明如何使用points_in_circle

# raster dimensions, 10 million points
N, M = 3200, 3200
# circle center and its radius in index space
i0, j0, r = 70, 20, 12.3

raster = fromfunction(lambda i,j: 100+10*i+j, (N, M), dtype=int)
print "raster is ready"
print raster

pts_iterator = points_in_circle((i0,j0,r), raster) # very quick, do not extract points yet
pts = array(list(pts_iterator)) # actually extract all points
print pts.size, "points extracted, sum = ", sum(pts)

在1000万个整数的光栅上,这很快。

如果您需要更具体的答案,请描述文件格式或将样本放在某处。

答案 1 :(得分:2)

Numpy允许你这样做,而且非常快:

import numpy

all_points = numpy.random.random((1000, 1000))  # Input array
# Size of your array of points all_points:
(image_size_x, image_size_y) = all_points.shape
# Disk definition:
(center_x, center_y) = (500, 500)
radius = 10

x_grid, y_grid = numpy.meshgrid(numpy.arange(image_size_x),
                                numpy.arange(image_size_y))
# Array of booleans with the disk shape
disk = ((x_grid-center_x)**2 + (y_grid-center_y)**2) <= radius**2

# You can now do all sorts of things with the mask "disk":

# For instance, the following array has only 317 points (about pi*radius**2):
points_in_disk = all_points[disk]
# You can also use masked arrays:
points_in_circle2 = numpy.ma.masked_array(all_points, ~disk)
from matplotlib import pyplot
pyplot.imshow(points_in_circle2)

答案 2 :(得分:1)

您需要一个可以读取光栅的库。我不确定如何在Python中执行此操作但是如果要使用Java编程,可以查看geotools(特别是使用一些新的栅格库集成)。如果你对C很好,我会推荐使用像GDAL这样的东西。

如果你想看一个桌面工具,你可以看看用python扩展QGIS来进行上述操作。

如果我没记错的话,PostGIS的Raster扩展可能支持基于向量的剪辑栅格。这意味着您需要为数据库中的要素创建圈子,然后导入栅格,然后您可以使用SQL来提取值。

如果你真的只是一个网格中有数字的文本文件,那么我会按照上面的建议去做。