如何在同一地理坐标系中求一个多边形与其他多边形的交点?

2024-09-29 23:23:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含数千个多边形的shapefile。他们中的许多人互相接触,但不交叉。我需要得到接触多边形的公共线。在

我尝试使用以下函数来实现我的目的,但是输出显示了一些MultiLineString,其中的行只有两个点,这应该是一个完整的LineString。在

def calcu_intersect_lines(cgidf):

    intersection = gpd.GeoDataFrame(columns=['geometry'], crs=cgidf.crs)

    while len(cgidf) > 1:
        choose = cgidf.iloc[0]
        cgidf.drop(cgidf.index[0], inplace=True)
        for i in range(len(cgidf.index)):
            cgids = cgidf.iloc[i]
            if choose.geometry.exterior.intersects(cgids.geometry.exterior):
                intersects = choose.geometry.exterior.intersection(cgids.geometry.exterior)
                index = len(intersection)
                intersection.loc[index] = [intersects]

            else:
                continue

        return intersection

对于MultiLineString,我尝试使用shapely.geometry.LineString.union()函数将同一条MultiLineString中的两条短线连接起来,如果它们彼此接触。但结果也显示了MultiLineString。在

geopandas本身的交集函数似乎也会导致MultiLineString。在

是否有任何方法返回正常结果(LineString不是MultiLineString对于连续公共行)?在


以下是输入和输出数据的一个小示例:

^{pr2}$

以下是h的值:

index  geometry
0      MULTILINESTRING ((0 0.5, 0.5 1), (0.5 1, 1 0.5))
1      MULTILINESTRING ((1 0.5, 1 0), (1 0, 0.5 -0.5))

两个^{中的LineString分别具有公共点(0.5, 1)和{}。在

我想要的结果如下:

index  geometry
0      LINESTRING (0 0.5, 0.5 1, 1 0.5))
1      LINESTRING (1 0.5, 1 0, 0.5 -0.5))

可能的解决方案:

在评论中,我被提议替换下面的一行

intersection.loc[index] = [intersects]

通过

intersection.loc[index] = [LineString([*intersects[0].coords, *map(lambda x: x.coords[1], intersects[1:])])]

在我的简单示例中,它很好地工作。然而,对于真正的shapefile,它将比这复杂得多。可能存在以下情况:

  1. 具有多条公共线的两个多边形。在

    from shapely.geometry import Polygon
    
    a = Polygon(((0., 0.), (0., 0.5), (0.5, 1.), (1., 0.5), (1., 0.), (0.5, -0.5), (0., 0.)))
    b = Polygon(((0., 0.5), (0.5, 1.), (1.2, 0.7), (1., 0.), (0.5, -0.5), (2., 0.5), (0., 2.)))
    

    对于a和{},它们有两条公共行LineString(((0., 0.5), (0.5, 1.)))和{}。在这种情况下,我可以简单地使用intersects函数来测试行是否接触。但还有另一个问题:

  2. MultiLineString中的行不整齐。在

    from shapely.geometry import MultiLineString
    
    ml = MultiLineString((((2, 3), (3, 4)), ((0, 2), (2, 3))))
    

    对于ml,此建议将返回错误的结果。 你对上面的第二个例子有什么想法吗?


Tags: 函数indexlen多边形locgeometrychooseshapely
1条回答
网友
1楼 · 发布于 2024-09-29 23:23:07

感谢乔治和其他投稿人的帮助,我已经解决了我的问题。 在here中引入的shapely.ops.linemerge()函数是我解决方案的关键。在

我把我的解决方案贴在这里:

from shapely import ops

def union_multils(ml):

    '''Union touched LineStrings in MultiLineString or GeometryCollection.

    Parameter
        -
    ml: GeometryCollection, MultiLineString or LineString

    return
       
    ul: MultiLineString or LineString: a MultiLineString suggest the LineStrings 
        in input ml is not connect entitly.
    '''

    # Drop Point and other geom_type(if exist) out
    ml = list(ml)
    ml = [l for l in ml if l.geom_type == 'LineString']

    # Union
    if len(ml) ==  1 and ml[0].geom_type == 'LineString':
        ul = ml[0]
    else:
        ul = ops.linemerge(ml)

    return ul

相关问题 更多 >

    热门问题