Python 从坐标参考系中的多边形边界获取光栅中的像素坐标

Python 从坐标参考系中的多边形边界获取光栅中的像素坐标,python,gis,raster,rasterio,Python,Gis,Raster,Rasterio,我有一些相对较大(10980 x 10980像素)的GeoTiff文件,它们都对应于相同的地理区域(并且具有相同的坐标参考系),我有大量对应于地块的多边形(100000+),我想从每个图像文件中提取对应于每个多边形的像素。目前,我这样做的方式是使用shapely多边形和rasterio.mask.mask函数,如下所示: 图像文件中文件名的: 以rasterio.open(文件名)作为src: 对于形状中的形状: 数据,\=rasterio.mask.mask(src,[shape],crop=

我有一些相对较大(10980 x 10980像素)的GeoTiff文件,它们都对应于相同的地理区域(并且具有相同的坐标参考系),我有大量对应于地块的多边形(100000+),我想从每个图像文件中提取对应于每个多边形的像素。目前,我这样做的方式是使用shapely多边形和rasterio.mask.mask函数,如下所示:

图像文件中文件名的
:
以rasterio.open(文件名)作为src:
对于形状中的形状:
数据,\=rasterio.mask.mask(src,[shape],crop=True)

这在经验上相当缓慢。如果我预先计算了遮罩索引,那么我只需要读取每个图像的整个数据一次,然后使用预先计算的索引来提取每个多边形的相关像素(我不需要它们处于正确的二维配置中,我只需要值),这非常快。但我不知道是否有一种快速的方法来获取这些像素索引。我知道我可以使用rasterio的函数来获得整个图像大小的遮罩,然后使用numpy来获得多边形内部元素的索引,但是这样就不需要为每个多边形构造一个10980 x 10980数组来制作遮罩,这非常慢。

我最后做的是,当我打开第一个图像时,然后对于每个多边形

  • 使用图像变换将多边形转换为像素坐标,并在整数像素坐标中查找包含多边形的矩形边界框
  • 若要确定边界框中的哪些像素实际位于多边形中,请为每个像素构造形状良好的多边形,并使用
    .intersects()
    方法(如果只希望包含完全位于多边形内部的像素,可以使用
    .contains()
    )。(我不确定这是否会很慢,但事实证明并非如此。)
  • 保存每个多边形中所有像素的坐标对列表
然后,对于您打开的每个新图像,您只需读取整个图像数据并为每个多边形的部分建立索引,因为您已经有了像素索引

代码大致如下所示:

导入数学
进口numpy
进口pyproj
导入光栅掩码
从shapely.geometry导入多边形
形状\像素=无
对于图像文件中的文件名:
以rasterio.open(文件名)作为src:
如果shape_像素为无:
投影仪=pyproj.Proj(src.crs)
像素坐标形状=[
多边形(zip(*~src.transform*numpy.array(projector(*zip(*shape.boundary.coords)()))))
形状中的形状
]
每个形状的像素数=[]
对于形状中的形状:
xmin=max(0,数学层(shape.bounds[0]))
ymin=max(0,数学层(shape.bounds[1]))
xmax=math.ceil(shape.bounds[2])
ymax=math.ceil(shape.bounds[3])
像素_平方={}
对于范围内的j(xmin,xmax+1):
对于范围内的i(ymin,ymax+1):
像素_正方形[(i,j)]=多边形。从_边界(j,i,j+1,i+1)
每个形状的像素数。追加([
像素方格中(坐标,像素)的坐标。items()
如果形状相交(像素)
])
整段数据=src.read()
对于每个形状的像素数:
ivals,jvals=zip(*像素)
形状数据=整体数据[0,IVAL,JVAL]
...