#include "area_business_geofault.h" #include #include #include "area_business.h" #include "event.h" #include "db_api/CDBSingletonDefine.h" #include "sys_setting.h" #include "common_tool.h" #include "log.h" #include "card.h" #include "config_file.h" #include "point.h" #include "area.h" struct geofault_data:business_data { geofault_data() { m_near_geofault_count=0; m_far_geofault_count=0; m_is_warning=false; } int m_near_geofault_count; int m_far_geofault_count; bool m_is_warning; }; std::unordered_map> area_business_geofault::_area_geofault_map; int area_business_geofault::_geofault_count_limit; void area_business_geofault::on_load_his(const std::shared_ptr&area_hover_ptr, const std::shared_ptr&card_ptr,std::shared_ptr&ptr) { on_enter(area_hover_ptr, card_ptr, ptr); } void area_business_geofault::on_enter(const std::shared_ptr&area_hover_ptr, const std::shared_ptr&card_ptr,std::shared_ptr& ptr) { if(!tool_other::is_coal_or_driving(card_ptr->m_type,card_ptr->get_vehicle_type_id())) { return; } auto ptr_temp = std::make_shared(); ptr = ptr_temp; double dist=0; if(_is_near(area_hover_ptr->m_area, card_ptr->x, card_ptr->y, dist)) { ptr_temp->m_near_geofault_count++; } else { ptr_temp->m_far_geofault_count++; } auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ET_VEHICLE_NEAR_GEOFAULT,DT_COMMON); ptr_temp->m_is_warning = (nullptr != ev_ptr_temp && !ev_ptr_temp->is_end()); } void area_business_geofault::on_hover(const std::shared_ptr&area_hover_ptr, const std::shared_ptr&card_ptr,std::shared_ptr ptr) { if(!tool_other::is_coal_or_driving(card_ptr->m_type,card_ptr->get_vehicle_type_id())) { return; } if(nullptr == ptr) { log_error("area_business_geofault::on_hover:nullptr == ptr"); return; } auto ptr_temp = static_cast(ptr.get()); double dist=0; if(_is_near(area_hover_ptr->m_area, card_ptr->x, card_ptr->y, dist)) { ptr_temp->m_far_geofault_count=0; ptr_temp->m_near_geofault_count++; } else { ptr_temp->m_near_geofault_count=0; ptr_temp->m_far_geofault_count++; } //确定告警 if(_geofault_count_limit <= ptr_temp->m_near_geofault_count) { ptr_temp->m_near_geofault_count=_geofault_count_limit; ptr_temp->m_is_warning = true; uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id); event_tool::instance()->handle_event(OT_CARD, ET_VEHICLE_NEAR_GEOFAULT, id, CYaSetting::m_sys_setting.geofault_warn_dis, dist, true); } //确定正常 if(_geofault_count_limit <= ptr_temp->m_far_geofault_count) { ptr_temp->m_far_geofault_count=_geofault_count_limit; if(ptr_temp->m_is_warning) { ptr_temp->m_is_warning = false; uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id); event_tool::instance()->handle_event(OT_CARD, ET_VEHICLE_NEAR_GEOFAULT, id, CYaSetting::m_sys_setting.geofault_warn_dis, dist, false); } } } void area_business_geofault::on_leave(const std::shared_ptr&area_hover_ptr, const std::shared_ptr&card_ptr,std::shared_ptr ptr) { if(!tool_other::is_coal_or_driving(card_ptr->m_type,card_ptr->get_vehicle_type_id())) { return; } if(nullptr == ptr) { log_error("area_business_geofault::on_leave:nullptr == ptr"); return; } uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id); event_tool::instance()->handle_event(OT_CARD, ET_VEHICLE_NEAR_GEOFAULT, id, CYaSetting::m_sys_setting.geofault_warn_dis, 1000, false); } void area_business_geofault::init(config_file& config) { _geofault_count_limit = std::stoi(config.get("service.geofault_count_limit","10")); } std::string area_business_geofault::_points2str(std::vector& points) { std::string str; for(auto&p : points) { char ch[64] = {0}; sprintf(ch, "x=%f,y=%f;", p.x, p.y); str.append(ch); } return str; } void area_business_geofault::init_geofault_from_db() { const char *sql = "select area_id, pt_data from dat_geofault g, dat_work_face w \ where g.workface_id=w.work_face_id;"; std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql,DBRes,Error); if(!Error.empty()) { log_error("init_geofault_from_db Error,%s",Error.c_str()); return; } uint64_t nCount = DBRes.GetRecordCount( Error ); if (static_cast(nCount) < 0) { log_error("错误,init_geofault_from_db. The record count=%ld\n", nCount ); return; } log_info( "init_geofault_from_db. The record count=%ld\n", nCount ); _area_geofault_map.clear(); while ( DBRes.GetNextRecod(Error) ) { int area_id = 0; DBRes.GetField( "area_id",area_id, Error ); std::string pt_data; DBRes.GetField( "pt_data",pt_data, Error ); std::vector points; std::vector strs = split(pt_data,';'); for (const auto & s:strs) { std::vector xy = split(s, ','); if (xy.size()!=2) { continue; } point pt; pt.x = std::atof(xy[0].c_str()); pt.y = std::atof(xy[1].c_str()); points.push_back(pt); } _area_geofault_map.insert({area_id,points}); } for(const auto &p : _area_geofault_map) { auto kk = p.second; std_debug("init_geofault_from_db:area_id:%d--points: %s",p.first, _points2str(kk).c_str()); log_info("init_geofault_from_db:area_id:%d--points: %s",p.first, _points2str(kk).c_str()); } } bool area_business_geofault::_is_near(std::shared_ptr& area_ptr, double x, double y, double& out_dist) { auto serch = _area_geofault_map.find(area_ptr->m_id); if(serch == _area_geofault_map.end()) { return false; } point pt(x, y); double min=0; out_dist=1000000; for(auto& p : serch->second) { min = pt.dist(p) * area_ptr->m_scale; if(min < out_dist) { out_dist = min; } if(min < CYaSetting::m_sys_setting.geofault_warn_dis) { return true; } } return false; }