Python 检查地理点是在多边形内部还是外部
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43892459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check if geo-point is inside or outside of polygon
提问by Federico Gentile
I am using python and I have defined the latitudes and longitudes (in degrees) of a polygon on the map.
My goal is to check if a generic point P
of coordinates x,y
falls within such polygon. I would like therefore to have a function that allows me to check such condition and return True
or False
if the point is inside or outside the polygon.
我正在使用 python 并且我已经定义了地图上多边形的纬度和经度(以度为单位)。我的目标是检查通用P
坐标点是否x,y
落在这样的多边形内。因此,我希望有一个函数可以让我检查这种条件并返回,True
或者False
该点是否在多边形内部或外部。
In this example the point is outside so the result would be False
在这个例子中,点在外面,所以结果是 False
Question: Is there a library/package that allows to reach my goal? if yes which one do you recommend? would you be able to give a small example on how to use it?
问题:是否有一个库/包可以实现我的目标?如果是,你推荐哪一个?你能举一个关于如何使用它的小例子吗?
Here is the code I have written so far:
这是我到目前为止编写的代码:
import numpy as np
# Define vertices of polygon (lat/lon)
v0 = [7.5, -2.5]
v1 = [2, 3.5]
v2 = [-2, 4]
v3 = [-5.5, -4]
v4 = [0, -10]
lats_vect = np.array([v0[0],v1[0],v2[0],v3[0],v4[0]])
lons_vect = np.array([v0[1],v1[1],v2[1],v3[1],v4[1]])
# Point of interest P
x, y = -6, 5 # x = Lat, y = Lon
## START MODIFYING FROM HERE; DO NOT MODIFY POLYGON VERTICES AND DATA TYPE
# Check if point of interest falls within polygon boundaries
# If yes, return True
# If no, return False
In order to plot the polygon and the point of interest I used cartopy and I wrote the following lines of code:
为了绘制多边形和兴趣点,我使用了 cartopy 并编写了以下代码行:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.PlateCarree())
ax.stock_img()
# Append first vertex to end of vector to close polygon when plotting
lats_vect = np.append(lats_vect, lats_vect[0])
lons_vect = np.append(lons_vect, lons_vect[0])
plt.plot([lons_vect[0:-1], lons_vect[1:]], [lats_vect[0:-1], lats_vect[1:]],
color='black', linewidth=1,
transform=ccrs.Geodetic(),
)
plt.plot(y, x,
'*', # marker shape
color='blue', # marker colour
markersize=8 # marker size
)
plt.show()
Note:
注意:
- points are connected to each other by Great Circles!
- I have researched in the internt and I ended up finding some similar questions like this onebut I had no success since they all use of
.shp
files which I do not have.
- 点通过大圆圈相互连接!
- 我研究的Internt的,我最终找到了一些类似的问题像这样的,但我没有成功,因为它们都使用的
.shp
是我没有的文件。
回答by Federico Gentile
Here is a possible solution to my problem.
这是我的问题的可能解决方案。
- Geographical coordinates must be stored properly. Example
np.array([[Lon_A, Lat_A], [Lon_B, Lat_B], [Lon_C, Lat_C]])
- Create the polygon
- Create the point to be tested
- Use
polygon.contains(point)
to test if point is inside (True
) or outside (False
) the polygon.
- 必须正确存储地理坐标。例子
np.array([[Lon_A, Lat_A], [Lon_B, Lat_B], [Lon_C, Lat_C]])
- 创建多边形
- 创建要测试的点
- 使用
polygon.contains(point)
如果点在内部测试(True
)或外部(False
)的多边形。
Here is the missing part of the code:
这是代码的缺失部分:
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
lons_lats_vect = np.column_stack((lons_vect, lats_vect)) # Reshape coordinates
polygon = Polygon(lons_lats_vect) # create polygon
point = Point(y,x) # create point
print(polygon.contains(point)) # check if polygon contains point
print(point.within(polygon)) # check if a point is in the polygon
Note: the polygon does not take into account great cycles apparently, therefore it is necessary to split the edges into many segments thus increasing the number of vertices.
注意:多边形显然没有考虑大循环,因此需要将边分成许多段从而增加顶点数。
Special case: If point lies on borders of Polygon特殊情况:如果点位于多边形的边界上
E.g. print(Polygon([(0, 0), (1, 0), (1, 1)]).contains(Point(0, 0)))
will fail
例如print(Polygon([(0, 0), (1, 0), (1, 1)]).contains(Point(0, 0)))
会失败
So one can use
所以可以使用
print(polygon.touches(point)) # check if point lies on border of polygon
回答by lfvv
Another way to do it is by using the even-odd algorithm explained in this link https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.htmlThe python code is given in wikipedia https://en.wikipedia.org/wiki/Even–odd_rule
另一种方法是使用此链接中解释的奇偶算法https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html维基百科https://en 中给出了 python 代码。 wikipedia.org/wiki/Even–odd_rule
Folks, just remember that the ORDER OF POINTS that make the polygon MATTER! I mean, different order results in different polygons.
伙计们,请记住使多边形变得重要的点顺序!我的意思是,不同的顺序会导致不同的多边形。