【问题标题】:Link each point in one GeoPandas dataframe to polygons in another dataframe将一个 GeoPandas 数据框中的每个点链接到另一个数据框中的多边形
【发布时间】:2020-02-19 03:02:15
【问题描述】:

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

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

我的地理数据框示例

多边形

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 的新手,我试图以最清晰的方式解释我的问题。我很高兴澄清任何一点。 谢谢。

【问题讨论】:

标签: python geometry geopandas


【解决方案1】:

我找到了一种方法来实现这一点,方法是使用a spatial join 连接两个数据框

joinDF=gpd.sjoin(pointsDF, polysgdf, how='left',op="within")

【讨论】:

  • 谢谢,我必须单独安装“pygeos”模块并在创建两个geoDataFrame之前设置选项“gpd.options.use_pygeos=True”,之后工作正常。更干净更简单
【解决方案2】:

使用 shapely 的 Point-in-Polygon 分析使用 .contains 函数,如下所示。

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

【讨论】:

  • 谢谢 Debjit。但是此代码不会返回所需的输出。但是,我能够对其进行修改。再次感谢。
猜你喜欢
  • 2020-01-30
  • 2021-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 2018-10-01
相关资源
最近更新 更多