#ifndef __TRAFFIC_LIGHT_H__ #define __TRAFFIC_LIGHT_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "traffic_info.h" #include "car.h" #include #include "geo_hash.h" #include "structdef.h" #include "classdef.h" NAMESPACE_POINT_BEGIN(NAMESPACE_POINT) //#define MAX_SCOPE_BIGCAR 300//像素 #define MID_CAR_LENGTH_GROUP 5//像素 #define RUN_LIGHT_DIS 20//闯红灯与绿灯的距离 //路口红绿灯 //大巷红绿灯 //路口规则 //小车避让大车规则 //代理模式 //装饰器模式 //抽象工厂模式 //x->大 speed 正 //x->恒 // y->大 speed 正 // y->小 speed 负 //x->小 speed 负 //这里的初始化红绿灯组vector初始化,因数据库配置和实际情况进行初始化,不能保证通用,需要在不同的情形下特殊处理 //这里是根据区域划分红绿灯,然后根据红绿灯位置按照(上行或者下行)进行排序 //这里初始化根据,每一条巷道为一组,遇到拐点,则是新的巷道。因为,拐点必有红绿灯。 //需要考虑到T字口和十字口中有车辆过来,但非是指定区域即辅运大巷 struct Manage { geo_list m_g; std::map> m_map; std::shared_ptr operator [](std::string cardid) { return m_map[cardid]; } const std::shared_ptr operator [](std::string cardid) const { auto iter = m_map.find(cardid); if(iter == m_map.end()) return nullptr; else return iter->second; } }; //初始化红绿灯组,根据区域进行划分 struct InitData { void read_dat_group(const char * fname); void read_dat_light(const char * fname); std::map> m_Map; void showInfo() { std::cout << "-------xxxxxxxxxxxxxxxxxxx------------------------\n"; for(const auto x : m_Map) std::cout << x.second->showinfo()< p) { m_owner = p; } virtual std::vector> handleRule(std::shared_ptr c= 0) = 0; virtual std::shared_ptr check_run_red_light(std::shared_ptr c ,double dis){return nullptr;} virtual void put(std::shared_ptr tlp) = 0; virtual void put(std::vector> && vec) = 0; virtual std::string showInfo() = 0; virtual std::vector find_near(int x,int y,int dist,const std::string & card_no); std::string itostr(int gid) { char buf[10]; sprintf(buf,"%d",gid); std::string str(buf); return std::move(str); } bool sortCar(const std::string &c1,const std::string &c2,std::shared_ptr tlp_ptr) { auto card1 = getCard(c1); auto card2 = getCard(c2); double d1=DBL_MAX, d2 = DBL_MAX; if(card2 != nullptr) { d2 = tlp_ptr->dist(card2->getX(),card2->getY()); } if(card1 != nullptr) { d1 = tlp_ptr->dist(card1->getX(),card1->getY()); } return d1 < d2; } // 在红绿灯组数组m_pTrafficLight中找离位置点(x,y)最近的灯组m_specialFlag、m_line、m_directDist以及m_id(灯组ID)信息 std::tuple findNearLightInfo(double x,double y,std::shared_ptr tlg_ptr) { int lightId = 0; double max = DBL_MAX; bool special = false; line l; double distDirect = 0; for(const auto px : tlg_ptr->m_pTrafficLight) { double tmp = px->dist(x,y); if(max > tmp) { max = tmp; special = px->m_specialFlag?true:false; l = px->m_line; distDirect = px->m_directDist; lightId= px->m_id; } } return std::make_tuple(special,l,distDirect,lightId); } std::shared_ptr getCard(const std::string &card_no); virtual ~Rule() {} std::weak_ptr m_owner; }; class CrossingRule:public Rule { public: CrossingRule() {} virtual void setPtr(std::shared_ptr p) { m_owner = p; } //谁先到达路口红绿灯指定的距离,which side turn green.then else turn red.. virtual bool getBigCarFlag(const std::string &card_no); //here should another thread to handle it . bool handleManualControl(std::shared_ptr pt); bool findNearLight(const std::string & card_no,std::shared_ptr tlg_ptr,bool a = false); bool handleSpecialAvondance(std::shared_ptr pt); bool handleCrossing(std::shared_ptr pt) ; virtual std::vector> handleRule(std::shared_ptr c=nullptr); void changeCarState(std::string & card_no,std::shared_ptr tlg_ptr); void put(std::shared_ptr tlp) { m_CTrafficLightGroupMap.push_back(tlp); // std::cout << tlp->showinfo()<> && vec) { m_CTrafficLightGroupMap = vec; // std::cout << "+++++++++++\n"; // for(const auto x : m_CTrafficLightGroupMap) // std::cout << x->showinfo()<m_gId<<",X:"<x<<"Y:"<y; for(const auto py : px->m_pTrafficLight) ss<<"[lId:"<m_id<<",x:"<x<<",y:"<y<<"],"; ss<<"},{"; } ss<<"}}"; return std::move(ss.str()); } public: std::vector> m_CTrafficLightGroupMap; }; class AvoidanceRule:public Rule { public: AvoidanceRule() {} virtual std::vector> handleRule(std::shared_ptr c=nullptr); virtual std::shared_ptr check_run_red_light(std::shared_ptr c,double reddis); void add_one(std::shared_ptr & pt,std::shared_ptr &c,std::vector> &vt,LIGHT_COLOUR lc,LIGHT_COLOUR lc_); void changeGroup(std::shared_ptr &p,point pt,LIGHT_COLOUR lc,LIGHT_COLOUR lc_); void eraseTwoGroup(std::shared_ptr &c,std::vector> &vt); void eraseTrafficLightGroup(bool a,std::shared_ptr &c,std::vector> &vt); std::vector> findGroup(double x,double y,int areaid,double vv, std::shared_ptr c); bool getMidCar(std::shared_ptr bigcar,std::shared_ptr & one,std::shared_ptr & two); bool Diff(std::shared_ptr &p,point pt,LIGHT_COLOUR lc,LIGHT_COLOUR lc_); //后续小车避让大车规则,只需要找到前方的两个红绿灯,找到两个对比一下之前的记录,如果灯组改变了,则修改,如果没变,则判断是否有小车,进行改变 //如果只找到一个红绿灯,查看是否含有记录,如果有,则不坐任何处理。 bool findTwoLightGroupMidCar(std::shared_ptr one,std::shared_ptrtwo,std::shared_ptr bigcar,std::shared_ptr car) ; void put(std::shared_ptr tlp) { m_CTrafficLightGroupMap[tlp->m_areaId].push_back(tlp); // std::cout << tlp->showinfo()<> && vec) { for(const auto x : vec) { m_CTrafficLightGroupMap[x->m_areaId].push_back(x); // std::cout << "=+++++++++++=\n"; // std::cout << x->showinfo()<m_areaId != x.first) x.second.push_back(t); } } } } for(auto &x : m_CTrafficLightGroupMap) { std::sort(x.second.begin(),x.second.end(),[](std::shared_ptr one ,std::shared_ptr two )->bool{return *one < *two;}); x.second.erase(std::unique(x.second.begin(),x.second.end(),[](std::shared_ptr one ,std::shared_ptr two )->bool{return *one == *two;}),x.second.end()); } // auto x = findGroup(4727,-100,6,-10); // for(auto c : x) // { // if(c!=nullptr) // std::cout << "4444444444444444444444444444444444------"<m_gId<<" "<x<<" "<y<m_gId<<" "<x<<" "<y< one ,std::shared_ptr two )->bool{return *one < *two;}); std::map> vtm; for(auto &x : m_CTrafficLightGroupMap) { if(x.second.size()<=1) continue; //line l(**x.second.begin(),**x.second.end()); auto abc = (*x.second.begin())->get_abc(**std::prev(x.second.end())); for(const auto y : vtm) { if(std::get<0>(abc)==std::get<0>(y.second)&&std::get<1>(abc)==std::get<1>(y.second)&&std::get<2>(abc)==std::get<2>(y.second)) { //should initialization with size when Using std::merge std::vector> vt(m_CTrafficLightGroupMap[y.first].size()+x.second.size()); for(const auto c:m_CTrafficLightGroupMap[y.first]) std::cout << c->x<<"---===0---="<y<x<<"---===0---="<y< one ,std::shared_ptr two )->bool{return *one < *two;}); x.second = vt; m_CTrafficLightGroupMap[y.first] = vt; } } vtm.insert({x.first,abc}); } #endif } virtual std::string showInfo() { //should sort first.. //sort(); std::stringstream ss; ss<<"AvoidanceRule:{{{"; for(const auto p : m_CTrafficLightGroupMap) { for(const auto px : p.second) { ss<<"AreaId:{"<m_gId<<",AreaId:"<m_areaId<<",X:"<x<<"Y:"<y; for(const auto py : px->m_pTrafficLight) ss<<"[lId:"<m_id<<",x:"<x<<",y:"<y<<"],"; ss<<"},{" ; } ss<<"},#------------------#{"; } ss<<"}}"; return std::move(ss.str()); } public: std::map>> m_CTrafficLightGroupMap; }; class CarManager; class DecoratorRule:public std::enable_shared_from_this { public: DecoratorRule(CarManager* m) :m_(m) { } std::string showInfo() { return m_rule->showInfo(); } void put(std::shared_ptr tlp) { m_rule->put(tlp); } void put(std::vector> && vec) { m_rule->put(std::move(vec)); } virtual void handleRule(std::shared_ptr c = nullptr){} virtual std::shared_ptr check_run_red_light(std::shared_ptr c ,double dis){return nullptr;} virtual std::shared_ptr getPtr() = 0; virtual void CreateRule() = 0; std::vector find_near(double x,double y,double dist,std::string cardid); std::shared_ptr getCard(const std::string &card_no); virtual ~DecoratorRule(){} std::shared_ptr m_rule; //std::shared_ptr m_; CarManager *m_; }; class Uncopyable { protected: Uncopyable(){} ~Uncopyable(){} private: Uncopyable(const Uncopyable & lhs); Uncopyable & operator=(const Uncopyable &lhs); }; class DecoratorRuleCrossing:public DecoratorRule,private Uncopyable { public: // DecoratorRuleCrossing(const DecoratorRuleCrossing &) = delete; // DecoratorRuleCrossing & operator=(const DecoratorRuleCrossing &) =delete; std::shared_ptr getPtr() { return shared_from_this(); } DecoratorRuleCrossing(CarManager* m) :DecoratorRule(m) ,b_exit(false) { m_pthread = NULL; } virtual void CreateRule() { m_rule = std::make_shared(); m_rule->setPtr(getPtr()); } void run(); void handleRule(std::shared_ptr c = nullptr) { m_pthread = new std::thread(&DecoratorRuleCrossing::run,this); } ~DecoratorRuleCrossing() { b_exit = true; if(m_pthread!=NULL) { m_pthread->join(); delete m_pthread; } } private: std::thread * m_pthread; bool b_exit; }; class DecoratorRuleAvoidance:public DecoratorRule { public: DecoratorRuleAvoidance(CarManager* m) :DecoratorRule(m) { } std::shared_ptr getPtr() { return shared_from_this(); } virtual void CreateRule() { m_rule = std::make_shared(); m_rule->setPtr(getPtr()); } void handleRule(std::shared_ptr c = nullptr); virtual std::shared_ptr check_run_red_light(std::shared_ptr c,double dis); private: }; /* static int str_split(char*s,char**rc) { char**o=rc; for(;*s;) { *o=strtok_r(s,",",&s); o++; } return o-rc; } int main() { Manage m; //test point func TrafficLightGroup *ctlg = new TrafficLightGroup(1,1,0,12,12.5,5,10,90) ; std::cout <<"direct:"<< ctlg->dist_direct(3,1)< r =std::make_shared (); DecoratorRule* drc = new DecoratorRuleCrossing(&m); drc->CreateRule(); drc->handleRule(); delete drc; //test line line l(point(100,10),point(120,10)); std::cout << l.dist(point(130,10))<(abc)<<' '<(abc)<<' '<(abc)< CrossingR = std::make_shared(m); //CrossingR->put(std::move(Id.m_CrossingMap)); //std::shared_ptr AvoidanceR = std::make_shared(m); uint64_t tt = time(NULL)*1000; std::shared_ptr bc24 = std::make_shared("2:4",tt,4470,75,false,1.1,2);//cardid timet x y bigcar speed,areaid std::shared_ptr bc22 = std::make_shared("2:2",tt,4650,75,false,-1.1,2);//cardid timet x y bigcar speed.areaid m.m_map.insert({"2:4",bc24}); m.m_map.insert({"2:2",bc22}); // CrossingR->update(4470,-75,"2:4"); // 这里需要把y转化成- m.m_g.update(4650,-75,"2:2"); //auto av = AvoidanceR->find_near(4600,-75,100,"2:4"); std::shared_ptr DecCrossingRule = std::make_shared(&m); std::shared_ptr DecAvoidanceRule = std::make_shared(&m); for(const auto px : Id.m_Map) { //if(px.second->m_gId == 1) // px.second->store(2); // if(px.second->m_gId == 5) // bc24->push_back(px.second); // if(px.second->m_gId == 6) // { // bc24->push_back(px.second); // px.second->store(3); // } DecAvoidanceRule->put(px.second); DecCrossingRule->put(px.second); } //DectoratorRule do next.. // DecCrossingRule->handleRule(); //DecAvoidanceRule->handleRule(); #if 0 //test the sort for TrafficLightGroup............ std::shared_ptr p = std::make_shared(1,2,0,12,12.5,5,10); std::shared_ptr p1 = std::make_shared(2,2,0,12,5,10); std::shared_ptr p2 = std::make_shared(3,2,0,12,12.5,5,10); std::vector> vp; vp.push_back(p); vp.push_back(p2); vp.push_back(p1); for(auto px:vp) std::cout << px->x<<"beforefdfdfd" << px->y< one,std::shared_ptr two)->bool{std::cout << two->x<x<<"fdfdfd" << px->y<handleRule(bc24); std::dynamic_pointer_cast(bc24)->x_ = 4600; std::cout <<"------------------------------------"<handleRule(bc24); std::cout<<"******************************************************************************888"<showInfo()<showInfo()<