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

如何用Python库(如Shapely)计算多个相交多边形的平均值?

多边形“平均”处理的Python实现方案

针对多个存在大量交集的多边形,以下几种基于Python库的方案可以实现符合直观预期的“平均”效果:

1. 顶点坐标平均法(适合形状相似的多边形)

直接对所有多边形的对应顶点坐标取均值,构建新多边形。适合顶点数量、顺序相近的多边形集合。

from shapely.geometry import Polygon
import numpy as np

def average_polygons_by_vertices(polygons):
    # 提取每个多边形的外轮廓顶点(忽略最后一个重复的闭合点)
    vertices_list = [np.array(poly.exterior.coords)[:-1] for poly in polygons]
    
    # 若顶点数量不一致,通过角度排序对齐(以质心为原点)
    def align_vertices(vertices):
        centroid = np.mean(vertices, axis=0)
        # 计算每个顶点相对于质心的角度
        angles = np.arctan2(vertices[:,1]-centroid[1], vertices[:,0]-centroid[0])
        # 按角度排序顶点
        return vertices[np.argsort(angles)]
    
    aligned_vertices = [align_vertices(v) for v in vertices_list]
    # 统一顶点数量(通过线性插值补点,示例补到最大数量)
    max_len = max(len(v) for v in aligned_vertices)
    resampled_vertices = []
    for v in aligned_vertices:
        if len(v) == max_len:
            resampled_vertices.append(v)
        else:
            # 线性插值补点
            indices = np.linspace(0, len(v)-1, max_len)
            resampled = np.array([np.interp(indices, np.arange(len(v)), v[:,0]),
                                 np.interp(indices, np.arange(len(v)), v[:,1])]).T
            resampled_vertices.append(resampled)
    
    # 计算顶点均值
    avg_vertices = np.mean(resampled_vertices, axis=0)
    return Polygon(avg_vertices)

2. 缓冲区交集迭代法(贴合重叠区域的直观平均)

从多边形交集出发,逐步扩展缓冲区,保留与多数多边形重叠的区域,最终得到介于交集和并集之间的“平均”形状。

from shapely.ops import unary_union, intersection

def average_polygons_by_buffer(polygons, step=0.1, overlap_threshold=0.7):
    total_polys = len(polygons)
    # 初始形状为所有多边形的交集
    current_shape = intersection(*polygons)
    
    # 迭代扩展缓冲区,直到重叠比例低于阈值
    while True:
        buffered_shape = current_shape.buffer(step)
        # 统计与buffered_shape相交的多边形数量
        overlap_count = sum(1 for poly in polygons if buffered_shape.intersects(poly))
        if overlap_count / total_polys < overlap_threshold:
            break
        current_shape = buffered_shape
    
    # 最后用所有多边形的并集裁剪,避免过度扩展
    final_shape = intersection(current_shape, unary_union(polygons))
    return final_shape
  • 参数说明:step控制每次扩展的步长,overlap_threshold控制保留的重叠比例(如0.7表示保留至少70%多边形覆盖的区域)。

3. 栅格化矢量化法(鲁棒性强,适合复杂形状)

将多边形转换为栅格,计算每个栅格点的覆盖比例,提取符合比例阈值的区域后再矢量化为多边形,适合处理顶点不规则的复杂多边形。

import rasterio
from rasterio.features import rasterize, shapes
import numpy as np
from shapely.geometry import shape
from shapely.ops import unary_union

def average_polygons_by_raster(polygons, resolution=100, coverage_threshold=0.5):
    # 获取所有多边形的边界范围
    union_shape = unary_union(polygons)
    bounds = union_shape.bounds
    # 计算栅格尺寸
    width = int((bounds[2] - bounds[0]) * resolution)
    height = int((bounds[3] - bounds[1]) * resolution)
    transform = rasterio.transform.from_bounds(*bounds, width, height)
    
    # 初始化栅格并累加每个多边形的覆盖
    raster = np.zeros((height, width), dtype=np.int32)
    for poly in polygons:
        raster += rasterize([poly], out_shape=(height, width), transform=transform)
    
    # 提取覆盖比例达标区域
    coverage_mask = (raster / len(polygons)) >= coverage_threshold
    # 矢量化回多边形
    shape_gen = shapes(coverage_mask.astype(np.uint8), transform=transform)
    avg_polygons = [shape(geom) for geom, val in shape_gen if val == 1]
    
    # 合并多个多边形(如果有)
    return unary_union(avg_polygons) if avg_polygons else None
  • 参数说明:resolution控制栅格精度(数值越高精度越高),coverage_threshold控制覆盖比例(如0.5表示保留至少被一半多边形覆盖的区域)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:05:05