查找与多边形相交的栅格单元格的索引

时间:2017-11-21 03:52:31

标签: python gdal ogr

我想获得落在多边形特征内或与多边形特征相交的所有栅格单元的索引列(行,列)。在python中寻找解决方案,理想情况下使用gdal / ogr模块。

其他帖子建议栅格化多边形,但如果可能的话,我宁愿直接访问单元格索引。

2 个答案:

答案 0 :(得分:1)

显然Rutger的解决方案就是采用这种方式,但是我会解决问题。我开发了一个脚本,通过以下方式完成了我需要的工作:

  1. 获取我要检查的每个矢量要素的边界框
  2. 使用边界框限制计算窗口(确定栅格的哪个部分可能有交叉点)
  3. 遍历栅格的此部分内的单元格,并为每个单元格构建多边形几何
  4. 使用ogr.Geometry.Intersects()检查单元格是否与面要素相交
  5. 请注意,我只定义了方法,但我认为实现应该非常清楚 - 只需使用适当的参数(match_cells object和geotransform matrix)调用ogr.Geometry。代码如下:

    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 :(得分:0)

如果您想手动执行此操作,则需要测试每个单元格: 方形v多边形交叉点和 Square v Line intersection。

如果将每个方格视为2d点,则变得更容易 - 它现在是Point v Polygon问题。在Game Dev论坛中查看碰撞算法。

祝你好运!