ant.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /**
  2. * 分站数据结构 site_list
  3. */
  4. #ifndef _ANT_LIST_HPP_
  5. #define _ANT_LIST_HPP_
  6. #include <math.h>
  7. #include <array>
  8. #include <deque>
  9. #include <tuple>
  10. #include <time.h>
  11. #include <sstream>
  12. #include <memory>
  13. #include <memory.h>
  14. #include <algorithm>
  15. #include <sstream>
  16. #include "log.h"
  17. #include "line.h"
  18. #include "point.h"
  19. #include "write-copy.h"
  20. #include "net-service.h"
  21. #include "common.h"
  22. #include "tool_time.h"
  23. #include "card_path.h"
  24. #include "db_api/CDBSingletonDefine.h"
  25. #include <boost/circular_buffer.hpp>
  26. class client;
  27. class area;
  28. struct path
  29. {
  30. std::array<line_v,2> m_line;
  31. path()
  32. {
  33. }
  34. std::string to_str() const
  35. {
  36. std::stringstream ss;
  37. for(int i=0;i<2;i++)
  38. {
  39. ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
  40. }
  41. return ss.str();
  42. }
  43. bool valid() const
  44. {
  45. return !m_line[0].empty();
  46. }
  47. line_v & operator[](int i)
  48. {
  49. return m_line[i];
  50. }
  51. const line_v & operator[](int i) const
  52. {
  53. return m_line[i];
  54. }
  55. };
  56. //?
  57. struct algo_config
  58. {
  59. const char*desc;
  60. int min_msg_cnt;
  61. int best_msg_cnt;
  62. double min_wait_time;
  63. double max_wait_time;
  64. };
  65. // 基站覆盖范围信息
  66. struct site_coverage_info{
  67. double m_distance; // 距离
  68. std::string m_cid; // 卡号
  69. uint64_t m_time; // 时间
  70. site_coverage_info()
  71. : m_distance(0.0)
  72. , m_cid("")
  73. , m_time(0)
  74. {}
  75. };
  76. //
  77. struct ant :point
  78. {
  79. std::array<path,2> m_path;
  80. int m_id;
  81. double m_angle = 0;
  82. boost::circular_buffer<double> m_cache_poa; // 缓存5个天线的相位差值
  83. ant()
  84. {
  85. m_cache_poa.set_capacity(5);
  86. }
  87. path & operator[](int i)
  88. {
  89. return m_path[i];
  90. }
  91. const path & operator[](int i) const
  92. {
  93. return m_path[i];
  94. }
  95. size_t size() const
  96. {
  97. return m_path.size();
  98. }
  99. void set_path(const std::vector<line_v>&v_line);
  100. void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator it);
  101. std::vector<point> getsol(const double &dist) const;
  102. bool phase_error();
  103. };
  104. struct site:point,std::enable_shared_from_this<site>
  105. {
  106. static algo_config g_config[];
  107. int m_algo; // TOF:0, TDOA:1, PDOA:2
  108. int m_num_dims; // 1维:1, 2维:2, 3维:3
  109. double m_scale = 2.0; // 地图比例尺
  110. point m_position;
  111. mutable double m_height=1.5;
  112. std::array<ant,2> m_ant;
  113. mutable double m_ant_dist=0;
  114. mutable double m_ant_dist_sum_new=0;
  115. mutable int m_ant_dist_cnt_new=0;
  116. ///分站位置 READER_TYPE_ID, 井上分站,井下分站
  117. int m_reader_type_id = 0;
  118. int m_map_id = 0;
  119. int m_area_id = 0;
  120. // 设备类型,分站、通信分站、交通灯等
  121. int m_device_type_id=0;
  122. // 是否为网络设备,0为can设备,1为网络设备
  123. int m_net_device_status;
  124. //pdoa
  125. double m_pdoa_offset = 0.0; // pdoa分站天线相位偏移量,90度的偏移值
  126. int m_pdoa_direction = 0; // pdoa分站天线1朝向
  127. std::shared_ptr<client> m_clt = nullptr;
  128. std::shared_ptr<area> m_area = nullptr;
  129. time_t m_time;
  130. time_t m_loc_time = time(0); // 基站定位时间
  131. // time_t m_rec_time; // 接收数据的时间
  132. // time_t m_lost_time; // 丢失时间
  133. // time_t m_last_send_time; // 最后向前端发送时间
  134. int m_id{-1};
  135. // int m_tick_count; // 分站发生消息的计数器
  136. // unsigned char m_reader_dir; // 分站方向,对于大小分站适用
  137. // unsigned char m_relay_counts; // 大小分站经过中继数
  138. bool m_power_check_enable=false;//该分站是否启用交流掉电检测功能(告警功能)
  139. bool m_power_ac_down=false; //false=交流电供电状态
  140. bool m_path_empty;
  141. std::array<int,32> m_timeoff_count;
  142. std::array<site_coverage_info, 2> m_coverage; // 0为正向参数,1为负向参数
  143. int m_package_count=0;
  144. int m_special = 0;
  145. int m_down_stream_idx = 0;
  146. site(int id=-1);
  147. time_t m_site_time=0; //分站报文中的时间
  148. void set_site_time(time_t site_time)
  149. {
  150. m_site_time=site_time;
  151. }
  152. time_t last_site_time()const
  153. {
  154. return m_site_time;
  155. }
  156. int index()const;
  157. const algo_config&config()const;
  158. int id()const
  159. {
  160. return m_id;
  161. }
  162. void set_client(const std::shared_ptr<client>& clt)
  163. {
  164. if(m_clt != clt)
  165. m_clt = clt;
  166. m_time = time(0);
  167. }
  168. std::shared_ptr<client> get_client()
  169. {
  170. return m_clt;
  171. }
  172. bool is_up_site()
  173. {
  174. return READER_TYPE_ID_UP == m_reader_type_id;
  175. }
  176. bool is_abnormal_site()
  177. {
  178. bool f=false;
  179. double d=ant_dist();
  180. if(!is_up_site() &&(d<1e-5 && d>-1e-5) )
  181. f=true;
  182. return f;
  183. }
  184. void create_area();
  185. const std::shared_ptr<area> &get_area()const{return m_area;}
  186. void clear_event();
  187. point get_dstp(const point pt) const
  188. {
  189. point tmp;
  190. for(const auto & p : m_ant[0].m_path){
  191. for(int i=0;i<2;i++){
  192. if(!p[i].empty()){
  193. if(p[i].contain(pt,0.01)){
  194. tmp = p[i][0];
  195. }
  196. }
  197. }
  198. }
  199. if(tmp.empty())
  200. log_info("(%f,%f) can't find the point at [%d]",pt.x,pt.y,m_id);
  201. return tmp;
  202. }
  203. void count_ant_dist(double dist_tof1, double dist_tof2)const
  204. {
  205. if(dist_tof1<10 || dist_tof2<10)
  206. return;
  207. double dist = fabs(dist_tof1 - dist_tof2);
  208. if(dist>5)
  209. return;
  210. m_ant_dist_sum_new += dist;
  211. m_ant_dist_cnt_new++;
  212. if(m_ant_dist_cnt_new >= 2500)
  213. {
  214. m_ant_dist = m_ant_dist_sum_new / m_ant_dist_cnt_new;
  215. m_ant_dist_sum_new = 0;
  216. m_ant_dist_cnt_new = 0;
  217. }
  218. }
  219. double ant_dist()const
  220. {
  221. return m_ant[0].dist(m_ant[1]);
  222. }
  223. bool is_path_empty()const
  224. {
  225. return m_path_empty;
  226. }
  227. bool have_valid_path()const
  228. {
  229. return m_id != -1 && ant_dist() > 0.1;
  230. }
  231. std::string to_string()const
  232. {
  233. std::stringstream ss;
  234. ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y<<" scale:"<<m_scale;
  235. for(const auto&a:m_ant)
  236. {
  237. ss<<"<";
  238. for(const auto&p:a.m_path)
  239. {
  240. ss<<"{"<<p.to_str()<<"}";
  241. }
  242. ss<<">";
  243. }
  244. return ss.str();
  245. }
  246. const point&path(int i)const
  247. {
  248. static point p;
  249. if(i>=(int)m_ant[0].m_path.size())
  250. return p ;
  251. return m_ant[0].m_path[i].m_line[0][1];
  252. }
  253. void set_path(const std::vector<line_v>&v_line);
  254. std::vector<point> solving(int ant_id, double dist)const
  255. {
  256. const ant &a = m_ant[ant_id];
  257. if(dist < 50 && dist > 0)
  258. {
  259. if(dist < m_height)
  260. {
  261. m_height = dist;
  262. dist = 0;
  263. }
  264. else
  265. {
  266. dist = sqrt(dist*dist - m_height*m_height);
  267. }
  268. }
  269. return std::move(a.getsol(dist));
  270. }
  271. std::vector<point> solving_pdoa(const int& ant_id, double dist)const
  272. {
  273. const ant& a = m_ant[ant_id];
  274. //logn_info(3, "[pdoa] solving_pdoa, dist=%.4f, a.x=%.4f, a.y=%.4f", dist, a.x, a.y);
  275. return std::move(a.getsol(dist));
  276. }
  277. ant&operator[](int i)
  278. {
  279. return m_ant[i];
  280. }
  281. const ant&operator[](int i) const
  282. {
  283. return m_ant[i];
  284. }
  285. void set_ex()
  286. {
  287. if(-1 == m_id)
  288. {
  289. return;
  290. }
  291. if(m_ant[0]==m_ant[1])
  292. {
  293. log_warn("%d分站天线坐标相等.", m_id);
  294. }
  295. set( (m_ant[0].x+m_ant[1].x)/2,(m_ant[0].y+m_ant[1].y)/2);
  296. }
  297. void delete_antenna(int antidx)
  298. {
  299. m_ant[antidx].set(point(0,0));
  300. }
  301. /*
  302. 处理分站供电状态,交流供电时,ac_down=false,直流供电时,ac_down=true
  303. 目前只有大分站实现了这个功能,并且井下安装时是否接入了该电信号也不确定
  304. ,所以需要有张表定义某个ID是否需要告警
  305. */
  306. void on_power_status(bool ac_down); //电源状态
  307. void set_algo(int _algo)
  308. {
  309. m_algo = _algo;
  310. }
  311. double get_site_dist(const int& sid);
  312. void push_poa(const double& poa1, const double& poa2)
  313. {
  314. m_ant[0].m_cache_poa.push_back(poa1);
  315. m_ant[1].m_cache_poa.push_back(poa2);
  316. }
  317. };
  318. struct visit_site_status:visitor<std::shared_ptr<site>>
  319. {
  320. bool visit(std::shared_ptr<site> s);
  321. };
  322. class sit_list_type_staff {};
  323. class sit_list_type_vehicle {};
  324. template <class sit_list_type>
  325. struct sit_list_template:single_base<sit_list_template<sit_list_type>, int, std::shared_ptr<site>>
  326. {
  327. public:
  328. void load(const std::string &id)
  329. {
  330. int sid=-1;
  331. if(!id.empty())sid=std::stoi(id);
  332. read_sit_list(sid);
  333. read_ant_path(sid);
  334. }
  335. ///id=-1为初始化所有
  336. void load_from_db(const std::string&ids="")
  337. {
  338. init_site(ids);
  339. load(ids);
  340. }
  341. void read_sit_list(int id=-1);
  342. void read_ant_path(int id=-1);
  343. void init_site(const std::string &ids="");
  344. private:
  345. sit_list_type m_type;
  346. };
  347. template <class sit_list_type>
  348. void sit_list_template<sit_list_type>::read_sit_list(int id/*=-1*/)
  349. {
  350. std::string sql;
  351. if (std::string(typeid(m_type).name()) == "sit_list_type_staff")
  352. {
  353. sql = "SELECT antenna_id, a.reader_id, idx, a.x, a.y, a.z, a.angle \
  354. FROM dat_antenna a, dat_reader r \
  355. WHERE a.reader_id = r.reader_id";
  356. }
  357. else
  358. {
  359. sql = "SELECT antenna_id, a.reader_id, idx, a.x, a.y, a.z, a.angle \
  360. FROM dat_antenna_v a, dat_reader_v r \
  361. WHERE a.reader_id = r.reader_id";
  362. }
  363. if (-1 == id)
  364. {
  365. sql.append(";");
  366. }
  367. else
  368. {
  369. sql.append(" AND antenna_id=");
  370. sql.append(std::to_string(id));
  371. sql.append(";");
  372. log_info("基础数据 增加或修改天线 sql=%s", sql.c_str());
  373. }
  374. std::string Error;
  375. YADB::CDBResultSet DBRes;
  376. sDBConnPool.Query(sql.c_str(), DBRes, Error);
  377. int nCount = DBRes.GetRecordCount(Error);
  378. if (nCount < 1)
  379. {
  380. log_error("基础数据 增加或修改失败,数据库中找不到: 天线id=%d", id);
  381. return;
  382. }
  383. log_info("init_antenna. The record count=%ld\n", nCount);
  384. while (DBRes.GetNextRecod(Error))
  385. {
  386. int antenna_id = 0;
  387. DBRes.GetField("antenna_id", antenna_id, Error);
  388. int reader_id = 0;
  389. DBRes.GetField("reader_id", reader_id, Error);
  390. int idx = 0;
  391. DBRes.GetField("idx", idx, Error);
  392. int antid = idx - 1;
  393. if (antid >= 2 || antid < 0)
  394. continue;
  395. double x = 0;
  396. DBRes.GetField("x", x, Error);
  397. double y = 0;
  398. DBRes.GetField("y", y, Error);
  399. double z = 0;
  400. DBRes.GetField("z", z, Error);
  401. double _angle = 0;
  402. DBRes.GetField("angle", _angle, Error);
  403. log_info("ant-position:reader=%d, antid=%d, x=%.2lf, y=%.2lf, angle=%.2f", reader_id, antid, x, y, _angle);
  404. if (-1 == id)
  405. {
  406. std::shared_ptr<site> site_ptr = nullptr;
  407. site_ptr = sit_list_template<sit_list_type>::instance()->get(reader_id);
  408. if (!site_ptr)
  409. continue;
  410. site_ptr->m_ant[antid].m_id = antenna_id;
  411. site_ptr->m_ant[antid].set(x, y);
  412. site_ptr->m_ant[antid].m_angle = _angle;
  413. site_ptr->set_ex();
  414. }
  415. else
  416. {
  417. auto site_ptr = sit_list_template<sit_list_type>::instance()->get(reader_id);
  418. if (site_ptr)
  419. {
  420. site_ptr->m_ant[antid].set(x, y);
  421. site_ptr->m_ant[antid].m_angle = _angle;
  422. site_ptr->set_ex();
  423. }
  424. log_info("基础数据 增加或修改天线成功:天线id:%d,分站id:%d", id, reader_id);
  425. }
  426. }
  427. }
  428. template <class sit_list_type>
  429. void sit_list_template<sit_list_type>::read_ant_path(int id/*=-1*/)
  430. {
  431. std::string sql;
  432. if (std::string(typeid(m_type).name()) == "sit_list_type_staff")
  433. {
  434. sql = "SELECT reader_id,tof_flag,b_x,b_y,b_z,e_x,e_y,e_z,spacing_ratio FROM dat_reader_path_tof_n";
  435. }
  436. else
  437. {
  438. sql = "SELECT reader_id,tof_flag,b_x,b_y,b_z,e_x,e_y,e_z,spacing_ratio FROM dat_reader_path_tof_n_v";
  439. }
  440. std::map<int, std::vector<line_v>> map_path;
  441. if (-1 == id)
  442. {
  443. sql.append(";");
  444. }
  445. else
  446. {
  447. sql.append(" where reader_id=");
  448. sql.append(std::to_string(id));
  449. sql.append(";");
  450. std_debug("修改path sql=%s", sql.c_str());
  451. log_info("修改path sql=%s", sql.c_str());
  452. }
  453. std::string Error;
  454. YADB::CDBResultSet DBRes;
  455. sDBConnPool.Query(sql.c_str(), DBRes, Error);
  456. int nCount = DBRes.GetRecordCount(Error);
  457. if (nCount < 1)
  458. {
  459. log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
  460. return;
  461. }
  462. log_info("read_ant_path. The record count=%ld\n", nCount);
  463. while (DBRes.GetNextRecod(Error))
  464. {
  465. int reader_id = 0;
  466. DBRes.GetField("reader_id", reader_id, Error);
  467. auto site_ptr = sit_list_template<sit_list_type>::instance()->get(reader_id);
  468. if (nullptr == site_ptr)
  469. {
  470. log_error("[site] 定义了分站路径,但是没有定义分站:%d", reader_id);
  471. continue;
  472. }
  473. else if (site_ptr->m_num_dims != 1) {
  474. log_info("[site] 多维定位分站,无需定义路径:%d", reader_id);
  475. continue;
  476. }
  477. int pid = 0;
  478. DBRes.GetField("tof_flag", pid, Error);
  479. double b_x = 0;
  480. DBRes.GetField("b_x", b_x, Error);
  481. double b_y = 0;
  482. DBRes.GetField("b_y", b_y, Error);
  483. double b_z = 0;
  484. DBRes.GetField("b_z", b_z, Error);
  485. double e_x = 0;
  486. DBRes.GetField("e_x", e_x, Error);
  487. double e_y = 0;
  488. DBRes.GetField("e_y", e_y, Error);
  489. double e_z = 0;
  490. DBRes.GetField("e_z", e_z, Error);
  491. double spacing_ratio = 0;
  492. DBRes.GetField("spacing_ratio", spacing_ratio, Error);
  493. log_info("src-path:site=%d,x0=%.2f,y0=%.2f,x1=%.2f,y1=%.2f", reader_id, b_x, b_y, e_x, e_y);
  494. point p1(b_x, b_y, spacing_ratio);
  495. point p2(e_x, e_y, spacing_ratio);
  496. map_path.insert(std::make_pair(reader_id, std::vector<line_v>()));
  497. map_path.find(reader_id)->second.push_back(line_v(p1, p2));
  498. #if 0
  499. auto &sit_ = *site_ptr;
  500. if (-1 != id)//清空path
  501. {
  502. sit_.clear_path();
  503. log_info("修改path 清空path,分站id=%d\n", id);
  504. }
  505. if (pid == 0)
  506. {
  507. line_v l(p1, p2);
  508. {
  509. point px = l.line::projection(sit_);
  510. sit_.set(px);
  511. for (int i = 0; i < 2; i++)
  512. {
  513. path p;
  514. p.m_slope[0] = spacing_ratio;
  515. p.m_line[0] = line_v(px, l[i]);
  516. sit_.m_ant[i].m_path.push_back(p);
  517. }
  518. }
  519. }
  520. else
  521. {
  522. ant &a = pid < 0 ? sit_.m_ant[0] : sit_.m_ant[1];
  523. if (a.m_path.size() != 0)
  524. {
  525. path &p = a.m_path[0];
  526. p.m_line[abs(pid) - 1] = line_v(p1, p2);
  527. p.m_slope[abs(pid) - 1] = spacing_ratio;
  528. }
  529. else
  530. {
  531. path p;
  532. p.m_line[abs(pid) - 1] = line_v(p1, p2);
  533. p.m_slope[abs(pid) - 1] = spacing_ratio;
  534. a.m_path.push_back(p);
  535. }
  536. if (abs(pid) == 1)
  537. sit_.set(p1);
  538. }
  539. #endif
  540. }
  541. #if 0
  542. if (-1 == id)
  543. {
  544. for (auto&_s : sit_list::instance()->m_map)
  545. {
  546. _s.second->deal_path();
  547. }
  548. }
  549. else
  550. {
  551. auto sit_ptr = sit_list::instance()->get(id);
  552. if (sit_ptr)
  553. {
  554. sit_ptr->deal_path();
  555. log_info("修改path成功,分站id=%d\n", id);
  556. }
  557. }
  558. #endif
  559. for (auto&vl : map_path)
  560. {
  561. auto sit_ptr = sit_list_template<sit_list_type>::instance()->get(vl.first);
  562. if (!sit_ptr)
  563. {
  564. log_error("[site] 定义了分站路径,但是没有定义分站:%d", vl.first);
  565. continue;
  566. }
  567. else if (sit_ptr->m_num_dims > 1) {
  568. log_info("[site] 多维定位分站,无需定义路径:%d", vl.first);
  569. continue;
  570. }
  571. sit_ptr->set_path(vl.second);
  572. point p;
  573. if (!sit_ptr->m_path_empty) {
  574. p = (*sit_ptr)[0][0][0].line::projection(*sit_ptr);
  575. sit_ptr->set(p);
  576. }
  577. if (p == *sit_ptr)
  578. log_info("[site_path]%s", sit_ptr->to_string().c_str());
  579. else
  580. log_info("[site_path_diff](%f,%f)--%f--%s", p.x, p.y, p.dist(*sit_ptr), sit_ptr->to_string().c_str());
  581. }
  582. card_path::init();
  583. }
  584. template <class sit_list_type>
  585. void sit_list_template<sit_list_type>::init_site(const std::string &ids/*=""*/)
  586. {
  587. std::string sql;
  588. log_info("init_site_type sql=%s", std::string(typeid(m_type).name()).c_str());
  589. if (std::string(typeid(m_type).name()) == "sit_list_type_staff")
  590. {
  591. /*std::string sql = "SELECT reader_id, reader_type_id, dat_reader.map_id, \
  592. area_id, device_type_id, dimension, dat_map.scale,need_power_alarm \
  593. ,x,y, pdoa_offset, pdoa_direction, isSpecial, down_stream_idx \
  594. FROM dat_reader, dat_map where \
  595. dat_reader.map_id=dat_map.map_id and state=0";*/
  596. sql = "SELECT r.reader_id, r.reader_type_id, r.map_id, r.area_id, r.device_type_id, r.dimension, m.scale, r.need_power_alarm, r.x, r.y, \
  597. r.pdoa_offset, r.pdoa_direction, r.isSpecial, r.down_stream_idx, \
  598. rc.plus_dist, rc.plus_card_id, rc.plus_occur_time, rc.minus_dist, rc.minus_card_id, rc.minus_occur_time \
  599. FROM dat_reader AS r \
  600. LEFT JOIN dat_map AS m ON r.map_id=m.map_id \
  601. LEFT JOIN his_reader_coverage AS rc ON r.reader_id = rc.reader_id \
  602. WHERE r.state=0;";
  603. }
  604. else
  605. {
  606. /*std::string sql = "SELECT reader_id, reader_type_id, dat_reader_v.map_id, \
  607. area_id, device_type_id, dimension, dat_map.scale,need_power_alarm \
  608. ,x,y, pdoa_offset, pdoa_direction, isSpecial, down_stream_idx \
  609. FROM dat_reader_v, dat_map where \
  610. dat_reader_v.map_id=dat_map.map_id and state=0";*/
  611. sql = "SELECT r.reader_id, r.reader_type_id, r.map_id, r.area_id, r.device_type_id, r.dimension, m.scale, r.need_power_alarm, r.x, r.y, \
  612. r.pdoa_offset, r.pdoa_direction, r.isSpecial, r.down_stream_idx, \
  613. rc.plus_dist, rc.plus_card_id, rc.plus_occur_time, rc.minus_dist, rc.minus_card_id, rc.minus_occur_time \
  614. FROM dat_reader_v AS r \
  615. LEFT JOIN dat_map AS m ON r.map_id=m.map_id \
  616. LEFT JOIN his_reader_coverage AS rc ON r.reader_id = rc.reader_id \
  617. WHERE r.state=0;";
  618. }
  619. if (ids.empty())
  620. {
  621. sql.append(";");
  622. }
  623. else
  624. {
  625. sql.append(" AND reader_id in (");
  626. sql += ids;
  627. sql.append(");");
  628. std_debug("增加或修改分站 sql=%s", sql.c_str());
  629. log_info("增加或修改分站 sql=%s", sql.c_str());
  630. }
  631. std::string Error;
  632. YADB::CDBResultSet DBRes;
  633. sDBConnPool.Query(sql.c_str(), DBRes, Error);
  634. int nCount = DBRes.GetRecordCount(Error);
  635. if (nCount < 1)
  636. {
  637. log_error("增加或修改失败,数据库中找不到: 分站id=%s", ids.c_str());
  638. return;
  639. }
  640. log_info("init_site. The record count=%ld\n", nCount);
  641. while (DBRes.GetNextRecod(Error))
  642. {
  643. int reader_id = 0;
  644. DBRes.GetField("reader_id", reader_id, Error);
  645. auto site_ptr = sit_list_template<sit_list_type>::instance()->get(reader_id);
  646. if (nullptr == site_ptr)
  647. {
  648. site_ptr = std::make_shared<site>(reader_id);
  649. sit_list_template<sit_list_type>::instance()->add(reader_id, site_ptr);
  650. }
  651. int reader_type_id = 0;
  652. DBRes.GetField("reader_type_id", reader_type_id, Error);
  653. int map_id = 0;
  654. DBRes.GetField("map_id", map_id, Error);
  655. int area_id = 0;
  656. DBRes.GetField("area_id", area_id, Error);
  657. int device_type_id = 0;
  658. DBRes.GetField("device_type_id", device_type_id, Error);
  659. int dimension = 0;
  660. DBRes.GetField("dimension", dimension, Error);
  661. double scale = 0;
  662. DBRes.GetField("scale", scale, Error);
  663. int power_alarm = 0;
  664. DBRes.GetField("need_power_alarm", power_alarm, Error);
  665. int down_stream_idx = 0;
  666. DBRes.GetField("down_stream_idx", down_stream_idx, Error);
  667. site_ptr->m_reader_type_id = reader_type_id;
  668. site_ptr->m_map_id = map_id;
  669. site_ptr->m_area_id = area_id;
  670. site_ptr->m_power_check_enable = power_alarm;
  671. site_ptr->m_device_type_id = device_type_id;
  672. site_ptr->m_num_dims = dimension;
  673. site_ptr->m_scale = scale;
  674. site_ptr->m_down_stream_idx = down_stream_idx;
  675. site_ptr->create_area();
  676. double x = 0, y = 0;
  677. DBRes.GetField("x", x, Error);
  678. DBRes.GetField("y", y, Error);
  679. site_ptr->x = x;
  680. site_ptr->y = y;
  681. double offset = 0.0;
  682. DBRes.GetField("pdoa_offset", offset, Error);
  683. site_ptr->m_pdoa_offset = offset;
  684. int direction = 0;
  685. if (DBRes.GetField("pdoa_direction", direction, Error)) {
  686. site_ptr->m_pdoa_direction = direction;
  687. }
  688. int special = 0;
  689. if (DBRes.GetField("isSpecial", special, Error)) {
  690. site_ptr->m_special = special;
  691. }
  692. double dist = 0;
  693. DBRes.GetField("plus_dist", dist, Error);
  694. site_ptr->m_coverage[0].m_distance = dist;
  695. std::string ctx = "";
  696. DBRes.GetField("plus_card_id", ctx, Error);
  697. site_ptr->m_coverage[0].m_cid = ctx;
  698. ctx.clear();
  699. DBRes.GetField("plus_occur_time", ctx, Error);
  700. site_ptr->m_coverage[0].m_time = tool_time::to_time(ctx);
  701. dist = 0;
  702. DBRes.GetField("plus_dist", dist, Error);
  703. site_ptr->m_coverage[1].m_distance = dist;
  704. ctx.clear();
  705. DBRes.GetField("plus_card_id", ctx, Error);
  706. site_ptr->m_coverage[1].m_cid = ctx;
  707. ctx.clear();
  708. DBRes.GetField("plus_occur_time", ctx, Error);
  709. site_ptr->m_coverage[1].m_time = tool_time::to_time(ctx);
  710. log_info("site_position: site=%d, x=%.2lf, y=%.2lf, area_id=%d, m_scale=%.2f, pdoa_offset=%.2f, pdoa_direction=%d, special=%d, device_type_id=%d, plus_dist=%.2f, minus_dist=%.2f", reader_id, x, y, area_id, scale, offset, direction, special, device_type_id, site_ptr->m_coverage[0].m_distance, site_ptr->m_coverage[1].m_distance);
  711. }
  712. }
  713. typedef sit_list_template<sit_list_type_staff> sit_list;
  714. typedef sit_list_template<sit_list_type_vehicle> sit_list_v;
  715. #endif