#include #include #include "db_api/CDBSingletonDefine.h" #include "log.h" #include #include "point.h" #include "tool_time.h" #include "common_tool.h" #include "db_tool.h" #include "monkey_car/monkeycar_area.h" #include "landmark.h" #include "area_business.h" #include #include #include "area_business.h" #include "site_area.h" #include "card.h" #include "tool_time.h" #include "websocket/ws_common.h" #include "websocket/wsClientMgr.h" #include "ant.h" //template<> std::shared_ptr single_base>::m_instance=std::make_shared(); struct underground_area:area { underground_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type) :area(id,limit_count_person,limit_time_person,scale,mapid,type) { } virtual bool in_area(const std::shared_ptr&s,const std::shared_ptr&c, const point & p,int &sarid) { return s&&!s->is_up_site(); } }; struct special_area:area { special_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type) :area(id,limit_count_person,limit_time_person,scale,mapid,type) {} virtual bool in_area(const std::shared_ptr&s,const std::shared_ptr&c, const point & p,int &sarid) { bool f=false; int id = c->get_area(); if(id == m_id) { f=true; sarid=m_id; } return f; } //推入特殊区域的是否需要其他信息 virtual void on_enter(const std::shared_ptr&a,const std::shared_ptr&c) { area::on_enter(a, c); YA::_CARD_POS_ cp; cp.area_id = m_id; swsClientMgr.SendSpecialAreaProcess(cp); } }; area::area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type) :m_id(id) ,m_area_type(type) ,m_limit_person_second(limit_time_person) ,m_limit_person_count(limit_count_person) ,m_scale(scale) ,m_mapid(mapid) ,m_person_count(0) ,m_vehicle_count(0) { m_area_business_list=area_business::get_instance_list(m_area_type); m_event_person_count = false; m_event_vehicle_count = false; } void area::on_hover(const std::shared_ptr&a,const std::shared_ptr&c) { a->m_last_time=tool_time::now_to_ms(); a->m_last_point=*c; for(const auto &i:m_area_business_list) { auto &x=a->get_business_data(i->area_business_type()); i->on_hover(a,c,x); } } void area::on_enter(const std::shared_ptr&a,const std::shared_ptr&c) { log_info("on_enter..%d areaId:%d",c->m_id,m_id); a->m_enter_time=tool_time::now_to_ms(); a->m_enter_point=*c; for(const auto &i:m_area_business_list) { auto &x=a->get_business_data(i->area_business_type()); i->on_enter(a,c,x); } } void area::on_leave(const std::shared_ptr&a,const std::shared_ptr&c) { log_info("on_leave..%d areaId:%d",c->m_id,m_id); a->m_last_time=tool_time::now_to_ms(); a->m_last_point=*c; for(const auto &i:m_area_business_list) { auto &x=a->get_business_data(i->area_business_type()); i->on_leave(a,c,x); } } bool area::in_area(const std::shared_ptr&s,const std::shared_ptr&c, const point & p,int & sarid) { if(m_bound.empty()) return false; int counter = 0; double xinters; point p1,p2; p1 = m_bound[0]; int size = m_bound.size(); for (int i=1;i<= size;i++) { p2 = m_bound[i%size]; if (p.y > std::min(p1.y,p2.y)) { if (p.y <= std::max(p1.y,p2.y)) { if (p.x <= std::max(p1.x,p2.x)) { if (p1.y != p2.y) { xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x; if (p1.x == p2.x || p.x <= xinters) counter++; } } } } p1 = p2; } return (counter % 2 == 0) ? false : true; } area_list::area_list() { } void area_list::init_monkeycar_area(int id) { std::string sql = "SELECT a.area_id, a.name, a.map_id, a.area_type_id, a.path, c.scale,\ over_count_person, over_count_vehicle, over_time_person, over_time_vehicle,\ over_speed_vehicle, is_attendance ,b.monkeycar_coordinate,b.monkeycar_speed,a.business_type \ FROM dat_area a ,dat_monkeycar_base_info b ,dat_map c\ where a.area_id = b.monkeycar_base_info_id and a.map_id = c.map_id"; if(-1 == id) { sql.append(";"); } else { sql.append(" AND a.area_id="); sql.append(std::to_string(id)); sql.append(";"); log_info("基础数据 monkeycar area 增加或修改区域 sql=%s", sql.c_str()); } std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql.c_str(),DBRes,Error); int nCount = DBRes.GetRecordCount( Error ); if (nCount < 1) { log_error("基础数据 monkeycar area 增加或修改失败,数据库中找不到: area_id=%d", id); return ; } std::unordered_map> map; while ( DBRes.GetNextRecod(Error) ) { int area_id = 0; DBRes.GetField( "area_id",area_id, Error ); int map_id = 0; DBRes.GetField( "map_id",map_id, Error ); unsigned int area_type_id = 0; DBRes.GetField( "area_type_id",area_type_id, Error ); int over_count_person = 0; DBRes.GetField( "over_count_person",over_count_person, Error ); int over_count_vehicle = 0; DBRes.GetField( "over_count_vehicle",over_count_vehicle, Error ); int over_time_person = 0; DBRes.GetField( "over_time_person",over_time_person, Error ); int over_time_vehicle = 0; DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error ); std::string path; DBRes.GetField( "path",path, Error ); double monkeycar_speed = 0; DBRes.GetField( "monkeycar_speed",monkeycar_speed, Error ); std::string monkeycar_coor; DBRes.GetField( "monkeycar_coordinate",monkeycar_coor, Error ); double scale=0; DBRes.GetField( "scale",scale, Error ); uint32_t b_type =0; DBRes.GetField( "business_type",b_type, Error ); log_info("monkeycar area init_area : id:%d,path:%s",area_id, path.c_str()); if(-1 == id) { std::shared_ptr da = std::make_shared(); da->m_default_speed = monkeycar_speed; da->m_point = init_path(monkeycar_coor); std::shared_ptr ap = std::make_shared(da,area_id,over_count_person, over_time_person,scale,map_id,b_type); ap->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle); ap->m_bound=init_path(path); for(const auto &p : ap->m_bound) log_info("point:monkey:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y); for(const auto &p : da->m_point) log_info("point:monkey_coor:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y); map.insert({area_id,ap}); } else { //这里后续需要把猴车得信息传递过去 std::shared_ptr da = std::make_shared(); da->m_default_speed = monkeycar_speed; da->m_point = init_path(monkeycar_coor); std::shared_ptr ap = std::make_shared(da,area_id,over_count_person, over_time_person,scale,map_id,b_type); if(auto area_=area_list::instance()->get(id)) area_=ap; else area_list::instance()->add(area_id,ap); ap->m_bound=init_path(path); ap->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle); for(const auto &p : ap->m_bound) log_info("point:monkey:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y); for(const auto &p : da->m_point) log_info("point:monkey_coor:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y); log_info("基础数据 monkeycar area增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,\ scale:%.2f,map_id:%d,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d", id,over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle); } } if(-1 == id) { log_info( "monkeycar area init_area. The record count=%d\n", nCount ); area_list::instance()->add(map); } } std::shared_ptr area_list::create(int type,int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t b_type) { if(type==AREA_TYPE_FORBIDDEN) { return std::make_shared(id,limit_count_person,limit_time_person,scale,mapid,b_type); } else if(type == AREA_TYPE_DOWNMINE) { return std::make_shared(id,limit_count_person,limit_time_person,scale,mapid,b_type); } else { return std::make_shared(id,limit_count_person,limit_time_person,scale,mapid,b_type); } } void area_list::init_from_db(int id/*=-1*/) { std::string sql = "SELECT a.area_id, a.name, a.map_id, a.area_type_id, a.path,b.scale, \ over_count_person, over_count_vehicle, over_time_person, over_time_vehicle, \ over_speed_vehicle, is_attendance,business_type, a.is_work_area\ FROM dat_area a,dat_map b\ where a.map_id = b.map_id and area_id not in \ (select monkeycar_base_info_id from dat_monkeycar_base_info)"; if(-1 == id) { sql.append(";"); } else { sql.append(" AND s.area_id="); sql.append(std::to_string(id)); sql.append(";"); log_info("基础数据 增加或修改区域 sql=%s", sql.c_str()); } std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql.c_str(),DBRes,Error); int nCount = DBRes.GetRecordCount( Error ); if (nCount < 1) { log_error("基础数据 增加或修改失败,数据库中找不到: area_id=%d:%s", id,sql.c_str()); return ; } std::unordered_map> map; while ( DBRes.GetNextRecod(Error) ) { int area_id = 0; DBRes.GetField( "area_id",area_id, Error ); int map_id = 0; DBRes.GetField( "map_id",map_id, Error ); unsigned int area_type_id = 0; DBRes.GetField( "area_type_id",area_type_id, Error ); int over_count_person = 0; DBRes.GetField( "over_count_person",over_count_person, Error ); int over_count_vehicle = 0; DBRes.GetField( "over_count_vehicle",over_count_vehicle, Error ); int over_time_person = 0; DBRes.GetField( "over_time_person",over_time_person, Error ); int over_time_vehicle = 0; DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error ); double over_speed_vehicle=0; DBRes.GetField( "over_speed_vehicle",over_speed_vehicle, Error ); std::string path; DBRes.GetField( "path",path, Error ); double scale = 0; DBRes.GetField( "scale",scale, Error ); uint32_t b_type =0; DBRes.GetField( "business_type",b_type, Error ); int is_work_area = 0; DBRes.GetField( "is_work_area",is_work_area, Error ); log_info("init_area : id:%d,path:%s",area_id, path.c_str()); if(-1 == id) { std::shared_ptr ap = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type); ap->m_limit_vehicle_second = over_time_vehicle; ap->m_limit_vehicle_count = over_count_vehicle; ap->m_over_speed_vehicle = over_speed_vehicle; ap->m_is_work_area = is_work_area; ap->m_bound=init_path(path); for(const auto &p : ap->m_bound) log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y); map.insert({area_id,ap}); } else { auto tmp_ptr = area_list::instance()->get(id); if(!tmp_ptr) { tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type); area_list::instance()->add(id, tmp_ptr); } tmp_ptr->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle); tmp_ptr->m_bound=init_path(path); tmp_ptr->m_over_speed_vehicle = over_speed_vehicle; tmp_ptr->m_is_work_area = is_work_area; for(const auto &p : tmp_ptr->m_bound) log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y); log_info("基础数据 增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,scale:%.2f,map_id:%d\ ,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d", id,over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle); } } if(-1 == id) { log_info( "init_area. The record count=%d\n", nCount ); area_list::instance()->add(map); } init_monkeycar_area(id); } std::vector area_list::init_path(std::string &str) { if(str.empty()) log_error("area path empty()..."); std::vector vp; std::vector vs; std::vector vs1; boost::split(vs,str,boost::is_any_of("ML ;")); for(auto & s:vs) { if(s.empty()) continue; boost::split(vs1,s,boost::is_any_of(",")); if(vs1.size()!=2) log_error("area path data Error.pls check data table."); vp.emplace_back(atof(vs1[0].c_str()),atof(vs1[1].c_str())); } return std::move(vp); } std::vector> area_list::get_area(const std::shared_ptr s,const std::shared_ptr &c,const point&pt,int & sarid) { std::vector> ret; auto map = area_list::instance()->m_map; for(const auto &a:map) if(a.second->in_area(s,c,pt,sarid)) ret.push_back(a.second); if(s) ret.push_back(s->get_area()); //区域覆盖不完全地图,很多车辆人行驶在地图外,如何确认. return std::move(ret); } area_hover::area_hover(std::shared_ptr&area,const point&pt) :m_area(area) { m_enter_time=m_last_time=tool_time::now_to_ms(); m_enter_point=m_last_point=pt; } void area_tool::on_point(const std::shared_ptr&s,const std::shared_ptr& c,const point&pt) { log_info("on_point...cardid:%d,type:%d",c->m_id,c->m_type); int special_area=-1; std::vector> areas=area_list::instance()->get_area(s,c, pt,special_area); if(special_area != -1) { areas.clear(); auto area_=area_list::instance()->get(special_area); areas.push_back(area_); } else std::sort(areas.begin(),areas.end(),[](const std::shared_ptr&l,const std::shared_ptr&r){ return l->id()id(); }); auto c1=m_hover_list.begin(),ce=m_hover_list.end(); auto a1=areas.begin() ,ae=areas.end(); std::vector> nlist; while (c1!=ce && a1!=ae) { if ((*c1)->id()<(*a1)->id()) { (*c1)->m_area->on_leave(*c1, c); ++c1; } else if ((*a1)->id()<(*c1)->id()) { nlist.push_back(std::make_shared(*a1,pt)); (*a1)->on_enter(nlist.back(),c); ++a1; } else { nlist.push_back(*c1); (*c1)->m_area->on_hover(*c1,c); ++c1,++a1; } } while(c1!=ce) { (*c1)->m_area->on_leave(*c1, c); ++c1; } while(a1!=ae) { nlist.push_back(std::make_shared(*a1,pt)); (*a1)->on_enter(nlist.back(),c); ++a1; } m_hover_list=std::move(nlist); //更新到数据库 std::string strAreaInfo = ""; for (std::vector>::iterator itvec = m_hover_list.begin(); itvec != m_hover_list.end(); ++itvec) { if ((*itvec)->id() > 0) { char tmpArea[128] = {0}; snprintf(tmpArea, 128, "%d,%lu|", (*itvec)->id(), (*itvec)->m_enter_time); strAreaInfo += tmpArea; } } char sql[1024] = {0}; snprintf(sql, 1024, "call card_location(%lu, %d, %lf, %lf, %lf,d '%s');", tool_other::type_id_to_u64(c->m_type, c->m_id), s->id(), pt.x, pt.y, pt.z, strAreaInfo.c_str()); db_tool::PushAsync(sql); } void area_tool::on_leave(const std::shared_ptr& c) { for(auto& t:m_hover_list) { t->m_area->on_leave(t, c); } } void area_tool::set_area_info(int mapid,double scale,int areaid,const point &pt,uint64_t t,int type) { if(0==type) { m_mapid = mapid; m_scale=scale; set_area_info(mapid,areaid,pt,t); } else if(1==type) { set_area_info(mapid,areaid,pt,t); } else if(2==type) { auto it =m_area_info.find(areaid); if(it != m_area_info.end()) m_area_info.erase(it); } else { log_info("wrong type.."); } } void area_tool::set_area_info(int mapid,int areaid,const point &pt,uint64_t t) { auto lm = Landmark_list::instance()->get(mapid,areaid,pt); int landmark_id = std::get<0>(lm); int landmark_dir = std::get<1>(lm); double landmark_dis = std::get<2>(lm)*m_scale; log_info("landmark:%d %d %.2f,(%.2f,%.2f),%f",landmark_id,landmark_dir,landmark_dis,pt.x,pt.y,m_scale); std::tuple tinfo=std::make_tuple(areaid,landmark_id,landmark_dir,landmark_dis,t); m_area_info[areaid].swap(tinfo); }