⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpath.cpp

📁 北京公交车查询系统 北京公交车查询系统
💻 CPP
字号:
#include "StdAfx.h"
#include "XPath.h"
#include "XLine.h"

#include <math.h>

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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -