www.pudn.com > 20065291434354190.rar > XPath.cpp


#include "StdAfx.h" 
#include "XPath.h" 
#include "XLine.h" 
 
#include  
 
XPath::XPath() 
{ 
	lines = 0; 
	distance = 0; 
	count = 0; 
} 
 
XPath::XPath (XLine& vLine, CString vStation1, CString vStation2) 
{ 
	lines = 0; 
	distance = 0; 
	count = 0; 
 
	int pos1 = 0; 
	int pos2 = 0; 
 
	for (int i = 0; i < (int)vLine.spots.size(); i++) 
	{ 
		CString name = vLine.spots[i].GetName(); 
	 
		if (name == vStation1)	pos1 = i; 
		if (name == vStation2)	pos2 = i; 
	} 
 
	if (pos1 < pos2) 
	{ 
		for (int i = pos1; i <= pos2; i ++)  
			Append(vLine.spots[i].GetName(), vLine.spots[i].GetPosition (), vLine.name); 
 
		lines = 1; 
	} 
	else if (vLine.isOneWay == false) 
	{ 
		for (int i = pos1; i >= pos2; i --)  
			Append(vLine.spots[i].GetName(), vLine.spots[i].GetPosition (), vLine.name); 
 
		lines = 1; 
	} 
} 
 
XPath::XPath (XLine& vLine1, XLine& vLine2, CString vStation1, CString vStation2, bool reverse) 
{ 
	lines = 0; 
	distance = 0; 
	count = 0; 
 
	struct { 
		int index1; 
		int index2; 
	} junctions [32]; 
 
	int junctionCount = 0; //交叉点个数 
 
	int index1 = -1; //vStation1在line1中的位置 
	int index2 = -1; //vStation2在line2中的位置 
 
	//<<根据line1顺序找出交叉点 
	for (size_t i = 0; i < vLine1.spots.size (); i ++) 
	{ 
		if (vLine1.spots [i].GetName () == "") continue; 
 
		if (index1 == -1 && vLine1.spots [i].GetName () == vStation1) 
			index1 = i; 
 
		for (size_t j = 0; j < vLine2.spots.size (); j ++) 
		{ 
			if (vLine2.spots [j].GetName () == "") continue; 
 
			if (index2 == -1 && vLine2.spots [j].GetName () == vStation2) 
				index2 = j; 
 
			if (vLine1.spots [i].GetName () == vLine2.spots [j].GetName ()) 
			{ 
				junctions [junctionCount].index1 = i; 
				junctions [junctionCount].index2 = j; 
				junctionCount ++; 
				break; 
			} 
		} 
	} 
	//>> 
 
	if (junctionCount == 0 || index1 == -1 || index2 == -1)//错误 
		return; 
 
	if (junctionCount == 1) 
	{ 
		if (reverse) return; 
 
		if (junctions [0].index1 > index1) 
		{ 
			for (int i = index1; i < junctions [0].index1; i++) 
				Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name); 
		} 
		else 
		{ 
			for (int i = index1; i > junctions [0].index1; i--) 
				Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name); 
		} 
 
		Append (vLine1.spots[junctions [0].index1].GetName (), vLine1.spots[junctions [0].index1].GetPosition (), vLine1.name, vLine2.name); 
	 
		if (junctions [0].index2 < index2) 
		{ 
			for (int i = junctions [0].index2+1; i <= index2 ; i++) 
				Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name); 
		} 
		else 
		{ 
			for (int i = junctions [0].index2-1; i >= index2 ; i--) 
				Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name); 
		} 
 
		lines = 2; 
	} 
	else 
	{ 
		bool sameDirection = junctions [1].index2 > junctions [0].index2; //判断line2是否与line1同向 
 
		//从A点开始, 从小到大 
		if (!reverse) 
		{ 
			int minJunction = -1; //line1中的位置 
			int maxJunction = -1; //line1中的位置 
			for (int i = 0; i < junctionCount; i ++) 
			{ 
				if (junctions [i].index1 < index1) continue; 
 
				if (minJunction == -1) 
					minJunction = junctions [i].index1; 
 
				//防止超过B点 
				if (sameDirection) //同向 
				{ 
					if (junctions [i].index2 > index2) 
						break; 
				} 
				else 
				{ 
					if (junctions [i].index2 < index2) 
						break; 
				} 
 
				maxJunction = junctions [i].index1; 
			} 
 
			if (minJunction != -1 && maxJunction != -1) 
			{ 
				int lastJunc = -1; //最后一个交叉点 
 
				//先沿line1走 
				for (int i = index1; i <= maxJunction; i ++) 
				{ 
					//判断是否是交叉点 
					bool bJunc = false; 
					for (int j = 0; j < junctionCount; j ++) 
					{ 
						if (i == junctions [j].index1) 
						{ 
							lastJunc = junctions [j].index2; 
							bJunc = true; 
							break; 
						} 
					} 
 
					if (bJunc) 
						Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name, vLine2.name); 
					else 
						Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name); 
				} 
 
				//再沿line2走 
				if (sameDirection) //同向 
				{ 
					for (int i = lastJunc+1; i <= index2; i ++) 
						Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name); 
				} 
				else 
				{ 
					for (int i = lastJunc-1; i >= index2; i --) 
						Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name); 
				} 
 
				lines = 2; 
			} 
		} 
		else //从A点开始, 从大到小 
		{ 
			int minJunction = -1; 
			int maxJunction = -1; 
			for (int i = junctionCount-1; i > 0; i --) 
			{ 
				if (junctions [i].index1 > index1) continue; 
 
				if (maxJunction == -1) 
					maxJunction = junctions [i].index1; 
 
				if (sameDirection) //同向 
				{ 
					if (junctions [i].index2 < index2) 
						break; 
				} 
				else 
				{ 
					if (junctions [i].index2 > index2) 
						break; 
				} 
 
				minJunction = junctions [i].index1; 
			} 
 
			if (minJunction != -1 && maxJunction != -1) 
			{ 
				int lastJunc = -1; 
 
				//先沿line1走 
				for (int i = index1; i >= minJunction; i --) 
				{ 
					//判断是否是交叉点 
					bool bJunc = false; 
					for (int j = 0; j < junctionCount; j ++) 
					{ 
						if (i == junctions [j].index1) 
						{ 
							lastJunc = junctions [j].index2; 
							bJunc = true; 
							break; 
						} 
					} 
 
					if (bJunc) 
						Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name, vLine2.name); 
					else 
						Append (vLine1.spots[i].GetName (), vLine1.spots[i].GetPosition (), vLine1.name); 
				} 
 
				//再沿line2走 
				if (sameDirection) //同向 
				{ 
					for (int i = lastJunc-1; i >= index2; i --) 
						Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name); 
				} 
				else 
				{ 
					for (int i = lastJunc+1; i <= index2; i ++) 
						Append (vLine2.spots[i].GetName (), vLine2.spots[i].GetPosition (), vLine2.name); 
				} 
 
				lines = 2; 
			} 
		} 
	} 
} 
 
XPath::~XPath() 
{ 
} 
 
int XPath::Append (CString vStation, PointF vPosition, CString vLine1, CString vLine2) 
{ 
	//计算距离 
	if (passages.size() > 0) 
	{ 
		PointF precPoint = passages[passages.size()-1].position; 
 
		distance += sqrtf ((precPoint.X - vPosition.X) *(precPoint.X - vPosition.X)  
							+ (precPoint.Y - vPosition.Y) * (precPoint.Y - vPosition.Y) ); 
	///*** 
		distance *=0.95; 
	} 
	 
	XPassage obj (vStation, vPosition, vLine1, vLine2); 
	passages.push_back(obj); 
 
	if (vStation != "") 
		count ++; 
 
	return (int) passages.size(); 
} 
 
int XPath::Remove (const XPassage& obj) 
{ 
	return (int) passages.size(); 
} 
 
CString XPath::ToString() 
{ 
	CString str; 
 
	CString strDistance; 
	strDistance.Format (_T("%.2f"), distance/100); 
 
	if (lines == 1) //直达 
	{ 
		//str = "从 " + passages[0].station + " 到 " + passages[passages.size ()-1].station + "\r\n"; 
		str = "直达线路: (" + passages[0].line1 + ") 里程(" + strDistance + ")\r\n"; 
 
		for (size_t i = 0; i < passages.size(); i++) 
		{ 
			if (passages[i].station == "") 
				continue; 
 
			str += passages[i].station; 
			if (i != passages.size () - 1) 
				 str += ", "; 
		} 
	} 
	else if (lines == 2) //直达 
	{ 
		//str = "从 " + passages[0].station + " 到 " + passages[passages.size ()-1].station + "\r\n"; 
		str = "转一趟线路: (" + passages[0].line1 + ", " + passages[passages.size ()-1].line1 + ") 里程(" + strDistance + ")\r\n"; 
 
		for (size_t i = 0; i < passages.size(); i++) 
		{ 
			if (passages[i].station == "") 
				continue; 
 
			if (passages[i].line2 == "") 
			{ 
				str += passages[i].station; 
				if (i != passages.size () - 1) 
					str += ", "; 
			} 
			else 
			{ 
				str += passages[i].station + "(换乘:" + passages[i].line2 + ")"; 
				if (i != passages.size () - 1) 
					str += ", "; 
			} 
 
		} 
	} 
 
	return str; 
} 
 
bool XPath::operator <  (const XPath& obj) 
{ 
	int a1, a2; 
	int b1, b2; 
	int c1, c2; 
	 
	if (lines == 2) 
		a1 = 150; 
	else 
		a1 = 100; 
	b1 = count*10; 
 
	if (obj.lines == 2) 
		a2 = 150; 
	else 
		a2 = 100; 
	b2 = obj.count * 10; 
 
	c1 = distance / 10; //1公里差不多相当于1站 
	c2 = obj.distance / 10; 
 
	return a1+b1+c1 < a2+b2+c2; 
}