You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中多边形相减及无孔洞多边形转换技术问询

多边形相减及去孔洞处理问题

需求说明

我有多个蓝色和红色Polygon,需要将所有红色Polygon从蓝色Polygon中批量相减。相减完成后,部分剩余Polygon可能带有孔洞,需要把这些带孔洞的Polygon转换为无孔洞的单一Polygon。

已尝试的实现方案

from typing import TypedDict
from shapely.geometry import MultiPolygon, Polygon


class Coords(TypedDict):
    x: list[float]
    y: list[float]


def subtract_polygons(group_a: list[Coords], group_b: list[Coords]):
    # Convert polygons to Shapely Polygon objects
    polygons_a = [Polygon(zip(group["x"], group["y"])) for group in group_a]
    polygons_b = [Polygon(zip(group["x"], group["y"])) for group in group_b]

    # Create a "negative" polygon for the hole in group B
    negative_polygons_b = [polygon.exterior for polygon in polygons_b]

    # Subtract each polygon in polygons_b from each polygon in polygons_a
    result_polygons = []
    for polygon_a in polygons_a:
        for negative_polygon_b in negative_polygons_b:
            result_polygon = polygon_a.difference(negative_polygon_b)
            result_polygons.append(result_polygon)

    # Convert the resulting geometry to MultiPolygon
    result_multipolygon = MultiPolygon(result_polygons)

    print("polygons_a", polygons_a)
    print("polygons_b", polygons_b)
    print("negative_polygons_b", negative_polygons_b)
    print("result_multipolygon", result_multipolygon)

group_a: list[Coords] = [
    {"x": [100, 200, 200, 100, 100], "y": [100, 100, 200, 200, 100]},
    {"x": [130, 230, 230, 130, 130], "y": [130, 130, 230, 230, 130]},
    {"x": [180, 280, 280, 180, 180], "y": [180, 180, 280, 280, 180]},
]
group_b: list[Coords] = [
    {"x": [150, 175, 175, 150, 150], "y": [150, 150, 175, 175, 150]},
    {"x": [150, 250, 250, 150, 150], "y": [220, 220, 320, 320, 220]},
]

subtract_polygons(group_a, group_b)

期望结果

最终得到单个无孔洞的凹多边形(示意图显示:蓝色区域合并后减去红色区域,形成一个整体的凹形区域,无内部孔洞)。

实际输入与结果

实际输出为多个分离的多边形,与期望的单一凹多边形不符。

控制台输出

polygons_a [
<POLYGON ((100 100, 200 100, 200 200, 100 200, 100 100))>,
<POLYGON ((130 130, 230 130, 230 230, 130 230, 130 130))>,
<POLYGON ((180 180, 280 180, 280 280, 180 280, 180 180))>
]

polygons_b [
<POLYGON ((150 150, 175 150, 175 175, 150 175, 150 150))>,
<POLYGON ((150 220, 250 220, 250 320, 150 320, 150 220))>
]

negative_polygons_b [
<LINEARRING (150 150, 175 150, 175 175, 150 175, 150 150)>,
<LINEARRING (150 220, 250 220, 250 320, 150 320, 150 220)>
]

result_multipolygon MULTIPOLYGON (
((100 200, 200 200, 200 100, 100 100, 100 200)),
((100 200, 200 200, 200 100, 100 100, 100 200)),
((130 230, 230 230, 230 130, 130 130, 130 230)),
((230 130, 130 130, 130 230, 150 230, 230 230, 230 220, 230 130)),
((180 280, 280 280, 280 180, 180 180, 180 280)),
((280 280, 280 180, 180 180, 180 220, 180 280, 250 280, 280 280))
)

内容的提问来源于stack exchange,提问作者LCIII

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 12:51:06