【问题标题】:How can I count the number of polygons a shape intersects?如何计算形状相交的多边形数量?
【发布时间】:2019-01-10 20:30:43
【问题描述】:

我有一个非常大的数据集,其中包含多边形和点,周围有缓冲区。我想在点数据中创建一个新列,其中包括点的缓冲区相交的多边形数。

这是一个简化的例子:

import pandas as pd
import geopandas as gp
from shapely.geometry import Polygon
from shapely.geometry import Point
import matplotlib.pyplot as plt

## Create polygons and points ##

df = gp.GeoDataFrame([['a',Polygon([(1, 0), (1, 1), (2,2), (1,2)])],
                     ['b',Polygon([(1, 0.25), (2,1.25), (3,0.25)])]],
                     columns = ['name','geometry'])
df = gp.GeoDataFrame(df, geometry = 'geometry')

points = gp.GeoDataFrame( [['box', Point(1.5, 1.115), 4],
                        ['triangle', Point(2.5,1.25), 8]],
                     columns=['name', 'geometry', 'value'], 
                     geometry='geometry')

##Set a buffer around the points##

buf = points.buffer(0.5)
points['buffer'] = buf
points = points.drop(['geometry'], axis = 1) 
points = points.rename(columns = {'buffer': 'geometry'})

此数据如下所示: 我想做的是在点数据框中创建另一列,其中包括点相交的多边形数量。

我尝试过使用 for 循环:

points['intersect'] = []
for geo1 in points['geometry']:
    for geo2 in df['geometry']:
        if geo1.intersects(geo2):
            points['intersect'].append('1')

然后我将求和以获得相交的总数。 但是,我收到错误消息:“值的长度与索引的长度不匹配”。我知道这是因为它试图将三行数据分配给只有两行的框架。

如何聚合计数,以便为第一个点分配值 2,为第二个点分配值 1?

【问题讨论】:

    标签: python-3.x geopandas


    【解决方案1】:

    如果您有大型数据集,我会使用 rtree 空间索引来解决问题,就像这样。

    import pandas as pd
    import geopandas as gp
    from shapely.geometry import Polygon
    from shapely.geometry import Point
    import matplotlib.pyplot as plt
    
    ## Create polygons and points ##
    
    df = gp.GeoDataFrame([['a',Polygon([(1, 0), (1, 1), (2,2), (1,2)])],
                         ['b',Polygon([(1, 0.25), (2,1.25), (3,0.25)])]],
                         columns = ['name','geometry'])
    df = gp.GeoDataFrame(df, geometry = 'geometry')
    
    points = gp.GeoDataFrame( [['box', Point(1.5, 1.115), 4],
                            ['triangle', Point(2.5,1.25), 8]],
                         columns=['name', 'geometry', 'value'], 
                         geometry='geometry')
    
    # generate spatial index
    sindex = df.sindex
    # define empty list for results
    results_list = []
    # iterate over the points
    for index, row in points.iterrows():
        buffer = row['geometry'].buffer(0.5)  # buffer
        # find approximate matches with r-tree, then precise matches from those approximate ones
        possible_matches_index = list(sindex.intersection(buffer.bounds))
        possible_matches = df.iloc[possible_matches_index]
        precise_matches = possible_matches[possible_matches.intersects(buffer)]
        results_list.append(len(precise_matches))
    # add list of results as a new column
    points['polygons'] = pd.Series(results_list)
    

    【讨论】:

    • 太棒了!谢谢你。我是否认为这会加快进程,因为 possible_matches 搜索将排除大型数据集中的大量多边形?
    • 没错。如果你想解释一下这个geoffboeing.com/2016/10/r-tree-spatial-index-python
    • 太好了,我一定会的!再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 2014-02-01
    • 2019-03-18
    • 2012-03-13
    相关资源
    最近更新 更多