公交站点方向的计算

# 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"
        else:
            prompt = "SD"
        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)

 

公交站点方向的计算

上一篇:android ActionBar 去掉menu分隔线


下一篇:Visual Studio中配置OpenCV常见问题