简体   繁体   English

geopandas 无法识别多边形中的点

[英]geopandas not recognizing point in polygon

I have two data frames.我有两个数据框。 One has polygons of buildings (around 70K) and the other has points that may or not be inside the polygons (around 100K).一个具有建筑物的多边形(大约 70K),另一个具有可能位于或不在多边形内的点(大约 100K)。 I need to identify if a point is inside a polygon or not.我需要确定一个点是否在多边形内。

When I plot both dataframes (example below), the plot shows that some points are inside the polygons and other are not.当我绘制两个数据框(下面的示例)时,该图显示某些点在多边形内,而其他点不在多边形内。 However, when I use .within(), the outcome says none of the points are inside polygons.但是,当我使用 .within() 时,结果表明没有任何点在多边形内。

I recreated the example creating one polygon and one point "by hand" rather than importing the data and in this case .within() does recognize that the point is in the polygon.我重新创建了“手动”创建一个多边形和一个点的示例,而不是导入数据,在这种情况下,.within() 确实识别出该点在多边形中。 Therefore, I assume I'm making a mistake but I don't know where.因此,我认为我犯了一个错误,但我不知道在哪里。

Example: (I'll just post the part that corresponds to one point and one polygon for simplicity. In this case, each data frame contains either a single point or a single polygon)示例:(为简单起见,我将只发布对应于一个点和一个多边形的部分。在这种情况下,每个数据框包含一个点或一个多边形)

1) Using the imported data. 1) 使用导入的数据。 The data frame dmR has the points and the data frame dmf has the polygon数据框 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')

The outcome shows that the point is inside the polygon .结果显示该点在多边形内 However,然而,

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

2) If I try to recreate this by hand, it would be as follows (there may be a better way to do this but I couldn't figure it out): 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')

In this case, the outcome also shows the point in the polygon .在这种情况下,结果还显示了多边形中的点 However,然而,

ex_p.within(ex)
0    True
dtype: bool

which recognize that the point is in the polygon.它识别出该点在多边形中。 All suggestions on what to do are appreciated!感谢所有关于做什么的建议! Thanks.谢谢。

I don't know if this is the most efficient way to do it but I was able to do what I needed within Python and using Geopandas.我不知道这是否是最有效的方法,但我能够在 Python 中并使用 Geopandas 做我需要的事情。

Instead of using point.within(polygon) approach, I did a spatial join ( geopandas.sjoin(df_1, df_2, how = 'inner', op = 'contains') ) This results in a new data frame that contains the points that are within polygons and excludes the ones that are not.我没有使用point.within(polygon)方法,而是进行了空间连接( geopandas.sjoin(df_1, df_2, how = 'inner', op = 'contains') )这会产生一个包含点的新数据框位于多边形内并排除不在多边形内的多边形。 More information on how to do this can be found here .可以在此处找到有关如何执行此操作的更多信息。

I assume something is fishy about your coordinate reference system (crs).我认为您的坐标参考系统(crs)有些可疑。 I cannot tell about dmr as it is not provided but ex_p is a naive geometry as you generated it from points without specifying the crs.我不能告诉dmr因为它没有提供,但ex_p是一个简单的几何体,因为你从点生成它而不指定 crs。 You can check the crs using:您可以使用以下方法检查 crs:

dmr.crs

Let's assume it's in 4326, then it will return:让我们假设它在 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

In this case you would need to set a CRS for ex_p first using:在这种情况下,您需要首先使用以下命令为ex_p设置 CRS:

ex_p = ex_p.set_crs(epsg=4326)

If you want to inherit the crs of dmr dynamically you can also use:如果你想动态继承dmr的 crs 你也可以使用:

ex_p = ex_p.set_crs(dmr.crs)

After you set a crs, you can re-project from one crs to another using:设置 crs 后,您可以使用以下命令从一个 crs 重新投影到另一个 crs:

ex_p = ex_p.to_crs(epsg=3395)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM