Python 查找与多边形相交的光栅单元的索引
我想为属于多边形要素或与多边形要素相交的所有光栅单元获取索引列表(行、列)。正在寻找python解决方案,最好是使用gdal/ogr模块Python 查找与多边形相交的光栅单元的索引,python,gdal,ogr,Python,Gdal,Ogr,我想为属于多边形要素或与多边形要素相交的所有光栅单元获取索引列表(行、列)。正在寻找python解决方案,最好是使用gdal/ogr模块 其他帖子建议对多边形进行栅格化,但如果可能的话,我宁愿直接访问单元索引。如果您想手动执行此操作,您需要测试每个单元: 正方形与v多边形相交 正方形v线交点 如果将每个正方形视为二维点,这将变得更容易-现在是点v多边形问题。检查游戏开发论坛中的冲突算法 祝你好运 显然,上面的Rutger解决方案就是解决这个问题的方法,但是我将保留我的解决方案。我开发了一个脚本,
其他帖子建议对多边形进行栅格化,但如果可能的话,我宁愿直接访问单元索引。如果您想手动执行此操作,您需要测试每个单元: 正方形与v多边形相交 正方形v线交点 如果将每个正方形视为二维点,这将变得更容易-现在是点v多边形问题。检查游戏开发论坛中的冲突算法
祝你好运 显然,上面的Rutger解决方案就是解决这个问题的方法,但是我将保留我的解决方案。我开发了一个脚本,通过以下内容实现了我所需要的:
ogr.Geometry.Intersects()
检查单元是否与多边形特征相交ogr.Geometry
object和geotransform matrix)调用match\u cells
)。代码如下:
from osgeo import ogr
# Convert projected coordinates to raster cell indices
def parse_coords(x,y,gt):
row,col = None,None
if x:
col = int((x - gt[0]) // gt[1])
# If only x coordinate is provided, return column index
if not y:
return col
if y:
row = int((y - gt[3]) // gt[5])
# If only x coordinate is provided, return column index
if not x:
return row
return (row,col)
# Construct polygon geometry from raster cell
def build_cell((row,col),gt):
xres,yres = gt[1],gt[5]
x_0,y_0 = gt[0],gt[3]
top = (yres*row) + y_0
bottom = (yres*(row+1)) + y_0
right = (xres*col) + x_0
left = (xres*(col+1)) + x_0
# Create ring topology
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(left,bottom)
ring.AddPoint(right,bottom)
ring.AddPoint(right,top)
ring.AddPoint(left,top)
ring.AddPoint(left,bottom)
# Create polygon
box = ogr.Geometry(ogr.wkbPolygon)
box.AddGeometry(ring)
return box
# Iterate over feature geometries & check for intersection
def match_cells(inputGeometry,gt):
matched_cells = []
for f,feature in enumerate(inputGeometry):
geom = feature.GetGeometryRef()
bbox = geom.GetEnvelope()
xmin,xmax = [parse_coords(x,None,gt) for x in bbox[:2]]
ymin,ymax = [parse_coords(None,y,gt) for y in bbox[2:]]
for cell_row in range(ymax,ymin+1):
for cell_col in range(xmin,xmax+1):
cell_box = build_cell((cell_row,cell_col),gt)
if cell_box.Intersects(geom):
matched_cells += [[(cell_row,cell_col)]]
return matched_cells
因为你没有提供一个有效的例子,所以你的出发点有点不清楚。我创建了一个包含1个多边形的数据集,如果您有一个包含多个多边形的数据集,但只希望以特定多边形为目标,则可以将
SQLStatement
或where
添加到gdal.Rasterize
调用中
样本多边形
光栅化
可以使用gdal.Rasterize
完成光栅化。您需要指定目标网格的属性。如果没有预定义的网格,则可以从多边形本身提取这些网格
ds = gdal.Rasterize('/vsimem/tmpfile', geojson, xRes=1, yRes=-1, allTouched=True,
outputBounds=[-120, 30, -100, 50], burnValues=1,
outputType=gdal.GDT_Byte)
mask = ds.ReadAsArray()
ds = None
gdal.Unlink('/vsimem/tmpfile')
转换为指数
可以使用Numpy从光栅化多边形检索索引:
y_ind, x_ind = np.where(mask==1)
你知道有什么好的资源描述如何做到这一点吗?如果我可以使用多边形的边界框来限制必须检查的光栅单元的数量,这可能是可行的。多边形可能不适合边界框。使用三角形中点的变化。你可以找到很多。确保对您选择的任何算法进行几个单元测试,以验证其正确性!这听起来比我的解决方案更复杂,但不幸的是,我现在没有时间来研究它。不过,我会在某个时候研究这个问题。谢谢你的建议!是的,在大多数情况下,这不是一个便宜的操作。这是可以理解的。幸运的是,虽然我将要处理的光栅很大,但多边形很小,而且相对较少。因此,对于我需要它执行的任务,这段代码执行得非常快。为什么不使用光栅化呢?它可能会更快,并且给出完全相同的结果。因为我需要单元格索引作为列表,而不是光栅产品。除非我误解了它的工作原理,否则我认为光栅化无法提供此功能。好吧,你赢了!这大约是我的方法的两倍,所需的代码也少得多。您能否建议一种方法,从多边形(shapefile)属性字段中获取刻录值,然后将其与坐标一起传递到numpy数组?使用
属性=“name”
代替刻录值=1
,如果要提取单个多边形,则每个特征的属性值必须是唯一的(或使用单独的步骤)。在我的情况下,不需要将单个特征分开。每个特性都属于一个类,我只需要确保类ID与单元索引保持连接。谢谢你的帮助!您知道有没有一种方法可以使用gdal.RasterizeLayer
来执行类似的操作(即,光栅化为临时文件)?几个月后,我刚刚重温了这段代码&我意识到如果我可以这样做会很方便,因为我可以在光栅化之前应用层属性过滤器。
y_ind, x_ind = np.where(mask==1)