struct area { uint32_t m_id; std::string m_name; std::atomic m_card_count; int id(); std::string name(); int get_card_count(); double get_limit_speed(); double get_limit_time_second(); double get_limit_card_count(); virtual int type()=0;//site:0,normal:1 void inc_card_count(int deta) { } virtual void on_hover(int card_id,const point&pt)=0; virtual void on_enter(int card_id,std::shared_ptr prev,const point&pt)=0; virtual void on_leave(int card_id,std::shared_ptr next,const point&pt)=0; virtual ~area(){} }; struct normal_area:area { std::vector m_bound; }; struct site_area:area { int32_t m_site_id; }; struct area_main { std::vector> m_normal_list,m_site_list; std::shared_ptr get_site_area(int site_id); std::shared_ptr get_normal_area(int id); std::vector> get_normal_area(const point&pt); static std::shared_ptr instance(); }; struct area_hover { std::shared_ptr m_area; time_t m_enter_time,m_last_time; void reset() { m_last_time=time(0); } void reset(std::shared_ptr a, time_t enter_time=0) { m_area=a; if(enter_time) { m_enter_time=m_last_time=enter_time; } else { m_last_time=time(0); } } bool operator == (const area_hover&o)const { return m_area->id()==o->m_area->id(); } bool operator < (const area_hover&o)const { return m_area->id()m_area->id(); } }; struct card_area_tool { area_hover m_site; std::vector m_normal; point m_last_point; void on_point(int card_id,int site_id,const point&pt,double speed) { //处理分站类型的区域 std::shared_ptr a=area_main::instance()->get_site_area(site_id); if(pt.empty())//解算前 { if(m_site==nullptr) { a->on_enter(card_id,nullptr); } else { if(*m_site==*a) { } else//离开分站范围,进入新的分站范围 { m_site->on_leave(card_id,a); a->on_enter(card_id,m_site); m_site=a; } } return; } std::vector> areas=get_normal_area(pt);//找出所有的区域 for(a:m_site-areas)//离开的区域 { a.on_leave(); area *a=area_main_inst->get_normal_area(pt); on_site_area_point(a,card_id); } } //插入进入新分站记录 //离开分站时更新记录//本版本只在数据库生成记录 void on_site_area_point(a,card_id,site_id,speed) { if(enter) do_att_biz(a,card_id); } //人卡考勤 void do_att_biz(a,card_id) { } //生成卡进入区域、在区域活跃和离开区域的调用 void on_normal_area_point(a,card_id,pt,speed) { if(hover) do_hover_biz(a,card_id,pt,speed); if(enter) do_enter_biz(a,card_id,pt,speed); } //检测是否超时 void on_timer(card_id) { } void do_hover_biz(a,card_id,pt,speed) { //区域超时超时检测 //区域超速检测 //电子围栏检测 } void do_enter_biz(a,card_id,pt,speed) { //当前区域超员检测 //车卡考勤逻辑检测 //电子围栏检测 } }; struct person_card:card { card_area_tool*m_area_tool; void on_point(int site_id,const point&pt,double speed) { m_area_tool->on_point(m_id,site_id,pt,speed); } };