|
@@ -1,6 +1,10 @@
|
|
|
#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;
|
|
@@ -19,3 +23,326 @@ location_card::location_card(uint32_t id,uint64_t type,uint32_t objid)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void location_card::init()
|
|
|
+{
|
|
|
+ m_areaid=-1;
|
|
|
+ m_mapid=-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)
|
|
|
+{
|
|
|
+ log_info("his_location:card[%d] area[%d] Point(%.2f,%.2f)--->(%.2f,%.2f)",m_cardid,areaid,m_p.x,m_p.y,p.x,p.y);
|
|
|
+
|
|
|
+ if(m_p.empty() || m_timestamp==0||m_areaid<0||m_mapid<0)
|
|
|
+ {
|
|
|
+ set(p,timestamp);
|
|
|
+ m_areaid=areaid;m_mapid=mapid;
|
|
|
+ m_d.emplace(p,timestamp);
|
|
|
+ return ;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ 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){
|
|
|
+ set(p,timestamp);
|
|
|
+ insert();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+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)"
|
|
|
+ "values(%d,%d,%d,'%s',%d,%d,'%.2f,%.2f',%f);";
|
|
|
+ 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);
|
|
|
+ log_info("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;
|
|
|
+
|
|
|
+ log_info("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;
|
|
|
+
|
|
|
+ log_info("his_location[%d]:%s[%lu,%lu]",m_cardid,nsql,timestamp,m_timestamp);
|
|
|
+ sDBConnPool.PushAsync(nsql);
|
|
|
+}
|
|
|
+
|
|
|
+//查询之前未处理数据last_time is null
|
|
|
+bool location_card::up_mine (const point & p1,int areaid,uint64_t timestamp)
|
|
|
+{
|
|
|
+ if (timestamp < m_timestamp || m_timestamp == 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ char nsql[512] = {0};
|
|
|
+ double t = (m_timestamp - m_timestamp) / 1000;
|
|
|
+ if (t < 0.001) t = 1.0;
|
|
|
+ double speed = 0.0;
|
|
|
+ int dist = p1.dist(m_p);
|
|
|
+ if(dist > 10) //当前点距离原来的点有点远
|
|
|
+ {
|
|
|
+ speed = dist / t;
|
|
|
+ if (std::isnan(speed) || std::isinf(speed)) {
|
|
|
+ speed = 0.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;";
|
|
|
+ snprintf(nsql, 512, sql, tool_time::to_str(timestamp / 1000).c_str(), speed, m_arg, 1, m_objid,tool_time::to_str(m_timestamp/1000).c_str());
|
|
|
+ log_info("up_mine: his_location[%d]:%s[%lu,%lu]",m_cardid,nsql,timestamp,m_timestamp);
|
|
|
+ sDBConnPool.PushAsync(nsql);
|
|
|
+
|
|
|
+ memset(nsql,0, sizeof(nsql));
|
|
|
+ const char * insert_sql = "replace into his_location (obj_id,card_type_id,ident,begin_time,last_time,map_id,area_id,begin_pt,direction)"
|
|
|
+ "values(%d,%d,%d,'%s',%d,%d,'%.2f,%.2f',%f);";
|
|
|
+ snprintf(nsql,512,insert_sql,m_objid,m_type,m_cardid,tool_time::to_str(timestamp/1000).c_str(),tool_time::to_str(timestamp/1000 + 1).c_str(),m_mapid
|
|
|
+ ,m_areaid,p1.x,p1.y,m_arg);
|
|
|
+ log_info("up_mine: his_location[%d,%lu]:%s",m_cardid,m_timestamp,nsql);
|
|
|
+ sDBConnPool.PushAsync(nsql);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ 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;";
|
|
|
+ snprintf(nsql, 512, sql, tool_time::to_str(timestamp / 1000).c_str(), 0.0, m_arg, 1, m_objid,tool_time::to_str(m_timestamp/1000).c_str());
|
|
|
+
|
|
|
+ log_info("up_mine: his_location[%d]:%s[%lu,%lu]",m_cardid,nsql,timestamp,m_timestamp);
|
|
|
+ sDBConnPool.PushAsync(nsql);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+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);
|
|
|
+}
|
|
|
+//virtual bool handle_message(const point &p,uint64_t timestamp)=0;
|
|
|
+bool location_card::handle_message(const point &p,uint64_t timestamp)
|
|
|
+{
|
|
|
+ bool flag = false;
|
|
|
+ //int df=0;
|
|
|
+ if(line_changed(p))//,df))
|
|
|
+ {
|
|
|
+ flag = true;
|
|
|
+ //std::vector<point> rc=find_path(m_d.back().p,p);
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ //if(df==1)flag=true;
|
|
|
+ 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)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;
|
|
|
+}
|