我有两个数据帧。一个具有建筑物的多边形(大约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
识别出该点在多边形中。所有建议做什么都表示赞赏!谢谢。
答案 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