XPath.cpp
上传用户:yokoluohf
上传日期:2013-02-25
资源大小:769k
文件大小:8k
源码类别:

GIS编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "XPath.h"
  3. #include "XLine.h"
  4. #include <math.h>
  5. XPath::XPath()
  6. {
  7. lines = 0;
  8. distance = 0;
  9. count = 0;
  10. }
  11. XPath::XPath (XLine& vLine, CString vStation1, CString vStation2)
  12. {
  13. lines = 0;
  14. distance = 0;
  15. count = 0;
  16. int pos1 = 0;
  17. int pos2 = 0;
  18. for (int i = 0; i < (int)vLine.spots.size(); i++)
  19. {
  20. CString name = vLine.spots[i].GetName();
  21. if (name == vStation1) pos1 = i;
  22. if (name == vStation2) pos2 = i;
  23. }
  24. if (pos1 < pos2)
  25. {
  26. for (int i = pos1; i <= pos2; i ++) 
  27. Append(vLine.spots[i].GetName(), vLine.spots[i].GetPosition (), vLine.name);
  28. lines = 1;
  29. }
  30. else if (vLine.isOneWay == false)
  31. {
  32. for (int i = pos1; i >= pos2; i --) 
  33. Append(vLine.spots[i].GetName(), vLine.spots[i].GetPosition (), vLine.name);
  34. lines = 1;
  35. }
  36. }
  37. XPath::XPath (XLine& vLine1, XLine& vLine2, CString vStation1, CString vStation2, bool reverse)
  38. {
  39. lines = 0;
  40. distance = 0;
  41. count = 0;
  42. struct {
  43. int index1;
  44. int index2;
  45. } junctions [32];
  46. int junctionCount = 0; //交叉点个数
  47. int index1 = -1; //vStation1在line1中的位置
  48. int index2 = -1; //vStation2在line2中的位置
  49. //<<根据line1顺序找出交叉点
  50. for (size_t i = 0; i < vLine1.spots.size (); i ++)
  51. {
  52. if (vLine1.spots [i].GetName () == "") continue;
  53. if (index1 == -1 && vLine1.spots [i].GetName () == vStation1)
  54. index1 = i;
  55. for (size_t j = 0; j < vLine2.spots.size (); j ++)
  56. {
  57. if (vLine2.spots [j].GetName () == "") continue;
  58. if (index2 == -1 && vLine2.spots [j].GetName () == vStation2)
  59. index2 = j;
  60. if (vLine1.spots [i].GetName () == vLine2.spots [j].GetName ())
  61. {
  62. junctions [junctionCount].index1 = i;
  63. junctions [junctionCount].index2 = j;
  64. junctionCount ++;
  65. break;
  66. }
  67. }
  68. }
  69. //>>
  70. if (junctionCount == 0 || index1 == -1 || index2 == -1)//错误
  71. return;
  72. if (junctionCount == 1)
  73. {
  74. if (reverse) return;
  75. if (junctions [0].index1 > index1)
  76. {
  77. for (int i = index1; i < junctions [0].index1; i++)
  78. Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name);
  79. }
  80. else
  81. {
  82. for (int i = index1; i > junctions [0].index1; i--)
  83. Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name);
  84. }
  85. Append (vLine1.spots[junctions [0].index1].GetName (), vLine1.spots[junctions [0].index1].GetPosition (), vLine1.name, vLine2.name);
  86. if (junctions [0].index2 < index2)
  87. {
  88. for (int i = junctions [0].index2+1; i <= index2 ; i++)
  89. Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name);
  90. }
  91. else
  92. {
  93. for (int i = junctions [0].index2-1; i >= index2 ; i--)
  94. Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name);
  95. }
  96. lines = 2;
  97. }
  98. else
  99. {
  100. bool sameDirection = junctions [1].index2 > junctions [0].index2; //判断line2是否与line1同向
  101. //从A点开始, 从小到大
  102. if (!reverse)
  103. {
  104. int minJunction = -1; //line1中的位置
  105. int maxJunction = -1; //line1中的位置
  106. for (int i = 0; i < junctionCount; i ++)
  107. {
  108. if (junctions [i].index1 < index1) continue;
  109. if (minJunction == -1)
  110. minJunction = junctions [i].index1;
  111. //防止超过B点
  112. if (sameDirection) //同向
  113. {
  114. if (junctions [i].index2 > index2)
  115. break;
  116. }
  117. else
  118. {
  119. if (junctions [i].index2 < index2)
  120. break;
  121. }
  122. maxJunction = junctions [i].index1;
  123. }
  124. if (minJunction != -1 && maxJunction != -1)
  125. {
  126. int lastJunc = -1; //最后一个交叉点
  127. //先沿line1走
  128. for (int i = index1; i <= maxJunction; i ++)
  129. {
  130. //判断是否是交叉点
  131. bool bJunc = false;
  132. for (int j = 0; j < junctionCount; j ++)
  133. {
  134. if (i == junctions [j].index1)
  135. {
  136. lastJunc = junctions [j].index2;
  137. bJunc = true;
  138. break;
  139. }
  140. }
  141. if (bJunc)
  142. Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name, vLine2.name);
  143. else
  144. Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name);
  145. }
  146. //再沿line2走
  147. if (sameDirection) //同向
  148. {
  149. for (int i = lastJunc+1; i <= index2; i ++)
  150. Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name);
  151. }
  152. else
  153. {
  154. for (int i = lastJunc-1; i >= index2; i --)
  155. Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name);
  156. }
  157. lines = 2;
  158. }
  159. }
  160. else //从A点开始, 从大到小
  161. {
  162. int minJunction = -1;
  163. int maxJunction = -1;
  164. for (int i = junctionCount-1; i > 0; i --)
  165. {
  166. if (junctions [i].index1 > index1) continue;
  167. if (maxJunction == -1)
  168. maxJunction = junctions [i].index1;
  169. if (sameDirection) //同向
  170. {
  171. if (junctions [i].index2 < index2)
  172. break;
  173. }
  174. else
  175. {
  176. if (junctions [i].index2 > index2)
  177. break;
  178. }
  179. minJunction = junctions [i].index1;
  180. }
  181. if (minJunction != -1 && maxJunction != -1)
  182. {
  183. int lastJunc = -1;
  184. //先沿line1走
  185. for (int i = index1; i >= minJunction; i --)
  186. {
  187. //判断是否是交叉点
  188. bool bJunc = false;
  189. for (int j = 0; j < junctionCount; j ++)
  190. {
  191. if (i == junctions [j].index1)
  192. {
  193. lastJunc = junctions [j].index2;
  194. bJunc = true;
  195. break;
  196. }
  197. }
  198. if (bJunc)
  199. Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name, vLine2.name);
  200. else
  201. Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name);
  202. }
  203. //再沿line2走
  204. if (sameDirection) //同向
  205. {
  206. for (int i = lastJunc-1; i >= index2; i --)
  207. Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name);
  208. }
  209. else
  210. {
  211. for (int i = lastJunc+1; i <= index2; i ++)
  212. Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name);
  213. }
  214. lines = 2;
  215. }
  216. }
  217. }
  218. }
  219. XPath::~XPath()
  220. {
  221. }
  222. int XPath::Append (CString vStation, PointF vPosition, CString vLine1, CString vLine2)
  223. {
  224. //计算距离
  225. if (passages.size() > 0)
  226. {
  227. PointF precPoint = passages[passages.size()-1].position;
  228. distance += sqrtf ((precPoint.X - vPosition.X) *(precPoint.X - vPosition.X) 
  229. + (precPoint.Y - vPosition.Y) * (precPoint.Y - vPosition.Y) );
  230. ///***
  231. distance *=0.95;
  232. }
  233. XPassage obj (vStation, vPosition, vLine1, vLine2);
  234. passages.push_back(obj);
  235. if (vStation != "")
  236. count ++;
  237. return (int) passages.size();
  238. }
  239. int XPath::Remove (const XPassage& obj)
  240. {
  241. return (int) passages.size();
  242. }
  243. CString XPath::ToString()
  244. {
  245. CString str;
  246. CString strDistance;
  247. strDistance.Format (_T("%.2f"), distance/100);
  248. if (lines == 1) //直达
  249. {
  250. //str = "从 " + passages[0].station + " 到 " + passages[passages.size ()-1].station + "rn";
  251. str = "直达线路: (" + passages[0].line1 + ") 里程(" + strDistance + ")rn";
  252. for (size_t i = 0; i < passages.size(); i++)
  253. {
  254. if (passages[i].station == "")
  255. continue;
  256. str += passages[i].station;
  257. if (i != passages.size () - 1)
  258.  str += ", ";
  259. }
  260. }
  261. else if (lines == 2) //直达
  262. {
  263. //str = "从 " + passages[0].station + " 到 " + passages[passages.size ()-1].station + "rn";
  264. str = "转一趟线路: (" + passages[0].line1 + ", " + passages[passages.size ()-1].line1 + ") 里程(" + strDistance + ")rn";
  265. for (size_t i = 0; i < passages.size(); i++)
  266. {
  267. if (passages[i].station == "")
  268. continue;
  269. if (passages[i].line2 == "")
  270. {
  271. str += passages[i].station;
  272. if (i != passages.size () - 1)
  273. str += ", ";
  274. }
  275. else
  276. {
  277. str += passages[i].station + "(换乘:" + passages[i].line2 + ")";
  278. if (i != passages.size () - 1)
  279. str += ", ";
  280. }
  281. }
  282. }
  283. return str;
  284. }
  285. bool XPath::operator <  (const XPath& obj)
  286. {
  287. int a1, a2;
  288. int b1, b2;
  289. int c1, c2;
  290. if (lines == 2)
  291. a1 = 150;
  292. else
  293. a1 = 100;
  294. b1 = count*10;
  295. if (obj.lines == 2)
  296. a2 = 150;
  297. else
  298. a2 = 100;
  299. b2 = obj.count * 10;
  300. c1 = distance / 10; //1公里差不多相当于1站
  301. c2 = obj.distance / 10;
  302. return a1+b1+c1 < a2+b2+c2;
  303. }