地理熊猫无法识别多边形中的点

时间:2020-02-20 20:59:46

标签: python polygon point geopandas

我有两个数据帧。一个具有建筑物的多边形(大约70K),另一个具有可能在多边形内部或不在其内部的点(大约100K)。我需要确定一个点是否在多边形内。

当我绘制两个数据框时(如下例所示),该图表明某些点在多边形内,而另一些则不在。但是,当我使用.within()时,结果表明所有点都不在多边形内部。

我重新创建了一个示例,即“手动”创建一个多边形和一个点,而不是导入数据,在这种情况下,.within()确实识别出该点在多边形中。因此,我认为自己犯了一个错误,但是我不知道在哪里。

示例:(为简单起见,我将只发布对应于一个点和一个多边形的部分。在这种情况下,每个数据框都包含一个点或单个多边形)

1)使用导入的数据。数据框dmR具有点,数据框dmf具有多边形

import pandas as pd
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
from shapely import wkt
from shapely.geometry import Point, Polygon
plt.style.use("seaborn")

# I'm skipping the data manipulation stage and 
# going to the point where the data are used.

print(dmR)

               geometry
35  POINT (-95.75207 29.76047)

print(dmf)
               geometry
41964  POLYGON ((-95.75233 29.76061, -95.75194 29.760...

# Plot
fig, ax = plt.subplots(figsize=(5,5))
minx, miny, maxx, maxy = ([-95.7525, 29.7603, -95.7515, 29.761])
ax.set_xlim(minx, maxx)
ax.set_ylim(miny, maxy)
dmR.plot(ax=ax, c='Red')
dmf.plot(ax=ax, alpha=0.5)
plt.savefig('imported_data.png')

结果 shows that the point is inside the polygon。但是,

print(dmR.within(dmf))
35       False
41964    False
dtype: bool

2)如果我尝试手动重新创建,则如下所示(可能有更好的方法来执行此操作,但我无法弄清楚):

# Get the vertices of the polygon to create it by hand
poly1 = dmf['geometry']
g = [i for i in poly1]
x,y = g[0].exterior.coords.xy
x,y

(array('d', [-95.752332508564, -95.75193554162979, -95.75193151831627, -95.75232848525047, -95.752332508564]),
 array('d', [29.760606530637265, 29.760607694859385, 29.76044470363038, 29.76044237518235, 29.760606530637265]))

# Create the polygon by hand using the corresponding vertices
coords = [(-95.752332508564, 29.760606530637265),
          (-95.75193554162979, 29.760607694859385),
          (-95.75193151831627, 29.7604447036303),
          (-95.75232848525047, 29.76044237518235),
         (-95.752332508564, 29.760606530637265)]
poly = Polygon(coords)

# Create point by hand (just copy the point from 1) above
p1 = Point(-95.75207, 29.76047)

# Create the GeoPandas data frames from the point and polygon
ex = gpd.GeoDataFrame()
ex['geometry']=[poly]
ex = ex.set_geometry('geometry')
ex_p = gpd.GeoDataFrame()
ex_p['geometry'] = [p1]
ex_p = ex_p.set_geometry('geometry')

# Plot and print
fig, ax = plt.subplots(figsize=(5,5))
ax.set_xlim(minx, maxx)
ax.set_ylim(miny, maxy)
ex_p.plot(ax=ax, c='Red')
ex.plot(ax = ax, alpha=0.5)
plt.savefig('by_hand.png')

在这种情况下,结果为also shows the point in the polygon。但是,

ex_p.within(ex)
0    True
dtype: bool

识别出该点在多边形中。所有建议做什么都表示赞赏!谢谢。

2 个答案:

答案 0 :(得分:0)

我不知道这是否是最有效的方法,但我能够在Python和使用Geopandas中完成所需的工作。

我没有使用point.within(polygon)方法,而是进行了空间连接(geopandas.sjoin(df_1, df_2, how = 'inner', op = 'contains')),这将产生一个新的数据框,其中包含多边形内的点,而排除了不在多边形内的点。有关如何执行此操作的更多信息,请参见here

答案 1 :(得分:0)

我认为您的坐标参考系统(crs)有点麻烦。我无法说出dmr,因为它没有提供,但是ex_p是一个幼稚的几何体,因为您是从点中生成的而未指定crs。您可以使用以下方法检查crs:

dmr.crs

假设它在4326中,那么它将返回:

<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

在这种情况下,您首先需要使用以下命令为ex_p设置CRS:

ex_p = ex_p.set_crs(epsg=4326)

如果您想动态继承dmr的crs,也可以使用:

ex_p = ex_p.set_crs(dmr.crs)

设置crs后,您可以使用以下方法将一个crs重新投影到另一个crs:

ex_p = ex_p.to_crs(epsg=3395)

有关该主题的更多信息: https://geopandas.org/projections.html

相关问题