import numpy as np def dist_point_linestring(p, line_string): """ Compute distance between a point and a line_string (a.k.a. polyline) """ a = line_string[:-1, :] b = line_string[1:, :] return np.min(linesegment_distances(p, a, b)) # Function from https://stackoverflow.com/a/58781995/2609987 def linesegment_distances(p, a, b): """ Cartesian distance from point to line segment Edited to support arguments as series, from: https://stackoverflow.com/a/54442561/11208892 Args: - p: np.array of single point, shape (2,) or 2D array, shape (x, 2) - a: np.array of shape (x, 2) - b: np.array of shape (x, 2) """ # normalized tangent vectors d_ba = b - a d = np.divide(d_ba, (np.hypot(d_ba[:, 0], d_ba[:, 1]).reshape(-1, 1))) # signed parallel distance components # rowwise dot products of 2D vectors s = np.multiply(a - p, d).sum(axis=1) t = np.multiply(p - b, d).sum(axis=1) # clamped parallel distance h = np.maximum.reduce([s, t, np.zeros(len(s))]) # perpendicular distance component # rowwise cross products of 2D vectors d_pa = p - a c = d_pa[:, 0] * d[:, 1] - d_pa[:, 1] * d[:, 0] return np.hypot(h, c)