実際にはポイントの結合であるポリゴンがいくつかあります。土地ではないポイント (ただし、川、湖、海など) を合理的に迅速に削除する方法が必要です。
だから私はこれまでのところ、左の写真から右の写真に移動する以下の方法を思いつきました:
import fiona
from shapely.geometry import Point, shape
# Shape files (Small Lakes Europe, Lakes, Coast)
le_loc = ".../water-polygons-split-4326/ne_10m_lakes_europe.shp"
lw_loc = ".../water-polygons-split-4326/ne_10m_lakes.shp"
c_loc = ".../water-polygons-split-4326/water_polygons.shp"
print("Opening Shape-Files")
le_poly = [shape(pol['geometry']) for pol in fiona.open(le_loc)]
lw_poly = [shape(pol['geometry']) for pol in fiona.open(lw_loc)]
c_poly = [shape(pol['geometry']) for pol in fiona.open(c_loc)]
def point_in_water(lat, lon):
xy_point = Point(lon, lat)
for one in [c_poly, lw_poly, le_poly]:
for shape in one:
if shape.contains(xy_point):
return True
return False
# Test (true)
print(point_in_water(46.268408, 6.180437))
次に、ループでポイントをテストします。
with open(in_csv) as f:
for x in csv.reader(f):
# Lat, Lng, Mins, Mode
if not point_in_water(float(x[0]), float(x[1])):
coords.append([x[0], x[1])
私の目的には問題ない 3 つのシェープ ファイルを使用します (湖のファイルは少し粗いです): coast、lakes、small lakes。
ただし、10,000 ポイントの場合、コードは少し遅くなります (約 30 個のファイルがあるため、300,000 ポイントを調べる必要があります)。
次のいずれかが可能かどうか疑問に思っていました。
1) ポイントをループして point.within(shape) をチェックする代わりに、シェイプをループして shape.contains(point) をチェックしています -> 改善があるかどうかわかりませんでしたか?
2)空間インデックスを使用するとおそらくこれが高速化されますが、RTree は Python 3.4 では動作しないと思います
3) おそらく、境界をチェックするだけのより高速な関数 (ラフを含む) があり、それをステップ 1 として使用し、次にステップ 2 として含むことができます。
4) ポイントをループする代わりに、ベクトル化して一度に渡す方法はありますか?
5) matpotlib の path.contains_point を使用できるように、形状の良いポリゴンをパスに変換する方が速いのではないでしょうか?
6) 最後に、ポイント イン ポリゴン テストにメルカトル図法を使用する必要があることに気付きましたが、私にはラフ カットで問題ありません (いずれにせよ、水のシェープファイルが非常に正確であるとは言えません)。
ありがとうございました