检查地理点是否在Python的多边形内部或外部

Fed*_*ile 20 python polygon coordinate-systems point-in-polygon shapely

我正在使用python,我已经定义了地图上多边形的纬度和经度(以度为单位).我的目标是检查一般P坐标点是否x,y落在这样的多边形内.因此,我希望有一个功能,允许我检查这种情况并返回True或者False如果该点在多边形内部或外部.

在此输入图像描述

在这个例子中,点在外面,结果就是 False

问题:是否有允许达到目标的库/包?如果是,你推荐哪一个?你能给出一个如何使用它的小例子吗?

这是我到目前为止编写的代码:

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
Run Code Online (Sandbox Code Playgroud)

为了绘制多边形和兴趣点,我使用了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()  
Run Code Online (Sandbox Code Playgroud)

注意:

  • 大圆圈相互连接点!
  • 我研究的Internt的,我最终找到了一些类似的问题像这样的,但我没有成功,因为它们都使用的.shp是我没有的文件.

Fed*_*ile 20

这是我的问题的可能解决方案.

  1. 必须正确存储地理坐标.例np.array([[Lon_A, Lat_A], [Lon_B, Lat_B], [Lon_C, Lat_C]])
  2. 创建多边形
  3. 创建要测试的点
  4. 使用polygon.contains(point)测试如果点在内部(True)或外部(False)的多边形.

这是代码中缺少的部分:

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 
Run Code Online (Sandbox Code Playgroud)

注意:多边形显然没有考虑很大的周期,因此有必要将边缘分成许多段,从而增加顶点的数量.

  • 最好先写纬度,后写经度。这里的逻辑没有任何问题,但为了安全起见,总比后悔好。 (2认同)

小智 19

还有一个新兴的 python 库turfpy。用于地理空间分析。

PyPI

GitHub

例子:

from turfpy.measurement import boolean_point_in_polygon
from geojson import Point, Polygon, Feature

point = Feature(geometry=Point((-46.6318, -23.5523)))
polygon = Polygon(
    [
        [
            (-46.653, -23.543),
            (-46.634, -23.5346),
            (-46.613, -23.543),
            (-46.614, -23.559),
            (-46.631, -23.567),
            (-46.653, -23.560),
            (-46.653, -23.543),
        ]
    ]
)
boolean_point_in_polygon(point, polygon)
Run Code Online (Sandbox Code Playgroud)


lfv*_*fvv 5

另一种方法是使用此链接中说明的偶数算法https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html python代码在Wikipedia https:// zh- CN中给出。 wikipedia.org/wiki/Even–odd_rule

伙计们,只要记住使多边形变得重要的ORDER OF POINTS!我的意思是,不同的顺序会导致不同的多边形。


BBD*_*Sys 5

您可以使用 pygeodesy 包,它不依赖于系统级地理包,并且它使用 Kenneth Gade 的 n 向量方法,

https://github.com/mrJean1/PyGeodesy

只是pip install pygeodesy

示例代码

from pygeodesy.sphericalNvector import LatLon

p = LatLon(45.1, 1.1)
b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
print (p.isenclosedBy(b))
Run Code Online (Sandbox Code Playgroud)

这应该输出True