123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- #include "his_location.h"
- #include "log.h"
- #include "tool_time.h"
- #include "card_path.h"
- #include "db_api/CDBSingletonDefine.h"
- #include <config_file.h>
- extern config_file config;
- uint32_t location_card::m_difftime=0;
- int location_card::m_distance=-1;
- location_card::location_card(uint32_t id,uint64_t type,uint32_t objid)
- :m_cardid(id)
- ,m_type(type)
- ,m_objid(objid)
- {
- init();
- if(location_card::m_distance==-1)
- {
- location_card::m_difftime=config.get("service.difftime",300);
- location_card::m_distance=config.get("service.distance",30);
- log_info("his_location_init:%u,%d",m_difftime,m_distance);
- }
- }
- void location_card::init()
- {
- m_areaid=-1;
- m_mapid=-1;
- m_siteid = -1;
- m_timestamp=0;
- m_p.set(0,0);
- std::queue<mini_data> tmp;
- m_d.swap(tmp);
- m_direct_index=0;
- last_timestamp=0;
- set_invalid();
- }
- void location_card::init_att(const point &pt,uint64_t time)
- {
- std::queue<mini_data> tmp;
- m_d.swap(tmp);
- m_d.emplace(pt,time);
- }
- void location_card::set_invalid()
- {
- m_arg=0x12345678;
- }
- bool location_card::is_valid()
- {
- return m_arg!=0x12345678;
- }
- double location_card::make_arg(const point &pt,const point &p)
- {
- log_info("his_location arg[%d],(%.2f,%.2f)--->(%.2f,%.2f)---->(%.2f,%.2f)",m_cardid,m_p.x,m_p.y,p.x,p.y,pt.x,pt.y);
- return std::arg(std::complex<double>(pt.x,pt.y)-std::complex<double>(p.x,p.y));
- }
- void location_card::set(const point &pt,uint64_t time)
- {
- m_timestamp=time;
- m_p.set(pt);
- init_att(pt,time);
- }
- bool location_card::line_changed(const point &pt)//,int &df)
- {
- if(!is_valid())
- return false;
- point p;
- if(m_d.empty())
- p=m_p;
- else
- p=m_d.back().p;
- if(point::eq(p.x,pt.x,0.2) && point::eq(p.y,pt.y,0.2)) return false;
- double dis1=m_p.dist(pt);
- if(dis1<2)return false;
- //double dis = p.dist(pt);
- double dis = m_p.dist(pt);
- double arg = make_arg(pt,m_p);
- //查看路径方向是否改变
- bool change_flag=(arg-m_arg > -1e-10 && arg-m_arg<1e-10);
- //change_flag为true,标识没有发生变化
- // if(change_flag)m_direct_index=0;
- log_info("his_location:line_changed:%d,%f,m_arg:%f,%s,%f,%f",m_cardid,arg,m_arg, change_flag?"same":"not same",m_arg-arg,dis);
- //if(dis<0.5 && fabs(fabs(arg)+fabs(m_arg)-3.141593)< 0.000005)
- // return false;
- //判断10次反向才做下一步动作
- // if(fabs(fabs(arg)+fabs(m_arg)-3.141593)< 0.000005)
- // {
- // if(++m_direct_index<=10)
- // {
- // df=1;return false;
- // }
- // }
- //return !point::eq(arg,m_arg,1e-10);
- return !change_flag;
- }
- bool location_card::is_speed_changed(const point& pt,uint64_t time)
- {
- bool flag = false;
- double v=0.0;
- point ps=m_d.back().p;
- if(ps.dist(pt)<0.1)return flag;
- if(m_d.size()>=4)
- {
- mini_data d1 = m_d.front();
- double dist = d1.p.dist(pt);
- double t = time-d1.time;
- v = dist/t*1000;
- m_d.pop();
- }
- m_d.emplace(pt,time);
- if(v<=0.1)
- return flag;
- double dist = m_p.dist(pt);
- double t = time - m_timestamp;
- double avge_speed= dist/t*1000;
- log_info("his_location cardid:%d:v:%.2f,avge_v:%.2f,(%.2f--%.2f)",m_cardid,v,avge_speed,0.7*avge_speed,1.3*avge_speed);
- if(v<(1-0.3)*avge_speed || v>(1+0.3)*avge_speed)
- flag=true;
- return flag;
- }
- bool location_card::time_out(const point &p,uint64_t time)
- {
- uint64_t t=last_timestamp==0?m_timestamp:last_timestamp;
- if(time-t>=30*1000 && m_p.dist(p)>0.1)
- return true;
- return false;
- }
- //区域是否发生变化
- bool location_card::is_area_changed(int new_areaid)
- {
- bool flag =false;
- if(m_areaid != new_areaid)
- {
- m_areaid = new_areaid;
- flag=true;
- }
- return flag;
- }
- //地图是否发生变化
- bool location_card::is_map_changed(int new_mapid)
- {
- bool flag =false;
- if(m_mapid != new_mapid)
- {
- m_mapid = new_mapid;
- flag=true;
- }
- return flag;
- }
- void location_card::push(uint64_t timestamp,const point & p,int32_t areaid,int32_t mapid,int32_t siteid,bool bclose/* = false*/)
- {
- //log_info("his_location: 1111111111111111111; timestamp=%d, p.x=%.2f, p.y=%.2f", timestamp, p.x, p.y);
- if (bclose) //卡移除后直接更新his_location
- {
- update(p,timestamp);
- init();
- return;
- }
- //log_info("his_location: m_p.empty()=%d, m_timestamp=%d, m_areaid=%d, m_mapid=%d, m_siteid=%d", m_p.empty(), m_timestamp, m_areaid, m_mapid, m_siteid);
- if(m_p.empty() || m_timestamp==0||m_areaid<0||m_mapid<0 || m_siteid < 0)
- {
- set(p,timestamp);
- m_areaid = areaid;
- m_mapid = mapid;
- m_siteid = siteid;
- m_d.emplace(p,timestamp);
- return ;
- }
- //log_info("his_location: 3333333333333333333333333");
- if(!is_valid())
- {
- //if(p==m_p)
- if(point::eq(p.x,m_p.x,0.2) && point::eq(p.y,m_p.y,0.2))
- {
- set(p,timestamp);
- log_info("his_location:%d New Point Too close.Point[%.2f,%.2f]",m_cardid,p.x,p.y);
- return ;
- }
- auto v=find_path(m_p,p);
- if(v.empty())
- m_arg=make_arg(p,m_p);
- else
- {
- log_info("his_location:more_abnormal_point....%d,(%.2f,%.2f)---(%.2f,%.2f)",m_cardid,m_p.x,m_p.y,p.x,p.y);
- handle_path(v,timestamp,true);
- set_invalid();
- return;
- }
- log_info("his_location:%d arg:%f",m_cardid,m_arg);
- insert();
- return;
- }
- //log_info("his_location: 44444444444444444444444444444444444");
- bool flag=false;
- int iflag=0;
- //判断是否路径发生了变化
- //这里现在又判断,如果反向了也会返回true.但是不运作,依然走下面的逻辑就会有问题
- //比如速度
- flag=handle_message(p,timestamp);
- if(time_out(p,timestamp))
- if(!flag)iflag=1;
- if(is_speed_changed(p,timestamp))
- if(!flag)iflag=2;
- if(is_area_changed(areaid))
- if(!flag)iflag=3;
- if(is_map_changed(mapid))
- if(!flag)iflag=4;
- log_info("his_location cardid:%d:%d",m_cardid,iflag);
- if(iflag)
- {
- update(p,timestamp,iflag);
- //set_invalid();
- if(iflag>1){
- m_siteid = siteid;
- set(p,timestamp);
- insert();
- }
- }
- }
- void location_card::insert(uint64_t timestamp, const point & p, int32_t areaid, int32_t mapid, int32_t siteid, double scale)
- {
- double speed = 0.0;
- double dist = 0.0;
- if(m_timestamp != 0){
- dist = m_p.dist(p)*scale;
-
- if(fabs(dist) < 1){
- return;
- }
-
- double t = (timestamp - m_timestamp)/1000;
- speed = dist/t;
- if(std::isnan(speed)|| std::isinf(speed))
- speed=0;
- }
- m_timestamp = timestamp;
- m_p = p;
- char sql[512] = {0};
- snprintf(sql, 512, "replace into his_location_simplify(obj_id, card_type_id, ident, loc_time, map_id, area_id, begin_pt, reader_id, speed) values (%d, %d, %d, '%s', %d, %d, '%.2f,%.2f', %d, %.2f);", m_objid, m_type, m_cardid, tool_time::to_str(timestamp/1000).c_str(), mapid, areaid, p.x, p.y, siteid, speed);
- logn_info(2, "his_location_simplify: %d-%lu: %s", m_cardid, timestamp, sql);
- sDBConnPool.PushAsync(sql);
- }
- void location_card::insert()
- {
- //std::string tabName=getTabName();
- char nsql[512]={0};
- const char * sql = "replace into his_location (obj_id,card_type_id,ident,begin_time,map_id,area_id,begin_pt,direction,reader_id)"
- "values(%d,%d,%d,'%s',%d,%d,'%.2f,%.2f',%f,%d);";
- snprintf(nsql,512,sql,m_objid,m_type,m_cardid,tool_time::to_str(m_timestamp/1000).c_str(),m_mapid,m_areaid,m_p.x,m_p.y,m_arg,m_siteid);
- logn_info(2, "his_location[%d,%lu]:%s", m_cardid, m_timestamp, nsql);
- sDBConnPool.PushAsync(nsql);
- }
- void location_card::update(const point &p,uint64_t timestamp,int flag/*=0*/,int dflag/*=0*/)
- {
- //std::string tabName=getTabName();
- char nsql[512]={0};
- const char * sql = "update his_location set last_time='%s',speed=%.3f,direction=%f,location_flag=%d where obj_id=%d and begin_time='%s' and last_time is null;";
- double dist = m_p.dist(p);
- double t = (timestamp - m_timestamp)/1000;
- double avge_speed = dist/t;
- if(std::isnan(avge_speed)|| std::isinf(avge_speed))avge_speed=0;
- logn_info(2, "his_location_time[%d]:%d[%lu,%lu,%lu]", m_cardid, flag, last_timestamp, timestamp, m_timestamp);
- if(last_timestamp != 0)
- {
- const char * ss = "update his_location set last_time='%s',speed=%.3f,direction=%f,location_flag=%d where obj_id=%d and begin_time='%s' and last_time = '%s';";
- snprintf(nsql,512,ss,tool_time::to_str(timestamp/1000).c_str(),avge_speed,m_arg,dflag,m_objid,tool_time::to_str(m_timestamp/1000).c_str(),tool_time::to_str(last_timestamp/1000).c_str());
- }
- else
- snprintf(nsql,512,sql,tool_time::to_str(timestamp/1000).c_str(),avge_speed,m_arg,dflag,m_objid,tool_time::to_str(m_timestamp/1000).c_str());
- if(flag==1) last_timestamp=timestamp;
- else last_timestamp=0;
- logn_info(2, "his_location[%d]:%s[%lu,%lu]", m_cardid, nsql, timestamp, m_timestamp);
- sDBConnPool.PushAsync(nsql);
- }
- std::vector<point> location_card::find_path(const point &p1,const point &p2)
- {
- std::vector<point> rc=card_path::inst().find_path(point(p1.x,-p1.y),point(p2.x,-p2.y));
- return std::move(rc);
- }
- bool location_card::handle_message(const point &p,uint64_t timestamp)
- {
- bool flag = false;
- if(line_changed(p))
- {
- flag = true;
- std::vector<point> rc=find_path(m_p,p);
- if(rc.empty())
- {
- log_info("his_location:line_changed rc.empty() %d",m_cardid);
- update(m_d.back().p,m_d.back().time);
- set(m_d.back().p,m_d.back().time);
- }
- else
- {
- if(handle_path(rc,timestamp,false))
- return true;
- }
- //置m_arg非法
- set_invalid();
- }else{
- log_info("his_location: line not change");
- }
- return flag;
- }
- bool location_card::handle_path(std::vector<point> &rc,uint64_t timestamp,bool flag)
- {
- double dis=0;
- point _p=m_p;
- std::for_each(rc.begin(),rc.end(),[&dis,&_p](point &pt){
- pt.y = pt.y;
- dis+=_p.dist(pt);
- _p=pt;
- });
- uint64_t t=timestamp/1000 - m_timestamp/1000;
- if(t==0||dis<0.1){
- log_info("his_location: card_id=%d, t=%d, dist=%.2f, rc.size=%d", m_cardid, t, dis, rc.size());
- return true;
- }
- double avge_speed= dis/t;
- //有拐点 盲区时间差 距离
- uint64_t difftime = t;
- int dflag = 0;
- if(!m_d.empty())
- difftime = timestamp/1000-(m_d.back().time)/1000;
- if(difftime >= location_card::m_difftime && dis>location_card::m_distance)
- {
- log_info("his_location[%d]:abnormal_line difftime:%lu,ltime:%u,dis:%.2f,limit_dis:%d",m_cardid,difftime,location_card::m_difftime,dis,location_card::m_distance);
- dflag=1;
- }
- for(const point & pp:rc)
- {
- m_arg=make_arg(pp,m_p);
- if(flag)insert();
- log_info("his_location[%d]:line_changed_x point(%.2f,%.2f)--circle point(%.2f,%.2f),speed:%.2f",m_cardid,m_p.x,m_p.y,pp.x,pp.y,avge_speed);
- double dist=m_p.dist(pp);uint64_t tt=dist/avge_speed*1000;
- uint64_t etime=m_timestamp+tt;
- update(pp,etime,0,dflag);
- set(pp,etime);
- flag=true;
- }
- return false;
- }
|