如何按特定折线对点进行分类
How to classify the points by a specific polylline
中国境内有一条分界线,将地区划分为南北。我已将此边界绘制为折线格式 shapefile Download link。
我想把下图中的那些点分成"North"和"South"。 Python中有没有什么有用的函数可以实现这个。
fiona 有 point.within 测试点 within/out 多边形的功能,但我没有搜索过用折线划分多个点的合适函数。
如有任何建议或提示,我们将不胜感激!
已更新
根据Prune提出的宝贵建议,我完成了。代码提供如下:
from shapely.geometry import shape
from shapely.geometry import LineString
# loading the boundary layer
import fiona
fname = './N-S_boundary.shp'
line1 = fiona.open(fname)
line1 = shape(line1.next()['geometry'])
# set a end point which is the southernmost for all stations.
end_point = (dy[dy['lat']==dy['lat'].min()]['lon'].values[0],dy[dy['lat']==dy['lat'].min()]['lat'].values[0])
# loop all monitoring stations for classification
dy['NS']= np.nan
for i in range(0,len(dy),1):
start_point = (dy['lon'].iloc[i],dy['lat'].iloc[i])
line2 = LineString([start_point, end_point])
if line1.intersection(line2).is_empty:
dy["NS"].iloc[i]='S'
else:
dy["NS"].iloc[i]='N'
color_dict= {'N':'steelblue','S':'r'}
dy['site_color']=dy['NS'].map(color_dict)
您可以从拓扑中应用一个简单的 属性。
首先,确保您的边界划分了宇宙(您正在处理的所有可用点)。您可能需要将边界延伸到海洋才能完成此操作。
现在,选择任何标记为该区域的参考点——要定义 "North" 和 "South",您必须至少有一个这样的点。 w.l.o.g。假设它是一个名为 Z
.
的 "South" 点
现在,对于每个要 class 化的点 A
,绘制一条从 A
到 Z
。找到这条路径与边界的交点。如果你有偶数个交叉点,那么 A
和 Z
在同一个 class ("South");否则,它在另一个 class ("North").
请注意,这需要 "partition" 的拓扑 属性 -- 边界线没有切线:如果您的路径接触到边界,则它必须完全交叉。
中国境内有一条分界线,将地区划分为南北。我已将此边界绘制为折线格式 shapefile Download link。
我想把下图中的那些点分成"North"和"South"。 Python中有没有什么有用的函数可以实现这个。
fiona 有 point.within 测试点 within/out 多边形的功能,但我没有搜索过用折线划分多个点的合适函数。
如有任何建议或提示,我们将不胜感激!
已更新
根据Prune提出的宝贵建议,我完成了。代码提供如下:
from shapely.geometry import shape
from shapely.geometry import LineString
# loading the boundary layer
import fiona
fname = './N-S_boundary.shp'
line1 = fiona.open(fname)
line1 = shape(line1.next()['geometry'])
# set a end point which is the southernmost for all stations.
end_point = (dy[dy['lat']==dy['lat'].min()]['lon'].values[0],dy[dy['lat']==dy['lat'].min()]['lat'].values[0])
# loop all monitoring stations for classification
dy['NS']= np.nan
for i in range(0,len(dy),1):
start_point = (dy['lon'].iloc[i],dy['lat'].iloc[i])
line2 = LineString([start_point, end_point])
if line1.intersection(line2).is_empty:
dy["NS"].iloc[i]='S'
else:
dy["NS"].iloc[i]='N'
color_dict= {'N':'steelblue','S':'r'}
dy['site_color']=dy['NS'].map(color_dict)
您可以从拓扑中应用一个简单的 属性。
首先,确保您的边界划分了宇宙(您正在处理的所有可用点)。您可能需要将边界延伸到海洋才能完成此操作。
现在,选择任何标记为该区域的参考点——要定义 "North" 和 "South",您必须至少有一个这样的点。 w.l.o.g。假设它是一个名为 Z
.
现在,对于每个要 class 化的点 A
,绘制一条从 A
到 Z
。找到这条路径与边界的交点。如果你有偶数个交叉点,那么 A
和 Z
在同一个 class ("South");否则,它在另一个 class ("North").
请注意,这需要 "partition" 的拓扑 属性 -- 边界线没有切线:如果您的路径接触到边界,则它必须完全交叉。