Проверьте, находится ли гео-точка внутри или вне полигона в Python

Я использую Python, и я определил широты и долготы (в градусах) многоугольника на карте. Моя цель - проверить x,y попадает ли общая точка P координат x,y в такой многоугольник. Поэтому я хотел бы иметь функцию, которая позволяет мне проверять такое условие и возвращать True или False если точка находится внутри или снаружи многоугольника.

enter image description here

В этом примере точка находится снаружи, поэтому результатом будет 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

Чтобы нарисовать многоугольник и интересную точку, я использовал 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()  

Примечание:

  • точки связаны друг с другом Великими кругами!
  • Я исследовал этот вопрос, и в итоге я нашел несколько похожих вопросов, таких как этот, но я не добился успеха, поскольку все они используют файлы .shp которых у меня нет.

Ответ 1

Вот возможное решение моей проблемы.

  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 

Примечание: многоугольник не учитывает, по-видимому, большие циклы, поэтому необходимо разбить края на многие сегменты, увеличив тем самым число вершин.

Ответ 2

Другой способ сделать это - использовать четный алгоритм, описанный в этой ссылке https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html Код python приведен в wikipedia https://ru. wikipedia.org/wiki/Even-odd_rule

Люди, просто помните, что ПОРЯДОК ОЧКОВ, которые делают многоугольник MATTER! Я имею в виду, что другой порядок приводит к разным полигонам.