pythongisshapefileshapelyfiona

How to classify the points by a specific polylline


There is a boundary inside China, which divide the region as North-South. I have drawn this boundary as a polyline format shapefile Download link.

I want to divide those points in the following figures into "North" and "South". Is there any useful function in Python can achieve this.

fiona has point.within function to test points within/out a polygon, but I have not searched a suitable function to divide multiple points by polyline.

Any advices or tips would be appreciated!

enter image description here

updated

According to the valuable suggestion made by Prune, I worked it out. The codes are provided as follows:

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)   

enter image description here


Solution

  • You can apply a simple property from topology.

    First, make sure that your boundary partitions the universe (all available points you're dealing with). You may need to extend the boundary through the ocean to finish this.

    Now, pick any reference point that is labeled as to the region -- to define "North" and "South", you must have at least one such point. w.l.o.g. assume it's a "South" point called Z.

    Now, for each point A you want to classify, draw a continuous path (a straight one is usually easiest, but not required) from A to Z. Find the intersections of this path with the boundary. If you have an even quantity of intersections, then A is in the same class ("South") as Z; other wise, it's in the other class ("North").

    Note that this requires a topological property of "partition" -- there are no tangents to the boundary line: if your path touches the boundary, it must cross completely.