web-dev-qa-db-ja.com

ジオポイントがポリゴンの内側か外側かを確認します

pythonを使用しており、地図上のポリゴンの緯度と経度(度)を定義しています。私の目標は、座標の汎用ポイント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
_

ポリゴンと関心のあるポイントをプロットするために、カートピーを使用し、次のコード行を作成しました。

_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_ファイルをすべて使用しているので成功しませんでした。
17

ここに私の問題の可能な解決策があります。

  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 

:ポリゴンは明らかに大きなサイクルを考慮していないため、エッジを多くのセグメントに分割して、頂点の数を増やす必要があります。

16

別の方法は、このリンクで説明されている偶奇アルゴリズムを使用することです https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html The pythonコードはウィキペディアで提供されています https://en.wikipedia.org/wiki/Even–odd_rule

皆さん、ポリゴンを重要にするポイントの順序を覚えておいてください!つまり、順序が異なると多角形も異なります。

5
lfvv