his_location.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include "his_location.h"
  2. #include "log.h"
  3. #include "tool_time.h"
  4. #include "card_path.h"
  5. #include "db_api/CDBSingletonDefine.h"
  6. #include <config_file.h>
  7. extern config_file config;
  8. uint32_t location_card::m_difftime=0;
  9. int location_card::m_distance=-1;
  10. location_card::location_card(uint32_t id,uint64_t type,uint32_t objid)
  11. :m_cardid(id)
  12. ,m_type(type)
  13. ,m_objid(objid)
  14. {
  15. init();
  16. if(location_card::m_distance==-1)
  17. {
  18. location_card::m_difftime=config.get("service.difftime",300);
  19. location_card::m_distance=config.get("service.distance",30);
  20. log_info("his_location_init:%u,%d",m_difftime,m_distance);
  21. }
  22. }
  23. void location_card::init()
  24. {
  25. m_areaid=-1;
  26. m_mapid=-1;
  27. m_timestamp=0;
  28. m_p.set(0,0);
  29. std::queue<mini_data> tmp;
  30. m_d.swap(tmp);
  31. m_direct_index=0;
  32. last_timestamp=0;
  33. set_invalid();
  34. }
  35. void location_card::init_att(const point &pt,uint64_t time)
  36. {
  37. std::queue<mini_data> tmp;
  38. m_d.swap(tmp);
  39. m_d.emplace(pt,time);
  40. }
  41. void location_card::set_invalid()
  42. {
  43. m_arg=0x12345678;
  44. }
  45. bool location_card::is_valid()
  46. {
  47. return m_arg!=0x12345678;
  48. }
  49. double location_card::make_arg(const point &pt,const point &p)
  50. {
  51. 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);
  52. return std::arg(std::complex<double>(pt.x,pt.y)-std::complex<double>(p.x,p.y));
  53. }
  54. void location_card::set(const point &pt,uint64_t time)
  55. {
  56. m_timestamp=time;
  57. m_p.set(pt);
  58. init_att(pt,time);
  59. }
  60. bool location_card::line_changed(const point &pt)//,int &df)
  61. {
  62. if(!is_valid())
  63. return false;
  64. point p;
  65. if(m_d.empty())p=m_p; else p=m_d.back().p;
  66. if(point::eq(p.x,pt.x,0.2) && point::eq(p.y,pt.y,0.2)) return false;
  67. double dis1=m_p.dist(pt);
  68. if(dis1<2)return false;
  69. //double dis = p.dist(pt);
  70. double dis = m_p.dist(pt);
  71. double arg = make_arg(pt,m_p);
  72. //查看路径方向是否改变
  73. bool change_flag=(arg-m_arg > -1e-10 && arg-m_arg<1e-10);
  74. //change_flag为true,标识没有发生变化
  75. // if(change_flag)m_direct_index=0;
  76. 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);
  77. //if(dis<0.5 && fabs(fabs(arg)+fabs(m_arg)-3.141593)< 0.000005)
  78. // return false;
  79. //判断10次反向才做下一步动作
  80. // if(fabs(fabs(arg)+fabs(m_arg)-3.141593)< 0.000005)
  81. // {
  82. // if(++m_direct_index<=10)
  83. // {
  84. // df=1;return false;
  85. // }
  86. // }
  87. //return !point::eq(arg,m_arg,1e-10);
  88. return !change_flag;
  89. }
  90. bool location_card::is_speed_changed(const point& pt,uint64_t time)
  91. {
  92. bool flag = false;
  93. double v=0.0;
  94. point ps=m_d.back().p;
  95. if(ps.dist(pt)<0.1)return flag;
  96. if(m_d.size()>=4)
  97. {
  98. mini_data d1 = m_d.front();
  99. double dist = d1.p.dist(pt);
  100. double t = time-d1.time;
  101. v = dist/t*1000;
  102. m_d.pop();
  103. }
  104. m_d.emplace(pt,time);
  105. if(v<=0.1)
  106. return flag;
  107. double dist = m_p.dist(pt);
  108. double t = time - m_timestamp;
  109. double avge_speed= dist/t*1000;
  110. 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);
  111. if(v<(1-0.3)*avge_speed || v>(1+0.3)*avge_speed)
  112. flag=true;
  113. return flag;
  114. }
  115. bool location_card::time_out(const point &p,uint64_t time)
  116. {
  117. uint64_t t=last_timestamp==0?m_timestamp:last_timestamp;
  118. if(time-t>=30*1000 && m_p.dist(p)>0.1)
  119. return true;
  120. return false;
  121. }
  122. bool location_card::is_area_changed(int new_areaid)
  123. {
  124. bool flag =false;
  125. if(m_areaid != new_areaid)
  126. {
  127. m_areaid = new_areaid;
  128. flag=true;
  129. }
  130. return flag;
  131. }
  132. bool location_card::is_map_changed(int new_mapid)
  133. {
  134. bool flag =false;
  135. if(m_mapid != new_mapid)
  136. {
  137. m_mapid = new_mapid;
  138. flag=true;
  139. }
  140. return flag;
  141. }
  142. void location_card::push(uint64_t timestamp,const point & p,int32_t areaid,int32_t mapid,bool bclose/* = false*/)
  143. {
  144. if (bclose) //卡移除后直接更新his_location
  145. {
  146. update(p,timestamp);
  147. return;
  148. }
  149. if(m_p.empty() || m_timestamp==0||m_areaid<0||m_mapid<0)
  150. {
  151. set(p,timestamp);
  152. m_areaid=areaid;m_mapid=mapid;
  153. m_d.emplace(p,timestamp);
  154. return ;
  155. }
  156. if(!is_valid())
  157. {
  158. //if(p==m_p)
  159. if(point::eq(p.x,m_p.x,0.2) && point::eq(p.y,m_p.y,0.2))
  160. {
  161. set(p,timestamp);
  162. log_info("his_location:%d New Point Too close.Point[%.2f,%.2f]",m_cardid,p.x,p.y);
  163. return ;
  164. }
  165. auto v=find_path(m_p,p);
  166. if(v.empty())
  167. m_arg=make_arg(p,m_p);
  168. else
  169. {
  170. log_info("his_location:more_abnormal_point....%d,(%.2f,%.2f)---(%.2f,%.2f)",m_cardid,m_p.x,m_p.y,p.x,p.y);
  171. handle_path(v,timestamp,true);
  172. set_invalid();
  173. return;
  174. }
  175. log_info("his_location:%d arg:%f",m_cardid,m_arg);
  176. insert();
  177. return;
  178. }
  179. bool flag=false;
  180. int iflag=0;
  181. //判断是否路径发生了变化
  182. //这里现在又判断,如果反向了也会返回true.但是不运作,依然走下面的逻辑就会有问题
  183. //比如速度
  184. flag=handle_message(p,timestamp);
  185. if(time_out(p,timestamp))
  186. if(!flag)iflag=1;
  187. if(is_speed_changed(p,timestamp))
  188. if(!flag)iflag=2;
  189. if(is_area_changed(areaid))
  190. if(!flag)iflag=3;
  191. if(is_map_changed(mapid))
  192. if(!flag)iflag=4;
  193. log_info("his_location cardid:%d:%d",m_cardid,iflag);
  194. if(iflag)
  195. {
  196. update(p,timestamp,iflag);
  197. //set_invalid();
  198. if(iflag>1){
  199. set(p,timestamp);
  200. insert();
  201. }
  202. }
  203. }
  204. void location_card::insert()
  205. {
  206. //std::string tabName=getTabName();
  207. char nsql[512]={0};
  208. const char * sql = "replace into his_location (obj_id,card_type_id,ident,begin_time,map_id,area_id,begin_pt,direction)"
  209. "values(%d,%d,%d,'%s',%d,%d,'%.2f,%.2f',%f);";
  210. 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);
  211. log_info("his_location[%d,%lu]:%s",m_cardid,m_timestamp,nsql);
  212. sDBConnPool.PushAsync(nsql);
  213. }
  214. void location_card::update(const point &p,uint64_t timestamp,int flag/*=0*/,int dflag/*=0*/)
  215. {
  216. //std::string tabName=getTabName();
  217. char nsql[512]={0};
  218. 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;";
  219. double dist = m_p.dist(p);
  220. double t = (timestamp - m_timestamp)/1000;
  221. double avge_speed= dist/t;
  222. if(std::isnan(avge_speed)|| std::isinf(avge_speed))avge_speed=0;
  223. log_info("his_location_time[%d]:%d[%lu,%lu,%lu]",m_cardid,flag,last_timestamp,timestamp,m_timestamp);
  224. if(last_timestamp != 0)
  225. {
  226. 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';";
  227. 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());
  228. }
  229. else
  230. 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());
  231. if(flag==1) last_timestamp=timestamp;
  232. else last_timestamp=0;
  233. log_info("his_location[%d]:%s[%lu,%lu]",m_cardid,nsql,timestamp,m_timestamp);
  234. sDBConnPool.PushAsync(nsql);
  235. }
  236. std::vector<point> location_card::find_path(const point &p1,const point &p2)
  237. {
  238. std::vector<point> rc=card_path::inst().find_path(point(p1.x,-p1.y),point(p2.x,-p2.y));
  239. return std::move(rc);
  240. }
  241. //virtual bool handle_message(const point &p,uint64_t timestamp)=0;
  242. bool location_card::handle_message(const point &p,uint64_t timestamp)
  243. {
  244. bool flag = false;
  245. //int df=0;
  246. if(line_changed(p))//,df))
  247. {
  248. flag = true;
  249. //std::vector<point> rc=find_path(m_d.back().p,p);
  250. std::vector<point> rc=find_path(m_p,p);
  251. if(rc.empty())
  252. {
  253. log_info("his_location:line_changed rc.empty() %d",m_cardid);
  254. update(m_d.back().p,m_d.back().time);
  255. set(m_d.back().p,m_d.back().time);
  256. }
  257. else
  258. {
  259. if(handle_path(rc,timestamp,false))
  260. return true;
  261. }
  262. //置m_arg非法
  263. set_invalid();
  264. }
  265. //if(df==1)flag=true;
  266. return flag;
  267. }
  268. bool location_card::handle_path(std::vector<point> &rc,uint64_t timestamp,bool flag)
  269. {
  270. double dis=0;point _p=m_p;
  271. std::for_each(rc.begin(),rc.end(),[&dis,&_p](point &pt){
  272. pt.y=-pt.y;dis+=_p.dist(pt);_p=pt;
  273. });
  274. uint64_t t=timestamp/1000 - m_timestamp/1000;
  275. if(t==0||dis<0.1)return true;
  276. double avge_speed= dis/t;
  277. //有拐点 盲区时间差 距离
  278. uint64_t difftime=t;int dflag=0;
  279. if(!m_d.empty()) difftime=timestamp/1000-(m_d.back().time)/1000;
  280. if(difftime>=location_card::m_difftime && dis>location_card::m_distance)
  281. {
  282. 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);
  283. dflag=1;
  284. }
  285. for(const point & pp:rc)
  286. {
  287. m_arg=make_arg(pp,m_p);
  288. if(flag)insert();
  289. 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);
  290. double dist=m_p.dist(pp);uint64_t tt=dist/avge_speed*1000;
  291. uint64_t etime=m_timestamp+tt;
  292. update(pp,etime,0,dflag);
  293. set(pp,etime);
  294. flag=true;
  295. }
  296. return false;
  297. }
  298. void location_card::deal_up_well()
  299. {
  300. //更新location
  301. if (m_d.size()>0)
  302. {
  303. last_timestamp = 0;
  304. update(m_d.back().p, m_d.back().time);
  305. }
  306. //重置参数
  307. init();
  308. }