GeoPandas:起来,给矢量数据“补洞”

其他   2022-08-22 17:00   湖北  

1、前言

我手里有个矢量数据,但内部有很多‘洞’,如下图所示现在需要根据洞的大小去修补,比如面积,把面积小于某个值,比如2000,的洞全部补上,而对于超过2000的洞则不用修补,希望最后得到的结果是如下所示

可以看到,比较小的洞已经消失了

2、思路

emmmmm我想了很久,结论是我不会补洞,但我会挖洞......

1、读取数据,使用geopandas.read_file(),获取到矢量数据的信息

2、获取整个矢量的外部边界,并将边界转成面,同时将原本的属性赋值给它,构建新的GeoDataFrame

3、获取到所有的洞,用列表存起来

4、根据筛选条件筛选出符合要求的洞,并构建成一个GeoDataFrame

5、利用裁剪进行“挖洞”

6、保存为新的矢量数据

3、代码

import geopandas
from geopandas import GeoSeries
from shapely.geometry import Polygon, MultiPolygon

def capHoles(file_path, out_path, area):
    """
    根据面积条件修补shp数据的空洞
    :param file_path: 输入数据
    :param out_path: 输出数据
    :param area: 筛选面积
    :return:
    "
""
    src_data = geopandas.read_file(file_path)
    # 根据原数据构建无洞的多边形
    # 获取多边形的外部边界
    outer_boundary = src_data.exterior

    # 转成面
    polygon_boundary = GeoSeries([Polygon(outer_boundary[i]) for i in range(len(outer_boundary))])
    polygon_dataframe = geopandas.GeoDataFrame(src_data, geometry=polygon_boundary, crs='EPSG:3857')

    # 求洞
    holes = polygon_dataframe.difference(src_data)
    polyList = []
    for i in range(len(holes)):
        if holes[i].geom_type == 'MultiPolygon':
            for j in range(len(holes[i])):
                polyList.append(holes[i][j])
        else:
            polyList.append(holes[i])
    holesSelect = []
    for hole in polyList:
        if hole.area < area:
            holesSelect.append(hole)
    holesPolygon = GeoSeries(holesSelect)
    holesDataFrame = geopandas.GeoDataFrame(geometry=src_data.geometry.append(holesPolygon), crs='EPSG:3857')

    # 裁剪
    outShp = polygon_dataframe.clip(holesDataFrame)
    outShp.to_file(out_path)

if __name__ == '__main__':
    file_path = r'D:\test\test3857.shp'
    out_path = r'D:\test\test.shp'
    area = 2000
    capHoles(file_path, out_path, area)

4、结果

基本满足要求,不过

“左上角这个正方形很拽啊!你很会打吗?你会打有个屁用啊?出来混要有势力,要有背景。你哪个道上的?”

“我叫阿杰,你不喜欢叫的话,你就叫我太子好了....”

“原来是小瘪三(小别扇)”

我是腰椎,see you!


壹贰叁言
赠予生活,聊以安慰。