his_location.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #ifndef __INCLUDE_HIS_LOCATION_HPP
  2. #define __INCLUDE_HIS_LOCATION_HPP
  3. #include <complex>
  4. #include <queue>
  5. #include "point.h"
  6. #include "log.h"
  7. #include "db_api/CDBConnPool.h"
  8. //速度
  9. //区域 地图变换
  10. //运动方向
  11. //路径变换
  12. struct location_card
  13. {
  14. location_card(uint32_t id,uint64_t type)
  15. :m_cardid(id)
  16. ,m_type(type)
  17. {
  18. init();
  19. }
  20. uint32_t m_cardid;//卡id
  21. uint16_t m_type;//卡类型
  22. double m_arg;//运动方向角度值
  23. int m_areaid;//区域
  24. int m_mapid;//地图
  25. uint64_t m_timestamp;//入库后的时间
  26. point m_p;//入库后的点
  27. struct mini_data
  28. {
  29. mini_data(const point &p,uint64_t t)
  30. :p(p)
  31. ,time(t)
  32. {}
  33. point p;
  34. uint64_t time;
  35. };
  36. std::queue<mini_data> m_d;
  37. void init()
  38. {
  39. m_areaid=-1;
  40. m_mapid=-1;
  41. m_timestamp=0;
  42. m_p.set(0,0);
  43. init_att();
  44. }
  45. void init_att()
  46. {
  47. m_arg=0x12345678;
  48. std::queue<mini_data> tmp;
  49. m_d.swap(tmp);
  50. }
  51. void set_invalid()
  52. {
  53. m_arg=0x12345678;
  54. }
  55. bool is_valid()
  56. {
  57. return m_arg!=0x12345678;
  58. }
  59. double make_arg(const point &pt,const point &p)
  60. {
  61. 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);
  62. return std::arg(std::complex<double>(pt.x,pt.y)-std::complex<double>(p.x,p.y));
  63. }
  64. void set(const point &pt,uint64_t time)
  65. {
  66. m_timestamp=time;
  67. m_p.set(pt);
  68. }
  69. bool line_changed(const point &pt)
  70. {
  71. if(!is_valid())
  72. return false;
  73. point p=m_d.back().p;
  74. if(p==pt)p=m_p;
  75. double arg = make_arg(pt,p);
  76. log_info("his_location:line_changed:%d,%.2f,m_arg:%.2f",m_cardid,arg,m_arg);
  77. return arg != m_arg;
  78. }
  79. bool is_speed_changed(const point& pt,uint64_t time)
  80. {
  81. bool flag = false;
  82. double v=0.0;
  83. if(m_d.size()>=4)
  84. {
  85. mini_data d1 = m_d.front();
  86. double dist = d1.p.dist(pt);
  87. double t = time-d1.time;
  88. v = dist/t*1000;
  89. m_d.pop();
  90. }
  91. m_d.emplace(pt,time);
  92. if(v==0.0)
  93. return flag;
  94. double dist = m_p.dist(pt);
  95. double t = time - m_timestamp;
  96. double avge_speed= dist/t*1000;
  97. log_info("his_location cardid:%d:v:%.2f,avge_v:%.2f,(%.2f--%.2f)",m_cardid,v,avge_speed,0.8*avge_speed,1.2*avge_speed);
  98. if(v<(1-0.2)*avge_speed && v>(1+0.2)*avge_speed)
  99. flag=true;
  100. return flag;
  101. }
  102. bool time_out(uint64_t time)
  103. {
  104. if(time-m_timestamp>=60*1000)
  105. return true;
  106. return false;
  107. }
  108. bool is_area_changed(int new_areaid)
  109. {
  110. bool flag =false;
  111. if(m_areaid != new_areaid)
  112. {
  113. m_areaid = new_areaid;
  114. flag=true;
  115. }
  116. return flag;
  117. }
  118. bool is_map_changed(int new_mapid)
  119. {
  120. bool flag =false;
  121. if(m_mapid != new_mapid)
  122. {
  123. m_mapid = new_mapid;
  124. flag=true;
  125. }
  126. return flag;
  127. }
  128. void push(uint64_t timestamp,const point & p,int32_t areaid,int32_t mapid)
  129. {
  130. if(m_p.empty() || m_timestamp==0||m_areaid<=0||m_mapid<=0)
  131. {
  132. set(p,timestamp);
  133. m_areaid=areaid;m_mapid=mapid;
  134. m_d.emplace(p,timestamp);
  135. return;
  136. }
  137. if(!is_valid())
  138. {
  139. if(p==m_p)
  140. {
  141. init_att();set(p,timestamp);
  142. m_d.emplace(p,timestamp);
  143. return ;
  144. }
  145. m_arg=make_arg(p,m_p);
  146. log_info("his_location:%d arg:%f",m_cardid,m_arg);
  147. insert();
  148. }
  149. bool flag=false;
  150. bool iflag=false;
  151. flag=handle_message(p,timestamp);
  152. if(time_out(timestamp))
  153. if(!flag)iflag=true;
  154. if(is_speed_changed(p,timestamp))
  155. if(!flag)iflag=true;
  156. if(is_area_changed(areaid))
  157. if(!flag)iflag=true;
  158. if(is_map_changed(mapid))
  159. if(!flag)iflag=true;
  160. if(iflag)
  161. {
  162. update(p,timestamp);
  163. set_invalid();
  164. set(p,timestamp);
  165. }
  166. }
  167. virtual std::string getTabName()=0;
  168. void insert()
  169. {
  170. std::string tabName=getTabName();
  171. char nsql[512]={0};
  172. const char * sql = "replace into %s (card_id,begin_time,map_id,area_id,begin_pt,direction)values(%03d%010d,'%s',%d,%d,'%.2f,%.2f',%f);";
  173. snprintf(nsql,512,sql,tabName.c_str(),m_type,m_cardid,tool_time::to_str_ex(m_timestamp).c_str(),m_mapid,m_areaid,m_p.x,m_p.y,m_arg);
  174. log_info("his_location[%d]:%s",m_cardid,nsql);
  175. sDBConnPool.PushAsync(nsql);
  176. }
  177. void update(const point &p,uint64_t timestamp)
  178. {
  179. std::string tabName=getTabName();
  180. char nsql[512]={0};
  181. const char * sql = "update %s set last_time='%s',speed=%.2f where card_id=%03d%010d and begin_time='%s';";
  182. double dist = m_p.dist(p);
  183. double t = timestamp - m_timestamp;
  184. double avge_speed= dist/t*1000;
  185. snprintf(nsql,512,sql,tabName.c_str(),tool_time::to_str_ex(timestamp).c_str(),avge_speed,m_type,m_cardid,tool_time::to_str_ex(m_timestamp).c_str());
  186. log_info("his_location[%d]:%s",m_cardid,nsql);
  187. sDBConnPool.PushAsync(nsql);
  188. }
  189. virtual bool handle_message(const point &p,uint64_t timestamp)=0;
  190. };
  191. struct location_staff:location_card
  192. {
  193. location_staff(uint32_t id,uint16_t type)
  194. :location_card(id,type)
  195. {}
  196. virtual std::string getTabName(){return std::string{"his_location_staff_"};}
  197. //人员如果运行方向发生变化的话,需要求的拐点。如果有拐点,入拐点。时间大与120s则不做处理。没有拐点,则不求
  198. virtual bool handle_message(const point &p,uint64_t timestamp)
  199. {
  200. bool flag = false;
  201. if(line_changed(p))
  202. {
  203. log_info("his_location:line_changed %d",m_cardid);
  204. flag=true;
  205. if(timestamp-m_timestamp>120*1000)
  206. {
  207. update(m_d.back().p,m_d.back().time);
  208. set(p,timestamp);
  209. }
  210. else
  211. {
  212. std::vector<point> rc=card_path::inst().find_path(m_p,p);
  213. if(rc.empty())
  214. {
  215. update(m_d.back().p,m_d.back().time);
  216. set(m_d.back().p,m_d.back().time);
  217. }
  218. else
  219. {
  220. if(rc.size()==1)
  221. {
  222. log_info("his_location:line_changed %d circle point(%.2f,%.2f)",m_cardid,rc[0].x,rc[0].y);
  223. update(rc[0],m_d.back().time);
  224. set(rc[0],m_d.back().time);
  225. }
  226. else if(rc.size()==2)
  227. {
  228. update(rc[0],m_d.back().time);
  229. set(rc[0],m_d.back().time);
  230. //
  231. m_arg=make_arg(rc[1],m_p);
  232. insert();
  233. //
  234. update(rc[1],timestamp);
  235. set(rc[1],timestamp);
  236. }
  237. else//更多的拐点
  238. {
  239. update(rc[0],m_d.back().time);
  240. set(rc[1],timestamp);
  241. }
  242. }
  243. }
  244. init_att();
  245. }
  246. return flag;
  247. }
  248. };
  249. struct location_vehicle:location_card
  250. {
  251. location_vehicle(uint32_t id,uint16_t type)
  252. :location_card(id,type)
  253. {}
  254. virtual std::string getTabName(){return std::string{"his_location_vehicle_"};}
  255. //车辆是有推送拐点的,所以不需要求拐点。如果运行方向发生变化的话,直接更新数据库即可,使用上一个点的时间。同时生成这一次的历史。
  256. virtual bool handle_message(const point &p,uint64_t timestamp)
  257. {
  258. bool flag =false;
  259. if(line_changed(p))
  260. {
  261. log_info("his_location:line_changed %d ",m_cardid);
  262. flag=true;
  263. update(m_d.back().p,m_d.back().time);
  264. set(m_d.back().p,m_d.back().time);init_att();
  265. }
  266. return flag;
  267. }
  268. };
  269. #endif