his_location.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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. #include "load_raw.h"
  8. extern config_file config;
  9. uint32_t location_card::m_difftime=0;
  10. int location_card::m_distance=-1;
  11. location_card::location_card(uint32_t id,uint64_t type,uint32_t objid)
  12. :m_cardid(id)
  13. ,m_type(type)
  14. ,m_objid(objid)
  15. {
  16. init();
  17. if(location_card::m_distance==-1)
  18. {
  19. location_card::m_difftime=config.get("service.difftime",300);
  20. location_card::m_distance=config.get("service.distance",30);
  21. log_info("his_location_init:%u,%d",m_difftime,m_distance);
  22. }
  23. }
  24. void location_card::init()
  25. {
  26. m_areaid=-1;
  27. m_mapid=-1;
  28. m_siteid = -1;
  29. m_timestamp=0;
  30. m_p.set(0,0);
  31. std::queue<mini_data> tmp;
  32. m_d.swap(tmp);
  33. m_direct_index=0;
  34. last_timestamp=0;
  35. set_invalid();
  36. }
  37. void location_card::init_att(const point &pt,uint64_t time)
  38. {
  39. std::queue<mini_data> tmp;
  40. m_d.swap(tmp);
  41. m_d.emplace(pt,time);
  42. }
  43. void location_card::set_invalid()
  44. {
  45. m_arg=0x12345678;
  46. }
  47. bool location_card::is_valid()
  48. {
  49. return m_arg!=0x12345678;
  50. }
  51. double location_card::make_arg(const point &pt,const point &p)
  52. {
  53. 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);
  54. return std::arg(std::complex<double>(pt.x,pt.y)-std::complex<double>(p.x,p.y));
  55. }
  56. void location_card::set(const point &pt,uint64_t time)
  57. {
  58. m_timestamp=time;
  59. m_p.set(pt);
  60. init_att(pt,time);
  61. }
  62. bool location_card::line_changed(const point &pt)//,int &df)
  63. {
  64. if(!is_valid())
  65. return false;
  66. point p;
  67. if(m_d.empty())
  68. p=m_p;
  69. else
  70. p=m_d.back().p;
  71. if(point::eq(p.x,pt.x,0.2) && point::eq(p.y,pt.y,0.2)) return false;
  72. double dis1=m_p.dist(pt);
  73. if(dis1<2)return false;
  74. //double dis = p.dist(pt);
  75. double dis = m_p.dist(pt);
  76. double arg = make_arg(pt,m_p);
  77. //查看路径方向是否改变
  78. bool change_flag=(arg-m_arg > -1e-10 && arg-m_arg<1e-10);
  79. //change_flag为true,标识没有发生变化
  80. // if(change_flag)m_direct_index=0;
  81. 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);
  82. return !change_flag;
  83. }
  84. bool location_card::is_speed_changed(const point& pt,uint64_t time)
  85. {
  86. bool flag = false;
  87. double v=0.0;
  88. point ps=m_d.back().p;
  89. if(ps.dist(pt)<0.1)return flag;
  90. if(m_d.size()>=4)
  91. {
  92. mini_data d1 = m_d.front();
  93. double dist = d1.p.dist(pt);
  94. double t = time-d1.time;
  95. v = dist/t*1000;
  96. m_d.pop();
  97. }
  98. m_d.emplace(pt,time);
  99. if(v<=0.1)
  100. return flag;
  101. double dist = m_p.dist(pt);
  102. double t = time - m_timestamp;
  103. double avge_speed= dist/t*1000;
  104. 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);
  105. if(v<(1-0.3)*avge_speed || v>(1+0.3)*avge_speed)
  106. flag=true;
  107. return flag;
  108. }
  109. bool location_card::time_out(const point &p,uint64_t time)
  110. {
  111. uint64_t t=last_timestamp==0?m_timestamp:last_timestamp;
  112. if(time-t>=30*1000 && m_p.dist(p)>0.1)
  113. return true;
  114. return false;
  115. }
  116. //区域是否发生变化
  117. bool location_card::is_area_changed(int new_areaid)
  118. {
  119. bool flag =false;
  120. if(m_areaid != new_areaid)
  121. {
  122. m_areaid = new_areaid;
  123. flag=true;
  124. }
  125. return flag;
  126. }
  127. //地图是否发生变化
  128. bool location_card::is_map_changed(int new_mapid)
  129. {
  130. bool flag =false;
  131. if(m_mapid != new_mapid)
  132. {
  133. m_mapid = new_mapid;
  134. flag=true;
  135. }
  136. return flag;
  137. }
  138. void location_card::push(uint64_t timestamp,const point & p,int32_t areaid,int32_t mapid,int32_t siteid,bool bclose/* = false*/)
  139. {
  140. //log_info("his_location: 1111111111111111111; timestamp=%d, p.x=%.2f, p.y=%.2f", timestamp, p.x, p.y);
  141. if (bclose) //卡移除后直接更新his_location
  142. {
  143. update(p,timestamp);
  144. init();
  145. return;
  146. }
  147. //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);
  148. if(m_p.empty() || m_timestamp==0||m_areaid<0||m_mapid<0 || m_siteid < 0)
  149. {
  150. set(p,timestamp);
  151. m_areaid = areaid;
  152. m_mapid = mapid;
  153. m_siteid = siteid;
  154. m_d.emplace(p,timestamp);
  155. return ;
  156. }
  157. if(!is_valid())
  158. {
  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. m_siteid = siteid;
  200. set(p,timestamp);
  201. insert();
  202. }
  203. }
  204. }
  205. void location_card::insert(uint64_t timestamp, const point & p, int32_t areaid, int32_t mapid, int32_t siteid, double scale)
  206. {
  207. double speed = 0.0;
  208. double dist = 0.0;
  209. if(m_timestamp != 0){
  210. dist = m_p.dist(p)*scale;
  211. if(fabs(dist) < 1){
  212. return;
  213. }
  214. double t = (timestamp - m_timestamp)/1000;
  215. speed = dist/t;
  216. if(std::isnan(speed)|| std::isinf(speed))
  217. speed=0;
  218. }
  219. m_timestamp = timestamp;
  220. m_p = p;
  221. char sql[512] = {0};
  222. 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);
  223. logn_info(2, "his_location_simplify: %d-%lu: %s", m_cardid, timestamp, sql);
  224. //zmg
  225. if (load_raw::m_is_history == false)
  226. {
  227. sDBConnPool.PushAsync(sql);
  228. }
  229. }
  230. void location_card::insert()
  231. {
  232. //std::string tabName=getTabName();
  233. char nsql[512]={0};
  234. const char * sql = "replace into his_location (obj_id,card_type_id,ident,begin_time,map_id,area_id,begin_pt,direction,reader_id)"
  235. "values(%d,%d,%d,'%s',%d,%d,'%.2f,%.2f',%f,%d);";
  236. 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);
  237. logn_info(2, "his_location[%d,%lu]:%s", m_cardid, m_timestamp, nsql);
  238. sDBConnPool.PushAsync(nsql);
  239. }
  240. void location_card::insert_simplify(const loc_point &pt, uint64_t timestamp)
  241. {
  242. if (timestamp <= 0) {
  243. return;
  244. }
  245. std::string time = tool_time::to_str(timestamp / 1000);
  246. if (load_raw::m_is_history)
  247. {
  248. time = load_raw::m_date;
  249. //历史记录覆盖,先删除原有同时间、卡号记录
  250. char sql[1024] = { 0 };
  251. snprintf(sql, 1024, "delete from his_location_simplify where obj_id = %d and loc_time = '%s'",
  252. pt.m_cid,
  253. time.c_str());
  254. log_info("[sql] %s", sql);
  255. sDBConnPool.PushAsync(sql);
  256. }
  257. //按新表插入
  258. char sql[1024] = { 0 };
  259. snprintf(sql, 1024, "insert into his_location_simplify(obj_id, loc_time, reader_id, speed, begin_pt, gesture, pdoa_distance, angle) values(%d, '%s', %d, %.2f, '%.2f,%.2f', %d, %.2f, %.2f)",
  260. pt.m_cid,
  261. time.c_str(),
  262. pt.m_sid,
  263. pt.m_speed == INFINITY ? 0.0 : pt.m_speed,
  264. pt.x,
  265. pt.y,
  266. pt.m_stat,
  267. pt.m_dist,
  268. pt.m_angle);
  269. log_info("[sql] %s", sql);
  270. sDBConnPool.PushAsync(sql);
  271. }
  272. void location_card::insert_cell_card(const loc_point &pt, uint64_t timestamp)
  273. {
  274. if (timestamp <= 0) {
  275. return;
  276. }
  277. std::string time = tool_time::to_str_ex(timestamp).c_str();
  278. {
  279. //历史记录覆盖,先删除原有同时间、卡号记录
  280. char sql[1024] = { 0 };
  281. snprintf(sql, 1024, "delete from his_location_cell_card where card_id = %d and loc_time = '%s'",
  282. pt.m_cid,
  283. time.c_str());
  284. log_info("[sql] %s", sql);
  285. sDBConnPool.PushAsync(sql);
  286. }
  287. //按新表插入
  288. char sql[1024] = { 0 };
  289. snprintf(sql, 1024, "insert into his_location_cell_card(card_id, loc_time, reader_id, speed, pdoa_distance, acceleration, angle_accumulation, cell_index, moving_direction, speed_change_rate, begin_pt) values(%d, '%s', %d, %.2f, %.2f, %.2f, %.2f, %d, '%s', %.2f, '%.2f,%.2f')",
  290. pt.m_cid,
  291. time.c_str(),
  292. pt.m_sid,
  293. pt.m_speed_avg == INFINITY ? 0.0 : pt.m_speed_avg,
  294. pt.m_dist,
  295. pt.m_acc,
  296. pt.m_rav,
  297. pt.m_cell_index,
  298. pt.m_direction.c_str(),
  299. pt.m_speed_change_rate,
  300. pt.x,
  301. pt.y);
  302. log_info("[sql] %s", sql);
  303. sDBConnPool.PushAsync(sql);
  304. }
  305. void location_card::insert_cell_reader(const loc_point &pt, uint64_t timestamp)
  306. {
  307. if (timestamp <= 0) {
  308. return;
  309. }
  310. std::string time = tool_time::to_str_ex(timestamp).c_str();
  311. {
  312. //历史记录覆盖,先删除原有同时间、卡号记录
  313. char sql[1024] = { 0 };
  314. snprintf(sql, 1024, "delete from his_location_cell_reader where reader_id = %d and cell_index = %d",
  315. pt.m_sid,
  316. pt.m_cell_index);
  317. log_info("[sql] %s", sql);
  318. sDBConnPool.PushAsync(sql);
  319. }
  320. //按新表插入
  321. char sql[1024] = { 0 };
  322. snprintf(sql, 1024, "insert into his_location_cell_reader(cell_index, reader_id, card_id, loc_time, pdoa_distance) values(%d, %d, %d, '%s', %.2f)",
  323. pt.m_cell_index,
  324. pt.m_sid,
  325. pt.m_cid,
  326. time.c_str(),
  327. pt.m_dist);
  328. log_info("[sql] %s", sql);
  329. sDBConnPool.PushAsync(sql);
  330. }
  331. void location_card::insert_vehicle_worktime(uint32_t card_id, uint64_t timestamp)
  332. {
  333. //按新表插入
  334. char sql[1024] = { 0 };
  335. std::string time = tool_time::to_str_ex(timestamp).c_str();
  336. snprintf(sql, 1024, "replace into his_vehicle_worktime (card_id, work_Time) values(%d, '%s'); ",
  337. card_id,
  338. time.c_str());
  339. log_info("[sql] %s", sql);
  340. sDBConnPool.PushAsync(sql);
  341. }
  342. void location_card::update(const point &p,uint64_t timestamp,int flag/*=0*/,int dflag/*=0*/)
  343. {
  344. //std::string tabName=getTabName();
  345. if(timestamp <= 0){
  346. return;
  347. }
  348. char nsql[512]={0};
  349. 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;";
  350. double dist = m_p.dist(p);
  351. double t = (timestamp - m_timestamp)/1000;
  352. double avge_speed = dist/t;
  353. if(std::isnan(avge_speed)|| std::isinf(avge_speed))avge_speed=0;
  354. logn_info(2, "his_location_time[%d]:%d[%lu,%lu,%lu]", m_cardid, flag, last_timestamp, timestamp, m_timestamp);
  355. if(last_timestamp != 0)
  356. {
  357. 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';";
  358. 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());
  359. }
  360. else
  361. 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());
  362. if(flag==1) last_timestamp=timestamp;
  363. else last_timestamp=0;
  364. logn_info(2, "his_location[%d]:%s[%lu,%lu]", m_cardid, nsql, timestamp, m_timestamp);
  365. sDBConnPool.PushAsync(nsql);
  366. }
  367. std::vector<point> location_card::find_path(const point &p1,const point &p2)
  368. {
  369. std::vector<point> rc=card_path::inst().find_path(point(p1.x,-p1.y),point(p2.x,-p2.y));
  370. return std::move(rc);
  371. }
  372. bool location_card::handle_message(const point &p,uint64_t timestamp)
  373. {
  374. bool flag = false;
  375. if(line_changed(p))
  376. {
  377. flag = true;
  378. std::vector<point> rc=find_path(m_p,p);
  379. if(rc.empty())
  380. {
  381. log_info("his_location:line_changed rc.empty() %d",m_cardid);
  382. update(m_d.back().p,m_d.back().time);
  383. set(m_d.back().p,m_d.back().time);
  384. }
  385. else
  386. {
  387. if(handle_path(rc,timestamp,false))
  388. return true;
  389. }
  390. //置m_arg非法
  391. set_invalid();
  392. }else{
  393. log_info("his_location: line not change");
  394. }
  395. return flag;
  396. }
  397. bool location_card::handle_path(std::vector<point> &rc,uint64_t timestamp,bool flag)
  398. {
  399. double dis=0;
  400. point _p=m_p;
  401. std::for_each(rc.begin(),rc.end(),[&dis,&_p](point &pt){
  402. pt.y = pt.y;
  403. dis+=_p.dist(pt);
  404. _p=pt;
  405. });
  406. uint64_t t=timestamp/1000 - m_timestamp/1000;
  407. if(t==0||dis<0.1){
  408. log_info("his_location: card_id=%d, t=%d, dist=%.2f, rc.size=%d", m_cardid, t, dis, rc.size());
  409. return true;
  410. }
  411. double avge_speed= dis/t;
  412. //有拐点 盲区时间差 距离
  413. uint64_t difftime = t;
  414. int dflag = 0;
  415. if(!m_d.empty())
  416. difftime = timestamp/1000-(m_d.back().time)/1000;
  417. if(difftime >= location_card::m_difftime && dis>location_card::m_distance)
  418. {
  419. 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);
  420. dflag=1;
  421. }
  422. for(const point & pp:rc)
  423. {
  424. m_arg=make_arg(pp,m_p);
  425. if(flag)insert();
  426. 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);
  427. double dist=m_p.dist(pp);uint64_t tt=dist/avge_speed*1000;
  428. uint64_t etime=m_timestamp+tt;
  429. update(pp,etime,0,dflag);
  430. set(pp,etime);
  431. flag=true;
  432. }
  433. return false;
  434. }