#include #include #include "db_api/CDBConnPool.h" #include "log.h" #include #include "point.h" #include "monkey_car/monkeycar_area.h" #include "landmark.h" #include #include #include"module_service/module_area.h" template<> std::shared_ptr single_base>::m_instance=std::make_shared(); void area::on_hover(uint32_t card_id,std::shared_ptr&c,double speed,int32_t type) { //check超时 log_info("on_hover..%d areaId:%d",card_id,m_id); // time_t now = time(NULL); // if(now-c->m_enter_time>m_limit_time_second && !c->m_is_over_time) // { // c->m_is_over_time=true; // //产生告警 // } module_area::on_hover(card_id,c,type); } void area::on_enter(uint32_t card_id,std::shared_ptr&c,double speed,int32_t type) { log_info("on_enter..%d areaId:%d",card_id,m_id); module_area::on_enter(card_id,c,type); } void area::on_leave(uint32_t card_id,std::shared_ptr&c,double speed,int32_t type) { log_info("on_leave..%d areaId:%d",card_id,m_id); module_area::on_leave(card_id,c,type); } bool area::in_area(const point & p) { 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() { std::unordered_map> map; const char *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 \ FROM dat_area a ,dat_monkeycar_base_info b ,dat_map c\ where a.area_id = b.monkeycar_areaid and a.map_id = c.map_id;"; std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql,DBRes,Error); if(!Error.empty()) log_error("monkeycar area init Error,%s",Error.c_str()); int nCount = DBRes.GetRecordCount( Error ); if (nCount > 0) { log_info( "init_monkey area. The record count=%d", nCount ); 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 ); float monkeycar_speed = 0; DBRes.GetField( "monkeycar_speed",monkeycar_speed, Error ); std::string monkeycar_coor; DBRes.GetField( "monkeycar_coordinate",monkeycar_coor, Error ); float scale=0; DBRes.GetField( "scale",scale, Error ); log_info("init_area : id:%d,path:%s",area_id, path.c_str()); 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,area_type_id); 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}); } } area_list::instance()->add(map); } void area_list::init_from_db() { std::unordered_map> map; const char *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 \ FROM dat_area a,dat_map b\ where a.map_id = b.map_id and area_id not in (select monkeycar_areaid from dat_monkeycar_base_info);"; std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql,DBRes,Error); if(!Error.empty()) log_error("monkeycar area init Error,%s",Error.c_str()); int nCount = DBRes.GetRecordCount( Error ); if (nCount > 0) { log_info( "init_area. The record count=%d\n", nCount ); 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 scale = 0; DBRes.GetField( "scale",scale, Error ); log_info("init_area : id:%d,path:%s",area_id, path.c_str()); std::shared_ptr ap = std::make_shared(area_id,over_count_person,over_time_person,scale,map_id,area_type_id); ap->m_limit_vehicle_second = over_time_vehicle; ap->m_limit_vehicle_count = over_count_vehicle; 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}); } } area_list::instance()->add(map); init_monkeycar_area(); } 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::shared_ptr area_list::get_area(const point&pt) { std::shared_ptr ret=nullptr; auto map = area_list::instance()->m_map; for(const auto &a:map) { if(a.second->in_area(pt)) ret = a.second; } //区域覆盖不完全地图,很多车辆人行驶在地图外,如何确认. return ret; } void area_tool::on_point(uint32_t card_id,const point&pt,double speed,int16_t type) { log_info("on_point...cardid:%d,type:%d",card_id,type); //获取地标信息 setLandmark(pt); if(m_area_hover != nullptr && m_area_hover->m_area->in_area(pt)) { do_hover_biz(card_id,speed,type); } else { auto area = area_list::instance()->get_area(pt); if(area == nullptr) { //这里使用分站区域比较合理 log_error("Cardid:%d can not find area..[x:%.2f,y:%.2f]",card_id,pt.x,pt.y); return; } if(m_area_hover==nullptr) { m_area_hover = std::make_shared(area,pt,speed); do_enter_biz(card_id,speed,type); } else { do_leave_biz(card_id,speed,type); m_area_hover.reset(new area_hover(area,pt,speed)); do_enter_biz(card_id,speed,type); } } } void area_hover::setLandmark(const point &pt) { set(pt); auto lm = Landmark_list::instance()->get(mapid(),id(),pt); landmark_id = std::get<0>(lm); landmark_dir = std::get<1>(lm); landmark_dis = std::get<2>(lm)*scale(); log_info("landmark:%d %d %.2f,(%.2f,%.2f),%f",landmark_id,landmark_dir,landmark_dis,pt.x,pt.y,scale()); }