• 公交站点方向的计算


    # 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)
  • 相关阅读:
    Oracle使用笔记
    跳转至锚点
    项目中使用到的AOP
    短信验证码接口使用
    阿里人脸识别接口
    java实现网页截图
    java后台接收微信服务号/订阅号消息
    java 实现redis缓存
    redis 常用命令
    被骗了,自己还不知道
  • 原文地址:https://www.cnblogs.com/ddzhen/p/14958139.html
Copyright © 2020-2023  润新知