GeoPandas:检查点是否在多边形中

时间:2019-10-22 22:32:16

标签: python pandas geometry geopandas

我搜索了问题,发现了这个question与我的问题不同。

我有两个地理数据框,一个包含points(约700个点)的房屋位置,另一个包含suburbs names及其polygon(约2973个多边形)。我想将每个点链接到一个多边形,以将每个房屋分配给正确的郊区。

我的地理数据框示例

ploygon

import geopandas as gpd
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon

#creating geo series
polys = gpd.GeoSeries({
    '6672': Polygon([(142.92288, -37.97886,), (141.74552, -35.07202), (141.74748, -35.06367)]),
    '6372': Polygon([(148.66850, -37.40622), (148.66883, -37.40609), (148.66920, -37.40605)]),
})

#creating geo dataframe
polysgdf = gpd.GeoDataFrame(geometry=gpd.GeoSeries(polys))
polysgdf

产生以下内容(我的原始地理数据框还包含一个suburb列,其中包含郊区名称,但我无法将其添加到示例中,您只能在下面看到该郊区ID)

        geometry
6672    POLYGON ((142.92288 -37.97886, 141.74552 -35.07202, 141.74748 -35.06367, 142.92288 -37.97886))
6372    POLYGON ((148.66850 -37.40622, 148.66883 -37.40609, 148.66920 -37.40605, 148.66850 -37.40622))

点地理数据框样本

points=[Point(145.103,-37.792), Point(145.09720, -37.86400), 
        Point(145.02190, -37.85450)]

pointsDF = gpd.GeoDataFrame(geometry=points,
                                  index=['house1_ID', 'house2_ID', 'house3_ID'])

pointsDF

产生以下内容

            geometry
house1_ID   POINT (145.10300 -37.79200)
house2_ID   POINT (145.09720 -37.86400)
house3_ID   POINT (145.02190 -37.85450)

我希望最终输出为pointsDF地理数据框,并将每栋房屋分配给相应的郊区。作为点和多边形匹配的结果。

示例:

suburbID subrubName    house_ID
6672      south apple  house1_ID
6372      water garden house2_ID

我是GeoPandas的新手,我试图以最清晰的方式解释我的问题。我很高兴澄清任何一点。 谢谢。

2 个答案:

答案 0 :(得分:0)

通过.contains函数使用shapely的多边形点分析,如下所示。

import geopandas as gpd
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon

polys = gpd.GeoSeries({
    '6672': Polygon([(0, 0), (0, 1), (1, 0)]),
    '6372': Polygon([(0, 1), (1, 1), (1, 0)]),
})

#creating geo dataframe
polysgdf = gpd.GeoDataFrame(geometry=gpd.GeoSeries(polys))
polysgdf
Out[48]: 
                            geometry
6672  POLYGON ((0 0, 0 1, 1 0, 0 0))
6372  POLYGON ((0 1, 1 1, 1 0, 0 1))

points=[Point(0.25,0.25), Point(0.75,0.75), 
        Point(145.02190, -37.85450)]

pointsDF = gpd.GeoDataFrame(geometry=points,
                                  index=['house1_ID', 'house2_ID', 'house3_ID'])

pointsDF
Out[49]: 
                            geometry
house1_ID          POINT (0.25 0.25)
house2_ID          POINT (0.75 0.75)
house3_ID  POINT (145.0219 -37.8545)

polysgdf['house_ID'] = ''
for i in range(0,len(pointsDF)):
    print('Check for house '+str(pointsDF.index.values.astype(str)[i]))
    for j in range(0,len(polysgdf)):
        print('Check for suburb '+str(polysgdf.index.values.astype(str)[j]))
        if polysgdf['geometry'][j].contains(pointsDF['geometry'][i]) == True:
            polysgdf['house_ID'][j] = pointsDF.index.values.astype(str)[i]

print(polysgdf)
                            geometry   house_ID
6672  POLYGON ((0 0, 0 1, 1 0, 0 0))  house1_ID
6372  POLYGON ((0 1, 1 1, 1 0, 0 1))  house2_ID

答案 1 :(得分:0)

我找到了一种方法,可以使用a spatial join

连接两个数据帧
joinDF=gpd.sjoin(pointsDF, polysgdf, how='left',op="within")