card_path.cpp 19 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. #include <stdio.h>
  2. #include <algorithm>
  3. #include <unordered_map>
  4. #include <set>
  5. #include <memory>
  6. #include <atomic>
  7. #include <thread>
  8. #include <list>
  9. #include "zlist.h"
  10. #include "line.h"
  11. #include "ant.h"
  12. #include "config_file.h"
  13. #include "card_path.h"
  14. #include "visit.h"
  15. namespace{
  16. static const double PI=3.1416;
  17. inline bool eq(double a,double b,double e=0.0001)
  18. {
  19. return fabs(a-b)<e;
  20. }
  21. struct vertex:point
  22. {
  23. float level;
  24. int sid0,sid1;
  25. vertex()
  26. :level(0)
  27. ,sid0(0)
  28. ,sid1(0)
  29. {}
  30. vertex(const point&pt,float level_=0,int site_id0=0,int site_id1=0)
  31. :point(pt)
  32. ,level(level_)
  33. ,sid0(site_id0)
  34. ,sid1(site_id1)
  35. {
  36. }
  37. std::string to_string()const
  38. {
  39. char buf[128];
  40. sprintf(buf,"%.2f,%.3lf,%d,%d,%.2lf",x,y,sid0,sid1,level/PI*180);
  41. return buf;
  42. }
  43. };
  44. struct vertex_list;
  45. struct base_path:std::array<int,2>
  46. {
  47. int sid;
  48. base_path(int i1=-1,int i2=-1,int _sid=0)
  49. {
  50. at(0)=i1;
  51. at(1)=i2;
  52. sid=_sid;
  53. }
  54. bool operator<(const base_path&o)const
  55. {
  56. int c=at(0)-o.at(0);
  57. if(c!=0)
  58. return c<0;
  59. return at(1)-o.at(1)<0;
  60. }
  61. point cross(const vertex_list&v_list, const base_path&o)const;
  62. bool contains(const vertex_list&v_list, const point&o, double e)const;
  63. double arg(const vertex_list&v)const;
  64. int type(const vertex_list&v)const;
  65. line_v as_line(const vertex_list&v)const;
  66. int level(const vertex_list&v)const;
  67. };
  68. struct vertex_list
  69. {
  70. std::vector<vertex> v;
  71. std::string to_string()const
  72. {
  73. std::string ret;
  74. ret.reserve(1024);
  75. char buf[128];
  76. for(int i=0,len=v.size();i<len;i++)
  77. {
  78. sprintf(buf,"vertex:%3d,%s\n",i,v[i].to_string().c_str());
  79. ret+=buf;
  80. }
  81. return std::move(ret);
  82. }
  83. void log()
  84. {
  85. log_info("%s",to_string().c_str());
  86. }
  87. static unsigned hash(const point&p)
  88. {
  89. return (((((unsigned)p.x)>>2)<<16) + (((unsigned)p.y)>>2));
  90. }
  91. int find(const point&p,double x=0.01)const
  92. {
  93. int rc=-1;
  94. double t;
  95. for(int i=0,len=v.size();i<len;i++)
  96. {
  97. t=p.dist(v[i]);
  98. if(t<x)
  99. {
  100. rc=i;
  101. x=t;
  102. }
  103. }
  104. return rc;
  105. }
  106. int add(const point&p,float level=0,int sid0=0,int sid1=0)
  107. {
  108. int i=find(p);
  109. if(i<0)
  110. {
  111. v.push_back(vertex(p,level,sid0,sid1));
  112. return v.size()-1;
  113. }
  114. vertex&v0=v[i];
  115. v0.level=std::max(v0.level,level);
  116. return i;
  117. }
  118. int size()const
  119. {
  120. return v.size();
  121. }
  122. const vertex&operator[](int i)const
  123. {
  124. return v[i];
  125. }
  126. vertex&operator[](int i)
  127. {
  128. return v[i];
  129. }
  130. };
  131. int base_path::level(const vertex_list&v)const
  132. {
  133. const vertex&p0=v[at(0)];
  134. const vertex&p1=v[at(1)];
  135. return p0.level+p1.level;
  136. }
  137. line_v base_path::as_line(const vertex_list&v)const
  138. {
  139. const vertex&p0=v[at(0)];
  140. const vertex&p1=v[at(1)];
  141. return line_v(p0,p1);
  142. }
  143. double base_path::arg(const vertex_list&v)const
  144. {
  145. return as_line(v).arg();
  146. }
  147. bool base_path::contains(const vertex_list&v, const point&o, double e)const
  148. {
  149. return as_line(v).contain(o,e);
  150. }
  151. point base_path::cross(const vertex_list&v, const base_path&o)const
  152. {
  153. line_v l0=as_line(v);
  154. line_v l1=o.as_line(v);
  155. return l0.crossing(l1);
  156. }
  157. void log_path(const std::vector<base_path>&path,const vertex_list&v_list,const char*add_info="")
  158. {
  159. log_info("%s\n","----------------------------------------------------------------");
  160. for(int i=0,len=path.size();i<len;i++)
  161. {
  162. double c=path[i].arg(v_list)/PI*180;
  163. log_info("base_path:%s %.6lf, %03d,(%d,%s),(%d,%s)",add_info,c,i,path[i][0],v_list[path[i][0]].to_string().c_str(),path[i][1],v_list[path[i][1]].to_string().c_str());
  164. }
  165. }
  166. struct handle_path :visitor<std::shared_ptr<site>>
  167. {
  168. std::vector<base_path> ret;
  169. vertex_list v;
  170. handle_path()
  171. {
  172. v.add(point(0,0),0,-1);
  173. }
  174. bool visit(std::shared_ptr<site> sit)
  175. {
  176. //auto&s=sites[i];
  177. const auto &s = *sit;
  178. if(!s.have_valid_path())
  179. return false;
  180. if(s.path(0).empty()||s.path(1).empty())
  181. return false;
  182. if(s[0].size()<2)
  183. return false;
  184. line_v l000 = s[0][0][0]; //天线->分站天线路径集合->路径
  185. line_v l010 = s[0][1][0];
  186. if(l000.is_same(l010))
  187. {
  188. int p0=v.add(point::min(s.path(0),s.path(1)),0,s.m_id);
  189. int p1=v.add(point::max(s.path(0),s.path(1)),0,s.m_id);
  190. ret.push_back(base_path(p0,p1));
  191. ret.back().sid=s.m_id;
  192. }
  193. else
  194. {
  195. point px = l000.line::crossing(l010);
  196. for(int i=0;i<2;i++)
  197. {
  198. int p0=v.add(point::min(px,s.path(i)),0,s.m_id);
  199. int p1=v.add(point::max(px,s.path(i)),0,s.m_id);
  200. ret.push_back(base_path(p0,p1));
  201. ret.back().sid=s.m_id;
  202. }
  203. }
  204. for(int i=0;i<2;i++)
  205. {
  206. if(!s[0][i][1].empty())
  207. {
  208. int p0=v.add(point::min(s[0][i][1][0],s[0][i][1][1]),0,s.m_id);
  209. int p1=v.add(point::max(s[0][i][1][0],s[0][i][1][1]),0,s.m_id);
  210. ret.push_back(base_path(p0,p1));
  211. ret.back().sid=s.m_id;
  212. }
  213. }
  214. return true;
  215. }
  216. };
  217. static std::vector<base_path> init_path(std::vector<base_path> & ret,vertex_list&v)
  218. {
  219. do
  220. {
  221. config_file cfg;
  222. if(cfg.open("../etc/path-not-cross.ini"))
  223. break;
  224. auto kset=cfg.keys();
  225. if(kset.empty())
  226. break;
  227. for(auto k:kset)
  228. {
  229. if(strncmp(k,"add_path",8)!=0)
  230. continue;
  231. const char* vv=cfg.get(k,"");
  232. point p0;
  233. point p1;
  234. if(sscanf(vv,"%lf,%lf,%lf,%lf",&p0.x,&p0.y,&p1.x,&p1.y)==4)
  235. {
  236. point p_0=point::min(p0,p1);
  237. point p_1=point::max(p0,p1);
  238. int p00=v.add(p_0,0,0);
  239. int p10=v.add(p_1,0,0);
  240. ret.push_back(base_path(p00,p10,0));
  241. }
  242. }
  243. break;
  244. }while(1);
  245. auto remove_dup=[](std::vector<base_path>&ret){
  246. std::sort(ret.begin(),ret.end());
  247. ret.erase(std::unique(ret.begin(),ret.end()),ret.end());
  248. };
  249. auto remove_empty=[](std::vector<base_path>&ret,vertex_list&v){
  250. ret.erase(std::remove_if(ret.begin(),ret.end(),[&v](base_path&p){
  251. point&p0=v[p[0]];
  252. point&p1=v[p[1]];
  253. return p0.dist(p1)<.00001;
  254. }),
  255. ret.end());
  256. };
  257. auto sort_path=[](std::vector<base_path> & ret,vertex_list&v){
  258. std::sort(ret.begin(),ret.end(),[&v](const base_path&p1,const base_path&p2){
  259. return point::min(v[p1[0]],v[p1[1]]) < point::min(v[p2[0]],v[p2[1]]);
  260. });
  261. };
  262. remove_dup(ret);
  263. sort_path(ret,v);
  264. log_path(ret,v,"合并前");
  265. //合并相同
  266. for(int i=0,len=ret.size();i<len;i++)
  267. {
  268. line_v li=ret[i].as_line(v);
  269. for(int j=i+1;j<len;j++)
  270. {
  271. line_v lj=ret[j].as_line(v);
  272. if(!lj.is_same(li,1)) //li线段两个点在lj直线上
  273. continue;
  274. line_v ij=lj.projection(li);//重叠
  275. if(ij.empty()&&ij[0].empty()&&ij[0].empty())
  276. continue;
  277. point p0=li.as_line().projection(v[ret[j][0]]);
  278. point p1=li.as_line().projection(v[ret[j][1]]);
  279. p0=point::min(p0,v[ret[i][0]]);
  280. p1=point::max(p1,v[ret[i][1]]);
  281. ret[j][0]=v.add(p0,0);
  282. ret[j][1]=v.add(p1,0);
  283. ret[i][0]=0;
  284. ret[i][1]=0;
  285. break;
  286. }
  287. }
  288. ret.erase(std::remove_if(ret.begin(),ret.end(),[&v](const base_path&p){
  289. return p[0]==0||p[1]==0;
  290. }),ret.end());
  291. sort_path(ret,v);
  292. log_path(ret,v,"合并后");
  293. //非路径交点配置
  294. std::vector<point> no_cross;
  295. auto in_no_cross=[&no_cross](const point&pt){
  296. for(auto p:no_cross)
  297. {
  298. if(p.dist(pt)<3)
  299. return true;
  300. }
  301. return false;
  302. };
  303. do
  304. {
  305. config_file cfg;
  306. if(cfg.open("../etc/path-not-cross.ini"))
  307. break;
  308. auto kset=cfg.keys();
  309. if(kset.empty())
  310. break;
  311. for(auto k:kset)
  312. {
  313. if(strncmp(k,"pt",2)!=0)
  314. continue;
  315. const char* v=cfg.get(k,"");
  316. point tmp;
  317. if(sscanf(v,"%lf,%lf",&tmp.x,&tmp.y)==2)
  318. no_cross.push_back(tmp);
  319. }
  320. for(auto p:no_cross)
  321. {
  322. log_info("no_cross_point:x=%lf,y=%lf",p.x,p.y);
  323. }
  324. break;
  325. }while(1);
  326. std::vector<std::vector<int>> p0(ret.size());
  327. std::vector<base_path> ret2;
  328. for(int i=0,len=ret.size();i<len;i++)
  329. {
  330. p0[i].push_back(ret[i][0]);
  331. for(int j=i+1;j<len;j++)
  332. {
  333. if(i==j) continue;
  334. point cr=ret[i].cross(v,ret[j]);
  335. if(cr.empty())
  336. continue;
  337. if(in_no_cross(cr))
  338. continue;
  339. double arg=fabs(ret[i].as_line(v).arg()-ret[j].as_line(v).arg());
  340. while(arg>PI/2)
  341. arg=PI-arg;
  342. if(arg/PI*180<5)//相交小于5度,不切分已有路径
  343. continue;
  344. int id=v.add(cr,arg,v[ret[i][0]].sid0,v[ret[j][0]].sid0);
  345. p0[i].push_back(id);
  346. p0[j].push_back(id);
  347. }
  348. p0[i].push_back(ret[i][1]);
  349. std::sort(p0[i].begin(),p0[i].end(),[&v](int i0,int i1){ return v[i0]<v[i1]; });
  350. #if 0
  351. if(p0[i].size())
  352. {
  353. for(int v=0;v<2;v++)
  354. {
  355. if(v[ret[i][v]].dist(v[p0[i].front()])<3)
  356. continue;
  357. if(v[ret[i][v]].dist(v[p0[i].back()])<3)
  358. continue;
  359. p0[i].push_back(ret[i][v]);
  360. std::sort(p0[i].begin(),p0[i].end(),[&v](int i0,int i1){ return v[i0]<v[i1]; });
  361. }
  362. }
  363. else
  364. {
  365. std::sort(p0[i].begin(),p0[i].end(),[&v](int i0,int i1){ return v[i0]<v[i1]; });
  366. }
  367. #endif
  368. auto it=std::unique(p0[i].begin(),p0[i].end());
  369. p0[i].erase(it,p0[i].end());
  370. for(int j=1,cnt=p0[i].size();j<cnt;j++)
  371. {
  372. ret2.push_back(base_path(p0[i][j - 1], p0[i][j]));
  373. ret2.back().sid = ret[i].sid;
  374. }
  375. }
  376. remove_empty(ret2,v);
  377. remove_dup(ret2);
  378. sort_path(ret,v);
  379. log_path(ret2,v,"拆分后");
  380. return std::move(ret2);
  381. }
  382. #if 0
  383. struct ghash
  384. {
  385. static std::tuple<int,int> decode(unsigned h)
  386. {
  387. const uint64_t S=0x8000000000000000;
  388. int x=0,y=0;
  389. for(int i=0;i<64;i++)
  390. {
  391. x<<=1;
  392. y<<=1;
  393. if(h&S)
  394. x|=1;
  395. h<<=1;
  396. if(h&S)
  397. y|=1;
  398. h<<=1;
  399. }
  400. return std::make_tuple(x-2147483648,y-2147483648);
  401. }
  402. static uint64_t encode(int64_t x, int64_t y)
  403. {
  404. return encode_(x+2147483648,y+2147483648);
  405. }
  406. public: //test
  407. static void test_code(int64_t x,int64_t y)
  408. {
  409. uint64_t h=ghash::encode(x,y);
  410. auto t=ghash::decode(h);
  411. printf("src x=%X,y=%X hash=%X,check x=%X,y=%X\n",x,y,h,std::get<0>(t),std::get<1>(t));
  412. }
  413. static void test()
  414. {
  415. for(int i=0;i<10;i++)
  416. {
  417. test_code((4<<i)-1,(4<<i)-1);
  418. test_code((4<<i)-1,(4<<i));
  419. test_code((4<<i)-1,(4<<i)-1);
  420. test_code((4<<i),(4<<i)-1);
  421. }
  422. }
  423. private:
  424. static unsigned encode_(unsigned short x, unsigned short y)
  425. {
  426. const unsigned S=0x8000;
  427. unsigned r=0;
  428. for(int i=0;i<16;i++)
  429. {
  430. r<<=2;
  431. if(x&S)
  432. {
  433. r|=(y&S)?3:2;
  434. }
  435. else
  436. {
  437. if(y&S) r|=1;
  438. }
  439. x<<=1;
  440. y<<=1;
  441. }
  442. return r;
  443. }
  444. };
  445. #endif
  446. struct geolist
  447. {
  448. std::unordered_map<uint64_t,int> geo2path;
  449. public:
  450. static uint64_t encode(double x0,double y0)
  451. {
  452. uint64_t x=(uint32_t)(x0*10);
  453. uint64_t y=(uint32_t)(y0*10);
  454. return (x<<32)|y;
  455. }
  456. int find(double x,double y)const
  457. {
  458. uint64_t h=encode(x,y);
  459. auto it=geo2path.find(h);
  460. if(it==geo2path.end())
  461. return -1;
  462. return it->second;
  463. }
  464. void add(double x,double y,int id)
  465. {
  466. uint64_t h=encode(x,y);
  467. geo2path.insert(std::make_pair(h,id));
  468. }
  469. int size()
  470. {
  471. return geo2path.size();
  472. }
  473. void print()
  474. {
  475. for(auto it=geo2path.begin();it!=geo2path.end();++it)
  476. {
  477. //std::cout<<it->first<<"\n";
  478. printf("%ld\n",it->first);
  479. }
  480. }
  481. geolist()
  482. {
  483. }
  484. ~geolist()
  485. {
  486. }
  487. };
  488. struct graph
  489. {
  490. vertex_list v;
  491. std::vector<std::vector<int>> d; //索引为起始顶点,数组内容为目标点
  492. std::vector<std::array<int,2>> l; //bast_path list
  493. geolist geo;
  494. graph()
  495. {}
  496. void init(const vertex_list&v_,const std::vector<base_path>&bp)
  497. {
  498. for(auto&p:bp)
  499. {
  500. int from=v.add(v_[p[0]]);
  501. int to=v.add(v_[p[1]]);
  502. l.push_back({from,to});
  503. int id=l.size()-1;
  504. line_v lv(v[from],v[to]);
  505. log_info("graph::init() site:%d line:%s\n",p.sid, lv.to_string().c_str());
  506. double cos=lv.cos_k();
  507. double sin=lv.sin_k();
  508. double x,y;
  509. for(double r=0,len=lv.length();r<len+0.1;r+=0.05)
  510. {
  511. x=lv[0].x+r*cos;
  512. y=lv[0].y+r*sin;
  513. // printf("x=%lf,y=%lf\n",x,y);
  514. for(int i=-1;i<=1;i++)
  515. for(int j=-1;j<=1;j++)
  516. {
  517. geo.add(x+i/10.,y+j/10.,id);
  518. }
  519. }
  520. add(from,to);
  521. }
  522. }
  523. std::vector<line_v> find_possible_path(const point&from,double dist) const
  524. {
  525. std::vector<line_v> ret;
  526. int start_pt_id=v.find(from,dist);
  527. if(start_pt_id==-1)
  528. return std::move(ret);
  529. point start_pt=v[start_pt_id];
  530. for(uint32_t i=0;i<d[start_pt_id].size();i++)
  531. {
  532. ret.push_back(line_v(start_pt,v[d[start_pt_id][i]]));
  533. }
  534. return std::move(ret);
  535. }
  536. void add(int from,int to)
  537. {
  538. if((int)d.size()<=from) d.resize(from+1);
  539. if((int)d.size()<=to) d.resize(to+1);
  540. d[from].push_back(to);
  541. d[to].push_back(from);
  542. }
  543. bool find(std::vector<int>&ret,int from,std::array<int,2>&to,std::set<int>&ex,int level)
  544. {
  545. if(level--<0)
  546. return false;
  547. ret.push_back(from);
  548. for(int p:d[from]) //在当前路径
  549. {
  550. if(ex.find(p)!=ex.end()) //找过
  551. continue;
  552. if(p==to[0]||p==to[1])//找到
  553. return true;
  554. // {
  555. // ret.push_back(p);
  556. // return true;
  557. // }
  558. }
  559. ex.insert(from);
  560. for(int p:d[from])//在下级路径
  561. {
  562. if(ex.find(p)!=ex.end())//找过
  563. continue;
  564. if(find(ret,p,to,ex,level)) //找到
  565. {
  566. return true;
  567. }
  568. }
  569. ret.pop_back();
  570. return false;
  571. }
  572. bool is_at_path(const point&pt)const
  573. {
  574. return geo.find(pt.x,pt.y)>=0;
  575. }
  576. struct item
  577. {
  578. item(int _vid=-1, int _g=0,int _h=0,std::shared_ptr<item> _parent=nullptr)
  579. :vid(_vid)
  580. ,g(_g)
  581. ,h(_h)
  582. ,parent(_parent)
  583. {
  584. }
  585. int vid=-1,g=0,h=0;
  586. std::shared_ptr<item> parent;
  587. int cost()const {return g+h;}
  588. bool operator< (const item&i) const
  589. {
  590. return vid<i.vid;
  591. }
  592. };
  593. std::vector<point> find2(const point&from,const point&to)
  594. {
  595. int f=geo.find(from.x,from.y);
  596. int t=geo.find(to.x,to.y);
  597. if(f<0 || t<0 || f==t)
  598. return {};
  599. std::set<std::shared_ptr<item>> open_set;
  600. std::set<int> close_set;
  601. open_set.insert(std::make_shared<item>(l[f][0],from.dist(v[l[f][0]]),to.dist(v[l[f][0]])));
  602. open_set.insert(std::make_shared<item>(l[f][1],from.dist(v[l[f][1]]),to.dist(v[l[f][1]])));
  603. std::shared_ptr<item> cur;
  604. while(open_set.size()>0)
  605. {
  606. cur=*open_set.begin();
  607. for(auto&i:open_set)
  608. {
  609. if(i->cost()<cur->cost())
  610. cur=i;
  611. }
  612. open_set.erase(cur);
  613. close_set.insert(cur->vid);
  614. if(cur->vid==l[t][0]||cur->vid==l[t][1])
  615. break;
  616. for(auto vid:d[cur->vid])
  617. {
  618. if(close_set.find(vid)!=close_set.end())
  619. continue;
  620. open_set.insert(std::make_shared<item>(vid,cur->g+v[cur->vid].dist(v[vid]),to.dist(v[vid]),cur));
  621. }
  622. }
  623. if(open_set.size()==0)
  624. {
  625. return {};
  626. }
  627. std::vector<point> rc;
  628. while(cur.get())
  629. {
  630. rc.push_back(v[cur->vid]);
  631. cur=cur->parent;
  632. }
  633. std::reverse(rc.begin(),rc.end());
  634. rc.push_back(to);
  635. auto bp=from;
  636. auto it1=rc.begin();
  637. for(auto it2=it1+1;it1!=rc.end() && it2!=rc.end();it2++)
  638. {
  639. if(line(bp,*it1).dist(*it2)<0.1)
  640. {
  641. *it1=*it2;
  642. }
  643. else
  644. {
  645. bp=*it1++;
  646. *it1=*it2;
  647. }
  648. }
  649. rc.erase(it1,rc.end());
  650. if(rc.size() && from.dist(*rc.begin())<0.1)
  651. {
  652. rc.erase(rc.begin());
  653. }
  654. return std::move(rc);
  655. }
  656. std::vector<point> find(const point&from,const point&to)
  657. {
  658. int f=geo.find(from.x,from.y);
  659. int t=geo.find(to.x,to.y);
  660. if(f<0 || t<0 || f==t)
  661. return {};
  662. #if 0
  663. std::vector<point> rc[2];
  664. for(int i=0;i<2;i++)
  665. {
  666. std::vector<int> ret;
  667. std::set<int> ex({l[f][1-i]});
  668. if(find(ret,l[f][i],l[t],ex,2))
  669. {
  670. for(auto id:ret)
  671. rc[i].push_back(v[id]);
  672. }
  673. }
  674. if(!rc[0].empty() && (rc[1].empty() || rc[0].size() < rc[1].size()))
  675. return std::move(rc[0]);
  676. else if(!rc[1].empty())
  677. return std::move(rc[1]);
  678. #endif
  679. std::vector<int> ret;
  680. int size=v.size();
  681. std::vector<double> mat(size+1,-1);
  682. std::vector<double> trace(size+1,-1);
  683. std::vector<bool> val(size+2,false);
  684. mat[l[t][0]]=to.dist(v[l[t][0]]);
  685. mat[l[t][1]]=to.dist(v[l[t][1]]);
  686. int f0=l[f][0],f1=l[f][1];
  687. for(int i=0;i<2;i++)
  688. {
  689. if(mat[f0]!=-1 && mat[f1]!=-1)
  690. break;
  691. for(int j=0;j<size;j++)
  692. if(mat[j]!=-1)val[j]=true;
  693. for(int j=0;j<size;j++)
  694. {
  695. if(val[j]==false)continue;
  696. for(unsigned int k=0;k<d[j].size();k++)
  697. {
  698. double dist=v[j].dist(v[d[j][k]]);
  699. if(mat[d[j][k]]==-1 || mat[j]+dist < mat[d[j][k]])
  700. {
  701. mat[d[j][k]] = mat[j]+dist;
  702. trace[d[j][k]] = j;
  703. }
  704. }
  705. }
  706. }
  707. mat[f0]=mat[f0]+from.dist(v[l[f][0]]);
  708. mat[f1]=mat[f1]+from.dist(v[l[f][1]]);
  709. std::vector<point> rc;
  710. if(mat[f0]!=-1 && (mat[f1]==-1 || mat[f0] < mat[f1]))
  711. {
  712. int temp=f0;
  713. while(temp!=-1)
  714. {
  715. rc.push_back(v[temp]);
  716. temp=trace[temp];
  717. }
  718. return std::move(rc);
  719. }
  720. else if(mat[f1]!=-1)
  721. {
  722. int temp=f1;
  723. while(temp!=-1)
  724. {
  725. rc.push_back(v[temp]);
  726. temp=trace[temp];
  727. }
  728. return std::move(rc);
  729. }
  730. return {};
  731. }
  732. };
  733. safe_shared_ptr<graph> g_graph(std::make_shared<graph>());
  734. }//namespace
  735. void card_path::init()
  736. {
  737. std::shared_ptr<graph> local_graph=std::make_shared<graph>();
  738. handle_path hp;
  739. sit_list::instance()->accept(hp);
  740. std::vector<base_path> opath=init_path(hp.ret,hp.v);
  741. local_graph->init(hp.v,opath);
  742. g_graph.set(local_graph);
  743. }
  744. card_path&card_path::inst()
  745. {
  746. static card_path path;
  747. return path;
  748. }
  749. std::vector<point> card_path::find_path(const point&from,const point&to)const
  750. {
  751. return g_graph.get()->find2(from,to);
  752. }
  753. bool card_path::is_at_path(const point&pt)const
  754. {
  755. return g_graph.get()->is_at_path(pt);
  756. }
  757. std::vector<line_v> card_path::find_possible_path(const point&from,double dist) const
  758. {
  759. return std::move(g_graph.get()->find_possible_path(from,dist));
  760. }
  761. #ifdef __DEBUG__
  762. void test_at_path(card_path&cp,const point&pt)
  763. {
  764. if(cp.is_at_path(pt))
  765. log_info("test (%.3lf,%.3lf) is-at-path:true\n",pt.x,pt.y);
  766. else
  767. log_info("test (%.3lf,%.3lf) is-at-path:false\n",pt.x,pt.y);
  768. }
  769. void test_find_path(card_path&cp,const point&p1,const point&p2)
  770. {
  771. printf("\nfind-path: from=(%.3lf,%.3lf),to=(%.3lf,%.3lf)\n",p1.x,p1.y,p2.x,p2.y);
  772. std::vector<point> rc=cp.find_path(p1,p2);
  773. for(uint32_t i=0;i<rc.size();i++)
  774. log_info("x=%.3lf,y=%.3lf\n",rc[i].x,rc[i].y);
  775. }
  776. void test_find_poss_path(const card_path&cp ,const point&from)
  777. {
  778. log_info("\nfind-poss_path: from=(%.3lf,%.3lf)\n",from.x,from.y);
  779. std::vector<line_v> rc=cp.find_possible_path(from,3);
  780. for(uint32_t i=0;i<rc.size();i++)
  781. {
  782. log_info("poss path from=(%.3lf,%.3lf) to=(%.3lf,%.3lf)\n", rc[i][0].x,rc[i][0].y, rc[i][1].x,rc[i][1].y);
  783. }
  784. }
  785. int main()
  786. {
  787. // std::unique_ptr<sit_list> sites(new sit_list());
  788. //sit_list::instance()->load("data_reader_antenna.txt","path_tof.txt");
  789. sit_list::instance()->load("1.txt","2.txt");
  790. card_path cp;
  791. cp.init();
  792. #if 0
  793. {
  794. test_at_path(cp,point(4773.104654,-104.0887));
  795. test_at_path(cp,point(4727,-74.8));
  796. test_at_path(cp,point(4727,-75.0));
  797. test_at_path(cp,point(4727,-75.2));
  798. test_at_path(cp,point(4727,-75.8));
  799. test_at_path(cp,point(4727,-90));
  800. test_at_path(cp,point(4727,-89.6));
  801. test_at_path(cp,point(4727,-89.8));
  802. test_at_path(cp,point(4727,-90));
  803. test_at_path(cp,point(4727,-90.2));
  804. test_at_path(cp,point(4727,-90.4));
  805. }
  806. #endif
  807. //test_at_path(cp,point(4726.90,376.85));
  808. test_find_path(cp,point(-227.6,174.9),point(-201.3,175.5));
  809. test_find_path(cp,point(-227.625219,174.945670),point(-170.085722,176.101574));
  810. test_find_path(cp,point(-393.1944,262.5324),point(-366.0754,274.1253));
  811. //test_find_path(cp,point(4637.000000,-75),point(4727,135));
  812. #if 1
  813. {
  814. test_find_path(cp,point(4637.000000,-75),point(4727,135));
  815. test_find_path(cp,point(4637.000000,-75),point(4727,120));
  816. test_find_path(cp,point(4700,-75),point(4727,120));
  817. test_find_path(cp,point(4725,-75),point(4727,135));
  818. test_find_path(cp,point(4727,-89.7),point(6144.3,-523));
  819. }
  820. #endif
  821. #if 0
  822. {
  823. test_find_poss_path(cp, point(4727,-89));
  824. test_find_poss_path(cp, point(4727,-90));
  825. test_find_poss_path(cp, point(4724,-75));
  826. test_find_poss_path(cp, point(4725,-75));
  827. test_find_poss_path(cp, point(4726,-75));
  828. test_find_poss_path(cp, point(4727,-75));
  829. test_find_poss_path(cp, point(4728,-75));
  830. test_find_poss_path(cp, point(4727,-7));
  831. test_find_poss_path(cp, point(4726.6,33));
  832. }
  833. #endif
  834. return 0;
  835. }
  836. #endif