def in_polygon(xpts, ypts, x_poly, y_poly, lib='mpl'): """ Find points inside an arbitraty polygon. Given coordinates of 2D space (`xpts`, `ypts`), returns a boolean array of the same size as `xpts` and `ypts` where True values indicate coordinates inside the polygon defined by (`x_poly`, `y_poly`). Setting the `lib` parameter chooses to use tools from matplotlib.path or shapely. Parameters ---------- xpts, ypts : array_like Input coordinates. x_poly, y_poly: array_like Polygon coordinates. lib : str Library to use ('mpl' or 'shp') Returns ------- boolean array True for points inside polygon. """ if lib == 'shp': # Polygon border poly = Polygon([(xp, yp) for (xp, yp) in zip(x_poly, y_poly)]) # Bool vector boolean = [ poly.contains(Point(x_pt, y_pt)) for (x_pt, y_pt) in zip(xpts, ypts) ] else: # Set up input pts = np.array([xpts, ypts]).T poly = mpltPath.Path([[xp, yp] for (xp, yp) in zip(x_poly, y_poly)]) # Bool vector boolean = poly.contains_points(pts) return boolean
#open zip code file pin_idx = {} r = shp.Reader(plz) print('Assigning coordinates to pin codes...') for n,s in tqdm(enumerate(r.shapeRecords())): pin = r.record(n)['plz'] poly = Polygon(s.shape.points) x_i,y_i,x_j,y_j = poly.bounds start = np.logical_and(np.greater_equal(points[:,0],x_i),np.less_equal(points[:,1], y_j)) end = np.logical_and(np.less_equal(points[:,0],x_j),np.greater_equal(points[:,1], y_i)) bidx = np.logical_and(start,end) poly = Path(s.shape.points) idx = poly.contains_points(points[bidx]) if pin in pin_idx.keys(): pin_idx[pin] += [*list(index[bidx][idx])] else: pin_idx[pin] = list(index[bidx][idx]) r.close() #save state w = shp.Writer('plz_nodes') w.fields = [('plz','N',8,0)] for pin,idx in pin_idx.items(): for i in idx: w.point(*points[i])