公交站点方向的计算
# coding:utf-8 import numpy as np import logging logging.basicConfig(level=logging.WARNING, format='%(asctime)s-%(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s', datefmt='%Y-%m-%d %H:%M:%S') from shapely.ops import split, nearest_points, snap from shapely.geometry import LineString, Point class vectorAngle(): def vecAttr(self, x, y): # 判断点所在的象限 # N # W O E # S ref = 0. if x == ref: if y == ref: res = 'OO' elif y > ref: res = 'ON' else: res = 'OS' elif x > ref: if y == ref: res = 'OE' elif y > ref: res = 'EN' else: res = "ES" else: if y == ref: res = "OW" elif y > ref: res = "WN" else: res = "WS" return res def vecAngle(self, x, y): flag = self.vecAttr(x, y) if flag == "OO": angle = 0. elif flag == "OE": angle = 0. elif flag == "EN": angle = np.arctan(y/x) elif flag == "ON": angle = np.pi / 2 elif flag == "WN": angle = np.pi - np.arctan(abs(y/x)) elif flag == "OW": angle = np.pi elif flag == "WS": angle = np.pi + np.arctan(abs(y/x)) elif flag == "OS": angle = np.pi * 1.5 else: angle = np.pi * 2.0 - np.arctan(abs(y/x)) return round(angle, 3) class stopAngle(vectorAngle): # func 用于计算站点的方向 def __init__(self, busline): # busline, 公交线路描点 dtype = busline.__class__ if dtype is list: self.line = LineString(busline) elif dtype is LineString: self.line = busline else: logging.warning(f"busline coords error:{busline}") def splitLine(self, stop): # 在站点处打断公交线路 # para: stop -> Point() p1, pr = nearest_points(self.line, stop) line_ = snap(self.line, p1, 0.0001) l1, l2 = split(line_, p1) return l1, l2 def stopAngle(self, stop): # 获取站点的方向 p1, pr = nearest_points(self.line, stop) line_ = snap(self.line, p1, 0.0001) l1, l2 = split(line_, p1) pline = line_.intersection(p1.buffer(0.1)) vec = np.array(pline.coords[-1]) - np.array(pline.coords[0]) angle = self.vecAngle(vec[0], vec[1]) if 0 <= angle <= np.pi/4: prompt = "ED" elif np.pi/4 < angle <= 3*np.pi/4: prompt = "NU" elif 3*np.pi/4 < angle <= 5*np.pi/4: prompt = "WU" elif 5*np.pi/4 < angle <= 7*np.pi/4: prompt = "SD"
else:
prompt = "ED"
return prompt if __name__ == "__main__": line = LineString(([0, 0], [2, 0], [2, 2], [0, 2], [0, 0])) pnts = [[1,0.0], [2,0], [1,2.1], [0.1,1]] stops = [Point(_)for _ in pnts] obj = stopAngle(line) for stop in stops: flag = obj.stopAngle(stop) logging.warning(flag)