我有几个多边形,它们实际上是点的联合。我想要一种相当快速的方法来删除不是陆地的点(但在河流、湖泊、海洋等)。
所以到目前为止,我已经想出了以下方法,它将我从左图带到右图:
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])
我使用三个适合我的目的的形状文件(湖泊有点粗糙):海岸、湖泊、小湖。
但是,对于 10,000 点,代码有点慢(我有大约 30 个文件,所以要检查 300,000 点)。
我想知道以下任何一项是否可能:
1) 我正在循环遍历形状并检查 shape.contains(point) 而不是遍历点并检查 point.within(shape) -> 我不确定是否会有改进?
2)使用空间索引可能会加快速度,但我认为 RTree 不再适用于 Python 3.4
3)也许有一个更快的功能(粗略的包含),它只检查边界,我可以将它用作第一步,然后包含作为步骤 2。
4)不是循环通过点,有没有办法一次矢量化和传递?
5)也许将形状优美的多边形转换为路径会更快,以便我可以使用matpotlib的path.contains_point?
6)最后,我意识到我可能应该使用墨卡托投影作为多边形测试中的点,但粗剪对我来说很好(它不像水形状文件那样超级准确)。
谢谢