main.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. #include <QCoreApplication>
  2. #include <QProcess>
  3. #include "stdarg.h"
  4. #include "road.h"
  5. #include "roadbuilder.h"
  6. #include <iostream>
  7. #include <getopt.h>
  8. #include <iostream>
  9. #include "rd5route.h"
  10. static char gstr_inputpath[256];
  11. static char gstr_outputpath[256];
  12. static char gstr_fromroad[256];
  13. static char gstr_fromlane[256];
  14. static char gstr_toroad[256];
  15. static char gstr_tolane[256];
  16. /**
  17. * @brief print_useage
  18. */
  19. void print_useage()
  20. {
  21. std::cout<<" -i --input $xodrfile : set input file path. eq. -i d:/lk.xodr"<<std::endl;
  22. std::cout<<" -o --output $outputfile : set output file. eq. -o d:/test.rd5"<<std::endl;
  23. std::cout<<" -h --help print help"<<std::endl;
  24. }
  25. int GetOptLong(int argc, char *argv[]) {
  26. int nRtn = 0;
  27. int opt; // getopt_long() 的返回值
  28. int digit_optind = 0; // 设置短参数类型及是否需要参数
  29. (void)digit_optind;
  30. // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
  31. // 第几个元素的描述,即是long_opts的下标值
  32. int option_index = 0;
  33. // 设置短参数类型及是否需要参数
  34. const char *optstring = "i:o:a:b:c:d:h";
  35. // 设置长参数类型及其简写,比如 --reqarg <==>-r
  36. /*
  37. struct option {
  38. const char * name; // 参数的名称
  39. int has_arg; // 是否带参数值,有三种:no_argument, required_argument,optional_argument
  40. int * flag; // 为空时,函数直接将 val 的数值从getopt_long的返回值返回出去,
  41. // 当非空时,val的值会被赋到 flag 指向的整型数中,而函数返回值为0
  42. int val; // 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值
  43. };
  44. 其中:
  45. no_argument(即0),表明这个长参数不带参数(即不带数值,如:--name)
  46. required_argument(即1),表明这个长参数必须带参数(即必须带数值,如:--name Bob)
  47. optional_argument(即2),表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
  48. */
  49. static struct option long_options[] = {
  50. {"input", required_argument, NULL, 'v'},
  51. {"output", required_argument, NULL, 'o'},
  52. {"fromroad", required_argument, NULL, 'a'},
  53. {"fromlane", required_argument, NULL, 'b'},
  54. {"toroad", required_argument, NULL, 'c'},
  55. {"tolane", required_argument, NULL, 'd'},
  56. {"help", no_argument, NULL, 'h'},
  57. // {"optarg", optional_argument, NULL, 'o'},
  58. {0, 0, 0, 0} // 添加 {0, 0, 0, 0} 是为了防止输入空值
  59. };
  60. while ( (opt = getopt_long(argc,
  61. argv,
  62. optstring,
  63. long_options,
  64. &option_index)) != -1) {
  65. // printf("opt = %c\n", opt); // 命令参数,亦即 -a -b -n -r
  66. // printf("optarg = %s\n", optarg); // 参数内容
  67. // printf("optind = %d\n", optind); // 下一个被处理的下标值
  68. // printf("argv[optind - 1] = %s\n", argv[optind - 1]); // 参数内容
  69. // printf("option_index = %d\n", option_index); // 当前打印参数的下标值
  70. // printf("\n");
  71. switch(opt)
  72. {
  73. case 'i':
  74. strncpy(gstr_inputpath,optarg,255);
  75. break;
  76. case 'o':
  77. strncpy(gstr_outputpath,optarg,255);
  78. break;
  79. case 'a':
  80. strncpy(gstr_fromroad,optarg,255);
  81. break;
  82. case 'b':
  83. strncpy(gstr_fromlane,optarg,255);
  84. break;
  85. case 'c':
  86. strncpy(gstr_toroad,optarg,255);
  87. break;
  88. case 'd':
  89. strncpy(gstr_tolane,optarg,255);
  90. break;
  91. case 'h':
  92. print_useage();
  93. nRtn = 1; //because use -h
  94. break;
  95. default:
  96. break;
  97. }
  98. }
  99. return nRtn;
  100. }
  101. int
  102. ipgErrorExit(tRoad *road)
  103. {
  104. int nErrMsg;
  105. tRoadMessageList msgList;
  106. nErrMsg = RoadGetMessageList(road, RMT_Error, &msgList);
  107. while (--nErrMsg>=0) fprintf(stderr, "%s\n", msgList.msg[nErrMsg].msg);
  108. RoadDeleteMessageList(road,&msgList);
  109. RoadClearMessageBuffer(road, RMT_Error);
  110. return ROAD_Error;
  111. }
  112. void
  113. ipgWarnMsg(tRoad *road)
  114. {
  115. int nWarn;
  116. tRoadMessageList msgList;
  117. nWarn = RoadGetMessageList(road, RMT_Warn, &msgList);
  118. while (--nWarn>=0) fprintf(stderr, "%s\n", msgList.msg[nWarn].msg);
  119. RoadDeleteMessageList(road,&msgList);
  120. RoadClearMessageBuffer(road, RMT_Warn);
  121. }
  122. int
  123. createRoadFile (tRoad *road, char* fname)
  124. {
  125. tObjId lObjId0,lObjId1,lObjId2, lsObjId, jObjId, segObjId, jArmObjId0,jArmObjId1,jArmObjId2;
  126. tRoadLink rLink;
  127. tRoadJunction rJunc;
  128. tRoadJunctionArm rJArm;
  129. tRoadSegment rSeg;
  130. tRoadLaneSection rLS;
  131. tRoadLane rLane,rBorderLane;
  132. tRoadZP rZP;
  133. double angle,length;
  134. // Creating the first Link
  135. memset(&rLink,0,sizeof(rLink));
  136. // The start (position and angle) is defined explicitly by rLink.xyz0={0,0,0} and rLink.angle0=0
  137. rLink.xyz0[0] = 0;
  138. rLink.xyz0[1] = 0;
  139. rLink.xyz0[2] = 0;
  140. rLink.angle0 = 0;
  141. rLink.rst = RST_Countryroad;
  142. rLink.material = NULL;
  143. if ((lObjId0=RoadAddLink(road,&rLink))==ROAD_InvalidObjId)
  144. return ipgErrorExit(road);
  145. // Creating the Reference line of the Link by adding a list of Segments
  146. memset(&rSeg,0,sizeof(rSeg));
  147. rSeg.type = RST_Straight;
  148. rSeg.param[0] = 50;
  149. if ((segObjId=RoadAddSegment(road,lObjId0,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  150. return ipgErrorExit(road);
  151. rSeg.type = RST_ClothRight;
  152. rSeg.param[0] = 1000;
  153. rSeg.param[1] = 100;
  154. rSeg.param[2] = 20;
  155. if ((segObjId=RoadAddSegment(road,lObjId0,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  156. return ipgErrorExit(road);
  157. rSeg.type = RST_TurnRight;
  158. rSeg.param[0] = 100;
  159. rSeg.param[1] = 15;
  160. rSeg.param[2] = 0;
  161. if ((segObjId=RoadAddSegment(road,lObjId0,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  162. return ipgErrorExit(road);
  163. rSeg.type = RST_ClothRight;
  164. rSeg.param[0] = 100;
  165. rSeg.param[1] = 1000;
  166. rSeg.param[2] = 20;
  167. if ((segObjId=RoadAddSegment(road,lObjId0,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  168. return ipgErrorExit(road);
  169. rSeg.type = RST_Straight;
  170. rSeg.param[0] = 15;
  171. rSeg.param[1] = 0;
  172. rSeg.param[2] = 0;
  173. if ((segObjId=RoadAddSegment(road,lObjId0,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  174. return ipgErrorExit(road);
  175. // Creating an Elevation profile
  176. memset(&rZP,0,sizeof(rZP));
  177. rZP.isAbsolute = 0;
  178. rZP.n = 6;
  179. rZP.node = (tRoadNode1D*) calloc(rZP.n,sizeof(tRoadNode1D));
  180. rZP.node[0].type = RTT_Cubic;
  181. rZP.node[0].s = 0;
  182. rZP.node[0].c[0] = 0;
  183. rZP.node[0].c[1] = 0;
  184. rZP.node[1].s = 15;
  185. rZP.node[1].c[0] = -0.03;
  186. rZP.node[1].c[1] = ROAD_UNDEFINED;
  187. rZP.node[2].s = 50;
  188. rZP.node[2].c[0] = 0.5;
  189. rZP.node[2].c[1] = ROAD_UNDEFINED;
  190. rZP.node[3].s = 80;
  191. rZP.node[3].c[0] = 0.0;
  192. rZP.node[3].c[1] = ROAD_UNDEFINED;
  193. rZP.node[4].lonR = RLR_Node1; //1;
  194. rZP.node[4].s = 50;
  195. rZP.node[4].c[0] = -0.5;
  196. rZP.node[4].c[1] = ROAD_UNDEFINED;
  197. rZP.node[5].lonR =RLR_Node1;// 1;
  198. rZP.node[5].s = 5;
  199. rZP.node[5].c[0] = -1.5;
  200. rZP.node[5].c[1] = ROAD_UNDEFINED;
  201. rZP.smooth = 0.0;
  202. if (RoadAddZProfile(road,lObjId0, ROT_LonZPElevation,&rZP)==ROAD_InvalidObjId)
  203. return ipgErrorExit(road);
  204. free(rZP.node);
  205. // Adding a Lane section to the Link
  206. memset(&rLS,0,sizeof(rLS));
  207. rLS.s = 0;
  208. if ((lsObjId=RoadAddLaneSection(road,lObjId0,&rLS))==ROAD_InvalidObjId)
  209. return ipgErrorExit(road);
  210. // Update of the internal road structure
  211. if (RoadBuilderUpdate(road)<0)
  212. return ipgErrorExit(road);
  213. // Adding a border lane on both sides
  214. memset(&rBorderLane,0,sizeof(rBorderLane));
  215. rBorderLane.type = RTT_Cubic;
  216. rBorderLane.w0 = 0.5;
  217. rBorderLane.w1 = 0.5;
  218. rBorderLane.attr.type = RLT_Border;
  219. if (RoadAddLane(road,lsObjId,R_RIGHT,&rBorderLane,ROAD_InvalidObjId)==ROAD_InvalidObjId)
  220. return ipgErrorExit(road);
  221. if (RoadAddLane(road,lsObjId,R_LEFT, &rBorderLane,ROAD_InvalidObjId)==ROAD_InvalidObjId)
  222. return ipgErrorExit(road);
  223. // Getting the length of the Link
  224. length = RoadGetLinkLength(road,lObjId0);
  225. // Adding a new Lane section at the end of the Link
  226. rLS.s = length-50;
  227. if ((lsObjId=RoadAddLaneSection(road,lObjId0,&rLS))==ROAD_InvalidObjId)
  228. return ipgErrorExit(road);
  229. // Adding Lanes to the new Lane section
  230. // First delete all default Lanes of this Lane section
  231. RoadDeleteAllLSLanes(road,lsObjId);
  232. memset(&rLane,0,sizeof(rLane));
  233. rLane.type = RTT_Cubic;
  234. rLane.w0 = 0;
  235. rLane.w1 = 4;
  236. rLane.attr.type = RLT_Road;
  237. rLane.n = 1;
  238. rLane.width = (tRoadNode1D*) calloc(rLane.n,sizeof(tRoadNode1D));
  239. rLane.width[0].lonR = RLR_Node0;
  240. rLane.width[0].s = 25;
  241. rLane.width[0].type = RTT_Cubic;
  242. rLane.width[0].c[0] = 4;
  243. if (RoadAddLane(road,lsObjId,R_RIGHT,&rLane,ROT_Invalid)==ROAD_InvalidObjId)
  244. return ipgErrorExit(road);
  245. free(rLane.width);
  246. rLane.n = 0;
  247. rLane.width = NULL;
  248. rLane.w0 = 3.5;
  249. rLane.w1 = 3.5;
  250. if (RoadAddLane(road,lsObjId,R_RIGHT,&rLane,ROT_Invalid)==ROAD_InvalidObjId)
  251. return ipgErrorExit(road);
  252. if (RoadAddLane(road,lsObjId,R_LEFT, &rLane,ROT_Invalid)==ROAD_InvalidObjId)
  253. return ipgErrorExit(road);
  254. if (RoadAddLane(road,lsObjId,R_RIGHT,&rBorderLane,ROT_Invalid)==ROAD_InvalidObjId)
  255. return ipgErrorExit(road);
  256. if (RoadAddLane(road,lsObjId,R_LEFT, &rBorderLane,ROT_Invalid)==ROAD_InvalidObjId)
  257. return ipgErrorExit(road);
  258. // Update of the internal road structure
  259. if (RoadBuilderUpdate(road)<0)
  260. return ipgErrorExit(road);
  261. RoadGetLink(road,lObjId0,&rLink);
  262. angle = RoadGetLinkHeading(road,lObjId0,length);
  263. angle = angle>180 ? angle-180 : angle+180;
  264. // Preparing to add a Junction to the end of the first Link
  265. memset(&rJunc,0,sizeof(rJunc));
  266. // The knot is defined explicitly using the position of the first Link's end
  267. rJunc.rjt = RJT_Simple;
  268. rJunc.knot[0] = rLink.xyz1[0];
  269. rJunc.knot[1] = rLink.xyz1[1];
  270. rJunc.knot[2] = rLink.xyz1[2];
  271. rJunc.rst = RST_Urban;
  272. // Creating the second Link
  273. memset(&rLink,0,sizeof(rLink));
  274. // The start (position and angle) is defined explicitly using the position of the Junction's knot
  275. rLink.xyz0[0] = rJunc.knot[0];
  276. rLink.xyz0[1] = rJunc.knot[1];
  277. rLink.xyz0[2] = rJunc.knot[2];
  278. rLink.angle0 = angle<200 ? angle+160 : angle+160-360;
  279. rLink.rst = RST_Countryroad;
  280. rLink.material = NULL;
  281. if ((lObjId1=RoadAddLink(road,&rLink))==ROAD_InvalidObjId)
  282. return ipgErrorExit(road);
  283. // Creating the Reference line of the Link by adding a list of Segments
  284. memset(&rSeg,0,sizeof(rSeg));
  285. rSeg.type = RST_Straight;
  286. rSeg.param[0] = 50;
  287. if ((segObjId=RoadAddSegment(road,lObjId1,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  288. return ipgErrorExit(road);
  289. // Adding a Lane section to the Link
  290. memset(&rLS,0,sizeof(rLS));
  291. rLS.s = 0;
  292. if ((lsObjId=RoadAddLaneSection(road,lObjId1,&rLS))==ROAD_InvalidObjId)
  293. return ipgErrorExit(road);
  294. // Update of the internal road structure
  295. if (RoadBuilderUpdate(road)<0)
  296. return ipgErrorExit(road);
  297. // Adding a border lane on both sides
  298. if (RoadAddLane(road,lsObjId,R_RIGHT,&rBorderLane,ROAD_InvalidObjId)==ROAD_InvalidObjId)
  299. return ipgErrorExit(road);
  300. if (RoadAddLane(road,lsObjId,R_LEFT,&rBorderLane,ROAD_InvalidObjId)==ROAD_InvalidObjId)
  301. return ipgErrorExit(road);
  302. // Creating the third Link
  303. memset(&rLink,0,sizeof(rLink));
  304. // The start (position and angle) is defined explicitly using the position of the Junction's knot
  305. rLink.xyz0[0] = rJunc.knot[0];
  306. rLink.xyz0[1] = rJunc.knot[1];
  307. rLink.xyz0[2] = rJunc.knot[2];
  308. rLink.angle0 = angle>70 ? angle-70 : angle-70+360;
  309. rLink.rst = RST_Countryroad;
  310. rLink.material = NULL;
  311. if ((lObjId2=RoadAddLink(road,&rLink))==ROAD_InvalidObjId)
  312. return ipgErrorExit(road);
  313. // Creating the Reference line of the Link by adding a list of Segments
  314. memset(&rSeg,0,sizeof(rSeg));
  315. rSeg.type = RST_Straight;
  316. rSeg.param[0] = 50;
  317. if ((segObjId=RoadAddSegment(road,lObjId2,&rSeg,ROAD_InvalidObjId))==ROAD_InvalidObjId)
  318. return ipgErrorExit(road);
  319. // Adding a Lane section to the Link
  320. memset(&rLS,0,sizeof(rLS));
  321. rLS.s = 0;
  322. if ((lsObjId=RoadAddLaneSection(road,lObjId2,&rLS))==ROAD_InvalidObjId)
  323. return ipgErrorExit(road);
  324. // Update of the internal road structure
  325. if (RoadBuilderUpdate(road)<0)
  326. return ipgErrorExit(road);
  327. // Adding a border lane on both sides
  328. if (RoadAddLane(road,lsObjId,R_RIGHT,&rBorderLane,ROAD_InvalidObjId)==ROAD_InvalidObjId)
  329. return ipgErrorExit(road);
  330. if (RoadAddLane(road,lsObjId,R_LEFT,&rBorderLane,ROAD_InvalidObjId)==ROAD_InvalidObjId)
  331. return ipgErrorExit(road);
  332. // Adding a Junction to connect the three Links
  333. if ((jObjId=RoadAddJunction(road,&rJunc))==ROAD_InvalidObjId)
  334. return ipgErrorExit(road);
  335. // Adding Junction arms to the Junction
  336. memset(&rJArm,0,sizeof(rJArm));
  337. rJArm.lengthOnLink = 10; // Defines the junction entry distance
  338. if ((jArmObjId0=RoadAddJunctionArm(road,jObjId,&rJArm))==ROAD_InvalidObjId)
  339. return ipgErrorExit(road);
  340. if ((jArmObjId1=RoadAddJunctionArm(road,jObjId,&rJArm))==ROAD_InvalidObjId)
  341. return ipgErrorExit(road);
  342. if ((jArmObjId2=RoadAddJunctionArm(road,jObjId,&rJArm))==ROAD_InvalidObjId)
  343. return ipgErrorExit(road);
  344. RoadJunctionSetMainArms(road,jObjId,jArmObjId0,jArmObjId1);
  345. // Connecting the Links to the Junction arms
  346. if (RoadJunctionArmConnectLink(road,jArmObjId0,lObjId0,1,ROAD_JUNC_FORCE_CONNECT)<0)
  347. return ipgErrorExit(road);
  348. if (RoadJunctionArmConnectLink(road,jArmObjId1,lObjId1,0,ROAD_JUNC_FORCE_CONNECT)<0)
  349. return ipgErrorExit(road);
  350. if (RoadJunctionArmConnectLink(road,jArmObjId2,lObjId2,0,ROAD_JUNC_FORCE_CONNECT)<0)
  351. return ipgErrorExit(road);
  352. // Creating Road markings automatically using the built-in function
  353. RoadBuilderAutoCompletion(road, AC_RoadMarkings);
  354. // Finishing update of the internal road structure
  355. RoadSetAllUpdateFlags(road);
  356. if (RoadBuilderFinish(road)<0)
  357. return ipgErrorExit(road);
  358. RoadWriteFile(road,fname,NULL);
  359. // Writing the road InfoFile
  360. // if (RoadWriteFile(road, fname ? fname:"Example.rd5", NULL)<0)
  361. // return ipgErrorExit(road);
  362. // Print all messages
  363. ipgWarnMsg(road);
  364. return ROAD_Ok;
  365. }
  366. #include <QFileInfo>
  367. int main(int argc, char *argv[])
  368. {
  369. QCoreApplication a(argc, argv);
  370. snprintf(gstr_fromroad,256,"1");
  371. snprintf(gstr_toroad,256,"3");
  372. snprintf(gstr_fromlane,256,"-1");
  373. snprintf(gstr_tolane,256,"-1");
  374. int nRtn = GetOptLong(argc,argv);
  375. if(nRtn == 1) //show help,so exit.
  376. {
  377. return 0;
  378. }
  379. #ifdef TESTC
  380. snprintf(gstr_inputpath,255,"D:/lk.xlsx");
  381. snprintf(gstr_outputpath,255,"D:/lk.rd5");
  382. #endif
  383. if(strncmp(gstr_inputpath , "",255) == 0)
  384. {
  385. std::cout<<"Please use -i set input file path."<<std::endl;
  386. print_useage();
  387. return 0;
  388. }
  389. char strout[1000];
  390. snprintf(strout,1000,"Input File Path: %s",gstr_inputpath);
  391. std::cout<<strout<<std::endl;
  392. if(strncmp(gstr_outputpath , "",255) == 0)
  393. {
  394. std::cout<<"Please use -o set output file path."<<std::endl;
  395. print_useage();
  396. return 0;
  397. }
  398. snprintf(strout,1000,"Output File Path: %s",gstr_outputpath);
  399. std::cout<<strout<<std::endl;
  400. char stroutxodrname[256];
  401. snprintf(stroutxodrname,255,"%s.xodr",gstr_outputpath);
  402. char strproccmd[600];
  403. snprintf(strproccmd,600,"cdaproc.exe -i %s -o %s",gstr_inputpath,stroutxodrname);
  404. std::cout<<" cmd : "<<strproccmd<<std::endl;
  405. QProcess * pProc = new QProcess();
  406. pProc->start(strproccmd);
  407. pProc->waitForFinished();
  408. QFileInfo fileinfo(stroutxodrname);
  409. if(!fileinfo.isFile())
  410. {
  411. std::cout<<" convert to cda FAIL."<<std::endl;
  412. return -1;
  413. }
  414. tRoad * pRoad;
  415. pRoad = RoadNew();
  416. if(pRoad == NULL)
  417. {
  418. std::cout<<" Road New Fail."<<std::endl;
  419. return -1;
  420. }
  421. else
  422. {
  423. std::cout<<" Road New Successfully."<<std::endl;
  424. }
  425. // createRoadFile(pRoad,"D:/z.rd5");
  426. int nrtn = RoadReadOpenDRIVE(pRoad,stroutxodrname);
  427. if(nrtn<0)
  428. {
  429. ipgErrorExit(pRoad);
  430. return -1;
  431. }
  432. rd5route * proute = new rd5route(pRoad);
  433. // proute->route();
  434. int nfromroad = atoi(gstr_fromroad);
  435. int ntoroad = atoi(gstr_toroad);
  436. int nfromlane = atoi(gstr_fromlane);
  437. int ntolane = atoi(gstr_tolane);
  438. proute->route(nfromroad,nfromlane,ntoroad,ntolane);
  439. // proute->route(1,-3,2,3);
  440. // proute->route(1,-1,1,-1);
  441. delete proute;
  442. RoadWriteFile(pRoad,gstr_outputpath,NULL);
  443. return 0;
  444. return a.exec();
  445. }