web-dev-qa-db-fra.com

Vérifier si le point géographique est à l'intérieur ou à l'extérieur du polygone en Python

J'utilise python et j'ai défini les latitudes et les longitudes (en degrés) d'un polygone sur la carte . Mon objectif est de vérifier si un point générique P de coordonnées x,y fait partie de ce polygone. J'aimerais donc avoir une fonction qui me permette de vérifier cette condition et de retourner True ou False si le point est à l'intérieur ou à l'extérieur du polygone.

 enter image description here

Dans cet exemple, le point est en dehors de sorte que le résultat serait False

Question: Existe-t-il une bibliothèque/package permettant d’atteindre mon objectif? si oui lequel recommandez-vous? Seriez-vous capable de donner un petit exemple sur la façon de l'utiliser?

Voici le code que j'ai écrit jusqu'à présent:

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 falls

Afin de tracer le polygone et le point d’intérêt, j’ai utilisé cartopy et j’ai écrit les lignes de code suivantes:

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()  

Remarque

  • les points sont reliés les uns aux autres par de grands cercles!
  • J'ai effectué des recherches sur Internet et j'ai fini par trouver des questions similaires comme celle-ci mais je n'ai pas eu de succès, car ils utilisent tous des fichiers .shp que je n'ai pas.
9
Federico Gentile

Voici une solution possible à mon problème.

  1. Les coordonnées géographiques doivent être correctement stockées. Exemple np.array([[Lon_A, Lat_A], [Lon_B, Lat_B], [Lon_C, Lat_C]])
  2. Créer le polygone
  3. Créer le point à tester
  4. Utilisez polygon.contains(point) pour vérifier si le point est à l'intérieur (True) ou à l'extérieur (False) du polygone.

Voici la partie manquante du 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 

Remarque : le polygone ne prend apparemment pas en compte les grands cycles. Il est donc nécessaire de scinder les arêtes en plusieurs segments, ce qui augmente le nombre de sommets. 

12
Federico Gentile

Une autre façon de le faire est d'utiliser l'algorithme pair-impair décrit dans ce lien https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html Le code python est donné dans wikipedia https://en.wikipedia.org/wiki/Even–odd_rule

N'oubliez pas, chers amis, que l'ORDRE DES POINTS qui fait que le polygone est IMPORTANT! Je veux dire, des résultats d'ordre différents dans des polygones différents.

3
lfvv