CPath.cs
上传用户:xum6868
上传日期:2009-12-02
资源大小:102k
文件大小:12k
源码类别:

GIS编程

开发平台:

C#

  1. using System;
  2. using System.Collections; 
  3. namespace MainSystem
  4. {
  5. struct Routine //一条公交线路
  6. {
  7. public short nFlag; //0:双向;1:上行;2:下行
  8. public short nStationNumber;
  9. public string szRoutineName;
  10. public string[] szStaionName;
  11. };
  12. struct Node
  13. {
  14. public short nNodeNumber;
  15. public short[] nRoutineOrder;
  16. public short[] nStationOrder;
  17. };
  18. struct Station
  19. {
  20. public string szStationName;
  21. public short nRoutineNumber;
  22. public short[] pnRoutineID;
  23. public short[] pnOrder;
  24. };
  25. struct PathNode
  26. {
  27. public short nSegNumber;
  28. public string[] szRoutineName;
  29. public string[] szFromStationName;
  30. public string[] szToStationName;
  31. };
  32. /// <summary>
  33. /// Summary description for CPath.
  34. /// </summary>
  35. public class CPath
  36. {
  37. private int TIMELIMIT = 3;
  38. private Routine[] _pRoutine;
  39. private Station[] _pStations;
  40. private short _nRCount;
  41. private short _nSCount;
  42. public CPath()
  43. {
  44. _pRoutine = new Routine[1000];
  45. _pStations = new Station[5000];
  46. }
  47. public void Build(CEnvironment env)
  48. {
  49. _nRCount = BuildRoutine(_pRoutine,env);
  50. _nSCount = BuildStationIndex(_pRoutine,_nRCount,_pStations);
  51. }
  52. short BuildRoutine(Routine[] pRoutine, CEnvironment env)
  53. {
  54. System.Data.DataTable typeTbl = env.m_dataSet.Tables["公交车站路线"];
  55. System.Data.DataRow[] rowstypes;
  56. if (env.m_szBusFilter != "")
  57. rowstypes = typeTbl.Select(env.m_szBusFilter);
  58. else
  59. rowstypes = typeTbl.Select();
  60. short nCount = 0;
  61. short nSCount = 0;
  62. string rName;
  63. string sName;
  64. string sTemp1;
  65. string sTemp2;
  66. string[] sNames = new string[350];
  67. foreach (System.Data.DataRow myRow in rowstypes)
  68. {
  69. rName = myRow[0].ToString();
  70. sTemp1 = myRow[1].ToString();
  71. sName = myRow[2].ToString();
  72. sTemp2 = myRow[0].ToString();
  73. if(nCount ==0)
  74. {
  75. pRoutine[nCount] = new Routine();
  76.  
  77. pRoutine[nCount].szRoutineName=string.Copy (rName);
  78. if(rName.Length > 4 && rName.Substring(rName.Length - 4,4).Equals("上行"))
  79. pRoutine[nCount].nFlag = 1;
  80. else if(rName.Length > 4 && rName.Substring(rName.Length - 4,4).Equals("下行"))
  81. pRoutine[nCount].nFlag = 2;
  82. else 
  83. pRoutine[nCount].nFlag = 0;
  84. nCount++;
  85. nSCount = 0;
  86. sNames[nSCount] = string.Copy(sName);
  87. nSCount = 1;
  88. }
  89. else
  90. {
  91. if(pRoutine[nCount-1].szRoutineName.Equals( rName))
  92. {
  93. sNames[nSCount]=string.Copy( sName);
  94. nSCount++;
  95. }
  96. else
  97. {
  98. //结束上一站
  99. pRoutine[nCount-1].nStationNumber = nSCount;
  100. pRoutine[nCount-1].szStaionName = new string [nSCount];
  101. for(short i=0;i<nSCount;i++)
  102. pRoutine[nCount-1].szStaionName[i] = string.Copy (sNames[i]);
  103. pRoutine[nCount] = new Routine();
  104. if(rName.Length > 4 && rName.Substring(rName.Length - 4,4).Equals("上行"))
  105. pRoutine[nCount].nFlag = 1;
  106. else if(rName.Length > 4 && rName.Substring(rName.Length - 4,4).Equals("下行"))
  107. pRoutine[nCount].nFlag = 2;
  108. else 
  109. pRoutine[nCount].nFlag = 0;
  110. pRoutine[nCount].szRoutineName=string.Copy( rName);
  111. nCount++;
  112. nSCount = 0;
  113. sNames[nSCount]=string.Copy (sName);
  114. nSCount = 1;
  115. }
  116. }
  117. }
  118. pRoutine[nCount-1].nStationNumber = nSCount;
  119. pRoutine[nCount-1].szStaionName = new string [nSCount];
  120. for(short i=0;i<nSCount;i++)
  121. pRoutine[nCount-1].szStaionName[i]= string.Copy( sNames[i]);
  122. return nCount;
  123. }
  124. short BuildStationIndex(Routine[] pAllRoutines,short nSize,Station[] pStations)
  125. {
  126. short nCount = 0;
  127. for(short i=0;i<nSize;i++)
  128. {
  129. for(short j=0;j<pAllRoutines[i].nStationNumber;j++)
  130. {
  131. short k;
  132. for( k=0;k<nCount;k++)
  133. {
  134. if(pStations[k].szStationName.Equals(pAllRoutines[i].szStaionName[j]))
  135. break;
  136. }
  137. if(k==nCount)
  138. {
  139. //添加一个新站
  140. pStations[k] = new Station();
  141.  
  142. pStations[k].szStationName=string.Copy(pAllRoutines[i].szStaionName[j]);
  143. pStations[k].nRoutineNumber=1;
  144. nCount++;
  145. }
  146. else
  147. pStations[k].nRoutineNumber++;
  148. }
  149. }
  150. //为各个站的信息分配内存
  151. for(int i=0;i<nCount;i++)
  152. {
  153. pStations[i].pnRoutineID = new short[pStations[i].nRoutineNumber];
  154. pStations[i].pnOrder = new short[pStations[i].nRoutineNumber];
  155. pStations[i].nRoutineNumber = 0; //下面重新数
  156. }
  157. //重新设置信息
  158. for(int i=0;i<nSize;i++)
  159. {
  160. for(short j=0;j<pAllRoutines[i].nStationNumber;j++)
  161. {
  162. short k;
  163. for(k=0;k<nCount;k++)
  164. {
  165. if(pStations[k].szStationName.Equals(pAllRoutines[i].szStaionName[j]))
  166. break;
  167. }
  168. pStations[k].pnRoutineID[pStations[k].nRoutineNumber] = (short)i;
  169. pStations[k].pnOrder[pStations[k].nRoutineNumber] = j;
  170. pStations[k].nRoutineNumber++;
  171. }
  172. }
  173. return nCount;
  174. }
  175. public ArrayList Search(string sz1, string sz2,ArrayList array)
  176. {
  177. Search(_pRoutine,_nRCount,_pStations,_nSCount,sz1,sz2,array);
  178. return array;
  179. }
  180. short Search(Routine[] pAllRoutines,short nSize,Station[] pStations,short nSCount,string szFrom,string szTo,ArrayList pResPath)
  181. {
  182. short nCount = 0;
  183. short nStationOrder;
  184. Node nodeCurrent  ;
  185. Queue queueNodes = new Queue(); //存储需要访问的节点
  186. short nRoutineCurrent;
  187. short nStationCurrent;
  188. short i;
  189. short nMinChangeTimes=1000; //第一次找到的换乘次数
  190. //先得到起点站的线路
  191. for(i=0;i<nSize;i++)
  192. {
  193. nStationOrder = HasStation( pAllRoutines[i],szFrom,0,0);
  194. if(nStationOrder >= 0)
  195. {
  196. nodeCurrent = new Node();
  197. nodeCurrent.nNodeNumber = 1;
  198. nodeCurrent.nRoutineOrder = new short [10];
  199. nodeCurrent.nStationOrder = new short [10];
  200. nodeCurrent.nRoutineOrder[0] = i;
  201. nodeCurrent.nStationOrder[0] = nStationOrder;
  202. //入队列操作
  203. queueNodes.Enqueue(nodeCurrent);
  204. }
  205. }
  206. while( !(0 == queueNodes.Count) )
  207. {
  208. nodeCurrent = (Node)queueNodes.Dequeue();//.GetFront();
  209. if((nodeCurrent.nNodeNumber>=TIMELIMIT+1) || (nodeCurrent.nNodeNumber>nMinChangeTimes-1) || (queueNodes.Count >1500000)) //换乘次数限制
  210. break;
  211. //得到队列头
  212. //从队头站点序列的最后一个站开始检索是否能够找到到站
  213. nRoutineCurrent = nodeCurrent.nRoutineOrder[nodeCurrent.nNodeNumber-1];
  214. nStationCurrent = nodeCurrent.nStationOrder[nodeCurrent.nNodeNumber-1];
  215. nStationOrder = HasStation( pAllRoutines[nRoutineCurrent], szTo, nStationCurrent, pAllRoutines[nRoutineCurrent].nFlag);
  216. if(nStationOrder>=0)  //表示找到
  217. {
  218. nodeCurrent.nRoutineOrder[nodeCurrent.nNodeNumber] = nRoutineCurrent;
  219. nodeCurrent.nStationOrder[nodeCurrent.nNodeNumber] = nStationOrder;
  220. nodeCurrent.nNodeNumber++;
  221. if(nodeCurrent.nNodeNumber>nMinChangeTimes)
  222. break;
  223. PathNode pPathTempNode = new PathNode();
  224. pPathTempNode.nSegNumber = (short)(nodeCurrent.nNodeNumber-1);
  225. pPathTempNode.szRoutineName = new string[pPathTempNode.nSegNumber];
  226. pPathTempNode.szFromStationName = new string[pPathTempNode.nSegNumber];
  227. pPathTempNode.szToStationName = new string[pPathTempNode.nSegNumber];
  228. for(i=0;i<pPathTempNode.nSegNumber;i++)
  229. {
  230. pPathTempNode.szRoutineName[i] =string.Copy(pAllRoutines[nodeCurrent.nRoutineOrder[i]].szRoutineName);
  231. pPathTempNode.szFromStationName[i] = string.Copy(pAllRoutines[nodeCurrent.nRoutineOrder[i]].szStaionName[nodeCurrent.nStationOrder[i]]);
  232. pPathTempNode.szToStationName[i] = string.Copy(pAllRoutines[nodeCurrent.nRoutineOrder[i+1]].szStaionName[nodeCurrent.nStationOrder[i+1]]);
  233. }
  234. pResPath.Add(pPathTempNode);
  235. if(nCount == 0)
  236. nMinChangeTimes = nodeCurrent.nNodeNumber;
  237. nCount++;
  238. if(nCount >20)
  239. break;
  240. }
  241. else  //要将所有可能的路径加入队列
  242. {
  243. for(i=(short)(nStationCurrent+1);i<pAllRoutines[nRoutineCurrent].nStationNumber;i++)
  244. {
  245. string szTheStation;
  246. szTheStation= string.Copy(pAllRoutines[nRoutineCurrent].szStaionName[i]);
  247. short j = SearchStation(pStations,nSCount,szTheStation);
  248. for(short k=0;k<pStations[j].nRoutineNumber;k++)
  249. {
  250. short l;
  251. for(l=0;l<nodeCurrent.nNodeNumber;l++)
  252. if(pStations[j].pnRoutineID[k]==nodeCurrent.nRoutineOrder[l])
  253. break;
  254. if(l<nodeCurrent.nNodeNumber) //说明已经处理过该线路
  255. continue;
  256. Node nodeTemp = new Node();
  257. nodeTemp.nNodeNumber = (short)(nodeCurrent.nNodeNumber+1);
  258. nodeTemp.nRoutineOrder = new short [10];
  259. nodeTemp.nStationOrder = new short [10];
  260. for(l=0;l<nodeCurrent.nNodeNumber;l++)
  261. {
  262. nodeTemp.nRoutineOrder[l] = nodeCurrent.nRoutineOrder[l];
  263. nodeTemp.nStationOrder[l] = nodeCurrent.nStationOrder[l];
  264. }
  265. nodeTemp.nRoutineOrder[nodeCurrent.nNodeNumber]=pStations[j].pnRoutineID[k];
  266. nodeTemp.nStationOrder[nodeCurrent.nNodeNumber]=pStations[j].pnOrder[k];
  267. queueNodes.Enqueue(nodeTemp);
  268. }
  269. }
  270. if( pAllRoutines[nRoutineCurrent].nFlag==0 ) //双向线路,需要两个方向查询
  271. {
  272. for(i=(short)(nStationCurrent-1);i>=0;i--)
  273. {
  274. string szTheStation;
  275. szTheStation=string.Copy(pAllRoutines[nRoutineCurrent].szStaionName[i]);
  276. short j = SearchStation(pStations,nSCount,szTheStation);
  277. for(short k=0;k<pStations[j].nRoutineNumber;k++)
  278. {
  279. short l;
  280. for(l=0;l<nodeCurrent.nNodeNumber;l++)
  281. if(pStations[j].pnRoutineID[k]==nodeCurrent.nRoutineOrder[l])
  282. break;
  283. if(l<nodeCurrent.nNodeNumber) //说明已经处理过该线路
  284. continue;
  285. Node nodeTemp = new Node();
  286. nodeTemp.nNodeNumber = (short)(nodeCurrent.nNodeNumber+1);
  287. nodeTemp.nRoutineOrder = new short [10];
  288. nodeTemp.nStationOrder = new short [10];
  289. for(l=0;l<nodeCurrent.nNodeNumber;l++)
  290. {
  291. nodeTemp.nRoutineOrder[l] = nodeCurrent.nRoutineOrder[l];
  292. nodeTemp.nStationOrder[l] = nodeCurrent.nStationOrder[l];
  293. }
  294. nodeTemp.nRoutineOrder[nodeCurrent.nNodeNumber]=pStations[j].pnRoutineID[k];
  295. nodeTemp.nStationOrder[nodeCurrent.nNodeNumber]=pStations[j].pnOrder[k];
  296. queueNodes.Enqueue(nodeTemp);
  297. }
  298. }
  299. }
  300. }
  301. }
  302. return nCount;
  303. }
  304. //根据站名得到它是一条公交线路上第几站,基0,-1表示没有
  305. //nSearchFrom为开始搜寻的站序号
  306. //nFlag标记向那个方向搜索,0表示双方向,1表示单向
  307. short HasStation(Routine theRoutine,string szStation,short nSearchFrom,short nFlag)
  308. {
  309. if( nFlag!=0 )
  310. {
  311. for(short i=nSearchFrom;i<theRoutine.nStationNumber;i++)
  312. if(theRoutine.szStaionName[i].Equals(szStation))
  313. return i;
  314. }
  315. else if( nFlag==0 )
  316. {
  317. for(short i=nSearchFrom;i<theRoutine.nStationNumber;i++) //正向搜索
  318. if(theRoutine.szStaionName[i].Equals(szStation))
  319. return i;
  320. for(short i=nSearchFrom;i>=0;i--) //反向搜索
  321. if(theRoutine.szStaionName[i].Equals(szStation))
  322. return i;
  323. }
  324. return -1;
  325. }
  326. short SearchStation(Station[] pStations,short nSCount,string theName)
  327. {
  328. short j;
  329. //用于统计时间
  330. for(j=0;j<nSCount;j++)
  331. {
  332. if(pStations[j].szStationName.Equals(theName))
  333. {
  334. return j;
  335. }
  336. }
  337. return j;
  338. }
  339. void FreeStationIndex(Station[] pStations,short nSize)
  340. {
  341. for(short i=0;i<nSize;i++)
  342. {
  343. pStations[i].pnRoutineID = null;
  344. pStations[i].pnOrder = null;
  345. }
  346. }
  347. void FreeRoutineInfo(Routine[] pAllRoutines,short nSize)
  348. {
  349. for(short i=0;i<nSize;i++)
  350. {
  351. pAllRoutines[i].szStaionName = null;
  352. }
  353. }
  354. }
  355. }