/************************************************************************
* 文件名    ：  dsuQuery.c
* 版权说明  ：  北京交控科技有限公司
* 版本号  	：  1.0
* 创建时间	：	2009.09.26
* 作者  		软件部	
* 功能描述	：	dsu查询函数文件  
* 使用注意	： 
* 修改记录	：	
************************************************************************/
#ifdef ZCAPP_VXWORKS_CODECONTROL
#include <vxWorks.h>
#endif /*End of ZCAPP_VXWORKS_CODECONTROL*/

#include "dquQueryExp.h"
#include "dsuVar.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "dquCbtcType.h"
#include "LinkConfigDataManage.h"

/*
* 功能描述： 利用运行方向信息以及道岔状态信息，查询得到当前link沿运行方向的相邻link。
* 输入参数： UINT16 LinkId, 当前Link编号
*            UCHAR Direction, 当前方向
*            UCHAR PointNum,  道岔信息，道岔个数
*            const POINT_STRU *pPointStru, 道岔信息
* 输出参数： UINT16 *pLinkId，当前Link的相邻Link编号
* 返回值：   1,查询成功
*            0,查询失败,输入数据无效，道岔失表
*		      	 0xFF,线路终点，未找到道岔
*             
*/
UINT8 dsuGetAdjacentLinkIDExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 LinkId, UCHAR Direction, UCHAR PointNum,const DQU_POINT_STATUS_STRU *pPointStru, UINT16 *pLinkId)
{
	UINT8 chReturnValue=0;             /*用于函数返回值*/
	UINT16 CurrentLinkIndex;           /*当前Link Index*/
	DSU_LINK_STRU *pCurrentLinkStru=NULL;   /*当前Link,获取本地数据使用*/
	UINT16 AdjancentLinkIndex;         /*当前Link Index*/
	DSU_LINK_STRU *pAdjancentLinkStru=NULL; /*当前Link,获取本地数据使用*/
	UINT8 FindFlag = 0;                /*查找标记，用于记录查找是否成功*/
	UINT8 i;                           /*用于循环*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if (NULL != pDsuEmapStru)
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*判断输入LinkID的有效性*/	
	if((LinkId>LINKINDEXNUM)||(dsuLinkIndex[LinkId] == 0xFFFF))
	{
		/*输入LinkId无效，查询失败，返回*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*判断输入方向有效性*/
	if((Direction!=EMAP_SAME_DIR)&&(Direction!=EMAP_CONVER_DIR))
	{
		/*输入方向无效，查询失败，返回*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*到此表示输入数据有效*/

	/*根据LinkID获取当前link结构体*/
	CurrentLinkIndex=dsuLinkIndex[LinkId];
	pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

	/*按照输入方向来分情况处理*/
	if(Direction==EMAP_CONVER_DIR)
	{
		/*Link反向查找，按照当前Link始端端点情况分情况处理*/
		if(pCurrentLinkStru->wOrgnJointMainLkId==DSU_NULL_16)
		{
			/*线路终点，当前link无相邻link，返回*/
			chReturnValue = 0xff;
			return chReturnValue;

		}else if(pCurrentLinkStru->wOrgnPointType==EMAP_AXLE_DOT)
		{
			/*计轴点*/
			/*相邻正线Link即为所求*/
			*pLinkId = pCurrentLinkStru->wOrgnJointMainLkId;

			/*查询成功，返回查询结果*/
			chReturnValue=1;
			return chReturnValue;

		}else if(pCurrentLinkStru->wOrgnPointType==EMAP_POINT_DOT)
		{
			/*当前始端端点类型是道岔点*/
			/*判断当前link是否为道岔的汇合Link*/
			if(pCurrentLinkStru->wOrgnJointSideLkId==DSU_NULL_16)
			{
				/*当前link非汇合Link，非混合link相邻Link只有一个，道岔状态也必须正确，以下验证道岔状态是否正确*/

				/*遍历道岔信息，查找当前道岔的状态信息*/
				FindFlag=0;
				for(i=0;i<PointNum;i++)
				{
					if (pPointStru[i].PointId == pCurrentLinkStru->wOrgnPointId)
					{
						/*说明已在输入道岔信息中查找到当前Link终端处的道岔*/

						/*置查找位为TRUR*/
						FindFlag=1;
						break;
					}
				}

				if(FindFlag==0)
				{
					/*没有找到当前道岔信息，当前Link相邻Link可能处于MA范围之外，返回失败*/
					chReturnValue=0xff;
					return chReturnValue;
				}

				/*获取相邻正线Link信息,也就是获取相邻汇合Link信息*/
				AdjancentLinkIndex=dsuLinkIndex[pCurrentLinkStru->wOrgnJointMainLkId];
				pAdjancentLinkStru=dsuStaticHeadStru->pLinkStru+AdjancentLinkIndex;

				if(((pPointStru[i].PointStatus == EMAP_POINT_STATUS_MAIN)&&(LinkId==pAdjancentLinkStru->wTmnlJointMainLkId))
					||((pPointStru[i].PointStatus == EMAP_POINT_STATUS_SIDE)&&(LinkId==pAdjancentLinkStru->wTmnlJointSideLkId)))
				{
					/*道岔状态正确有两种情况：1.相邻道岔为定位，当前Link是相邻Link的正线相邻Iink。
					2.相邻道岔为反位，当前Link是相邻Link的侧线相邻Iink。
					*/
					*pLinkId=pCurrentLinkStru->wOrgnJointMainLkId;
				
					/*查询成功，返回查询结果*/
					chReturnValue=1;
					return chReturnValue;
				}
				else
				{
					/*已找到相邻道岔，但是相邻道岔的道岔状态不对或者道岔状态失表，发生严重错误，函数返回失败*/
					chReturnValue=0;
					return chReturnValue;
				}
				
			}
			else
			{
				/*当前link为道岔的汇合Link*/
				/*遍历道岔信息，查找当前道岔的状态信息*/
				FindFlag=0;
				for(i=0;i<PointNum;i++)
				{
					if (pPointStru[i].PointId == pCurrentLinkStru->wOrgnPointId)
					{
						/*说明已在输入道岔信息中查找到当前Link终端处的道岔*/

						/*置查找位为TRUR*/
						FindFlag=1;
						break;
					}
				}

				if(FindFlag==0)
				{
					/*没有找到当前道岔信息，当前Link相邻Link可能处于MA范围之外，返回失败*/
					chReturnValue=0xff;
					return chReturnValue;
				}
				else
				{
					/*根据道岔的实时状态信息分类讨论*/
					if (pPointStru[i].PointStatus == EMAP_POINT_STATUS_MAIN)
					{
						/*道岔状态位于定位*/
						/*起点相邻正线Link即为所求*/
						*pLinkId=pCurrentLinkStru->wOrgnJointMainLkId;

						/*查询成功，返回查询结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else if(pPointStru[i].PointStatus == EMAP_POINT_STATUS_SIDE)
					{
						/*道岔状态位于反位*/
						/*起点相邻侧线Link即为所求*/
						*pLinkId=pCurrentLinkStru->wOrgnJointSideLkId;
						
						/*查询成功，返回查询结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*道岔失表， POINTLOSESTATUS 失表返回值的处理*/
						chReturnValue=0U;
						return chReturnValue;
					}
				}

			}

		}
		else
		{
			/*Link端点类型不合法*/
			chReturnValue=0U;
			return chReturnValue;
		}

	}
	else /*if(Direction==SAMEDIR)*/
	{
		/*正向于Link方向查找*/

		/*Link正向查找，按照当前Link终端端点情况分情况处理*/
		if(pCurrentLinkStru->wTmnlJointMainLkId==DSU_NULL_16)
		{
			/*端点类型为线路终点，返回查询结果*/
			chReturnValue = 0xff;
			return chReturnValue;

		}else if(pCurrentLinkStru->wTmnlPointType==EMAP_AXLE_DOT)
		{
			/*当前Link终端端点计轴点*/
			/*相邻正线Link即为所求*/

			*pLinkId=pCurrentLinkStru->wTmnlJointMainLkId;
			chReturnValue=1;
			return chReturnValue;

		}else if (pCurrentLinkStru->wTmnlPointType == EMAP_POINT_DOT)
		{
			/*当前Link终端端点道岔点*/

			/*判断当前link是否为道岔的汇合Link*/
			if(pCurrentLinkStru->wTmnlJointSideLkId==DSU_NULL_16)
			{
				/*当前link非汇合Link，非混合link相邻Link只有一个，道岔状态也必须正确，以下验证道岔状态是否正确*/

				/*遍历道岔信息，查找当前道岔的状态信息*/
				FindFlag=0;
				for(i=0;i<PointNum;i++)
				{
					if (pPointStru[i].PointId == pCurrentLinkStru->wTmnlPointId)
					{
						/*说明已在输入道岔信息中查找到当前Link终端处的道岔*/

						/*置查找位为TRUR*/
						FindFlag=1;
						break;
					}
				}

				if(FindFlag==0)
				{
					/*没有找到当前道岔信息，当前Link相邻Link可能处于MA范围之外，返回失败*/
					chReturnValue=0xff;
					return chReturnValue;
				}

				/*获取相邻正线Link信息,也就是获取相邻汇合Link信息*/
				AdjancentLinkIndex=dsuLinkIndex[pCurrentLinkStru->wTmnlJointMainLkId];
				pAdjancentLinkStru=dsuStaticHeadStru->pLinkStru+AdjancentLinkIndex;

				if(((pPointStru[i].PointStatus == EMAP_POINT_STATUS_MAIN)&&(LinkId==pAdjancentLinkStru->wOrgnJointMainLkId))
					||((pPointStru[i].PointStatus == EMAP_POINT_STATUS_SIDE)&&(LinkId==pAdjancentLinkStru->wOrgnJointSideLkId)))
				{
					/*道岔状态正确有两种情况：1.相邻道岔为定位，当前Link是相邻Link的正线相邻Iink。
					2.相邻道岔为反位，当前Link是相邻Link的侧线相邻Iink。
					*/
					*pLinkId=pCurrentLinkStru->wTmnlJointMainLkId;

					/*查询成功，返回查询结果*/
					chReturnValue=1;
					return chReturnValue;
				}
				else
				{
					/*已找到相邻道岔，但是相邻道岔的道岔状态不对或者道岔状态失表，发生严重错误，函数返回失败*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}
			else
			{
				/*当前汇合Link，按照道岔实时状态分类处理*/

				/*查找当前道岔信息*/
				FindFlag=0;
				for(i=0;i<PointNum;i++)
				{
					if (pPointStru[i].PointId == pCurrentLinkStru->wTmnlPointId)
					{
						/*说明已在输入道岔信息中查找到当前Link终端处的道岔*/
						FindFlag=1;
						break;
					}
				}

				if(FindFlag==0)
				{
					/*没有找到当前道岔信息，当前Link相邻Link可能处于MA范围之外，返回失败*/
					chReturnValue=0xff;
					return chReturnValue;
				}
				else
				{
					/*根据道岔实时状态，分情况处理*/
					if(pPointStru[i].PointStatus==EMAP_POINT_STATUS_MAIN)
					{
						/*当前Link是汇合Link，道岔定位，终点相邻正线Link即为所求*/

						*pLinkId=pCurrentLinkStru->wTmnlJointMainLkId;

						/*查询成功，返回查询结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else if (pPointStru[i].PointStatus == EMAP_POINT_STATUS_SIDE)
					{
						/*当前Link是汇合Link，道岔反位，终点相邻侧线Link即为所求*/

						*pLinkId=pCurrentLinkStru->wTmnlJointSideLkId;
						
						/*查询成功，返回查询结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*当前Link是汇合Link，失表  POINTLOSESTATUS，返回失败*/
						chReturnValue=0U;
						return chReturnValue;
					}
				}

			}

		}
		else
		{
			/*Link端点类型不合法，函数返回失败*/
			chReturnValue=0U;
			return chReturnValue;
		}
	}

	/*此处不可达*/
	
}


/*
* 功能描述： 功能函数，根据当前位置，和位移以及输入的道岔信息，得到新位置.
             如果一个点即当前Lnk起点，又是下一个Link终点，按照离当前点pLODStru最近的Link Id返回
* 输入参数： const LOD_STRU * pLODStru, 当前位置
*            INT32 Displacement,        位移，有符号，如果符号为负表示方向取反
*            UCHAR PointNum,            道岔数量
*            const POINT_STRU * pPointStru,  道岔信息
* 输出参数： LOD_STRU *pNewLODStru       新位置
* 返回值：   1,成功
*            0,失败
*注意：合库和燕房使用
*/
static UCHAR dsuLODCalcuExp_DFT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStru, INT32 Displacement, UCHAR PointNum, const DQU_POINT_STATUS_STRU *pPointStru, LOD_STRU *pNewLODStru)
{
	UINT8 chReturnValue=0U;       /*用于函数返回值*/
	UINT16 CurrentLinkId = 0U;         /*用于查找过程中临时保存当前LinkID*/
	UINT16 CurrentLinkIndex = 0U; /*当前Link Index*/
	DSU_LINK_STRU *pCurrentLinkStru=NULL;/*用于循环查找过程中临时保存当前Link结构体*/
	UINT8 FindDir = 0U;                  /*用于记录实际操作过程中的查找方向*/
	INT32 FindDisplacement = 0;         /*临时保存偏移量*/
	INT32 FindDisplacementSum = 0;       /*用于累加位移偏移量*/
	UINT16 k;                        /*循环用变量*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != pLODStru) 
		&& (NULL != pPointStru) && (NULL != pNewLODStru))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*参数指针为空*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*判断输入LinkID的有效性*/
	if((pLODStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStru->Lnk] == 0xFFFF))
	{
		/*输入LinkId无效，查询失败，返回*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*判断入口数据偏移量的有效性*/
	if (pLODStru->Off > LinkLengthExp(pDsuEmapStru,pLODStru->Lnk))
	{
		/*数据无效，查询失败，返回*/
		chReturnValue=0U;
		return chReturnValue;
	}
	/*判断输入方向有效性*/
	if((pLODStru->Dir!=EMAP_SAME_DIR)&&(pLODStru->Dir!=EMAP_CONVER_DIR))
	{
		/*输入方向无效，查询失败，返回*/
		chReturnValue=0U;
		return chReturnValue;
	}	

	/*特殊情况处理，偏移量Displacement为0*/
	if (Displacement == 0)
	{
		/*displacement如果为0，返回当前位置为所求*/
		pNewLODStru->Lnk=pLODStru->Lnk;
		pNewLODStru->Off=pLODStru->Off;
		pNewLODStru->Dir=pLODStru->Dir;

		/*查询成功，返回查询结果*/
		chReturnValue=1;
		return chReturnValue;
	}

	/*如果displacement小于0，则按照displacement绝对值来查找新位置，方向取反*/
	if((pLODStru->Dir==EMAP_SAME_DIR)&&(Displacement>0))
	{
		/*正向查找*/
		FindDir=EMAP_SAME_DIR;
		FindDisplacement=Displacement;
	}
	else if((pLODStru->Dir==EMAP_CONVER_DIR)&&(Displacement<0))
	{
		/*正向查找*/
		FindDir=EMAP_SAME_DIR;
		FindDisplacement=-Displacement;
	}
	else if((pLODStru->Dir==EMAP_SAME_DIR)&&(Displacement<0))
	{
		/*反向查找*/
		FindDir=EMAP_CONVER_DIR;
		FindDisplacement=-Displacement;
	}
	else if((pLODStru->Dir==EMAP_CONVER_DIR)&&(Displacement>0))
	{
		/*反向查找*/
		FindDir=EMAP_CONVER_DIR;
		FindDisplacement=Displacement;
	}
	else
	{
		/*不可达分支*/
	}

	/*根据LinkID从数据库中查找当前link信息*/
	CurrentLinkIndex=dsuLinkIndex[pLODStru->Lnk];
	pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;
	if(FindDir==EMAP_SAME_DIR)
	{
		/*正向查找*/

		/*根据当前位置正向累加偏移量*/
		FindDisplacementSum=pCurrentLinkStru->dwLength-pLODStru->Off;

		/*根据位移判断新位置是否在同一个Link上*/
		if(FindDisplacementSum>=FindDisplacement)
		{
			/*说明在同一个link上，累加位移得到新位置*/
			pNewLODStru->Lnk=pCurrentLinkStru->wId;
			pNewLODStru->Off=pLODStru->Off+FindDisplacement;
			pNewLODStru->Dir=pLODStru->Dir;
			chReturnValue=1;
			return chReturnValue;
		}
		else
		{
			for (k=0;k<LINKINDEXNUM;k++)
			{
				/*此处循环并不是为了要遍历每一个Link，而是对循环计数，不能超过LINKINDEXNUM*/
				if( 1==dsuGetAdjacentLinkIDExp(pDsuEmapStru,pCurrentLinkStru->wId, FindDir, PointNum, pPointStru,&CurrentLinkId) )
				{
					/*pCurrentLinkStru指向相邻Link,相邻Link变为当前Link*/
					CurrentLinkIndex=dsuLinkIndex[CurrentLinkId];
					pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

					FindDisplacementSum+=pCurrentLinkStru->dwLength;
					if(FindDisplacementSum>=FindDisplacement)
					{
						/*累加的位移值加上当前Link长度大于输入偏移量，说明目的位置当前link上*/
						pNewLODStru->Lnk=pCurrentLinkStru->wId;
						pNewLODStru->Off=FindDisplacement-(FindDisplacementSum-pCurrentLinkStru->dwLength);
						pNewLODStru->Dir=pLODStru->Dir;
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*累加的位移值加上当前Link长度小于输入偏移量，说明目的位置不在当前link上，循环继续向前查找下一个Link*/
					}
				}
				else
				{
					/*获取下一个link失败*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}
				
			/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
			chReturnValue=0U;
			return chReturnValue;
		}
	}
	else
	{
		/*反向查找*/

		/*累加偏移量置0*/
		FindDisplacementSum=0;

		/*根据当前位置反向累加偏移量*/
		FindDisplacementSum=pLODStru->Off;

		if(FindDisplacementSum>=FindDisplacement)
		{
			/*说明在同一个link上*/
			pNewLODStru->Lnk=pCurrentLinkStru->wId;
			pNewLODStru->Off=pLODStru->Off-FindDisplacement;
			pNewLODStru->Dir=pLODStru->Dir;

			/*查询成功，返回查询结果*/
			chReturnValue=1;
			return chReturnValue;
		}
		else
		{
			for (k=0;k<LINKINDEXNUM;k++)
			{
				/*此处循环并不是为了要遍历每一个Link，而是对循环计数，不能超过LINKINDEXNUM*/
				if( 1==dsuGetAdjacentLinkIDExp(pDsuEmapStru,pCurrentLinkStru->wId, FindDir, PointNum, pPointStru,&CurrentLinkId) )
				{
					/*pCurrentLinkStru指向相邻Link*/
					CurrentLinkIndex=dsuLinkIndex[CurrentLinkId];
					pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

					FindDisplacementSum+=pCurrentLinkStru->dwLength;
					if(FindDisplacementSum>=FindDisplacement)
					{
						/*累加的位移值加上当前Link长度大于输入偏移量，说明目的位置当前link上*/
						pNewLODStru->Lnk=pCurrentLinkStru->wId;
						pNewLODStru->Off=(FindDisplacementSum-FindDisplacement);
						pNewLODStru->Dir=pLODStru->Dir;
                        /*查询成功，输出查询结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*累加的位移值加上当前Link长度小于输入偏移量，说明目的位置不在当前link上，循环继续向前查找下一个Link*/
					}
				}
				else
				{
					/*获取下一个link失败*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}

			/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
			chReturnValue=0U;
			return chReturnValue;
		}
	}
}

/*
* 功能描述： 功能函数，根据当前位置，和位移以及输入的道岔信息，得到新位置.
             如果一个点即当前Lnk起点，又是下一个Link终点，按照离当前点pLODStru最近的Link Id返回
* 输入参数： const LOD_STRU * pLODStru, 当前位置
*            INT32 Displacement,        位移，有符号，如果符号为负表示方向取反
*            UCHAR PointNum,            道岔数量
*            const POINT_STRU * pPointStru,  道岔信息
* 输出参数： LOD_STRU *pNewLODStru       新位置
* 返回值：   1,成功
*            0,失败
*author:qxt 20170811 互联互通增加link逻辑方向变化点
*/
static UCHAR dsuLODCalcuExp_HLT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStru, INT32 Displacement, UCHAR PointNum, const DQU_POINT_STATUS_STRU *pPointStru, LOD_STRU *pNewLODStru)
{
	UINT8 chReturnValue=0U;       /*用于函数返回值*/
	UINT8 chFlag=1u;              /*函数执行失败标记*/
	UINT16 wCurrentLinkId = 0U;         /*用于查找过程中临时保存当前LinkID*/
	UINT16 wCurrentLinkIndex = 0U; /*当前Link Index*/
	DSU_LINK_STRU *pCurrentLinkStru=NULL;/*用于循环查找过程中临时保存当前Link结构体*/
	UINT8 wFindDir = 0U;                  /*用于记录实际操作过程中的查找方向*/
	INT32 dwFindDisplacement = 0;         /*临时保存偏移量*/
	INT32 dwFindDisplacementSum = 0;       /*用于累加位移偏移量*/
	UINT16 k=0U;             /*循环用变量*/
	UINT8 tmpLODDir = 0xff;    /*临时变量,保存入口方向信息*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL == pLODStru) || (NULL == pPointStru) || (NULL == pNewLODStru))
	{
		/*位置参数指针为空*/
		chFlag = 0U;
	}
	else if ((NULL != pDsuEmapStru)&&(NULL != pDsuEmapStru->dsuEmapIndexStru)&&(NULL!=pDsuEmapStru->dsuStaticHeadStru))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;

		/*判断输入LinkID的有效性*/
		if((pLODStru->Lnk>LINKINDEXNUM)||(DSU_NULL_16 == dsuLinkIndex[pLODStru->Lnk]))
		{
			/*输入LinkId无效，查询失败，返回*/
			chFlag=0U;
		}

		/*判断入口数据偏移量的有效性*/
		if (pLODStru->Off > LinkLengthExp(pDsuEmapStru,pLODStru->Lnk))
		{
			/*数据无效，查询失败，返回*/
			chFlag=0U;
		}
		/*判断输入方向有效性*/
		if((EMAP_SAME_DIR!=pLODStru->Dir)&&(EMAP_CONVER_DIR!=pLODStru->Dir))
		{
			/*输入方向无效，查询失败，返回*/
			chFlag=0U;
		}	
	}
	else
	{
		/*电子地图数据指针为空*/
		chFlag = 0U;

	}
	
	if (0U!=chFlag)
	{
		/*特殊情况处理，偏移量Displacement为0*/
		if (0U==Displacement)
		{
			/*displacement如果为0，返回当前位置为所求*/
			pNewLODStru->Lnk=pLODStru->Lnk;
			pNewLODStru->Off=pLODStru->Off;
			pNewLODStru->Dir=pLODStru->Dir;

			/*查询成功，返回查询结果*/
			chReturnValue=1;
		}
		else/*0!=Displacement*/
		{
			tmpLODDir = pLODStru->Dir;
			
			/*如果displacement小于0，则按照displacement绝对值来查找新位置，方向取反*/
			if((EMAP_SAME_DIR==pLODStru->Dir)&&(Displacement>0))
			{
				/*正向查找*/
				wFindDir=EMAP_SAME_DIR;
				dwFindDisplacement=Displacement;
			}
			else if((EMAP_CONVER_DIR==pLODStru->Dir)&&(Displacement<0))
			{
				/*正向查找*/
				wFindDir=EMAP_SAME_DIR;
				dwFindDisplacement=-Displacement;
			}
			else if((EMAP_SAME_DIR==pLODStru->Dir)&&(Displacement<0))
			{
				/*反向查找*/
				wFindDir=EMAP_CONVER_DIR;
				dwFindDisplacement=-Displacement;
			}
			else if((EMAP_CONVER_DIR==pLODStru->Dir)&&(Displacement>0))
			{
				/*反向查找*/
				wFindDir=EMAP_CONVER_DIR;
				dwFindDisplacement=Displacement;
			}
			else
			{
				/*不可达分支*/
			}

			/*根据LinkID从数据库中查找当前link信息*/
			wCurrentLinkIndex=dsuLinkIndex[pLODStru->Lnk];
			pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;

			/*查询的新位置在查询起点所在的Link的情况*/
			if(EMAP_SAME_DIR==wFindDir)
			{
				/*正向查找*/

				/*根据当前位置正向累加偏移量*/
				dwFindDisplacementSum=pCurrentLinkStru->dwLength-pLODStru->Off;

				/*根据位移判断新位置是否在同一个Link上*/
				if(dwFindDisplacementSum>=dwFindDisplacement)
				{
					/*说明在同一个link上，累加位移得到新位置*/
					pNewLODStru->Lnk=pCurrentLinkStru->wId;
					pNewLODStru->Off=pLODStru->Off+dwFindDisplacement;
					pNewLODStru->Dir=pLODStru->Dir;
					chReturnValue=1;
				}
				else
				{
                    /*不作处理*/
				}
			}
			else/*FindDir=EMAP_CONVER_DIR*/
			{
				/*反向查找*/

				/*累加偏移量置0*/
				dwFindDisplacementSum=0;

				/*根据当前位置反向累加偏移量*/
				dwFindDisplacementSum=pLODStru->Off;

				if(dwFindDisplacementSum>=dwFindDisplacement)
				{
					/*说明在同一个link上*/
					pNewLODStru->Lnk=pCurrentLinkStru->wId;
					pNewLODStru->Off=pLODStru->Off-dwFindDisplacement;
					pNewLODStru->Dir=pLODStru->Dir;

					/*查询成功，返回查询结果*/
					chReturnValue=1;
				}
				else
				{
					/*不作处理*/
				}
			}

			/*查询的新位置与查询起点不在同一个Link*/
			if (1!=chReturnValue)
			{
				/*此处循环并不是为了要遍历每一个Link，而是对循环计数，不能超过LINKINDEXNUM*/
				for (k=0;k<LINKINDEXNUM;k++)
				{	
					if( 1==dsuGetAdjacentLinkIDExp(pDsuEmapStru,pCurrentLinkStru->wId, wFindDir, PointNum, pPointStru,&wCurrentLinkId) )
					{	

						/*判断Link是否为逻辑方向变化点(查询方向为正且该link的终点为逻辑方向变化点 或 查询反方向且该link的起点为逻辑方向变化)*/
						if(((EMAP_SAME_DIR==wFindDir)&&(0x55==pCurrentLinkStru->wLogicDirChanged))||  
							((EMAP_CONVER_DIR==wFindDir)&&(0xaa==pCurrentLinkStru->wLogicDirChanged)))
						{	
							wFindDir =~ wFindDir;/*有变化点，改变查找方向*/
							tmpLODDir =~ tmpLODDir;/*有变化点,改变输出位置逻辑方向*/
						}

						/*pCurrentLinkStru指向相邻Link,相邻Link变为当前Link*/
						wCurrentLinkIndex=dsuLinkIndex[wCurrentLinkId];
						pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;

						dwFindDisplacementSum+=pCurrentLinkStru->dwLength;
						if(dwFindDisplacementSum>=dwFindDisplacement)/*累加的位移值加上当前Link长度大于输入偏移量，说明目的位置当前link上*/
						{

							/*最终点所在位置为查找方向反向*/
							if (EMAP_CONVER_DIR==wFindDir)
							{
								pNewLODStru->Lnk=pCurrentLinkStru->wId;
								pNewLODStru->Off=dwFindDisplacementSum-dwFindDisplacement;
								pNewLODStru->Dir=tmpLODDir;
							}
							/*最终点所在位置为查找方向正向 */
							else
							{

								pNewLODStru->Lnk=pCurrentLinkStru->wId;
								pNewLODStru->Off=dwFindDisplacement-(dwFindDisplacementSum-pCurrentLinkStru->dwLength);
								pNewLODStru->Dir=tmpLODDir;
							}					
							chReturnValue=1;
							break;
						}
						else
						{												
							/*累加的位移值加上当前Link长度小于输入偏移量，说明目的位置不在当前link上，循环继续向前查找下一个Link*/
						}
					}
					else
					{
						/*获取下一个link失败*/
						chReturnValue=0U;
						break;
					}
				}/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
			}			

		}/*(0!=Displacement) end*/

	}/*if (0!=chFlag) end */
	
	return chReturnValue;

}

/*访问接口*/
UINT8 dsuLODCalcuExp(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStru, INT32 Displacement, UCHAR PointNum, const DQU_POINT_STATUS_STRU *pPointStru, LOD_STRU *pNewLODStru)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if (DQU_CBTC_HLT == cbtcVersionType)
	{
		rtnValue =dsuLODCalcuExp_HLT(pDsuEmapStru,pLODStru,Displacement, PointNum,pPointStru,pNewLODStru);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType) || (DQU_CBTC_FAO == cbtcVersionType) ||(DQU_CBTC_DG == cbtcVersionType) )
	{
		rtnValue =dsuLODCalcuExp_DFT(pDsuEmapStru,pLODStru,Displacement, PointNum,pPointStru,pNewLODStru);
	}
	else
	{
		rtnValue = 0U;
		
	}
	return rtnValue; 
}

/*
* 功能描述： 由A，B两者位置和B点方向得到两者位移。
* 输入参数： const LOD_STRU * pLODAStru, A点位置
*            const LOD_STRU * pLODBStru, B点位置
*            UINT8 PointNum,             道岔数量
*            const POINT_STRU * pPointStru, 道岔信息结构体
* 输出参数： INT32 *Displacement，       AB位移，是有符号数。符号表示方向，
             AB位移以LinkB方向为参照。AB方向与LinkB方向相同，位移值取正，否则位移值取负。
* 返回值：   1,成功
*            0,失败
* 使用注意：注意此处只按照B的方向进行查找，未关注A点的方向。（合库和燕房项目使用）
*/
static UINT8 dsuDispCalcuByLOCExp_DFT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODAStru, const LOD_STRU *pLODBStru, 
	UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, INT32 *Displacement)
{
	UINT8 chReturnValue = 0;     /*用于函数返回值*/
	UINT8 chFunRtn=0U;     /*调用函数返回值*/
	UINT16 CurrentLinkId = 0U;     /*用于查找过程中临时保存当前LinkID*/
	UINT16 CurrentLinkIndex; /*查找过程中记录Link Index临时变量*/

	UINT8 AFindFlag=2U;/*0，查找失败。1，查找成功。2,继续查找。*/
	UINT8 BFindFlag=2U;/*0，查找失败。1，查找成功。2,继续查找。*/
	INT32 AFindDisplacementSum=0;        /*A查找B过程中的位移累加值*/
	INT32 BFindDisplacementSum=0;        /*B查找A过程中位移累加值*/
	DSU_LINK_STRU *pACurrentLinkStru=NULL;    /*A当前Link*/
	DSU_LINK_STRU *pBCurrentLinkStru=NULL;    /*B当前Link*/
	UINT16 k;                        /*循环用变量*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) 
		&& (NULL!= pLODAStru) && (NULL!= pLODBStru) 
		&& (NULL != pPointStru) && (NULL != Displacement))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*参数指针为空*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*预置函数返回值为0*/
	*Displacement=0U;

	/*判断输入A LinkID的有效性*/
	if((pLODAStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODAStru->Lnk] == 0xFFFF))
	{
		/*输入LinkId无效,查询失败，返回*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*判断输入B LinkID的有效性*/
	if((pLODBStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODBStru->Lnk] == 0xFFFF))
	{
		/*输入LinkId无效,查询失败，返回*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*判断入口数据linkA偏移量的有效性*/
	if (pLODAStru->Off > LinkLengthExp(pDsuEmapStru,pLODAStru->Lnk))
	{
		/*入口数据异常，查询失败*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*判断入口数据linkB偏移量的有效性*/
	if (pLODBStru->Off > LinkLengthExp(pDsuEmapStru,pLODBStru->Lnk))
	{
		/*入口数据异常，查询失败*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*判断linkB运行方向的正确性*/
	if ((EMAP_SAME_DIR != pLODBStru->Dir) && (EMAP_CONVER_DIR != pLODBStru->Dir))
	{
		/*入口数据异常，查询失败*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*特殊情况处理，LinkA与LinkB处于同一Link上*/
	if(pLODAStru->Lnk == pLODBStru->Lnk)
	{
		/*A,B位于同一link，计算两点间距离信息*/
		*Displacement = pLODBStru->Off-pLODAStru->Off;
		
		if (EMAP_SAME_DIR == pLODBStru->Dir)
		{
			/**/
		}
		else
		{
			/*方向相反，转换位移符号*/
			*Displacement=-(*Displacement);
		}

		/*函数查询成功，返回*/		
		chReturnValue=1;
		return 1;
	}


	/*根据LinkID获取当前link*/
	CurrentLinkIndex=dsuLinkIndex[pLODAStru->Lnk];
	pACurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;
	CurrentLinkIndex=dsuLinkIndex[pLODBStru->Lnk];
	pBCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

	/*按照B的方向不同进行分类*/
	/*查找基本方法为A和B各自按照B的方向向前查找，如果找到对方，记录查找到的位移，返回结果*/
	if (pLODBStru->Dir==EMAP_SAME_DIR)
	{
		/*沿正向查找*/
		/*累加位移值*/
		AFindDisplacementSum=pACurrentLinkStru->dwLength-pLODAStru->Off;
		BFindDisplacementSum=pBCurrentLinkStru->dwLength-pLODBStru->Off;
		for (k=0;k<LINKINDEXNUM;k++)
		{
			/*此处循环是为了计数，循环次数不能超过LINKINDEXNUM*/
			if(AFindFlag==2)
			{
				/*A向前查找一个link*/
				chFunRtn=dsuGetAdjacentLinkIDExp(pDsuEmapStru,pACurrentLinkStru->wId, EMAP_SAME_DIR, PointNum, pPointStru,&CurrentLinkId);
				if( 1==chFunRtn )
				{
					/*pACurrentLinkStru指向相邻Link*/
					CurrentLinkIndex=dsuLinkIndex[CurrentLinkId];
					pACurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

					if(pACurrentLinkStru->wId==pLODBStru->Lnk)
					{
						/*A找到了B*/

						/*查找成功*/
						AFindFlag=1;
						/*累加偏移量，计算结果值*/
						AFindDisplacementSum+=(pLODBStru->Off);
						/*此时A沿正向找到了B，偏移量为正*/
						*Displacement=AFindDisplacementSum;

						/*查找成功，返回结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*A没有找到B，累加偏移量，继续查找*/
						AFindDisplacementSum+=pACurrentLinkStru->dwLength;
					}
				}
				else if( 0xff==chFunRtn )
				{
					/*线路终点或者道岔未找到，A点停止查找*/
					AFindFlag=0U;
				}
				else
				{
					/*A获取下一个link失败,Link失表或者输入错误*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}

			/*B向前查找一个link*/
			if(BFindFlag==2){
				chFunRtn=dsuGetAdjacentLinkIDExp(pDsuEmapStru,pBCurrentLinkStru->wId,EMAP_SAME_DIR, PointNum, pPointStru,&CurrentLinkId);
				if( 1== chFunRtn)
				{
					/*pBCurrentLinkStru指向相邻Link*/
					CurrentLinkIndex=dsuLinkIndex[CurrentLinkId];
					pBCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

					if(pBCurrentLinkStru->wId==pLODAStru->Lnk)
					{
						/*B找到了A*/
						BFindFlag=1;

						/*累加偏移量，计算结果值*/
						BFindDisplacementSum+=(pLODAStru->Off);

						/*此时B沿正向找到了A，偏移量为负*/
						*Displacement=-BFindDisplacementSum;

						/*查找成功，返回结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*如果B没有找到A，累加偏移量，继续查找*/
						BFindDisplacementSum+=pBCurrentLinkStru->dwLength;
					}
				}
				else if( 0xff==chFunRtn )
				{
					/*线路终点或者道岔未找到，停止查找*/
					BFindFlag=0U;			
				}
				else
				{
					/*B获取下一个link失败,Link失表或者输入错误*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}

			if((AFindFlag==0)&&(BFindFlag==0))
			{
				/*A，B均结束查找并且没有找到对方，函数返回失败*/
				chReturnValue=0U;
				return chReturnValue;
			}
			else
			{
				/*此时AFindFlag，BFindFlag至少有一个为2，继续查找*/
			}

		}
		
		/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
		chReturnValue=0U;
		return chReturnValue;

	}
	else /*if (pLODBStru->Dir==CONVERDIR)*/
	{
		/*A,B均沿反向向查找*/
		AFindDisplacementSum=pLODAStru->Off;
		BFindDisplacementSum=pLODBStru->Off;
		for (k=0;k<LINKINDEXNUM;k++)
		{
			/*此处循环是为了计数，循环次数不能超过LINKINDEXNUM*/
			if(AFindFlag==2)
			{
				/*A向前查找一个link*/
				chFunRtn=dsuGetAdjacentLinkIDExp(pDsuEmapStru,pACurrentLinkStru->wId, EMAP_CONVER_DIR, PointNum, pPointStru,&CurrentLinkId);
				if( 1==chFunRtn )
				{
					/*pACurrentLinkStru指向相邻Link*/
					CurrentLinkIndex=dsuLinkIndex[CurrentLinkId];
					pACurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

					if(pACurrentLinkStru->wId==pLODBStru->Lnk)
					{
						/*A找到了B*/

						/*查找成功*/
						AFindFlag=1;
						AFindDisplacementSum+=(pACurrentLinkStru->dwLength-pLODBStru->Off);

						/*此时A沿反向找到了B，偏移量为正*/
						*Displacement=AFindDisplacementSum;

						/*查找成功，返回结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*如果A没有找到B，累加偏移量，继续查找*/
						AFindDisplacementSum+=pACurrentLinkStru->dwLength;
					}
				}
				else if( 0xff==chFunRtn )
				{
					/*线路终点或者道岔未找到，停止查找*/
					AFindFlag=0;
				}
				else/*( 0==chReturnValue )*/
				{
					/*A获取下一个link失败,Link失表或者输入错误*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}

			/*B向前查找一个link*/
			if(BFindFlag==2){
				chFunRtn=dsuGetAdjacentLinkIDExp(pDsuEmapStru,pBCurrentLinkStru->wId, EMAP_CONVER_DIR, PointNum, pPointStru,&CurrentLinkId);
				if( 1== chFunRtn)
				{
					/*pACurrentLinkStru指向相邻Link*/
					CurrentLinkIndex=dsuLinkIndex[CurrentLinkId];
					pBCurrentLinkStru=dsuStaticHeadStru->pLinkStru+CurrentLinkIndex;

					if(pBCurrentLinkStru->wId==pLODAStru->Lnk)
					{
						/*B找到了A*/

						/*查找成功*/
						BFindFlag=1;
						BFindDisplacementSum+=(pBCurrentLinkStru->dwLength-pLODAStru->Off);

						/*此时B沿反向找到了A，偏移量为负*/
						*Displacement=-BFindDisplacementSum;

						/*查找成功，返回结果*/
						chReturnValue=1;
						return chReturnValue;
					}
					else
					{
						/*如果B没有找到A，累加偏移量，继续查找*/
						BFindDisplacementSum+=pBCurrentLinkStru->dwLength;
					}
				}
				else if( 0xff==chFunRtn )
				{
					/*线路终点或者道岔未找到，停止查找*/
					BFindFlag=0;			
				}
				else /*( 0==chReturnValue )*/
				{
					/*B获取下一个link失败,Link失表或者输入错误*/
					chReturnValue=0U;
					return chReturnValue;
				}
			}

			if((AFindFlag==0)&&(BFindFlag==0))
			{
				/*A，B均结束查找并且没有找到对方，函数返回失败*/
				chReturnValue=0U;
				return chReturnValue;
			}
			else
			{
				/*此时AFindFlag，BFindFlag至少有一个为2，继续查找*/
			}

		}

		/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
		chReturnValue=0U;
		return chReturnValue;

	}
}

/*
* 功能描述： 由A，B两者位置和A点方向得到两者位移。
* 输入参数： const LOD_STRU * pLODAStru, A点位置
*            const LOD_STRU * pLODBStru, B点位置
*            UINT8 PointNum,             道岔数量
*            const POINT_STRU * pPointStru, 道岔信息结构体
* 输出参数： INT32 *Displacement，       AB位移，是有符号数。符号表示方向，
             AB位移以LinkA方向为参照。AB方向与LinkA方向相同，位移值取正，否则位移值取负。
* 返回值：   1,成功
*            0,失败
* 使用注意：注意此处只按照A的方向进行查找，未关注B点的方向。（互联互通项目使用）
* author:qxt 20170811
*/
static UINT8 dsuDispCalcuByLOCExp_HLT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODAStru, const LOD_STRU *pLODBStru, 
									  UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, INT32 *Displacement)
{
	UINT8 chReturnValue =0U;     /*用于函数返回值*/
	UINT8 chFunRtn=0U;     /*调用函数返回值*/
	UINT8 chFlag=1;           /*函数执行失败标记*/
	UINT16 wCurrentLinkId = 0U;     /*用于查找过程中临时保存当前LinkID*/
	UINT16 wCurrentLinkIndex=0U; /*查找过程中记录Link Index临时变量*/

	UINT8 wAFindFlag=2;/*0，查找失败。1，查找成功。2,继续查找。*/
	UINT8 wBFindFlag=2;/*0，查找失败。1，查找成功。2,继续查找。*/
	INT32 dwAFindDisplacementSum=0;        /*A查找B过程中的位移累加值*/
	INT32 dwBFindDisplacementSum=0;        /*B查找A过程中位移累加值*/
	DSU_LINK_STRU *pACurrentLinkStru=NULL;    /*A当前Link*/
	DSU_LINK_STRU *pBCurrentLinkStru=NULL;    /*B当前Link*/
	UINT16 k=0U;                        /*循环用变量*/
	UINT8 wAFindDir = 0;               /*用于记录实际操作A查找B过程中的查找方向,初始值为A的方向 */
    UINT8 wBFindDir = 0;               /*用于记录实际操作B查找A过程中的查找方向,初始值为A的方向 */
	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;

	if ((NULL == pLODAStru) || (NULL == pLODBStru) || (NULL == pPointStru) || (NULL == Displacement))
	{
		/*输入空指针,查询失败*/
		chFlag = 0U;
	}
	else if ((NULL != pDsuEmapStru)&&(NULL!=pDsuEmapStru->dsuEmapIndexStru)&&(NULL!=pDsuEmapStru->dsuStaticHeadStru))
	{
		/*预置函数返回值为0*/
		*Displacement = 0;

		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;

		/*判断输入A LinkID的有效性*/
		if((pLODAStru->Lnk>LINKINDEXNUM)||(DSU_NULL_16 == dsuLinkIndex[pLODAStru->Lnk]))
		{
			/*输入LinkId无效,查询失败*/
			chFlag=0U;
		}

		/*判断输入B LinkID的有效性*/
		if((pLODBStru->Lnk>LINKINDEXNUM)||(DSU_NULL_16 == dsuLinkIndex[pLODBStru->Lnk]))
		{
			/*输入LinkId无效,查询失败*/
			chFlag=0U;
		}

		/*判断入口数据linkA偏移量的有效性*/
		if (pLODAStru->Off > LinkLengthExp(pDsuEmapStru,pLODAStru->Lnk))
		{
			/*入口数据异常，查询失败*/
			chFlag=0U;
		}

		/*判断入口数据linkB偏移量的有效性*/
		if (pLODBStru->Off > LinkLengthExp(pDsuEmapStru,pLODBStru->Lnk))
		{
			/*入口数据异常，查询失败*/
			chFlag=0U;
		}

		/*判断linkA运行方向的正确性*/
		if ((EMAP_SAME_DIR != pLODAStru->Dir) && (EMAP_CONVER_DIR != pLODAStru->Dir))
		{
			/*入口数据异常，查询失败*/
			chFlag=0U;
		}
	}
	else
	{
		/*电子地图数据指针为空*/
		chFlag = 0U;		
	}	

	
	if (0U!=chFlag)
	{
		/*特殊情况处理，LinkA与LinkB处于同一Link上*/
		if(pLODAStru->Lnk == pLODBStru->Lnk)
		{
			/*A,B位于同一link，计算两点间距离信息*/
			*Displacement = pLODBStru->Off-pLODAStru->Off;

			if (EMAP_SAME_DIR == pLODAStru->Dir)
			{
				/*无需处理*/
			}
			else
			{
				/*方向相反，转换位移符号*/
				*Displacement=-(*Displacement);
			}

			/*函数查询成功*/
			chReturnValue = 1;
			
		}
		else/*A、B不在同一link*/
		{
			/*根据LinkID获取当前link*/
			wCurrentLinkIndex=dsuLinkIndex[pLODAStru->Lnk];
			pACurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;
			wCurrentLinkIndex=dsuLinkIndex[pLODBStru->Lnk];
			pBCurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;

			/*初始查找方向*/
			wAFindDir=pLODAStru->Dir;
			wBFindDir=pLODAStru->Dir;
			/*按照A的方向不同进行分类*/
			if (EMAP_SAME_DIR==pLODAStru->Dir)
			{
				/*沿正向查找*/
				/*累加位移值*/
				dwAFindDisplacementSum=pACurrentLinkStru->dwLength-pLODAStru->Off;
				dwBFindDisplacementSum=pBCurrentLinkStru->dwLength-pLODBStru->Off;
			}
			else /*if (pLODAStru->Dir==CONVERDIR)*/
			{
				/*A,B均沿反向向查找*/
				dwAFindDisplacementSum=pLODAStru->Off;
				dwBFindDisplacementSum=pLODBStru->Off;
			}

			/*查找基本方法为A和B各自按照A的方向向前查找，如果找到对方，记录查找到的位移，返回结果*/
			for (k=0U;k<LINKINDEXNUM;k++)
			{
				/*此处循环是为了计数，循环次数不能超过LINKINDEXNUM*/
				if(2==wAFindFlag)
				{
					/*A向前查找一个link*/
					chFunRtn=dsuGetAdjacentLinkIDExp(pDsuEmapStru,pACurrentLinkStru->wId, wAFindDir, PointNum, pPointStru,&wCurrentLinkId);
					if( 1==chFunRtn )
					{
						/*如果该Link为逻辑方向变化点(查询方向为正且该link的终点为逻辑方向变化点 或 查询反方向且该link的起点为逻辑方向变化)*/
						/* 0x55表示link终点为逻辑方向变化点，0xaa表示link起点为逻辑方向变化点*/
						if(((EMAP_SAME_DIR==wAFindDir)&&(0x55==pACurrentLinkStru->wLogicDirChanged))||  
							((EMAP_CONVER_DIR==wAFindDir)&&(0xaa==pACurrentLinkStru->wLogicDirChanged)))
						{							 
							wAFindDir=~wAFindDir;/*有变化点，改变查找方向*/
						}

						/*pACurrentLinkStru指向相邻Link*/
						wCurrentLinkIndex=dsuLinkIndex[wCurrentLinkId];
						pACurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;

						if(pACurrentLinkStru->wId==pLODBStru->Lnk)
						{
							/*A找到了B*/

							/*查找成功*/
							wAFindFlag=1;
							/*累加偏移量，计算结果值*/
							if (EMAP_SAME_DIR==wAFindDir)/*最终找到B点时的查询方向为正时*/
							{
								dwAFindDisplacementSum+=(pLODBStru->Off);
							}
							else/*最终找到B点时的查询方向为反时*/
							{
								dwAFindDisplacementSum+=(pACurrentLinkStru->dwLength-pLODBStru->Off);
							}
							/*此时A沿A的方向找到了B，偏移量为正*/
							*Displacement=dwAFindDisplacementSum;
                             chReturnValue = 1;
							/*查找成功，退出*/
							break;
							
						}
						else
						{
							/*A没有找到B，累加偏移量，继续查找*/
							dwAFindDisplacementSum+=pACurrentLinkStru->dwLength;
						}
					}
					else if( 0xff==chFunRtn )
					{
						/*线路终点或者道岔未找到，A点停止查找*/
						wAFindFlag=0U;
					}
					else
					{
						/*A获取下一个link失败,Link失表或者输入错误*/
						chReturnValue=0U;
						break;
					}
				}

				/*B向前查找一个link*/
				if(2==wBFindFlag){
					chFunRtn=dsuGetAdjacentLinkIDExp(pDsuEmapStru,pBCurrentLinkStru->wId,wBFindDir, PointNum, pPointStru,&wCurrentLinkId);
					if( 1== chFunRtn)
					{
						/*如果该Link为逻辑方向变化点(查询方向为正且该link的终点为逻辑方向变化点 或 查询反方向且该link的起点为逻辑方向变化)*/
						/* 0x55表示link终点为逻辑方向变化点，0xaa表示link起点为逻辑方向变化点*/
						if(((EMAP_SAME_DIR==wBFindDir)&&(0x55==pBCurrentLinkStru->wLogicDirChanged))||  
							((EMAP_CONVER_DIR==wBFindDir)&&(0xaa==pBCurrentLinkStru->wLogicDirChanged)))
						{							 
							wBFindDir=~wBFindDir;/*有变化点，改变查找方向*/
						}
						/*pBCurrentLinkStru指向相邻Link*/
						wCurrentLinkIndex=dsuLinkIndex[wCurrentLinkId];
						pBCurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;

						if(pBCurrentLinkStru->wId==pLODAStru->Lnk)
						{
							/*B找到了A*/
							wBFindFlag=1;

							/*累加偏移量，计算结果值*/
							if (EMAP_SAME_DIR==wBFindDir)/*最终找到B点时的查询方向为正时*/
							{
								dwBFindDisplacementSum+=(pLODAStru->Off);
							}
							else/*最终找到B点时的查询方向为反时*/
							{
								dwBFindDisplacementSum+=(pBCurrentLinkStru->dwLength-pLODAStru->Off);
							}

							/*此时B沿A的方向找到了A，偏移量为负*/
							*Displacement=-dwBFindDisplacementSum;
                             chReturnValue = 1;
							/*查找成功，退出*/
							break;
						}
						else
						{
							/*如果B没有找到A，累加偏移量，继续查找*/
							dwBFindDisplacementSum+=pBCurrentLinkStru->dwLength;
						}
					}
					else if( 0xff==chFunRtn )
					{
						/*线路终点或者道岔未找到，停止查找*/
						wBFindFlag=0U;			
					}
					else
					{
						/*B获取下一个link失败,Link失表或者输入错误*/
						chReturnValue=0U;
						break;
					}
				}

				if((0U==wAFindFlag)&&(0U==wBFindFlag))
				{
					/*A，B均结束查找并且没有找到对方，函数返回失败*/
					chReturnValue=0U;
					break;
				}
				else
				{
					/*此时AFindFlag，BFindFlag至少有一个为2，继续查找*/
				}

			}/*for循环end*/

			/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
			/*如果没找到，此时chReturnValue=0*/
		}
	}/*（0!=chReturnValue）end*/

	return chReturnValue;
}


/*
*访问接口
* 功能描述： 由A，B两者位置得到两者位移。
* 输入参数： const LOD_STRU * pLODAStru, A点位置
*            const LOD_STRU * pLODBStru, B点位置
*            UINT8 PointNum,             道岔数量
*            const POINT_STRU * pPointStru, 道岔信息结构体
* 输出参数： INT32 *Displacement，       AB位移，是有符号数。符号表示方向，            
* 返回值：   1,成功
*            0,失败
* 使用注意：合库和燕房项目算法是按照B的方向查找，AB位移以LinkB方向为参照；
            互联互通项目因增加逻辑方向变化点，算法改为按照A的方向查找，AB位移以LinkA方向为参照。
* author:qxt 20170811
*/
UINT8 dsuDispCalcuByLOCExp(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODAStru, const LOD_STRU *pLODBStru, 
						   UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, INT32 *Displacement)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if (DQU_CBTC_HLT == cbtcVersionType)
	{
		rtnValue=dsuDispCalcuByLOCExp_HLT(pDsuEmapStru, pLODAStru, pLODBStru,PointNum,pPointStru,Displacement);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType) || (DQU_CBTC_FAO == cbtcVersionType) ||(DQU_CBTC_DG == cbtcVersionType))
	{
		rtnValue=dsuDispCalcuByLOCExp_DFT(pDsuEmapStru, pLODAStru, pLODBStru,PointNum,pPointStru,Displacement);
	}
	else
	{
		rtnValue = 0U;		
	}
	return rtnValue; 
}


/*
* 函数功能：	此函数的功能是查询两个位置间包含的link序列。
* ****************************************************************************************************
*        1          2              3                4                    5              6
*       -----×---------*--×--------------×--------------------×-------*-----×------------
*                       S                                                 E
*        图例：  ×，Link端点。*，查询输入的位置。1，2，3...Link示意编号
*        如图所示：Link3，4为所求结果。
*        此处方向按照pLODEndStru方向来查找，
*        S沿着pLODEndStru->Dir方向查找，找到E则返回成功，找不到则返回失败。
* ****************************************************************************************************
* 入口参数：	const LOD_STRU * pLODStartStru,	始端位置
*               const LOD_STRU * pLODEndStru	终端位置
*               const UINT8 PointNum			道岔数目 
*               const POINT_STRU * pPointStru	道岔信息
* 出口参数：	UINT16 wLinkID[DSU_MAX_LINK_BETWEEN]				Link序列数组
*               UINT16 *wLinkNumber                             Link个数
* 返回值：   	0,  查询失败
*               1,  查询成功                                                             
* 使用注意：    目前的做法没有包含两端的Link Id。
*               函数要求两个点之间可以形成区域，否则返回0
*               合库和燕房项目使用
*/
static UINT8 dsuGetLinkBtwLocExp_DFT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStartStru, const LOD_STRU *pLODEndStru,
					   UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, 
					   UINT16 wLinkID[DSU_MAX_LINK_BETWEEN], UINT16 *wLinkNumber)
{
	UINT16 chFindLinkNum = 0;   /*找到的link的数目*/
	UINT16 wCurrentLinkID = 0;  /*当前link编号*/
	UINT16 wNextLinkID = 0;     /*相邻link编号*/
	UINT16 wFindLink[DSU_MAX_LINK_BETWEEN];/*找到的link序列数组*/
	UINT16 i = 0;           /*循环用变量*/
	UINT8 chReturnValue = 0;/*函数返回值*/
	UINT16 k;                        /*循环用变量*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != pLODStartStru) && (NULL != pLODEndStru)
		&& (NULL != pPointStru) && (NULL != wLinkNumber))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
	}
	else
	{
		/*参数指针为空*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*Link个数返回值预置0*/
	*wLinkNumber=0;

	/*判断入口数据Link的有效性*/
	if((pLODStartStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStartStru->Lnk] == 0xFFFF)
	    ||(pLODEndStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODEndStru->Lnk] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*判断入口数据方向的正确性*/
	if ((pLODEndStru->Dir != EMAP_SAME_DIR) && (pLODEndStru->Dir != EMAP_CONVER_DIR))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		chReturnValue = 0;
		return chReturnValue;
	}

	if(pLODStartStru->Lnk==pLODEndStru->Lnk)
	{
		/*始端与终端在同一个Link上，*/

		/*link数为0*/
		*wLinkNumber=0;


		if (((pLODEndStru->Dir==EMAP_SAME_DIR)&&(pLODEndStru->Off>=pLODStartStru->Off))
			||((pLODEndStru->Dir==EMAP_CONVER_DIR)&&(pLODEndStru->Off<=pLODStartStru->Off)))
		{	
			/*查询确保函数从起点能够到达终点*/
			/*返回查询成功，退出*/
			chReturnValue = 1;
			return chReturnValue;	
		}
		else
		{
			/*返回查询成功，退出*/
			chReturnValue = 0;
			return chReturnValue;	
		}

	}	
	
	/*将始端link作为当前link*/
	wCurrentLinkID = pLODStartStru->Lnk;

	/*在找到的当前link不等于终端link时，持续while循环*/
	for (k=0;k<LINKINDEXNUM;k++)
	{
		/*此处循环是为了计数，循环次数不能超过LINKINDEXNUM*/

		/*调用功能函数“查询当前link的相邻link”，查询当前link的相邻link*/
		chReturnValue=dsuGetAdjacentLinkIDExp(pDsuEmapStru,wCurrentLinkID, pLODEndStru->Dir,  PointNum, pPointStru,&wNextLinkID);

		/*通过函数返回值，判断是否正确*/
		if (chReturnValue!=1)
		{
			/*查询失败，返回查询错误*/
			chFindLinkNum=0;
			chReturnValue = 0;
			return chReturnValue;
		}
		
		/*将找到的相邻link作为新的当前link*/
		wCurrentLinkID=wNextLinkID;
		
		if(wCurrentLinkID != pLODEndStru->Lnk)
		{
			if (chFindLinkNum>=DSU_MAX_LINK_BETWEEN)
			{
				/*缓冲区已满，返回失败，此种情况实际执行时不应该出现*/
				chFindLinkNum=0;
				chReturnValue = 0;
				return chReturnValue;
			}
			else
			{
				/*当前Link不等于结束Link，更新局部数组，同时将找到的link数目加一*/
				wFindLink[chFindLinkNum] = wCurrentLinkID;
				chFindLinkNum++;
			}
	
		}
		else
		{
			/*当前Link是结束Link，当前Link不写入结果中，找到终端link，退出循环*/
			break;
		}


	}

	if(k==LINKINDEXNUM)
	{
		/*循环因为k==LINKINDEXNUM结束，说明查找次数超过LINKINDEXNUM，此现象不可能发生*/
		chReturnValue=0U;
		return chReturnValue;
	}

	/*退出循环，找到终端link,输出找到的link序列*/
	for (i=0; i<chFindLinkNum; i++)
	{
		wLinkID[i] = wFindLink[i];
	}

	/*找到的Link数量赋值*/
	*wLinkNumber=chFindLinkNum;

	/*返回查询成功，退出*/
	chReturnValue = 1;
	return chReturnValue;	
}

/*
* 函数功能：	此函数的功能是查询两个位置间包含的link序列。
* ****************************************************************************************************
*        1          2              3                4                    5              6
*       -----×---------*--×--------------×--------------------×-------*-----×------------
*                       S                                                 E
*        图例：  ×，Link端点。*，查询输入的位置。1，2，3...Link示意编号
*        如图所示：Link3，4为所求结果。
*        此处方向按照pLODStartStru方向来查找，
*        S沿着pLODStartStru->Dir方向查找，找到E则返回成功，找不到则返回失败。
* ****************************************************************************************************
* 入口参数：	const LOD_STRU * pLODStartStru,	始端位置
*               const LOD_STRU * pLODEndStru	终端位置
*               const UINT8 PointNum			道岔数目 
*               const POINT_STRU * pPointStru	道岔信息
* 出口参数：	UINT16 wLinkID[DSU_MAX_LINK_BETWEEN]				Link序列数组
*               UINT16 *wLinkNumber                             Link个数
* 返回值：   	0,  查询失败
*               1,  查询成功                                                             
* 使用注意：    目前的做法没有包含两端的Link Id。
*               函数要求两个点之间可以形成区域，否则返回0
*               内部调用函数，互联互通项目使用
*  author: qxt 20170814
*/
static UINT8 dsuGetLinkBtwLocExp_HLT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStartStru, const LOD_STRU *pLODEndStru,
									 UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, 
									 UINT16 wLinkID[DSU_MAX_LINK_BETWEEN], UINT16 *wLinkNumber)
{
	UINT16 chFindLinkNum = 0;   /*找到的link的数目*/
	UINT16 wCurrentLinkID = 0;  /*当前link编号*/
	UINT16 wNextLinkID = 0;     /*相邻link编号*/
	UINT16 wFindLink[DSU_MAX_LINK_BETWEEN];/*找到的link序列数组*/
	UINT16 i = 0;           /*循环用变量*/
	UINT8 chReturnValue = 0;/*函数返回值*/
	UINT16 k=0U;                        /*循环用变量*/
	UINT16 wCurrentLinkIndex = 0; /*当前Link Index */
	DSU_LINK_STRU *pCurrentLinkStru=NULL;/*用于循环查找过程中临时保存当前Link结构体*/
	UINT8 wFindDir = 0;               /*用于记录实际操作过程中的查找方向*/
	UINT8 chFlag=1;      /*函数执行失败标识位*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;/*add by qxt 20161029*/

	if ((NULL == pLODStartStru) || (NULL == pLODEndStru) || (NULL == pPointStru) || (NULL == wLinkNumber))
	{
		/*输入空指针,查询失败*/
		chFlag = 0U;
	}
	else if ((NULL != pDsuEmapStru)&&(NULL !=pDsuEmapStru->dsuEmapIndexStru)&&(NULL!=pDsuEmapStru->dsuStaticHeadStru))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;/*add by qxt 20161029*/

		/*Link个数返回值预置0*/
		*wLinkNumber = 0;

		/*判断入口数据Link的有效性*/
		if((pLODStartStru->Lnk>LINKINDEXNUM)||(DSU_NULL_16==dsuLinkIndex[pLODStartStru->Lnk])
			||(pLODEndStru->Lnk>LINKINDEXNUM)||(DSU_NULL_16==dsuLinkIndex[pLODEndStru->Lnk]))
		{
			/*入口数据无效，数据异常，查询失败，返回错误*/
			chFlag = 0U;
		}

		/*判断入口数据方向的正确性*/
		if ((EMAP_SAME_DIR!=pLODStartStru->Dir) && (EMAP_CONVER_DIR!=pLODStartStru->Dir))
		{
			/*入口数据无效，数据异常，查询失败，返回错误*/
			chFlag = 0U;
		}
	}
	else
	{
		/*电子地图数据指针为空*/
		chFlag = 0U;
	}

	

	if (0U!=chFlag)
	{
		/*始端与终端在同一个Link上，*/
		if(pLODStartStru->Lnk==pLODEndStru->Lnk)
		{			
     		/*link数为0*/
			*wLinkNumber=0;
			if (((EMAP_SAME_DIR==pLODStartStru->Dir)&&(pLODEndStru->Off>=pLODStartStru->Off))
				||((EMAP_CONVER_DIR==pLODStartStru->Dir)&&(pLODEndStru->Off<=pLODStartStru->Off)))
			{	
				/*查询确保函数从起点能够到达终点*/
				/*返回查询成功，退出*/
				chReturnValue = 1;
			}
			else
			{
				/*返回查询成功，退出*/
				chReturnValue = 0;
			}

		}
		else/*始端与终端不在同一个Link上 start*/
		{
			/*将始端link作为当前link*/
			wCurrentLinkID = pLODStartStru->Lnk;

			/*根据LinkID从数据库中查找当前link信息*/
			wCurrentLinkIndex=dsuLinkIndex[wCurrentLinkID];
			pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;
			/*将初始查询方向设置为起点的方向 */
			wFindDir=pLODStartStru->Dir;

			/*在找到的当前link不等于终端link时，持续while循环*//*此处循环是为了计数，循环次数不能超过LINKINDEXNUM*/
			for (k=0;k<LINKINDEXNUM;k++)
			{		
				/*调用功能函数“查询当前link的相邻link”，查询当前link的相邻link*/
				chReturnValue=dsuGetAdjacentLinkIDExp(pDsuEmapStru,wCurrentLinkID,wFindDir,  PointNum, pPointStru,&wNextLinkID);

				/*通过函数返回值，判断是否正确*/
				if (chReturnValue!=1)
				{
					/*查询失败，返回查询错误*/
					chFindLinkNum=0;
					chReturnValue = 0;
					break;
				}


				/*判断该Link是否有逻辑方向变化点(查询方向为正且该link的终点为逻辑方向变化点 或 查询反方向且该link的起点为逻辑方向变化)*/
				if(((EMAP_SAME_DIR==wFindDir)&&(0x55==pCurrentLinkStru->wLogicDirChanged))||  
					((EMAP_CONVER_DIR==wFindDir)&&(0xaa==pCurrentLinkStru->wLogicDirChanged)))
				{							 
					wFindDir=~wFindDir;/*有变化点，改变查找方向*/
				}

				/*将找到的相邻link作为新的当前link*/
				wCurrentLinkID=wNextLinkID;

				/*pCurrentLinkStru指向相邻Link,相邻Link变为当前Link*/
				wCurrentLinkIndex=dsuLinkIndex[wCurrentLinkID];
				pCurrentLinkStru=dsuStaticHeadStru->pLinkStru+wCurrentLinkIndex;

				if(wCurrentLinkID != pLODEndStru->Lnk)
				{
					if (chFindLinkNum>=DSU_MAX_LINK_BETWEEN)
					{
						/*缓冲区已满，返回失败，此种情况实际执行时不应该出现*/
						chFindLinkNum=0;
						chReturnValue = 0;
						break;
					}
					else
					{
						/*当前Link不等于结束Link，更新局部数组，同时将找到的link数目加一*/
						wFindLink[chFindLinkNum] = wCurrentLinkID;
						chFindLinkNum++;
					}

				}
				else
				{
					/*当前Link是结束Link，当前Link不写入结果中，找到终端link，退出循环*/
					break;
				}

			}/*for循环结束*/

			/*查找次数超过LINKINDEXNUM*/
			if((k!=LINKINDEXNUM)&&(0!=chReturnValue))
			{
				/*退出循环，找到终端link,输出找到的link序列*/
				for (i=0; i<chFindLinkNum; i++)
				{
					wLinkID[i] = wFindLink[i];
				}

				/*找到的Link数量赋值*/
				*wLinkNumber=chFindLinkNum;
				/*返回查询成功*/
				chReturnValue = 1;

			}		

		}/*始端与终端不在同一个Link上 end*/		

	}/*(0!=chFlag) end*/	
	return chReturnValue;	
}

/*访问接口*/
UINT8 dsuGetLinkBtwLocExp(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStartStru, const LOD_STRU *pLODEndStru,
						  UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, 
						  UINT16 wLinkID[DSU_MAX_LINK_BETWEEN], UINT16 *wLinkNumber)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if ((DQU_CBTC_HLT == cbtcVersionType)||(DQU_CBTC_CC == cbtcVersionType))
	{
		rtnValue=dsuGetLinkBtwLocExp_HLT(pDsuEmapStru,pLODStartStru,pLODEndStru,PointNum,pPointStru,wLinkID,wLinkNumber);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType) || (DQU_CBTC_FAO == cbtcVersionType)||(DQU_CBTC_DG == cbtcVersionType) )
	{
		rtnValue=dsuGetLinkBtwLocExp_DFT(pDsuEmapStru,pLODStartStru,pLODEndStru,PointNum,pPointStru,wLinkID,wLinkNumber);
	}
	else
	{
		rtnValue = 0U; 
	}
	return rtnValue;
}

/*
* 函数功能： 此函数的功能是将判断当前位置是否在指定区域范围内。
* ****************************************************************************************************
*
*       --------------*--------------------*---------------------*-----------------
*                     S                    C                     E
*       查找算法为，计算位移DisplacementSC，DisplacementCE。如果两个位移符号相同，说明C在SE区域内
*
* ****************************************************************************************************
* 入口参数： const LOD_STRU * pLODStartStru,	区域始端位置
*            const LOD_STRU * pLODEndStru,	区域终端位置
*            const UINT8 PointNum,			道岔数目 
*            const POINT_STRU * pPointStru,	道岔信息
*			 const LOD_STRU * pCurrentLODStru,当前位置
* 出口参数： UINT8 *pLocInArea         1,在指定区域
*                                     0,不在指定区域
* 返回值：   0，查询失败
*            1，查询成功
* 使用注意：1.在当前位置在区域端点位置时，暂时按如下规则判断：
*             1) 当前位置在区域起点，认为该点属于本区域；
*             2) 当前位置在区域终点，认为该点不属于本区域；
*             3) 3点重合返回在区域内。
*           2.如果待查找的起点与终点都在区域内，可以调用两次本函数，互换始端与终端位置，只要两次调用有一次在区域内，说明在点在始端与终端形成的闭区域内
*           3.如果SE区域不存在，则函数返回0失败。如果SC,或者SE不存在，则函数返回1成功，但是点C不在区域内
*  合库和燕房使用
*/
static UINT8 dsuCheckLocInAreaExp_DFT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU * pLODStartStru, const LOD_STRU * pLODEndStru,
						UINT8 PointNum, const DQU_POINT_STATUS_STRU * pPointStru, 
						const LOD_STRU * pCurrentLODStru,UINT8 *pLocInArea)
{
	UINT8 chReturnValue = 0;/*函数返回值*/
	INT32 DisplacementSC; /*start -> current 位移*/
	INT32 DisplacementCE; /*current -> end 位移 */
	INT32 DisplacementSE; /*start -> end 位移 */
	LOD_STRU CurrentLODStru; /*另设一个变量来存储当前LOD，方向取pLODEndStru方向，这样在计算位移时，
							  按照统一的方向来计算位移*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != pLODStartStru) && (NULL != pLODEndStru)
		&& (NULL != pPointStru) && (NULL != pLocInArea))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
	}
	else
	{
		/*参数指针为空*/
		chReturnValue = 0;
		return chReturnValue;
	}


	/*默认置不在区域内*/
	*pLocInArea=0;

	/*判断入口数据当前位置link编号输入的有效性*/
	if((pCurrentLODStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pCurrentLODStru->Lnk] == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据当前位置偏移量输入的有效性*/
	if (pCurrentLODStru->Off > LinkLengthExp(pDsuEmapStru,pCurrentLODStru->Lnk))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据当前位置方向的有效性*/
	if ((EMAP_SAME_DIR != pCurrentLODStru->Dir) && (EMAP_CONVER_DIR != pCurrentLODStru->Dir))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	
	/*判断入口数据起点位置link编号输入的有效性*/
	if((pLODStartStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStartStru->Lnk] == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据起点位置link偏移量输入的有效性*/
	if (pLODStartStru->Off > LinkLengthExp(pDsuEmapStru,pLODStartStru->Lnk))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据起点方向的有效性*/
	if ((EMAP_SAME_DIR != pLODStartStru->Dir) && (EMAP_CONVER_DIR != pLODStartStru->Dir))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*判断入口数据输入终点位置link编号的有效性*/
	if((pLODEndStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODEndStru->Lnk] == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据终点位置link偏移量输入的有效性*/
	if (pLODEndStru->Off > LinkLengthExp(pDsuEmapStru,pLODEndStru->Lnk))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据终点方向的有效性*/
	if ((EMAP_SAME_DIR != pLODEndStru->Dir) && (EMAP_CONVER_DIR != pLODEndStru->Dir))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}


	CurrentLODStru.Lnk=pCurrentLODStru->Lnk;
	CurrentLODStru.Off=pCurrentLODStru->Off;
	CurrentLODStru.Dir=pLODEndStru->Dir;

	/*利用位移判断3点关系*/

	/*查询DisplacementSE*/
	chReturnValue= dsuDispCalcuByLOCExp(pDsuEmapStru,pLODStartStru, pLODEndStru,  PointNum,   pPointStru, &DisplacementSE);
	if(chReturnValue!=1)
	{
		/*位移查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	else
	{
		/*SE区域存在，函数返回值为1*/
		chReturnValue=1;
	}

	/*查询DisplacementSC*/
	chReturnValue= dsuDispCalcuByLOCExp(pDsuEmapStru,pLODStartStru, &CurrentLODStru,  PointNum,   pPointStru, &DisplacementSC);
	if(chReturnValue!=1)
	{
		/*位移查询失败*/
		*pLocInArea=0;
		chReturnValue=0;
		return chReturnValue;
	}

	/*查询DisplacementCE*/
	chReturnValue= dsuDispCalcuByLOCExp(pDsuEmapStru,&CurrentLODStru, pLODEndStru,  PointNum,   pPointStru, &DisplacementCE);
	if(chReturnValue!=1)
	{
		/*位移查询失败*/
		*pLocInArea=0;
		chReturnValue=0;
		return chReturnValue;
	}

	if((DisplacementSC==0)&&(DisplacementCE==0))
	{
		/*三点重合*/
		*pLocInArea=1;
		chReturnValue = 1;
		return chReturnValue;
	}

	if(DisplacementSC==0)
	{
		/*只与区域的起点重合*/
		*pLocInArea=1;
		chReturnValue = 1;
		return chReturnValue;
	}

	if(DisplacementCE==0)
	{
		/*当前位置在区域终点*/
		*pLocInArea=0;
		chReturnValue = 1;
		return chReturnValue;
	}

	/*判断DisplacementSC，DisplacementCE符号是否相同*/
	if( ((DisplacementSC>0)&&(DisplacementCE>0))||((DisplacementSC<0)&&(DisplacementCE<0)))
	{
		/*DisplacementSC，DisplacementCE符号相同*/
		*pLocInArea=1;
		chReturnValue = 1;
		return chReturnValue;
	}
	else
	{
		/*DisplacementSC，DisplacementCE符号不相同，当前位置不在区域内*/
		*pLocInArea=0;
		chReturnValue = 1;
		return chReturnValue;
	}

}

/*
* 函数功能： 此函数的功能是将判断当前位置是否在指定区域范围内。
* ****************************************************************************************************
*
*       --------------*--------------------*---------------------*-----------------
*                     S                    C                     E
*       因新增Link逻辑方向变化点，查找算法改为，计算位移DisplacementCS，DisplacementCE。如果两个位移符号相异，说明C在SE区域内
*
* ****************************************************************************************************
* 入口参数： const LOD_STRU * pLODStartStru,	区域始端位置
*            const LOD_STRU * pLODEndStru,	区域终端位置
*            const UINT8 PointNum,			道岔数目 
*            const POINT_STRU * pPointStru,	道岔信息
*			 const LOD_STRU * pCurrentLODStru,当前位置
* 出口参数： UINT8 *pLocInArea         1,在指定区域
*                                     0,不在指定区域
* 返回值：   0，查询失败
*            1，查询成功
* 使用注意：1.在当前位置在区域端点位置时，暂时按如下规则判断：
*             1) 当前位置在区域起点，认为该点属于本区域；
*             2) 当前位置在区域终点，认为该点不属于本区域；
*             3) 3点重合返回在区域内。
*           2.如果待查找的起点与终点都在区域内，可以调用两次本函数，互换始端与终端位置，只要两次调用有一次在区域内，说明在点在始端与终端形成的闭区域内
*           3.如果SE区域不存在，则函数返回0失败。如果SC,或者SE不存在，则函数返回1成功，但是点C不在区域内
*author:qxt 20170811
*/
static UINT8 dsuCheckLocInAreaExp_HLT(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStartStru, const LOD_STRU *pLODEndStru,
						UINT8 PointNum, const DQU_POINT_STATUS_STRU *pPointStru, 
						const LOD_STRU *pCurrentLODStru,UINT8 *pLocInArea)
{
	UINT8 chReturnValue = 0;/*函数返回值*/
	UINT8 chFlag=1;     /*函数执行失败标识位*/
	UINT8 chRtnCS = 0;/*计算位移CS函数返回值*/
	UINT8 chRtnCE = 0;/*计算位移CE函数返回值*/
	INT32 dwDisplacementCS=0; /*current -> start 位移*/
	INT32 dwDisplacementCE=0; /*current -> end 位移 */
	INT32 dwDisplacementSE=0; /*start -> end 位移 */
	LOD_STRU struCurrentLOD; /*另设一个变量来存储当前LOD，方向取pLODStartStru方向，这样在计算位移时，
							  按照统一的方向来计算位移*/
	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;

	if ((NULL == pLODStartStru) || (NULL == pLODEndStru) 
		|| (NULL == pPointStru) || (NULL == pLocInArea) || (NULL == pCurrentLODStru))
	{
		/*输入空指针,查询失败*/
		chFlag = 0U;
	}
	
	if ((0U!= chFlag) && (NULL != pDsuEmapStru)&&(NULL !=pDsuEmapStru->dsuEmapIndexStru))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;

		/*默认置不在区域内*/
		*pLocInArea = 0;

		/*判断入口数据当前位置link编号输入的有效性*/
		if((pCurrentLODStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pCurrentLODStru->Lnk] == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
		/*判断入口数据当前位置偏移量输入的有效性*/
		if (pCurrentLODStru->Off > LinkLengthExp(pDsuEmapStru,pCurrentLODStru->Lnk))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
		/*判断入口数据当前位置方向的有效性*/
		if ((EMAP_SAME_DIR != pCurrentLODStru->Dir) && (EMAP_CONVER_DIR != pCurrentLODStru->Dir))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}

		/*判断入口数据起点位置link编号输入的有效性*/
		if((pLODStartStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStartStru->Lnk] == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
		/*判断入口数据起点位置link偏移量输入的有效性*/
		if (pLODStartStru->Off > LinkLengthExp(pDsuEmapStru,pLODStartStru->Lnk))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
		/*判断入口数据起点方向的有效性*/
		if ((EMAP_SAME_DIR != pLODStartStru->Dir) && (EMAP_CONVER_DIR != pLODStartStru->Dir))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}

		/*判断入口数据输入终点位置link编号的有效性*/
		if((pLODEndStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODEndStru->Lnk] == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
		/*判断入口数据终点位置link偏移量输入的有效性*/
		if (pLODEndStru->Off > LinkLengthExp(pDsuEmapStru,pLODEndStru->Lnk))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
		/*判断入口数据终点方向的有效性*/
		if ((EMAP_SAME_DIR != pLODEndStru->Dir) && (EMAP_CONVER_DIR != pLODEndStru->Dir))
		{
			/*入口参数异常，查询失败*/
			chFlag = 0U;
		}
	}
	else
	{
		/*电子地图数据指针为空*/
		chFlag = 0U;
	}

	
	if (0U!=chFlag)
	{
		/*利用位移判断3点关系*/
		struCurrentLOD.Lnk=pCurrentLODStru->Lnk;
		struCurrentLOD.Off=pCurrentLODStru->Off;
		struCurrentLOD.Dir=pLODStartStru->Dir;
		/*查询DisplacementSE*/
		chReturnValue= dsuDispCalcuByLOCExp(pDsuEmapStru,pLODStartStru, pLODEndStru,  PointNum,   pPointStru, &dwDisplacementSE);
		if(1U != chReturnValue)
		{
			/*位移查询失败*/
			chReturnValue = 0;
		}
		else/*SE区域存在*/
		{
			
			/*查询DisplacementCS*/
			chRtnCS= dsuDispCalcuByLOCExp(pDsuEmapStru,&struCurrentLOD,pLODStartStru,PointNum,   pPointStru, &dwDisplacementCS);

			/*查询DisplacementCE*/
			chRtnCE= dsuDispCalcuByLOCExp(pDsuEmapStru,&struCurrentLOD,pLODEndStru,PointNum, pPointStru, &dwDisplacementCE);

			if((1!=chRtnCS)||(1!=chRtnCE))
			{
				/*位移查询失败*/
				*pLocInArea=0;
				chReturnValue=0;
			}

			else
			{
				/*三点重合*/
				if((0==dwDisplacementCS)&&(0==dwDisplacementCE))
				{
					*pLocInArea=1;
					chReturnValue = 1;
				}
                /*只与区域的起点重合*/
				else if(0==dwDisplacementCS)
				{
					
					*pLocInArea=1;
					chReturnValue = 1;
				}

				/*当前位置在区域终点*/
				else if(0==dwDisplacementCE)
				{
					
					*pLocInArea=0;
					chReturnValue = 1;
				}

				/*判断DisplacementCS，DisplacementCS符号是否不同 changed by qxt*/
				else if( ((dwDisplacementCS>0)&&(dwDisplacementCE<0))||((dwDisplacementCS<0)&&(dwDisplacementCE>0)))
				{
					/*DisplacementCS，DisplacementCE符号不相同*/
					*pLocInArea=1;
					chReturnValue = 1;
				}
				else
				{
					/*DisplacementCS，DisplacementCE符号相同，当前位置不在区域内*/
					*pLocInArea=0;
					chReturnValue = 1;
				}

			}		
		}/*SE区域存在 end*/	
	}

	return chReturnValue;
}

/*访问接口*/
UINT8 dsuCheckLocInAreaExp(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU * pLODStartStru, const LOD_STRU * pLODEndStru,
						   UINT8 PointNum, const DQU_POINT_STATUS_STRU * pPointStru, 
						   const LOD_STRU * pCurrentLODStru,UINT8 *pLocInArea)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if (DQU_CBTC_HLT == cbtcVersionType)
	{
		rtnValue =dsuCheckLocInAreaExp_HLT(pDsuEmapStru,pLODStartStru,pLODEndStru,PointNum,pPointStru,pCurrentLODStru,pLocInArea);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType) || (DQU_CBTC_FAO == cbtcVersionType)|| (DQU_CBTC_DG == cbtcVersionType))
	{
		rtnValue =dsuCheckLocInAreaExp_DFT(pDsuEmapStru,pLODStartStru,pLODEndStru,PointNum,pPointStru,pCurrentLODStru,pLocInArea);
	}
	else
	{
		rtnValue = 0U;
		
	}
	return rtnValue; 
}

/************************************************************************

函数功能：	此函数的功能是利用link的ID信息查询link的长度信息
入口参数：	const UINT16 wLinkID		link的ID	
出口参数：	无
返回值：	UINT32 dwLinkLength	查询失败: 0xffffffff; 查询成功: 返回查找到的link长度                                                                
************************************************************************/
/*功能函数，查询link长度*/
UINT32 LinkLengthExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 wLinkID)
{
	UINT32 dwLinkLength = 0;/*函数返回值*/
	DSU_LINK_STRU *pstLinK;/*指向link信息的结构体指针*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;

	if (NULL != pDsuEmapStru)
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		dwLinkLength = 0xffffffff;
		return dwLinkLength;
	}

	/*判断数据输入的有效性*/
	if((wLinkID>LINKINDEXNUM)||(dsuLinkIndex[wLinkID] == 0xFFFF))
	{
		/*无效数据输入，查询失败，返回默认值*/
		dwLinkLength = 0xffffffff;
		return dwLinkLength;
	}
	/*利用管理函数找到link长度信息，返回*/
	pstLinK = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[wLinkID];
	dwLinkLength = pstLinK->dwLength;
	return dwLinkLength;
}

/*
* 函数功能： 此函数的功能是将判断当前位置是否在指定区域范围内。
             此函数的功能与CheckLocInArea是有区别的。CheckLocInArea对方向没有要求，假设所有涉及的方向都是正确的。
			 而CheckLocInAreaQuick要求从StartLOD能够到达EndLOD。
* ****************************************************************************************************
*
*       --------------*--------------------*---------------------*-----------------
*                     S                    C                     E
*       查找算法为，首先判断当前位置与输入的S，E是否在同一Link上，
*       如果在同一Link上，根据方向和位移判断是否在区域内，如果不在同一Link，判断CLinkId是否与SE之间的某一LinkId相同
*       由于两点之间的Link可以保存下来，所以对于多次调用本函数查询是否在区域内的函数效率很有帮助
*
* ****************************************************************************************************
* 入口参数： const LOD_STRU * pLODStartStru,	区域始端位置
*            const LOD_STRU * pLODEndStru,	区域终端位置
* 出口参数：	UINT16 wLinkID[DSU_MAX_LINK_BETWEEN]				Link序列数组
*               UINT16 *wLinkNumber                             Link个数
*			 const LOD_STRU * pCurrentLODStru,当前位置
* 出口参数： UINT8 *pLocInArea         1,在指定区域
*                                     0,不在指定区域
* 返回值：   0，查询失败
*            1，查询成功
* 使用注意：1.在当前位置在区域端点位置时，暂时按如下规则判断：
*             1) 当前位置在区域起点，认为该点属于本区域；
*             2) 当前位置在区域终点，认为该点不属于本区域；
*             3) 3点重合返回在区域内。
*           2.如果待查找的起点与终点都在区域内，可以调用两次本函数，互换始端与终端位置，只要两次调用有一次在区域内，说明在点在始端与终端形成的闭区域内
*           3.如果SE区域不存在，则函数返回0失败。如果SC,或者SE不存在，则函数返回1成功，但是点C不在区域内
*/
UINT8 dsuCheckLocInAreaQuickExp(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU * pLODStartStru, const LOD_STRU * pLODEndStru,
	UINT16 wLinkNumber,UINT16 wLinkID[DSU_MAX_LINK_BETWEEN],
	const LOD_STRU * pCurrentLODStru,UINT8 *pLocInArea)
{
	UINT8 chReturnValue = 0;/*函数返回值*/
	UINT16 i = 0;          /*循环用变量*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != pLODStartStru) && (NULL != pLODEndStru) && (NULL != wLinkID)
		&& (NULL!= pCurrentLODStru) && (NULL!= pLocInArea))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
	}
	else
	{
		/*参数指针为空*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*默认置不在区域内*/
	*pLocInArea=0;

	/*判断入口数据输入的有效性*/
	if((pCurrentLODStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pCurrentLODStru->Lnk] == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据输入的有效性*/
	if((pLODStartStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStartStru->Lnk] == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}
	/*判断入口数据输入的有效性*/
	if((pLODEndStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODEndStru->Lnk] == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*三点重合，返回在区域内*/
	if((pCurrentLODStru->Off==pLODStartStru->Off)&&(pCurrentLODStru->Off==pLODEndStru->Off)&&
	   (pCurrentLODStru->Lnk==pLODStartStru->Lnk)&&(pCurrentLODStru->Lnk==pLODEndStru->Lnk))
	{
		*pLocInArea=1;
		chReturnValue = 1;
		return chReturnValue;
	}

	/*判断C点是否在S点或者E点所在Lnk上，并且在SE区域内*/

	if(pLODEndStru->Dir==EMAP_SAME_DIR)
	{	
		/*当前方向为正方向*/

		if ((pCurrentLODStru->Lnk==pLODStartStru->Lnk)&&(pCurrentLODStru->Lnk==pLODEndStru->Lnk))
		{
			/*S,C,ELink相同*/
			if ((pCurrentLODStru->Off>=pLODStartStru->Off)&&(pCurrentLODStru->Off<pLODEndStru->Off))
			{
				*pLocInArea=1;
				chReturnValue = 1;
				return chReturnValue;
			}
			else
			{
				*pLocInArea=0;
				chReturnValue = 1;
				return chReturnValue;
			}
		}

		else if(pCurrentLODStru->Lnk==pLODStartStru->Lnk)
		{
			if (pCurrentLODStru->Off>=pLODStartStru->Off)
			{
				/*当前C点Lnk与S点相同且当前C点Off大于等于S点Off，在区域内*/
				*pLocInArea=1;
				chReturnValue = 1;
				return chReturnValue;
			}
			else
			{
				*pLocInArea=0;
				chReturnValue = 1;
				return chReturnValue;
			}

		}
		else if(pCurrentLODStru->Lnk==pLODEndStru->Lnk)
		{
			if (pCurrentLODStru->Off<pLODEndStru->Off)
			{
				/*当前C点Lnk与E点相同且当前C点Off小于E点of，在区域内*/
				*pLocInArea=1;
				chReturnValue = 1;
				return chReturnValue;
			}
			else
			{
				*pLocInArea=0;
				chReturnValue = 1;
				return chReturnValue;
			}

		}
		else
		{
			/*不满足，C点与S点或E点不相同Lnk*/
		}
	}
	else if(pLODEndStru->Dir==EMAP_CONVER_DIR)
	{
		/*当前方向为反方向*/

		if ((pCurrentLODStru->Lnk==pLODStartStru->Lnk)&&(pCurrentLODStru->Lnk==pLODEndStru->Lnk))
		{
			if ((pCurrentLODStru->Off<=pLODStartStru->Off)&&(pCurrentLODStru->Off>pLODEndStru->Off))
			{
				/*当前C点Lnk与S点相同且在区域内*/
				*pLocInArea=1;
				chReturnValue = 1;
				return chReturnValue;
			}
			
			else
			{
				*pLocInArea=0;
				chReturnValue = 1;
				return chReturnValue;
			}
		}
		else if(pCurrentLODStru->Lnk==pLODStartStru->Lnk)
		{
			if (pCurrentLODStru->Off<=pLODStartStru->Off)
			{
				/*当前C点Lnk与S点相同且在区域内*/
				*pLocInArea=1;
				chReturnValue = 1;
				return chReturnValue;
			}
			else
			{
				*pLocInArea=0;
				chReturnValue = 1;
				return chReturnValue;
			}
		}
		else if(pCurrentLODStru->Lnk==pLODEndStru->Lnk)
		{
			if (pCurrentLODStru->Off>pLODEndStru->Off)
			{
				/*当前C点Lnk与E点相同且在区域内*/
				*pLocInArea=1;
				chReturnValue = 1;
				return chReturnValue;
			}
			else
			{
				*pLocInArea=0;
				chReturnValue = 1;
				return chReturnValue;
			}
		}
		else
		{

			/*不满足，C点与S点或E点不相同*/
		}
	}
	else
	{
		/*入口参数异常，查询失败*/
		chReturnValue = 0;
		return chReturnValue;
	}

	/*判断C点不在S点或者E点所在Lnk上，循环查找C点Lnk是否与SE中间某一个Lnk相等*/
	for(i=0;i<wLinkNumber;i++)
	{
		if(pCurrentLODStru->Lnk==wLinkID[i])
		{
			/*当前C点Lnk与SE区域内的某一个LnkId相同，返回在区域内*/
			*pLocInArea=1;
			chReturnValue = 1;
			return chReturnValue;
		}
	}

	/*当前C点与SE中任意一个Lnk都不相同，返回不在区域内*/
	*pLocInArea=0;
	chReturnValue = 1;
	return chReturnValue;

}

/*
* 函数功能： 此函数的功能是判断当前位置是否在指定区域范围内，此函数是对dsuCheckLocInAreaQuick
             的一个补充。用于将当前方向取反，再计算是否在区域内。
* 入口参数： const LOD_STRU * pLODStartStru,	区域始端位置
*            const LOD_STRU * pLODEndStru,	区域终端位置
* 出口参数： UINT16 wLinkID[DSU_MAX_LINK_BETWEEN]				Link序列数组
*            UINT16 *wLinkNumber                             Link个数
*			 const LOD_STRU * pCurrentLODStru,当前位置
*            UINT8 *pLocInArea         1,在指定区域
*                                     0,不在指定区域
* 返回值：   0，查询失败
*            1，查询成功
*/
UINT8 dsuCheckLocInAreaQuickExp2(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU * pLODStartStru, const LOD_STRU * pLODEndStru,
	UINT16 wLinkNumber,UINT16 wLinkID[DSU_MAX_LINK_BETWEEN],
	const LOD_STRU * pCurrentLODStru,UINT8 *pLocInArea)
{
	LOD_STRU TempLODStartStru;
	LOD_STRU TempLODEndStru;
	LOD_STRU TempCurrentLODStru;


	memcpy(&TempLODStartStru,pLODStartStru,sizeof(LOD_STRU));
	memcpy(&TempLODEndStru,pLODEndStru,sizeof(LOD_STRU));
	memcpy(&TempCurrentLODStru,pCurrentLODStru,sizeof(LOD_STRU));

	/*将三个LOD的方向取反*/
	if (pLODEndStru->Dir==EMAP_SAME_DIR)
	{
		TempLODStartStru.Dir=EMAP_CONVER_DIR;
		TempLODEndStru.Dir=EMAP_CONVER_DIR;
		TempCurrentLODStru.Dir=EMAP_CONVER_DIR;
	}
	else
	{
		TempLODStartStru.Dir=EMAP_SAME_DIR;
		TempLODEndStru.Dir=EMAP_SAME_DIR;
		TempCurrentLODStru.Dir=EMAP_SAME_DIR;
	}

	return dsuCheckLocInAreaQuickExp(pDsuEmapStru,&TempLODStartStru,&TempLODEndStru,wLinkNumber,wLinkID,&TempCurrentLODStru,pLocInArea);
}

/*****************************以下为坡度平缓计算过程中需要用到的函数**************************/
/************************************************************************

 	函数功能：	此函数的功能是查询当前Garde的相邻Grade
	入口参数：	const UINT16 wCurrentGradeID	当前坡度编号
				const UCHAR chDirection			期望运行方向
				const UCHAR PointNum			MA范围内道岔数目
				const DQU_POINT_STATUS_STRU * pPointStru	MA范围内道岔信息		
	出口参数：	无
	返回值：	UINT16 wFindGradeID	查询失败: 0xffff; 查询成功: 返回相邻的坡度ID                                                              
************************************************************************/
/*功能函数,查询当前Garde的相邻Grade*/
UINT16 FindAdjacentGradeIDExp(DSU_EMAP_STRU *pDsuEmapStru,const UINT16 wCurrentGradeID, const UCHAR chDirection,
						   const UCHAR PointNum, const DQU_POINT_STATUS_STRU * pPointStru)
{
	UINT16 wFindGradeID = 0;/*函数返回值*/
	DSU_GRADE_STRU *pstGrade=NULL;/*指向坡度信息的结构体指针*/
	const DQU_POINT_STATUS_STRU * pstPointStrut=NULL;/*存储道岔信息的局部变量*/
	UINT16 wPointId = 0;/*存储坡度关联道岔点的ID*/
	UCHAR i = 0;/*循环用变量*/
	
	/*全局变量改传参调用涉及的全局变量*/
	UINT16 GRADEINDEXNUM = 0;
	UINT16* dsuGradeIndex = NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru = NULL;
	if ((NULL != pDsuEmapStru) && (NULL != pPointStru))
	{
		GRADEINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->GRADEINDEXNUM;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*数据无效，返回查询失败*/
		wFindGradeID = 0xffff;
		return wFindGradeID;
	}

	/*判断输入的有效性*/
	if((wCurrentGradeID>GRADEINDEXNUM)||(dsuGradeIndex[wCurrentGradeID] == 0xFFFF))
	{
		/*数据无效，返回查询失败*/
		wFindGradeID = 0xffff;
		return wFindGradeID;
	}	

	/*判断入口数据方向的有效性*/
	if ((EMAP_SAME_DIR != chDirection) && (EMAP_CONVER_DIR != chDirection))
	{
		/*数据无效，返回查询失败*/
		wFindGradeID = 0xffff;
		return wFindGradeID;
	}
	
	/*在期望运行方向与link的逻辑方向相同时，向当前坡度的末端相邻坡度进行查询*/
	if (EMAP_SAME_DIR == chDirection)
	{

		/*利用管理函数直接找到当前坡度的信息*/
		pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[wCurrentGradeID];

		if ((0xffff == pstGrade->wTmnlJointSideGradeId)&&(0xffff == pstGrade->wTmnlJointMainGradeId))
		{
			/*当前坡度已经没有相邻坡度，函数返回0*/
			wFindGradeID = 0xffff;
		     return wFindGradeID;
		}
		/*在当前坡度的末端相邻侧线坡度为空时，其末端相邻正线坡度即为所求*/
		if (0xffff == pstGrade->wTmnlJointSideGradeId)
		{
			/*查询成功，返回相关信息*/
			wFindGradeID = pstGrade->wTmnlJointMainGradeId;
			return wFindGradeID;
		}
		else
		{
			/*在当前坡度的末端相邻侧线坡度不为空时，需利用实时的道岔状态来判断相邻坡度*/

			/*导入道岔信息*/
			pstPointStrut = pPointStru;

			/*遍历道岔信息*/				
			wPointId = pstGrade->wTmnlRelatePointId;

			for (i=0; i<PointNum; i++)
			{
				if (wPointId == pstPointStrut->PointId)
				{
					/*道岔失去表示,数据异常，查询失败，返回默认值，退出*/
					if (EMAP_POINT_STATUS_LOSE == pstPointStrut->PointStatus)
					{
						wFindGradeID = 0xffff;
						return wFindGradeID;
					}
					else
					{
						/*道岔处于定位,其末端相邻正线坡度即为所求*/
						if (EMAP_POINT_STATUS_MAIN == pstPointStrut->PointStatus)
						{
							wFindGradeID = pstGrade->wTmnlJointMainGradeId;
							return wFindGradeID;								
						}
						else
						{
							/*道岔处于反位,其末端相邻侧线坡度即为所求*/
							wFindGradeID = pstGrade->wTmnlJointSideGradeId;
							return wFindGradeID;		
						}							
					}
				}
				pstPointStrut++;
			}

			/*没有找到相关的道岔信息,查询失败,返回默认值*/
			wFindGradeID = 0xffff;
			return wFindGradeID;
		}				
	}/*end of  if (SAMEDIR == chDirection)*/
	else
	{
		/*在期望运行方向与link的逻辑方向相反时，向当前坡度的始端端相邻坡度进行查询*/



		/*利用管理函数直接找到当前坡度的信息*/
		pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[wCurrentGradeID];

		if ((0xffff == pstGrade->wOrgnJointSideGradeId)&&(0xffff == pstGrade->wOrgnJointMainGradeId))
		{
			/*当前坡度已经没有相邻坡度，函数返回0*/
			wFindGradeID = 0xffff;
			return wFindGradeID;
		}
		/*在当前坡度的始端相邻侧线坡度为空时，其始端相邻正线坡度即为所求*/
		if (0xffff == pstGrade->wOrgnJointSideGradeId)
		{
			/*查询成功，返回坡度ID*/
			wFindGradeID = pstGrade->wOrgnJointMainGradeId;
			return wFindGradeID;
		}
		else
		{
			/*在当前坡度的始端相邻侧线坡度不为空时，需利用实时的道岔状态来判断相邻坡度*/

			/*导入道岔信息*/
			pstPointStrut = pPointStru;

			/*遍历道岔信息*/
			wPointId = pstGrade->wOrgnRelatePointId;

			for (i=0; i<PointNum; i++)
			{
				if (wPointId == pstPointStrut->PointId)
				{
					/*道岔失去表示,数据异常，查询失败，返回默认值，退出*/
					if (EMAP_POINT_STATUS_LOSE == pstPointStrut->PointStatus)
					{
						wFindGradeID = 0xffff;
						return wFindGradeID;
					}
					else
					{
						/*道岔处于定位,其始端相邻正线坡度即为所求*/
						if(EMAP_POINT_STATUS_MAIN == pstPointStrut->PointStatus)
						{
							wFindGradeID = pstGrade->wOrgnJointMainGradeId;
							return wFindGradeID;								
						}
						else
						{
							/*道岔处于反位,其始端相邻侧线坡度即为所求*/
							wFindGradeID = pstGrade->wOrgnJointSideGradeId;
							return wFindGradeID;		
						}							
					}
				}
				pstPointStrut++;
			}

			/*没有找到相关的道岔信息,查询失败,返回默认值*/
			wFindGradeID = 0xffff;
			return wFindGradeID;
		}
	}
}
/*
*函数功能：查询某点所在坡度ID
*输入参数：UINT16 linkId,UINT32 offset待计算点
*输出参数：UINT16 GradeID所在坡度ID
*返回值：  0函数执行失败，1成功
*/
static UINT8 dsuGetGradeIdbyLocExp_DFT(DSU_EMAP_STRU *pDsuEmapStru, const UINT16 linkId, const UINT32 offset, UINT16 *GradeID)
{
	UINT16 i=0,j=0;							/*循环计数变量*/
	DSU_GRADE_STRU* curGrade=NULL;          		/*当前坡度临时变量*/
	UINT8 bReturnValue;						/*函数返回值变量*/
	DSU_LINK_STRU *pLinkStru=NULL;				/*Link信息结构体指针*/
	
	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != GradeID))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	if((linkId>LINKINDEXNUM)||((dsuLinkIndex[linkId]) == 0xFFFF))
	{
		/*入口参数异常，查询失败*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*获取当前位置的link对应的位置信息行*/
	pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[linkId];

	/*当前link的“Link坡度信息属性”为无统一坡度*/
	if(0 == pLinkStru->wGrade)
	{
		for(i=0;i<dsuDataLenStru->wGradeLen;i++)
		{
			/*初始化当前坡度*/
			curGrade = dsuStaticHeadStru->pGradeStru + i;
			/*如果起始link与输入link相同*/
			if(linkId == curGrade->wOrgnLinkId)
			{
				/*输入偏移量>=当前坡度起点偏移量*/
				if((offset>=curGrade->dwOrgnLinkOfst) && ((offset - curGrade->dwOrgnLinkOfst)<= curGrade->dwGradeLength))
				{
					/*输入当前坡度ID*/
					*GradeID = curGrade->wId;
					bReturnValue = 1;
					return bReturnValue;
				}
				else
				{
					/*继续向下执行*/
				}
			}
			/*如果终端link与输入link相同*/
			else if(linkId == curGrade->wTmnlLinkId)
			{
				/*输入偏移量<=当前坡度终点偏移量*/
				if(offset <= curGrade->dwTmnlLinkOfst)
				{
					/*输入当前坡度ID*/
					*GradeID = curGrade->wId;
					bReturnValue = 1;
					return bReturnValue;
				}
				else
				{
					/*继续向下执行*/
				}
			}
			/*与中间link相同*/
			else
			{
				j=0;
				while(0xffff !=(curGrade->wIncludeLinkId[j]))
				{
					if(linkId == (curGrade->wIncludeLinkId[j]))
					{
						*GradeID = curGrade->wId;
						bReturnValue = 1;
						return bReturnValue;
					}
					else
					{
						j++;
					}
				}
			}
		}
		/*遍历完坡度，没找到该点*/
		bReturnValue = 0;
		return bReturnValue;
	}
	else
	/*当前link的“Link坡度信息属性”为统一坡度*/
	{
		/*统一坡度不需要使用坡度ID信息,置为无效*/
		*GradeID = 0xffff;
		bReturnValue = 1;
		return bReturnValue;
	}
}

/*
*函数功能：查询某点所在坡度ID
*输入参数：UINT16 linkId,UINT32 offset待计算点
*输出参数：UINT16 GradeID所在坡度ID
*返回值：  0函数执行失败，1成功
*/
static UINT8 dsuGetGradeIdbyLocExp_CPK(DSU_EMAP_STRU *pDsuEmapStru, const UINT16 linkId, const UINT32 offset, UINT16 *GradeID)
{
	UINT16 i = 0;							/*循环计数变量*/
	UINT8 bReturnValue = 0;					/*函数返回值变量*/
	DSU_LINK_STRU *pLinkStru = NULL;		/*Link信息结构体指针*/
	DSU_GRADE_STRU *pGradeStru = NULL;		/*坡度信息结构体指针*/

	DSU_GRADE_LINKIDX_STRU *pTempGradeLinkIdxStru = NULL;
	UINT16 tempGradeID = 0;

	UINT16 LINKINDEXNUM = 0;
	UINT16 *dsuLinkIndex = NULL;
	UINT16 *dsuGradeIndex = NULL;			/*坡度信息索引数组*/
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru = NULL;

	if ((NULL != pDsuEmapStru) && (NULL != pDsuEmapStru->dsuEmapIndexStru) && (NULL != pDsuEmapStru->dsuStaticHeadStru) && (NULL != GradeID))
	{
		/*全局变量改传参调用涉及的全局变量*/
		LINKINDEXNUM = pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex = pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex = pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru = pDsuEmapStru->dsuStaticHeadStru;

		if ((linkId <= LINKINDEXNUM) && (DSU_NULL_16 != dsuLinkIndex[linkId]))
		{
			/*获取当前位置的link对应的位置信息行*/
			pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[linkId];

			if((offset >= 0) && (offset <= pLinkStru->dwLength))
			{
				pTempGradeLinkIdxStru = g_dsuEmapExtendStru->pDsuGradeInLinkIdx;
				pTempGradeLinkIdxStru = pTempGradeLinkIdxStru + pLinkStru->wId;

				if (0 != pLinkStru->wGrade)/*当前link的“Link坡度信息属性”为统一坡度*/
				{
					if (0 == pTempGradeLinkIdxStru->wGradeCount)
					{
						*GradeID = DSU_NULL_16;/*统一坡度不需要使用坡度ID信息,置为无效*/
						bReturnValue = 1;
					}
					else
					{
						/*错误分支*/
						bReturnValue = 0;
					}			
				}
				else/*当前link的“Link坡度信息属性”为无统一坡度*/
				{
					if (1 == pTempGradeLinkIdxStru->wGradeCount)
					{
						tempGradeID = pTempGradeLinkIdxStru->wGradeId[0];
						*GradeID = tempGradeID;
						bReturnValue = 1;
					} 
					else if (1 < pTempGradeLinkIdxStru->wGradeCount)
					{
						for (i = 0; i < pTempGradeLinkIdxStru->wGradeCount; i++)
						{
							tempGradeID = pTempGradeLinkIdxStru->wGradeId[i];

							/*获取当前坡度对应的信息行*/
							pGradeStru = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[tempGradeID];

							/*当一个link上有多个坡度时，处在该link中间某段的坡度必不含中间link，故只需判断该link上每个坡度的首、尾link与输入的参数linkId是否相同即可。*/
							if ((linkId == pGradeStru->wOrgnLinkId) && (linkId == pGradeStru->wTmnlLinkId))/*一个link对应多个坡度，且坡度位于link的中间某段*/
							{
								if ((offset >= pGradeStru->dwOrgnLinkOfst) && ((offset - pGradeStru->dwOrgnLinkOfst) <= pGradeStru->dwGradeLength))
								{
									*GradeID = tempGradeID;
									bReturnValue = 1;
									break;
								} 
							} 
							else if ((linkId != pGradeStru->wOrgnLinkId) && (linkId == pGradeStru->wTmnlLinkId))/*一个link对应多个坡度，且坡度位于link的始端*/
							{
								if (offset <= pGradeStru->dwTmnlLinkOfst)
								{
									*GradeID = tempGradeID;
									bReturnValue = 1;
									break;
								} 								
							}
							else if ((linkId == pGradeStru->wOrgnLinkId) && (linkId != pGradeStru->wTmnlLinkId))/*一个link对应多个坡度，且坡度位于link的终端*/
							{
								if (offset >= pGradeStru->dwOrgnLinkOfst)
								{
									*GradeID = tempGradeID;
									bReturnValue = 1;
									break;
								} 								
							}
							else
							{
								/*错误分支*/
								bReturnValue = 0;
							}

						}
						/*link上没有找到对应的坡度*/
						if(i == pTempGradeLinkIdxStru->wGradeCount)
						{		   
						   bReturnValue = 0;
						}
					}
					else
					{
						/*错误分支*/
						bReturnValue = 0;
					}
				}
			}
			else
			{
				/*输入偏移量参数不合法，查询失败*/
				bReturnValue = 0;
			}			
		} 
		else
		{
			/*输入link编号异常，查询失败*/
			bReturnValue = 0;
		}				
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
	}	 
	return bReturnValue;
}

/*
*函数功能：查询某点所在坡度ID
*输入参数：UINT16 linkId,UINT32 offset待计算点
*输出参数：UINT16 GradeID所在坡度ID
*返回值：  0函数执行失败，1成功
*修改说明：对CPK/HLT查询某点所在坡度ID算法进行了优化，共同使用dsuGetGradeIdbyLocExp_CPK，
*		  FAO/DG继续使用原有算法，
*         modify by lmy 20171221
*/
UINT8 dsuGetGradeIdbyLocExp(DSU_EMAP_STRU *pDsuEmapStru, const UINT16 linkId, const UINT32 offset, UINT16 *GradeID)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType = 0;
	cbtcVersionType = GetCbtcSysType();

	if((DQU_CBTC_CPK == cbtcVersionType) || (DQU_CBTC_HLT == cbtcVersionType))
	{
		rtnValue = dsuGetGradeIdbyLocExp_CPK(pDsuEmapStru, linkId, offset, GradeID);
	} 
	else if((DQU_CBTC_FAO == cbtcVersionType) ||(DQU_CBTC_DG == cbtcVersionType))
	{
		rtnValue = dsuGetGradeIdbyLocExp_DFT(pDsuEmapStru, linkId, offset, GradeID);
	}
	else
	{
		rtnValue = 0U;		
	}
	return rtnValue; 
}

/*************
*函数功能：计算某点坡度平缓后的坡度值
*输入参数：Point 所求坡度点
*输出参数： 
*返回值：  0函数执行失败 1 点在坡度第一段 2 点在坡度第2段 3 点在坡度第3段
****************/
UINT8 dsuCalculateGradeValueExp_FAO(DSU_EMAP_STRU *pDsuEmapStru,UINT16 LinkId,UINT32 ofst,FLOAT32* GradeVal)
{
	UINT8  funcRtn;
	UINT16 gradeId;             /*点所在坡度ID*/
	UINT8  bReturnValue = 0;    /*函数返回值*/
	UINT32 arcEndOfst  = 0;     /*坡度第一个分界点所处相对位置*/
	UINT32 arcStartOfst = 0;    /*坡度第二个分界点所处相对位置*/
	UINT32 relLocation = 0;     /*当前点所处相对位置*/
	FLOAT64 angleValue = 0;     /*角度变化值*/
	FLOAT64 tempAngleValue = 0;     /*计算出的临时值*/
	DSU_GRADE_STRU* curGrade=NULL;        /*当前坡度临时变量*/
	DSU_GRADE_STRU  curGradeTmp;        /*当前坡度临时变量*/
	DSU_GRADE_STRU* frontGrade=NULL;        /*当前坡度前方相邻坡度临时变量*/
	DSU_GRADE_STRU* rearGrade=NULL;       /*当前坡度后方相邻坡度临时变量*/
	FLOAT32 curGradeVal;
	FLOAT64 tempValue;              /*临时变量，用来存表达式计算值*/
	UINT8 GradeTrend = 0;
	UINT8 RtnGetGradFrnt = 0;
	UINT8 RtnGetGradNxt = 0;

	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != GradeVal))
	{
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*计算出点所在坡度*/
	funcRtn = dsuGetGradeIdbyLocExp(pDsuEmapStru,LinkId,ofst,&gradeId);
	if(0 == funcRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*计算出点所在坡度两分界点所处相对位置*/
	funcRtn = dsuDividPointDistanceFromOriginExp(pDsuEmapStru,gradeId,LinkId,&arcEndOfst,&arcStartOfst);
	if(0 == funcRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*计算出点所在坡度两分界点所处相对位置*/
	funcRtn = dsuGetDistanceFromOriginExp(pDsuEmapStru,gradeId,LinkId,ofst,&relLocation);
	if(0 == funcRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}

	/*为了方便计算，对分界点的相对距离进行以下处理*/
	if(0xFFFFFFFF == arcEndOfst)
	{
		arcEndOfst = 0;
	}

	if(0xffff != gradeId)
	{
		/*初始化当前坡度*/
		curGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[gradeId];
		/*方向为正，坡度值为正*/
		if(0x55 == curGrade->wInclineDir)
		{
			curGradeVal = (FLOAT32)(1.0*curGrade->wGradValue)/10000;
		}
		else
			/*方向反，坡度值为负*/
		{
			curGradeVal = (FLOAT32)(-1.0*curGrade->wGradValue)/10000;
		}

		/*获取前面相邻坡度*/
		if(0xffff != curGrade->wOrgnJointMainGradeId)
		{
			frontGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[curGrade->wOrgnJointMainGradeId];
		}
		else
		{
			/*线路终点或关联统一坡度,不再进行坡度平缓*/
			* GradeVal = (FLOAT32)(10000*curGradeVal);
			/*返回成功*/
			bReturnValue = 2;
			return bReturnValue;
		}

		/*获取后面相邻坡度*/
		if(0xffff != curGrade->wTmnlJointMainGradeId)
		{
			rearGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[curGrade->wTmnlJointMainGradeId];
		}
		else
		{
			/*线路终点或关联统一坡度,不再进行坡度平缓*/
			* GradeVal = (FLOAT32)(10000*curGradeVal);
			/*返回成功*/
			bReturnValue = 2;
			return bReturnValue;
		}
	}
	else
	{	
		/*获取当前的统一坡度值,因为0不再进行运算和方向判定*/
		curGradeVal = dsuStaticHeadStru->pConGradeStru->wGrade;

		/*当前为统一坡度时,为方便后面计算,在该处赋值*/
		curGradeTmp.wId = 0xFFFF;
		curGradeTmp.dwRadius = 0;
		curGradeTmp.wInclineDir = 0x55;
		curGradeTmp.wGradValue = curGradeVal;
		curGrade = &curGradeTmp;


		/*使用前的初始化*/
		frontGrade = NULL;
		rearGrade = NULL;

		/*获取前面相邻坡度*/
		RtnGetGradFrnt = dsuGetGradeFrntExp(pDsuEmapStru,LinkId, &frontGrade);

		/*获取后面相邻坡度*/
		RtnGetGradNxt = dsuGetGradeRearExp(pDsuEmapStru,LinkId, &rearGrade);

		/*若前面或后面相邻坡度查询失败*/
		if((0U==RtnGetGradFrnt)||(0U==RtnGetGradNxt))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}

		/*20141122添加：若查询前面和后面坡度时,发现当前坡度在线路终点,不再进行平缓*/
		if((2==RtnGetGradFrnt)||(2==RtnGetGradNxt))
		{
			* GradeVal = (FLOAT32)(10000*curGradeVal);
			/*返回成功*/
			bReturnValue = 2;
			return bReturnValue;
		}
	}

	/*
	1 没有分界点的时候，即相邻坡度与当前坡度差小于千分之20
	2 当前点处于分界点所标示的弧度外
	*/
	if((relLocation >= arcEndOfst) && (relLocation <= arcStartOfst))
	{

		* GradeVal = (FLOAT32)(10000*curGradeVal);
		/*返回成功*/
		bReturnValue = 2;
		return bReturnValue;
	}
	/*当前点在第一个分界点弧度内*/
	else if(relLocation < arcEndOfst)
	{
		if(NULL != frontGrade)
		{
			/*计算角度变化值*/
			if(0 == frontGrade->dwRadius)
			{
				/*曲率半径为0，角度变化值为0*/
				angleValue = 0;
			}
			else
			{
				/*角度变化值*/
				angleValue = (FLOAT32)((arcEndOfst + relLocation)/(1.0*frontGrade->dwRadius));
			}
			/*坡度是上坡，取正值*/
			if(0x55 == frontGrade->wInclineDir)
			{
				tempValue = (1.0*frontGrade->wGradValue)/10000;
			}
			/*下坡取负值*/
			else 
			{
				tempValue = (-1.0*frontGrade->wGradValue)/10000;
			}
			/*if用来判断角度变化值是增加值还是减少值*/
			if(dquGradeTrendExp(pDsuEmapStru,frontGrade->wId,curGrade->wId,&GradeTrend))
			{
				/*坡度减少*/
				if(1 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue - angleValue;
				}
				/*坡度增加*/
				else if(2 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue + angleValue;
				}
				/*坡度不变化*/
				else
				{
					tempAngleValue = tempValue ;
				}

				/*转换为FLOAT32类型*/
				*  GradeVal = (FLOAT32)(tempAngleValue*10000);
				/*返回成功*/
				bReturnValue = 1;
				return bReturnValue;
			}
			else
			{
				/*不可达*/
				bReturnValue = 0;
				return bReturnValue;
			}
		}
		else
		{
			/*转换为FLOAT32类型*/
			*  GradeVal = (FLOAT32)(curGradeVal);
			/*返回成功*/
			bReturnValue = 1;
			return bReturnValue;
		}
	}
	/*在第三分界段内*/
	else
	{
		if(NULL != rearGrade)
		{
			/*计算角度变化值*/
			if(0 == curGrade->dwRadius)
			{
				/*曲率半径为0，角度变化值为0*/
				angleValue = 0;
			}
			else
			{
				/*角度变化值*/
				angleValue = (FLOAT32)((relLocation - arcStartOfst)/(1.0*curGrade->dwRadius));
			}

			if(0x55 == curGrade->wInclineDir)
			{
				tempValue = (1.0*curGrade->wGradValue)/10000;
			}
			else
			{
				tempValue = (-1.0*curGrade->wGradValue)/10000;
			}

			/*if用来判断角度变化值是增加值还是减少值*/
			if(dquGradeTrendExp(pDsuEmapStru,curGrade->wId,rearGrade->wId,&GradeTrend))
			{
				/*坡度值减少*/
				if(1 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue - angleValue;				
				}
				/*坡度值增加*/
				else if(2 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue + angleValue;
				}
				/*坡度值不变化*/
				else
				{
					tempAngleValue = tempValue;
				}

				/*转换为FLOAT32类型*/
				*  GradeVal = (FLOAT32)(tempAngleValue*10000);
				/*返回成功*/
				bReturnValue = 3;
				return bReturnValue;
			}
			else
			{
				/*不可达*/
				bReturnValue = 0;
				return bReturnValue;
			}
		}
		else
		{
			/*转换为FLOAT32类型*/
			*  GradeVal = (FLOAT32)(curGradeVal);
			/*返回成功*/
			bReturnValue = 3;
			return bReturnValue;
		}
	}	
}

UINT8 dsuCalculateGradeValueExp_CPK(DSU_EMAP_STRU *pDsuEmapStru,UINT16 LinkId,UINT32 ofst,FLOAT32* GradeVal)
{
	UINT8  funcRtn;
	UINT16 gradeId;             /*点所在坡度ID*/
	UINT8  bReturnValue = 0;    /*函数返回值*/
	UINT32 arcEndOfst  = 0;     /*坡度第一个分界点所处相对位置*/
	UINT32 arcStartOfst = 0;    /*坡度第二个分界点所处相对位置*/
	UINT32 relLocation = 0;     /*当前点所处相对位置*/
	FLOAT64 angleValue = 0;     /*角度变化值*/
    FLOAT64 tempAngleValue = 0;     /*计算出的临时值*/
    DSU_GRADE_STRU* curGrade=NULL;        /*当前坡度临时变量*/
    DSU_GRADE_STRU  curGradeTmp;        /*当前坡度临时变量*/
	DSU_GRADE_STRU* frontGrade=NULL;        /*当前坡度前方相邻坡度临时变量*/
	DSU_GRADE_STRU* rearGrade=NULL;       /*当前坡度后方相邻坡度临时变量*/
	FLOAT32 curGradeVal;
	FLOAT64 tempValue;              /*临时变量，用来存表达式计算值*/
	UINT8 GradeTrend = 0;
	UINT8 RtnGetGradFrnt = 0;
	UINT8 RtnGetGradNxt = 0;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != GradeVal))
	{
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*参数指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*计算出点所在坡度*/
	funcRtn = dsuGetGradeIdbyLocExp(pDsuEmapStru,LinkId,ofst,&gradeId);
	if(0 == funcRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*计算出点所在坡度两分界点所处相对位置*/
	funcRtn = dsuDividPointDistanceFromOriginExp(pDsuEmapStru,gradeId,LinkId,&arcEndOfst,&arcStartOfst);
	if(0 == funcRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*计算出点所在坡度两分界点所处相对位置*/
	funcRtn = dsuGetDistanceFromOriginExp(pDsuEmapStru,gradeId,LinkId,ofst,&relLocation);
	if(0 == funcRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}

	/*为了方便计算，对分界点的相对距离进行以下处理*/
	if(0xFFFFFFFF == arcEndOfst)
	{
		arcEndOfst = 0;
	}
	
	if(0xffff != gradeId)
	{
		/*初始化当前坡度*/
		curGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[gradeId];
		/*方向为正，坡度值为正*/
		if(0x55 == curGrade->wInclineDir)
		{
			curGradeVal = (FLOAT32)(1.0*curGrade->wGradValue)/10000;
		}
		else
		/*方向反，坡度值为负*/
		{
			curGradeVal = (FLOAT32)(-1.0*curGrade->wGradValue)/10000;
		}
		
		/*获取前面相邻坡度*/
		if(0xffff != curGrade->wOrgnJointMainGradeId)
		{
			frontGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[curGrade->wOrgnJointMainGradeId];
		}
		/*else
		{
			*GradeVal = (FLOAT32)(10000*curGradeVal);
			bReturnValue = 2;
			return bReturnValue;
		}*/
		
		/*获取后面相邻坡度*/
		if(0xffff != curGrade->wTmnlJointMainGradeId)
		{
			rearGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[curGrade->wTmnlJointMainGradeId];
		}
		/*else
		{
			*GradeVal = (FLOAT32)(10000*curGradeVal);
			bReturnValue = 2;
			return bReturnValue;
		}*/
	}
	else
	{	
		/*获取当前的统一坡度值,因为0不再进行运算和方向判定*/
		curGradeVal = dsuStaticHeadStru->pConGradeStru->wGrade;
		
		/*当前为统一坡度时,为方便后面计算,在该处赋值*/
		curGradeTmp.wId = 0xFFFF;
		curGradeTmp.dwRadius = 0;
		curGradeTmp.wInclineDir = 0x55;
		curGradeTmp.wGradValue = (UINT16)curGradeVal;
		curGrade = &curGradeTmp;
		

		/*使用前的初始化*/
		frontGrade = NULL;
		rearGrade = NULL;
			
		/*获取前面相邻坡度*/
		RtnGetGradFrnt = dsuGetGradeFrntExp(pDsuEmapStru,LinkId, &frontGrade);
		
		/*获取后面相邻坡度*/
		RtnGetGradNxt = dsuGetGradeRearExp(pDsuEmapStru,LinkId, &rearGrade);
		
		/*若前面或后面相邻坡度查询失败*/
		if((0==RtnGetGradFrnt)||(0==RtnGetGradNxt))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}

		/*20141122添加：若查询前面和后面坡度时,发现当前坡度在线路终点,不再进行平缓*/
		if((2==RtnGetGradFrnt)||(2==RtnGetGradNxt))
		{
			* GradeVal = (FLOAT32)(10000*curGradeVal);
			/*返回成功*/
			bReturnValue = 2;
			return bReturnValue;
		}
	}
	
	/*
	 1 没有分界点的时候，即相邻坡度与当前坡度差小于千分之20
	 2 当前点处于分界点所标示的弧度外
	*/
	if((relLocation >= arcEndOfst) && (relLocation <= arcStartOfst))
	{

		* GradeVal = (FLOAT32)(10000*curGradeVal);
		/*返回成功*/
	    bReturnValue = 2;
	    return bReturnValue;
	}
	/*当前点在第一个分界点弧度内*/
	else if(relLocation < arcEndOfst)
	{
		if(NULL != frontGrade)
		{
			/*计算角度变化值*/
			if(0 == frontGrade->dwRadius)
			{
			  /*曲率半径为0，角度变化值为0*/
			  angleValue = 0;
			}
			else
			{
				/*角度变化值*/
			   angleValue = (FLOAT32)((arcEndOfst + relLocation)/(1.0*frontGrade->dwRadius));
			}
			/*坡度是上坡，取正值*/
			if(0x55 == frontGrade->wInclineDir)
			{
				tempValue = (1.0*frontGrade->wGradValue)/10000;
			}
			/*下坡取负值*/
			else 
			{
				tempValue = (-1.0*frontGrade->wGradValue)/10000;
			}
			/*if用来判断角度变化值是增加值还是减少值*/
			if(dquGradeTrendExp(pDsuEmapStru,frontGrade->wId,curGrade->wId,&GradeTrend))
			{
				/*坡度减少*/
				if(1 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue - angleValue;
				}
				/*坡度增加*/
				else if(2 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue + angleValue;
				}
				/*坡度不变化*/
				else
				{
					tempAngleValue = tempValue ;
				}

				/*转换为FLOAT32类型*/
				*  GradeVal = (FLOAT32)(tempAngleValue*10000);
				/*返回成功*/
				bReturnValue = 1;
				return bReturnValue;
			}
			else
			{
				/*不可达*/
				bReturnValue = 0;
				return bReturnValue;
			}
		}
		else
		{
			/*转换为FLOAT32类型*/
			*  GradeVal = (FLOAT32)(curGradeVal);
			/*返回成功*/
			bReturnValue = 1;
			return bReturnValue;
		}
	}
	/*在第三分界段内*/
	else
	{
		if(NULL != rearGrade)
		{
			/*计算角度变化值*/
			if(0 == curGrade->dwRadius)
			{
			  /*曲率半径为0，角度变化值为0*/
			  angleValue = 0;
			}
			else
			{
				/*角度变化值*/
			   angleValue = (FLOAT32)((relLocation - arcStartOfst)/(1.0*curGrade->dwRadius));
			}

			if(0x55 == curGrade->wInclineDir)
			{
				tempValue = (1.0*curGrade->wGradValue)/10000;
			}
			else
			{
				tempValue = (-1.0*curGrade->wGradValue)/10000;
			}
			
			/*if用来判断角度变化值是增加值还是减少值*/
			if(dquGradeTrendExp(pDsuEmapStru,curGrade->wId,rearGrade->wId,&GradeTrend))
			{
				/*坡度值减少*/
				if(1 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue - angleValue;				
				}
				/*坡度值增加*/
				else if(2 == GradeTrend)
				{
					/*计算平缓后的坡度值*/
					tempAngleValue = tempValue + angleValue;
				}
				/*坡度值不变化*/
				else
				{
					tempAngleValue = tempValue;
				}
			
				/*转换为FLOAT32类型*/
				*  GradeVal = (FLOAT32)(tempAngleValue*10000);
				/*返回成功*/
				bReturnValue = 3;
				return bReturnValue;
			}
			else
			{
				/*不可达*/
				bReturnValue = 0;
				return bReturnValue;
			}
		}
		else
		{
			/*转换为FLOAT32类型*/
			*  GradeVal = (FLOAT32)(curGradeVal);
			/*返回成功*/
			bReturnValue = 3;
			return bReturnValue;
		}
	}	
}

/*************
*访问接口
*函数功能：计算某点坡度平缓后的坡度值
*输入参数：Point 所求坡度点
*输出参数： 
*返回值：  0函数执行失败 1 点在坡度第一段 2 点在坡度第2段 3 点在坡度第3段
*备注：增加对单轨项目标识的处理，modify by qxt 20170726
****************/
UINT8 dsuCalculateGradeValueExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 LinkId,UINT32 ofst,FLOAT32 *GradeVal)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if (DQU_CBTC_FAO == cbtcVersionType)
	{
		rtnValue=dsuCalculateGradeValueExp_FAO(pDsuEmapStru,LinkId,ofst, GradeVal);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType) || (DQU_CBTC_HLT == cbtcVersionType)||(DQU_CBTC_DG == cbtcVersionType)  )
	{
		rtnValue=dsuCalculateGradeValueExp_CPK(pDsuEmapStru,LinkId,ofst, GradeVal);
	}
	else
	{
		rtnValue = 0U;		
	}
	return rtnValue; 
}

/*************
*函数功能：计算某坡度平缓后，分成的几个部分的分界点与起点的距离
*输入参数：gradeId 坡度ID
*输出参数：UINT32* endPointDistance UINT32* startPointDistance
*返回值：  0函数执行失败   1成功
备注：     如果不需要平缓计算的点，设为无效值ffffffff  返回值为1
****************/
UINT8 dsuDividPointDistanceFromOriginExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 GradeId,UINT16 linkId,UINT32* endPointDistance,UINT32* startPointDistance)
{
	DSU_GRADE_STRU* curGrade=NULL;        /*当前坡度临时变量*/
	DSU_GRADE_STRU* frontGrade=NULL;      /*前面坡度*/
	DSU_GRADE_STRU* rearGrade=NULL;       /*后面面坡度*/
	UINT16 gradeValue = 0;           /*坡度差值*/
	UINT32 arcLength = 0;			 /*弧长*/
	UINT8 bReturnValue = 0;			 /*函数返回值*/
	UINT8 RtnGetGradFrnt = 0;		 /*获取前面坡度结果*/
	UINT8 RtnGetGradNxt = 0;		 /*获取后面坡度结果*/

	DSU_GRADE_STRU curGradeTmp;		/*当前坡度临时变量*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 GRADEINDEXNUM=0U;
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != endPointDistance) && (NULL != startPointDistance))
	{
		GRADEINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->GRADEINDEXNUM;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*参数指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*若输入的坡度编号不为空,则在坡度表中处理*/
	if(0xffff != GradeId)
	{
		if((GradeId>GRADEINDEXNUM)||((dsuGradeIndex[GradeId]) == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}
		
		/*初始化当前坡度*/
		curGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[GradeId];
		
		/*前面有相邻坡度*/
		if(curGrade->wOrgnJointMainGradeId != 0xFFFF)
		{
			/*初始化前面相邻坡度*/
			frontGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[curGrade->wOrgnJointMainGradeId];
		}
		/*前面没有相邻坡度*/
		else
		{
			/*终点设为无效值*/
			* endPointDistance = 0xFFFFFFFF;
			frontGrade = NULL;
		}
		
		/*后面有相邻坡度*/
		if(curGrade->wTmnlJointMainGradeId != 0xFFFF)
		{
			/*初始化后面相邻坡度*/
			rearGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[curGrade->wTmnlJointMainGradeId];
		}
		/*后面没有相邻坡度*/
		else
		{
			/*起点设为无效值*/
			* startPointDistance = 0xFFFFFFFF;
			rearGrade = NULL;
		}
	}
	else
	/*当前所在坡度为统一坡度*/
	{
		memset(&curGradeTmp, 0, sizeof(curGradeTmp));

		/*根据信息,填写当前坡度信息*/
		curGradeTmp.wInclineDir = EMAP_SAME_DIR;
		curGradeTmp.wGradValue =  dsuStaticHeadStru->pConGradeStru->wGrade;
		curGradeTmp.dwRadius = 0;

		curGrade = &curGradeTmp;

		/*使用前的初始化*/
		frontGrade = NULL;
		rearGrade = NULL;
		
		/*获取前面相邻坡度*/
		RtnGetGradFrnt = dsuGetGradeFrntExp(pDsuEmapStru,linkId, &frontGrade);
		
		/*获取后面相邻坡度*/
		RtnGetGradNxt = dsuGetGradeRearExp(pDsuEmapStru,linkId, &rearGrade);
		
		/*若前面或后面相邻坡度查询失败*/
		if((0==RtnGetGradFrnt)||(0==RtnGetGradNxt))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}
	}
		
	/**************计算linkEndId 和  endOfst******************/
	/*前面有相邻坡度*/
	if(NULL != frontGrade)
	{
		/*竖曲线半径无效*/
		if(frontGrade->dwRadius == 0xFFFFFFFF)
		{
			/*终点设为无效值*/
			* endPointDistance = 0xFFFFFFFF;
		}
		else
		{
			/*计算坡度差值，都是上坡或下坡*/
			if((frontGrade->wInclineDir) == (curGrade->wInclineDir))
			{
				gradeValue = abs((INT16)curGrade->wGradValue - (INT16)frontGrade->wGradValue);
			}
			else
			{
				/*一个上坡，一个下坡*/
				gradeValue = curGrade->wGradValue + frontGrade->wGradValue;
			}
			/*计算弧长*/
			arcLength = gradeValue*((frontGrade->dwRadius)/20000);
			* endPointDistance = arcLength;
		}
	}
	else
	{
		/*终点设为无效值*/
		* endPointDistance = 0xFFFFFFFF;
	}
	/**************计算完毕linkEndId 和  endOfst******************/
		

	/**************计算linkStartId 和  startOfst******************/
	/*后面有相邻坡度*/
	if(NULL != rearGrade)
	{
		/*竖曲线半径无效*/
		if(rearGrade->dwRadius == 0xFFFFFFFF)
		{
			/*终点设为无效值*/
			* startPointDistance = 0xFFFFFFFF;
		}
		else
		{
			/*计算坡度差值，都是上坡或下坡*/
			if((rearGrade->wInclineDir) == (curGrade->wInclineDir))
			{
				gradeValue = abs((INT16)curGrade->wGradValue - (INT16)rearGrade->wGradValue);
			}
			else
			{
				/*一个上坡，一个下坡*/
				gradeValue = curGrade->wGradValue + rearGrade->wGradValue;
			}
			/*计算弧长*/
			arcLength = gradeValue*((curGrade->dwRadius)/20000);
			* startPointDistance = curGrade->dwGradeLength - arcLength;
		}
	}
	else
	{
		/*起点设为无效值*/
		* startPointDistance = 0xFFFFFFFF;
	}
	/**************计算完毕linkStartId 和  startOfst******************/

	bReturnValue = 1;
	return bReturnValue;
}

/*************
*函数功能：给定坡度上某一点及坡度id，计算该点距离坡度起点的距离
*输入参数：gradeId 坡度ID
           UINT16 linkId UINT32 Ofst
*输出参数：UINT32 *length  长度
          
*返回值：  0函数执行失败   1成功  
****************/
UINT8 dsuGetDistanceFromOriginExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 GradeId,UINT16 linkId,UINT32 Ofst,UINT32* length)
{
	UINT16 j=0U;                 /*循环变量*/
	DSU_GRADE_STRU* curGrade=NULL;   /*坡度结构体临时变量*/
	DSU_LINK_STRU * plink=NULL;      /*link结构体指针临时变量*/
	UINT8 bReturnValue;         /*函数返回值*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 GRADEINDEXNUM=0U;
	UINT16	*dsuLinkIndex=NULL;
	UINT16	*dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != length))
	{
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		GRADEINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->GRADEINDEXNUM;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*参数指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	if(0xffff != GradeId)
	{
		if((GradeId>GRADEINDEXNUM)||((dsuGradeIndex[GradeId]) == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}

		curGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[GradeId];
		if(0 == curGrade->dwOrgnLinkOfst)
		{
			* length = 0;
		}
		else
		{
			* length = 1;
		}
		/*点在起始link上*/
		if((linkId == curGrade->wOrgnLinkId) && (Ofst >= curGrade->dwOrgnLinkOfst))
		{
			* length += Ofst - curGrade->dwOrgnLinkOfst;
			bReturnValue = 1;
			 return bReturnValue;
		}
		else
		{
			plink = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[curGrade->wOrgnLinkId];
			* length += plink->dwLength - curGrade->dwOrgnLinkOfst;
			j=0U;
			/*先从中间link上找找*/
			while(0xFFFF != curGrade->wIncludeLinkId[j])
			{
				if(j>=GRADE_INCLUDE_LINK_NUM)
				{
					/*数据错误，退出 不可能有这么多包含link*/
					bReturnValue = 0;
					return bReturnValue;
				}
				plink = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[curGrade->wIncludeLinkId[j]];
				/*落在中间某link上*/
				if((linkId == curGrade->wIncludeLinkId[j]) && (Ofst <= plink->dwLength))
				{
					* length += Ofst;
					bReturnValue = 1;
					return bReturnValue;
				}
				else
				{ 
					/*否则把中间link的长度累加起来*/
					* length += plink->dwLength;
					j++;
				}
			}
			/*中间link没找到，看末端link*/
			if((linkId == curGrade->wTmnlLinkId) && (Ofst <= curGrade->dwTmnlLinkOfst))
			{
				* length += Ofst;
				bReturnValue = 1;
				return bReturnValue;
			}
			else
			{
				bReturnValue = 0;
				return bReturnValue;
			}
		}
	}
	else
	{
		* length = Ofst;
		bReturnValue = 1;
		return bReturnValue;	
	}
}

/************************************************************************

 	函数功能：	此函数的功能是查询给定的两位置间的最差坡度。函数查询起点至
				终点范围内所有的线路坡度，并挑出最差坡度（最大下坡）。规定
				上坡为正，下坡为负，函数的功能即为挑出范围内坡度的最小值。
				函数返回最差坡度的千分数。

	入口参数：	const LOD_STRU * pLODStartStru		查询起点位置和方向（实际为列车车尾位置和方向）
				const LOD_STRU * pLODEndStru		查询终点位置和方向
				const UCHAR PointNum				MA中的道岔数量
				const POINT_STRU * pPointStru		道岔信息结构体
	出口参数：	FLOAT64 * Gradient					列车车尾至MA终点范围内最差坡度的千分数（上坡为正，下坡为负）
	返回值：	UCHAR bReturnValue					 	
				0：查询失败；
 				1：查询正确；
     注：在计算的过程中，用的万分值，返回值前，有/10的操作，因此返回
	     的坡度值为千分值                                                     
************************************************************************/
/*14 两位置间最差坡度查询*/
static UCHAR dsuGradientGetExp_FAO(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU * pLODStartStru, const LOD_STRU * pLODEndStru,
					 const UCHAR PointNum, const DQU_POINT_STATUS_STRU * pPointStru, FLOAT32 * Gradient)
{
	UINT16 wCurrentGradeID = 0;/*当前的坡度编号*/
	UINT16 wNextGradeID = 0;/*当前坡度的相邻坡度编号*/
	UCHAR bReturnValue = 0;/*函数返回值*/
	UINT8 bLocGradeReturn = 0;/*函数“获取当前位置的坡度信息”返回值*/
	UCHAR rstGradeNxt = 0;  /*获取相邻link坡度的返回值*/
	UCHAR rstGetIdNxt = 0;	/*获取相邻link的返回值*/
	DSU_GRADE_STRU *pstGrade=NULL;/*指向坡度信息的结构体指针*/
	DSU_GRADE_STRU stGrade; /*指向坡度信息的结构体变量*/
	UINT16 i=0U;  
	UINT16 wCurrentLinkId;	/*当前坡度的link的ID*/

	FLOAT32 StartPointGradeVal;
	FLOAT32 EndPointGradeVal;
	UINT16 StartGradeId;
	UINT16 EndGradeId;
	UINT8  StartPointGradeRtn;
	UINT8  EndPointGradeRtn;
	FLOAT32 Coefficient = 1;          /*坡度系数，上坡为1 下坡为-1*/
	FLOAT32 CurGradeVal;
	FLOAT32 minGradeVal;
	FLOAT32 maxGradeVal;

	UINT16  StartLinkId;
	UINT32  StartOfst;
	UINT16  EndLinkId;
	UINT32  EndOfst;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16	 LINKINDEXNUM=0U;
	UINT16	*dsuLinkIndex=NULL;
	UINT16	*dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL!=pLODStartStru) && (NULL!=pLODEndStru) 
		&& (NULL!=pPointStru) && (NULL!= Gradient))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*入口参数指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据起点Link的有效性*/
	if((pLODStartStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStartStru->Lnk] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据起点link偏移量的有效性*/
	if (pLODStartStru->Off > LinkLengthExp(pDsuEmapStru,pLODStartStru->Lnk))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据起点方向的有效性*/
	if ((EMAP_SAME_DIR != pLODStartStru->Dir) && (EMAP_CONVER_DIR != pLODStartStru->Dir))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据Link的有效性*/
	if((pLODEndStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODEndStru->Lnk] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据终点link偏移量的有效性*/
	if (pLODEndStru->Off > LinkLengthExp(pDsuEmapStru,pLODEndStru->Lnk))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据终点方向的有效性*/
	if ((EMAP_SAME_DIR != pLODEndStru->Dir) && (EMAP_CONVER_DIR != pLODEndStru->Dir))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}


	/*方向为正，系数取1*/
	if(0x55 == pLODStartStru->Dir)
	{
		Coefficient = 1;
		StartLinkId = pLODStartStru->Lnk;
		StartOfst = pLODStartStru->Off;
		EndLinkId = pLODEndStru->Lnk;
		EndOfst = pLODEndStru->Off;
	}
	/*方向为反，系数取-1 起点终点调换位置*/
	else 
	{
		Coefficient = -1;
		StartLinkId = pLODEndStru->Lnk;
		StartOfst = pLODEndStru->Off;
		EndLinkId = pLODStartStru->Lnk;
		EndOfst = pLODStartStru->Off;
	}

	/*****************以下计算起点和终点坡度值*********************/
	bLocGradeReturn = dsuGetGradeIdbyLocExp(pDsuEmapStru,StartLinkId,StartOfst,&StartGradeId);
	/*函数调用失败，返回错误*/
	if (0 == bLocGradeReturn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	StartPointGradeRtn =  dsuCalculateGradeValueExp(pDsuEmapStru,StartLinkId,StartOfst,&StartPointGradeVal);
	/*函数调用失败，返回错误*/
	if (0 == StartPointGradeRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*终点坡度值计算*/
	bLocGradeReturn = dsuGetGradeIdbyLocExp(pDsuEmapStru,EndLinkId,EndOfst,&EndGradeId);
	/*函数调用失败，返回错误*/
	if (0 == bLocGradeReturn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	EndPointGradeRtn =  dsuCalculateGradeValueExp(pDsuEmapStru,EndLinkId,EndOfst,&EndPointGradeVal);
	/*函数调用失败，返回错误*/
	if (0 == EndPointGradeRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*****************起点和终点坡度值计算完毕*********************/


	/****如果两点在同一坡度内****/
	if((StartGradeId == EndGradeId)&&
		(0xffff != StartGradeId)&&(0xffff != EndGradeId))
	{
		/*在同一个分界段内*/
		if(StartPointGradeRtn == EndPointGradeRtn)
		{
			/*返回最小的那个*/
			if(EndPointGradeVal < StartPointGradeVal)
			{
				minGradeVal = EndPointGradeVal;
				maxGradeVal = StartPointGradeVal;
			}
			else
			{
				minGradeVal = StartPointGradeVal;
				maxGradeVal = EndPointGradeVal;
			}
		}
		/*不在同一分界段内，需考虑中间分界段坡度值*/
		else
		{
			pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[StartGradeId];
			/*当前坡度值，上坡为正，下坡为负*/
			if(0x55 == pstGrade->wInclineDir)
			{
				CurGradeVal = (FLOAT32)(1.0 * pstGrade->wGradValue);
			}
			else
			{
				CurGradeVal = (FLOAT32)(-1.0 * pstGrade->wGradValue);
			}

			/*取得最小值*/
			if((EndPointGradeVal<=CurGradeVal)&& (EndPointGradeVal<=StartPointGradeVal))
			{
				minGradeVal = EndPointGradeVal;
			}
			else if((StartPointGradeVal<=CurGradeVal)&& (StartPointGradeVal<=EndPointGradeVal))
			{
				minGradeVal = StartPointGradeVal;
			}
			else
			{
				minGradeVal = CurGradeVal;
			}
			/*取最大值*/
			if((EndPointGradeVal>=CurGradeVal)&& (EndPointGradeVal>=StartPointGradeVal))
			{
				maxGradeVal = EndPointGradeVal;
			}
			else if((StartPointGradeVal>=CurGradeVal)&& (StartPointGradeVal>=EndPointGradeVal))
			{
				maxGradeVal = StartPointGradeVal;
			}
			else
			{
				maxGradeVal = CurGradeVal;
			}

		}
	}
	/*****不在同一坡度*****/
	else
	{
		if(0xffff != StartGradeId)
		{
			pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[StartGradeId];
			/*当前坡度值，上坡为正，下坡为负*/
			if(0x55 == pstGrade->wInclineDir)
			{
				CurGradeVal = (FLOAT32)(1.0 * pstGrade->wGradValue);
			}
			else
			{
				CurGradeVal = (FLOAT32)(-1.0 * pstGrade->wGradValue);
			}
			/*取得当前坡度段起点前方的最大最小坡度值*/
			if(1 == StartPointGradeRtn)
			{
				if(CurGradeVal>StartPointGradeVal)
				{
					minGradeVal = StartPointGradeVal;
					maxGradeVal = CurGradeVal;
				}
				else
				{
					minGradeVal = CurGradeVal;
					maxGradeVal = StartPointGradeVal;
				}
			}
			else if(2 == StartPointGradeRtn)
			{
				minGradeVal = CurGradeVal;
				maxGradeVal = StartPointGradeVal;
			}
			else
			{
				minGradeVal = StartPointGradeVal;
				maxGradeVal = StartPointGradeVal;
			}
		}
		else
		{
			/*起始坡度为统一坡度,仅对最大最小值进行初始赋值*/
			minGradeVal = StartPointGradeVal;
			maxGradeVal = StartPointGradeVal;
		}

		if(0xffff != EndGradeId)
		{
			pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[EndGradeId];
			/*终端所在坡度值，上坡为正，下坡为负*/
			if(0x55 == pstGrade->wInclineDir)
			{
				CurGradeVal = (FLOAT32)(1.0 * pstGrade->wGradValue);
			}
			else
			{
				CurGradeVal = (FLOAT32)(-1.0 * pstGrade->wGradValue);
			}
			/*取得当前坡度段起点前方的最大最小坡度值*/
			if(1 == EndPointGradeRtn)
			{
				/*从末端点中找到最小最大坡度值*/
				if(maxGradeVal<EndPointGradeVal)
				{
					maxGradeVal = EndPointGradeVal;
				}
				else if(minGradeVal>EndPointGradeVal)
				{
					minGradeVal = EndPointGradeVal;
				}
				else
				{
					/*继续执行*/
				}
			}
			else if(2 == EndPointGradeRtn)
			{
				/*从末端点中找到最小最大坡度值*/
				if(maxGradeVal<EndPointGradeVal)
				{
					maxGradeVal = EndPointGradeVal;
				}
				else if(minGradeVal>EndPointGradeVal)
				{
					minGradeVal = EndPointGradeVal;
				}
				else
				{
					/*继续执行*/
				}
			}
			else
			{
				/*算出最大值*/
				if((EndPointGradeVal>= maxGradeVal)&&(EndPointGradeVal>= CurGradeVal))
				{
					maxGradeVal = EndPointGradeVal;
				}
				else if((CurGradeVal>= maxGradeVal)&&(CurGradeVal>= EndPointGradeVal))
				{
					maxGradeVal = CurGradeVal;
				}
				else
				{
					/*继续执行*/
				}

				/*算出最小值*/
				if((EndPointGradeVal<= minGradeVal)&&(EndPointGradeVal<= CurGradeVal))
				{
					minGradeVal = EndPointGradeVal;
				}
				else if((CurGradeVal<= minGradeVal)&&(CurGradeVal<=EndPointGradeVal ))
				{
					minGradeVal = CurGradeVal;
				}
				else
				{
					/*继续执行*/
				}
			}
		}
		else
		{
			/*终点坡度为统一坡度*/
			/*从末端点中找到最小最大坡度值*/
			if(maxGradeVal<EndPointGradeVal)
			{
				maxGradeVal = EndPointGradeVal;
			}
			else if(minGradeVal>EndPointGradeVal)
			{
				minGradeVal = EndPointGradeVal;
			}
			else
			{
				/*继续执行*/
			}
		}


		/*设当前坡度id为起始坡度id*/
		wCurrentGradeID = StartGradeId;
		/*记录当前link的id信息*/
		wCurrentLinkId = StartLinkId;

		/*循环获取起点终点间的坡度信息并比对得到最大,最小值*/
		for(i=0U;i<dsuDataLenStru->wGradeLen;i++)
		{
			if(0xffff != wCurrentGradeID)
			{
				/*在坡度表中查询当前坡度的前面坡度*/
				wNextGradeID = FindAdjacentGradeIDExp(pDsuEmapStru,wCurrentGradeID, 0x55, PointNum, pPointStru);

				/*获取前方坡度*/
				if (0xffff != wNextGradeID)
				{
					/*若查询得到的坡度关联ID不为空,利用管理函数找到当前的坡度信息*/
					pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[wNextGradeID];	
					/*获取当前所用坡度的终点link信息*/
					wCurrentLinkId = pstGrade->wTmnlLinkId;
				}				
				else
				{
					/*若在坡度表中获取到的终点关联坡度为无效,则可能为线路终点,或者在统一坡度表中的信息*/



					/*在link表中查询前面坡度是否在统一坡度表中,*/
					rstGradeNxt = dsuGetGradeRearExp(pDsuEmapStru,wCurrentLinkId, &pstGrade);

					if((1 == rstGradeNxt)&&(NULL == pstGrade))
					{
						/*若前面坡度在统一坡度表中,则获取统一坡度表信息,参与坡度比较*/
						stGrade.wInclineDir = EMAP_SAME_DIR;
						stGrade.wGradValue = dsuStaticHeadStru->pConGradeStru->wGrade;
						pstGrade = &stGrade;

						/*相邻坡度为统一坡度,编号置为无效*/
						wNextGradeID = 0xffff;
					}
					else
					{
						/*若前面坡度未在统一坡度表中,则当前查询应为线路终点*/
						/*线路终点(找到线路终点也未能找到终点坡度ID)*/
						bReturnValue = 0;
						return bReturnValue;
					}
					/*更新当前link的ID信息以便统一坡度表关系的查询*/
					rstGetIdNxt = dsuGetAdjacentLinkIDExp(pDsuEmapStru,wCurrentLinkId, 0x55, PointNum, pPointStru, &wCurrentLinkId);

					if(1 != rstGetIdNxt)
					{
						/*查询线路link失败*/
						bReturnValue = 0;
						return bReturnValue;
					}
				}
			}
			else
			{
				/*查询当前link的始端相邻坡度*/
				rstGradeNxt = dsuGetGradeRearExp(pDsuEmapStru,wCurrentLinkId, &pstGrade);

				if(1 == rstGradeNxt)
				{
					if(NULL == pstGrade)
					{
						/*若前面坡度在统一坡度表中,则获取统一坡度表信息,参与坡度比较*/
						stGrade.wInclineDir = EMAP_SAME_DIR;
						stGrade.wGradValue = dsuStaticHeadStru->pConGradeStru->wGrade;
						pstGrade = &stGrade;

						/*相邻坡度为统一坡度,编号置为无效*/
						wNextGradeID = 0xffff;
					}
					else
					{
						/*按照实际查询得到pstGrade的坡度表中的坡度值进行处理*/
						/*记录当前link的相邻坡度ID*/
						wNextGradeID = pstGrade->wId;
					}

					/*为避免在坡度表中的查询不完全,若在统一坡度表中的处理不计入循环*/
					if(i>=1)
					{
						i--;
					}
				}
				else
				{
					/*线路终点(找到线路终点也未能找到终点坡度ID)*/
					bReturnValue = 0;
					return bReturnValue;
				}

				if (wCurrentLinkId == EndLinkId)
				{
					/*查到终端坡度*/
					break;
				}

				/*20141122添加：更新当前link的ID信息以便统一坡度表关系的查询*/
				rstGetIdNxt = dsuGetAdjacentLinkIDExp(pDsuEmapStru,wCurrentLinkId, 0x55, PointNum, pPointStru, &wCurrentLinkId);

				if(1 != rstGetIdNxt)
				{
					/*查询线路link失败*/
					bReturnValue = 0;
					return bReturnValue;
				}
			}

			/*更新当前坡度ID信息以便坡度表关系的查询*/
			wCurrentGradeID = wNextGradeID;

			if( ((wNextGradeID == EndGradeId) && ((0xffff != wNextGradeID) && (0xffff != EndGradeId))) ||
				((wCurrentLinkId == EndLinkId) && (0xffff == wNextGradeID)) )
			{
				/*查到终端坡度*/
				break;
			}

			if(0x55 == pstGrade->wInclineDir)
			{
				/*如果有更大的坡度或更小的坡度，替换当前值*/
				if(minGradeVal>=pstGrade->wGradValue)
				{
					minGradeVal = pstGrade->wGradValue;
				}
				if(maxGradeVal<=pstGrade->wGradValue)
				{
					maxGradeVal = pstGrade->wGradValue;
				}
			}
			else
			{
				/*如果有更大的坡度或更小的坡度，替换当前值*/
				if(minGradeVal>=-1.0*pstGrade->wGradValue)
				{
					minGradeVal = (FLOAT32)(-1.0*pstGrade->wGradValue);
				}
				if(maxGradeVal<=-1.0*pstGrade->wGradValue)
				{
					maxGradeVal = (FLOAT32)(-1.0*pstGrade->wGradValue);
				}
			}
		}

		if(i>=dsuDataLenStru->wGradeLen)
		{
			/*没找到末端坡度*/
			bReturnValue = 0;
			return bReturnValue;
		}
	}

	/*根据运行方向确定最差坡度值*/
	if(0x55 == pLODStartStru->Dir)
	{
		* Gradient = minGradeVal/10;
		bReturnValue = 1;
		return bReturnValue;
	}
	else
	{
		* Gradient = (FLOAT32)(-1.0 * maxGradeVal/10);
		bReturnValue = 1;
		return bReturnValue;
	}

}

/************************************************************************

 	函数功能：	此函数的功能是查询给定的两位置间的最差坡度。函数查询起点至
				终点范围内所有的线路坡度，并挑出最差坡度（最大下坡）。规定
				上坡为正，下坡为负，函数的功能即为挑出范围内坡度的最小值。
				函数返回最差坡度的千分数。

	入口参数：	const LOD_STRU * pLODStartStru		查询起点位置和方向（实际为列车车尾位置和方向）
				const LOD_STRU * pLODEndStru		查询终点位置和方向
				const UCHAR PointNum				MA中的道岔数量
				const POINT_STRU * pPointStru		道岔信息结构体
	出口参数：	FLOAT64 * Gradient					列车车尾至MA终点范围内最差坡度的千分数（上坡为正，下坡为负）
	返回值：	UCHAR bReturnValue					 	
				0：查询失败；
 				1：查询正确；
     注：在计算的过程中，用的万分值，返回值前，有/10的操作，因此返回
	     的坡度值为千分值                                                     
************************************************************************/
static UCHAR dsuGradientGetExp_CPK(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU * pLODStartStru, const LOD_STRU * pLODEndStru,
					 const UCHAR PointNum, const DQU_POINT_STATUS_STRU * pPointStru, FLOAT32 * Gradient)
{
	UINT16 wCurrentGradeID = 0;/*当前的坡度编号*/
	UINT16 wNextGradeID = 0;/*当前坡度的相邻坡度编号*/
	UCHAR bReturnValue = 0;/*函数返回值*/
	UINT8 bLocGradeReturn = 0;/*函数“获取当前位置的坡度信息”返回值*/
	UCHAR rstGradeNxt = 0;  /*获取相邻link坡度的返回值*/
	UCHAR rstGetIdNxt = 0;	/*获取相邻link的返回值*/
    DSU_GRADE_STRU *pstGrade=NULL;/*指向坡度信息的结构体指针*/
	DSU_GRADE_STRU stGrade; /*指向坡度信息的结构体变量*/
	UINT16 i=0U;  
	UINT16 wCurrentLinkId;	/*当前坡度的link的ID*/

	FLOAT32 StartPointGradeVal;
	FLOAT32 EndPointGradeVal;
	UINT16 StartGradeId;
	UINT16 EndGradeId;
	UINT8  StartPointGradeRtn;
	UINT8  EndPointGradeRtn;
	FLOAT32 Coefficient = 1;          /*坡度系数，上坡为1 下坡为-1*/
	FLOAT32 CurGradeVal;
	FLOAT32 minGradeVal;
	FLOAT32 maxGradeVal;

	UINT16  StartLinkId;
	UINT32  StartOfst;
	UINT16  EndLinkId;
	UINT32  EndOfst;

	DSU_LINK_STRU *pLinkStru=NULL;				/*Link信息结构体指针*/
    DSU_LINK_STRU *pLinkStruEnd=NULL;		   /*Link信息结构体指针 add by zlj 20161024*/
	/*全局变量改传参调用涉及的全局变量*/
	UINT16	 LINKINDEXNUM=0U;
	UINT16	*dsuLinkIndex=NULL;
	UINT16	*dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != pLODStartStru) && (NULL != pLODEndStru) 
		&& (NULL != pPointStru) && (NULL != Gradient))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据起点Link的有效性*/
	if((pLODStartStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODStartStru->Lnk] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据起点link偏移量的有效性*/
	if (pLODStartStru->Off > LinkLengthExp(pDsuEmapStru,pLODStartStru->Lnk))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据起点方向的有效性*/
	if ((EMAP_SAME_DIR != pLODStartStru->Dir) && (EMAP_CONVER_DIR != pLODStartStru->Dir))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据Link的有效性*/
	if((pLODEndStru->Lnk>LINKINDEXNUM)||(dsuLinkIndex[pLODEndStru->Lnk] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据终点link偏移量的有效性*/
	if (pLODEndStru->Off > LinkLengthExp(pDsuEmapStru,pLODEndStru->Lnk))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	/*判断入口数据终点方向的有效性*/
	if ((EMAP_SAME_DIR != pLODEndStru->Dir) && (EMAP_CONVER_DIR != pLODEndStru->Dir))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}


	/*方向为正，系数取1*/
	if(0x55 == pLODStartStru->Dir)
	{
		Coefficient = 1;
		StartLinkId = pLODStartStru->Lnk;
		StartOfst = pLODStartStru->Off;
		EndLinkId = pLODEndStru->Lnk;
		EndOfst = pLODEndStru->Off;
	}
	/*方向为反，系数取-1 起点终点调换位置*/
	else 
	{
		Coefficient = -1;
		StartLinkId = pLODEndStru->Lnk;
		StartOfst = pLODEndStru->Off;
		EndLinkId = pLODStartStru->Lnk;
		EndOfst = pLODStartStru->Off;
	}

	/*****************以下计算起点和终点坡度值*********************/
	bLocGradeReturn = dsuGetGradeIdbyLocExp(pDsuEmapStru,StartLinkId,StartOfst,&StartGradeId);
	/*函数调用失败，返回错误*/
	if (0 == bLocGradeReturn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	StartPointGradeRtn =  dsuCalculateGradeValueExp(pDsuEmapStru,StartLinkId,StartOfst,&StartPointGradeVal);
	/*函数调用失败，返回错误*/
	if (0 == StartPointGradeRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*终点坡度值计算*/
	bLocGradeReturn = dsuGetGradeIdbyLocExp(pDsuEmapStru,EndLinkId,EndOfst,&EndGradeId);
	/*函数调用失败，返回错误*/
	if (0 == bLocGradeReturn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	EndPointGradeRtn =  dsuCalculateGradeValueExp(pDsuEmapStru,EndLinkId,EndOfst,&EndPointGradeVal);
	/*函数调用失败，返回错误*/
	if (0 == EndPointGradeRtn)
	{
		bReturnValue = 0;
		return bReturnValue;
	}
	/*****************起点和终点坡度值计算完毕*********************/

	
	/****如果两点在同一坡度内****/
	if((StartGradeId == EndGradeId)&&
	   (0xffff != StartGradeId) && (0xffff != EndGradeId))
	{
		/*在同一个分界段内*/
		if(StartPointGradeRtn == EndPointGradeRtn)
		{
			/*返回最小的那个*/
			if(EndPointGradeVal < StartPointGradeVal)
			{
				minGradeVal = EndPointGradeVal;
				maxGradeVal = StartPointGradeVal;
			}
			else
			{
				minGradeVal = StartPointGradeVal;
				maxGradeVal = EndPointGradeVal;
			}
		}
		/*不在同一分界段内，需考虑中间分界段坡度值*/
		else
		{
			pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[StartGradeId];
			/*当前坡度值，上坡为正，下坡为负*/
			if(0x55 == pstGrade->wInclineDir)
			{
				CurGradeVal = (FLOAT32)(1.0 * pstGrade->wGradValue);
			}
			else
			{
				CurGradeVal = (FLOAT32)(-1.0 * pstGrade->wGradValue);
			}

			/*取得最小值*/
			if((EndPointGradeVal<=CurGradeVal)&& (EndPointGradeVal<=StartPointGradeVal))
			{
				minGradeVal = EndPointGradeVal;
			}
			else if((StartPointGradeVal<=CurGradeVal)&& (StartPointGradeVal<=EndPointGradeVal))
			{
				minGradeVal = StartPointGradeVal;
			}
			else
			{
				minGradeVal = CurGradeVal;
			}
			/*取最大值*/
			if((EndPointGradeVal>=CurGradeVal)&& (EndPointGradeVal>=StartPointGradeVal))
			{
				maxGradeVal = EndPointGradeVal;
			}
			else if((StartPointGradeVal>=CurGradeVal)&& (StartPointGradeVal>=EndPointGradeVal))
			{
				maxGradeVal = StartPointGradeVal;
			}
			else
			{
				maxGradeVal = CurGradeVal;
			}

		}
	}
    /*****不在同一坡度*****/
	else
	{
		if(0xffff != StartGradeId)
		{
			pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[StartGradeId];
			/*当前坡度值，上坡为正，下坡为负*/
			if(0x55 == pstGrade->wInclineDir)
			{
				CurGradeVal = (FLOAT32)(1.0 * pstGrade->wGradValue);
			}
			else
			{
				CurGradeVal = (FLOAT32)(-1.0 * pstGrade->wGradValue);
			}
			/*取得当前坡度段起点前方的最大最小坡度值*/
			if(1 == StartPointGradeRtn)
			{
				if(CurGradeVal>StartPointGradeVal)
				{
					minGradeVal = StartPointGradeVal;
					maxGradeVal = CurGradeVal;
				}
				else
				{
					minGradeVal = CurGradeVal;
					maxGradeVal = StartPointGradeVal;
				}
			}
			else if(2 == StartPointGradeRtn)
			{
				minGradeVal = CurGradeVal;
				maxGradeVal = StartPointGradeVal;
			}
			else
			{
				minGradeVal = StartPointGradeVal;
				maxGradeVal = StartPointGradeVal;
			}
		}
		else
		{
			/*起始坡度为统一坡度,仅对最大最小值进行初始赋值*/
			minGradeVal = StartPointGradeVal;
			maxGradeVal = StartPointGradeVal;
		}
		
		if(0xffff != EndGradeId)
		{
			pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[EndGradeId];
			/*终端所在坡度值，上坡为正，下坡为负*/
			if(0x55 == pstGrade->wInclineDir)
			{
				CurGradeVal = (FLOAT32)(1.0 * pstGrade->wGradValue);
			}
			else
			{
				CurGradeVal = (FLOAT32)(-1.0 * pstGrade->wGradValue);
			}
			/*取得当前坡度段起点前方的最大最小坡度值*/
			if(1 == EndPointGradeRtn)
			{
				/*从末端点中找到最小最大坡度值*/
				if(maxGradeVal<EndPointGradeVal)
				{
					maxGradeVal = EndPointGradeVal;
				}
				else if(minGradeVal>EndPointGradeVal)
				{
					minGradeVal = EndPointGradeVal;
				}
				else
				{
					/*继续执行*/
				}
			}
			else if(2 == EndPointGradeRtn)
			{
				/*从末端点中找到最小最大坡度值*/
				if(maxGradeVal<EndPointGradeVal)
				{
					maxGradeVal = EndPointGradeVal;
				}
				else if(minGradeVal>EndPointGradeVal)
				{
					minGradeVal = EndPointGradeVal;
				}
				else
				{
					/*继续执行*/
				}
			}
			else
			{
				/*算出最大值*/
				if((EndPointGradeVal>= maxGradeVal)&&(EndPointGradeVal>= CurGradeVal))
				{
					maxGradeVal = EndPointGradeVal;
				}
				else if((CurGradeVal>= maxGradeVal)&&(CurGradeVal>= EndPointGradeVal))
				{
					maxGradeVal = CurGradeVal;
				}
				else
				{
					/*继续执行*/
				}

				/*算出最小值*/
				if((EndPointGradeVal<= minGradeVal)&&(EndPointGradeVal<= CurGradeVal))
				{
					minGradeVal = EndPointGradeVal;
				}
				else if((CurGradeVal<= minGradeVal)&&(CurGradeVal<=EndPointGradeVal ))
				{
					minGradeVal = CurGradeVal;
				}
				else
				{
					/*继续执行*/
				}
			}
		}
		else
		{
			/*终点坡度为统一坡度*/
			/*从末端点中找到最小最大坡度值*/
			if(maxGradeVal<EndPointGradeVal)
			{
				maxGradeVal = EndPointGradeVal;
			}
			else if(minGradeVal>EndPointGradeVal)
			{
				minGradeVal = EndPointGradeVal;
			}
			else
			{
				/*继续执行*/
			}
		}
		

		/*设当前坡度id为起始坡度id*/
		wCurrentGradeID = StartGradeId;
		/*记录当前link的id信息*/
		wCurrentLinkId = StartLinkId;

		pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[wCurrentLinkId];

		pLinkStruEnd = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[EndLinkId];/*add by zlj 20161024*/
		/*当前link的“Link坡度信息属性”为无统一坡度*/
		/*if(0 == pLinkStru->wGrade)*//*changed by zlj 20161024*/
        if((0 == pLinkStru->wGrade)||(0 == pLinkStruEnd->wGrade))
		{

			/*循环获取起点终点间的坡度信息并比对得到最大,最小值*/
			for(i=0;i<dsuDataLenStru->wGradeLen;i++)
			{
				if(0xffff != wCurrentGradeID)
				{
					/*在坡度表中查询当前坡度的前面坡度*/
					wNextGradeID = FindAdjacentGradeIDExp(pDsuEmapStru,wCurrentGradeID, 0x55, PointNum, pPointStru);
					
					/*获取前方坡度*/
					if (0xffff != wNextGradeID)
					{
						/*若查询得到的坡度关联ID不为空,利用管理函数找到当前的坡度信息*/
						pstGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[wNextGradeID];	
						/*获取当前所用坡度的终点link信息*/
						wCurrentLinkId = pstGrade->wTmnlLinkId;
					}				
					else
					{
						/*若在坡度表中获取到的终点关联坡度为无效,则可能为线路终点,或者在统一坡度表中的信息*/
						
						/*在link表中查询前面坡度是否在统一坡度表中,*/
						rstGradeNxt = dsuGetGradeRearExp(pDsuEmapStru,wCurrentLinkId, &pstGrade);
						
						if((1 == rstGradeNxt)&&(NULL == pstGrade))
						{
							/*若前面坡度在统一坡度表中,则获取统一坡度表信息,参与坡度比较*/
							stGrade.wInclineDir = EMAP_SAME_DIR;
							stGrade.wGradValue = dsuStaticHeadStru->pConGradeStru->wGrade;
							pstGrade = &stGrade;
							
							/*相邻坡度为统一坡度,编号置为无效*/
							wNextGradeID = 0xffff;
						}
						else
						{
							/*若前面坡度未在统一坡度表中,则当前查询应为线路终点*/
							/*线路终点(找到线路终点也未能找到终点坡度ID)*/
							bReturnValue = 0;
							return bReturnValue;
						}
						/*更新当前link的ID信息以便统一坡度表关系的查询*/
						rstGetIdNxt = dsuGetAdjacentLinkIDExp(pDsuEmapStru,wCurrentLinkId, 0x55, PointNum, pPointStru, &wCurrentLinkId);

						if(1 != rstGetIdNxt)
						{
							/*查询线路link失败*/
							bReturnValue = 0;
							return bReturnValue;
						}
					}
				}
				else
				{
					/*查询当前link的始端相邻坡度*/
					rstGradeNxt = dsuGetGradeRearExp(pDsuEmapStru,wCurrentLinkId, &pstGrade);
					
					if(1 == rstGradeNxt)
					{
						if(NULL == pstGrade)
						{
							/*若前面坡度在统一坡度表中,则获取统一坡度表信息,参与坡度比较*/
							stGrade.wInclineDir = EMAP_SAME_DIR;
							stGrade.wGradValue = dsuStaticHeadStru->pConGradeStru->wGrade;
							pstGrade = &stGrade;

							/*相邻坡度为统一坡度,编号置为无效*/
							wNextGradeID = 0xffff;
						}
						else
						{
							/*按照实际查询得到pstGrade的坡度表中的坡度值进行处理*/
							/*记录当前link的相邻坡度ID*/
							wNextGradeID = pstGrade->wId;
						}
						
						/*为避免在坡度表中的查询不完全,若在统一坡度表中的处理不计入循环*/
						if(i>=1)
						{
							i--;
						}
					}
					else
					{
						/*线路终点(找到线路终点也未能找到终点坡度ID)*/
						bReturnValue = 0;
						return bReturnValue;
					}

					if (wCurrentLinkId == EndLinkId)
					{
						/*查到终端坡度*/
						break;
					}
					/*20141122添加：更新当前link的ID信息以便统一坡度表关系的查询*/
					rstGetIdNxt = dsuGetAdjacentLinkIDExp(pDsuEmapStru,wCurrentLinkId, 0x55, PointNum, pPointStru, &wCurrentLinkId);

					if(1 != rstGetIdNxt)
					{
						/*查询线路link失败*/
						bReturnValue = 0;
						return bReturnValue;
					}
				}
				
				/*更新当前坡度ID信息以便坡度表关系的查询*/
				wCurrentGradeID = wNextGradeID;
				
				if( ((wNextGradeID == EndGradeId)&&((0xffff != wNextGradeID)&&(0xffff != EndGradeId)))||
					((wCurrentLinkId == EndLinkId)&&(0xffff == wNextGradeID)) )
				{
					/*查到终端坡度*/
					break;
				}
			
				if(0x55 == pstGrade->wInclineDir)
				{
					/*如果有更大的坡度或更小的坡度，替换当前值*/
					if(minGradeVal>=pstGrade->wGradValue)
					{
						minGradeVal = pstGrade->wGradValue;
					}
					if(maxGradeVal<=pstGrade->wGradValue)
					{
						maxGradeVal = pstGrade->wGradValue;
					}
				}
				else
				{
					/*如果有更大的坡度或更小的坡度，替换当前值*/
					if(minGradeVal>=-1.0*pstGrade->wGradValue)
					{
						minGradeVal = (FLOAT32)(-1.0*pstGrade->wGradValue);
					}
					if(maxGradeVal<=-1.0*pstGrade->wGradValue)
					{
						maxGradeVal = (FLOAT32)(-1.0*pstGrade->wGradValue);
					}
				}
			}
        }
		else
		{
			*Gradient = minGradeVal/10;
			bReturnValue = 1;
			return bReturnValue;
		}

		if(i>=dsuDataLenStru->wGradeLen)
		{
			/*没找到末端坡度*/
			bReturnValue = 0;
			return bReturnValue;
		}
	}
	
	/*根据运行方向确定最差坡度值*/
	if(0x55 == pLODStartStru->Dir)
	{
		*Gradient = minGradeVal/10;
		bReturnValue = 1;
	    return bReturnValue;
	}
	else
	{
		*Gradient = (FLOAT32)(-1.0 * maxGradeVal/10);
		bReturnValue = 1;
	    return bReturnValue;
	}

}


/*访问接口*/
/*备注：增加对单轨项目标识的处理，modify by qxt 20170726*/
UCHAR dsuGradientGetExp(DSU_EMAP_STRU *pDsuEmapStru,const LOD_STRU *pLODStartStru, const LOD_STRU *pLODEndStru,
	const UCHAR PointNum, const DQU_POINT_STATUS_STRU *pPointStru, FLOAT32 *Gradient)
{
	UINT8 cbtcVersionType=0U;
	UCHAR bReturnValue = 0;/*函数返回值*/
	cbtcVersionType=GetCbtcSysType();
	
	if (DQU_CBTC_FAO == cbtcVersionType)
	{
		bReturnValue=dsuGradientGetExp_FAO(pDsuEmapStru,pLODStartStru, pLODEndStru, PointNum,pPointStru,Gradient);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType)||(DQU_CBTC_HLT == cbtcVersionType)||(DQU_CBTC_DG == cbtcVersionType) )
	{
		bReturnValue=dsuGradientGetExp_CPK(pDsuEmapStru,pLODStartStru, pLODEndStru, PointNum,pPointStru,Gradient);
	}

	else
	{
		bReturnValue = 0;		
	}
	return bReturnValue;
}


/*
函数功能：判断后一坡度的坡度值相比前一个坡度的坡度值是增加，不变化还是减少 
输入参数：UINT16 fistGradeID,UINT16 secondGradeID
输出参数：GradeTrend 坡度 
			1： 减少  
			2： 增加
			0： 不变化
  返回值：0失败 1成功
*/
UINT8 dquGradeTrendExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 fistGradeID,UINT16 secondGradeID,UINT8 *GradeTrend)
{
	UINT8 bReturnValue = 0;	
	INT32 signedFirstGrade=0;/*带有符号的坡度值--前一个坡度*/
	INT32 signedSecondGrade=0;/*带有符号的坡度值--后一个坡度*/
	DSU_GRADE_STRU *fistGrade=NULL;/*指向坡度信息的结构体指针*/
	DSU_GRADE_STRU *secondGrade=NULL;/*指向坡度信息的结构体指针*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 GRADEINDEXNUM=0U;
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != GradeTrend))
	{
		GRADEINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->GRADEINDEXNUM;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*入口指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}


	if(0xffff != fistGradeID)
	{
		if((fistGradeID>GRADEINDEXNUM)||((dsuGradeIndex[fistGradeID]) == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}
		
		/*初始化坡度*/
		fistGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[fistGradeID];
			
		/*0x55=EMAP_SAME_INC_LINE表示上坡,坡度值为正数
		  0xaa=EMAP_CONVER_INC_LINE表示下坡，坡度值为负数*/
	
		/*前一个坡度*/
		if (fistGrade->wInclineDir == EMAP_SAME_INC_LINE) 
		{
			signedFirstGrade=(INT32)fistGrade->wGradValue;
		}
		else if (fistGrade->wInclineDir == EMAP_CONVER_INC_LINE)
		{
			signedFirstGrade=(-1)*((INT32)(fistGrade->wGradValue));
		}
		else
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}
	}
	else
	{
		signedFirstGrade = dsuStaticHeadStru->pConGradeStru->wGrade;
	}	

	if(0xffff != secondGradeID)
	{
		if((secondGradeID>GRADEINDEXNUM)||((dsuGradeIndex[secondGradeID]) == 0xFFFF))
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}
		
		/*初始化坡度*/
		secondGrade = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[secondGradeID];
		
		/*后一个坡度*/
		if (secondGrade->wInclineDir == EMAP_SAME_INC_LINE) 
		{
			signedSecondGrade=(INT32)secondGrade->wGradValue;
		}
		else if (secondGrade->wInclineDir == EMAP_CONVER_INC_LINE)
		{
			signedSecondGrade=(-1)*((INT32)(secondGrade->wGradValue));
		}
		else
		{
			/*入口参数异常，查询失败*/
			bReturnValue = 0;
			return bReturnValue;
		}
	}
	else
	{
		signedSecondGrade = dsuStaticHeadStru->pConGradeStru->wGrade;
	}	
	
	if((0xffff != fistGradeID)&&(0xffff != secondGradeID)&&
		(secondGradeID != fistGrade->wTmnlJointMainGradeId)&&(secondGradeID != fistGrade->wTmnlJointSideGradeId))
	{
	    /*入口参数异常，查询失败*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*
	用后一个坡度的坡度值减去前一个坡度的坡度值
	结果为正：坡度值增加
	结果为负：坡度值减少
	结果为零：坡度值不变化
	*/

	if (signedSecondGrade-signedFirstGrade > 0)
	{
		*GradeTrend = 2;
		bReturnValue = 1;
		return bReturnValue;
	}
	else if (signedSecondGrade-signedFirstGrade < 0)
	{
		*GradeTrend = 1;
		bReturnValue = 1;
		return bReturnValue;
	}
	else
	{
		*GradeTrend = 0;
		bReturnValue = 1;
		return bReturnValue;
	}

}

/*
函数功能：获取前面的坡度
输入参数：UINT16 linkId,当前link
输出参数：gradeFrnt 坡度 
			Null：  线路终点或前面坡度为统一坡度  
			非Null：前面坡度在坡度表中可查
  返回值：0失败 1成功 2线路终点
*/
UINT8 dsuGetGradeFrntExp_FAO(DSU_EMAP_STRU *pDsuEmapStru,UINT16 linkId, DSU_GRADE_STRU** gradeFrnt)
{	
	UINT16 GradeIDOrg = 0;					/*记录前面坡度的ID*/
	UINT16 GradeID = 0;						/*记录当前坡度的ID*/
	UINT8  bReturnValue = 0;				/*函数返回值*/
	DSU_LINK_STRU *pLinkStru=NULL;				/*Link信息结构体指针*/
	DSU_LINK_STRU *pLinkStruOrg=NULL;       		/*link的临时变量*/
	DSU_GRADE_STRU* gradeFrntTmp=NULL;			/*临时坡度变量*/
	UINT16 i = 0;							/*循环计数变量*/
	UINT8 RstGetOrg = 0;					/*查询前面坡度Id返回值*/
	UINT8 RstGetCur = 0;					/*查询当前坡度Id返回值*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != gradeFrnt))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
	}

	/*判断入口数据起点Link的有效性*/
	if(( 0 != bReturnValue) && (linkId>LINKINDEXNUM)||(dsuLinkIndex[linkId] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*若当前link位置相邻的link在坡度表中可以查询到,则获取对应数据行;*/	
	pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[linkId];

	for(i=0;i<dsuDataLenStru->wLinkLen;i++)
	{
		if(0xffff != pLinkStru->wOrgnJointMainLkId)
		{
			pLinkStruOrg = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[pLinkStru->wOrgnJointMainLkId];

			/*若相邻link的坡度不为统一坡度*/
			if(0 == pLinkStruOrg->wGrade)
			{
				/*查询起点关联link对应的坡度ID*/
				RstGetOrg = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStruOrg->wId, pLinkStruOrg->dwLength, &GradeIDOrg);

				/*查询当前link对应的坡度ID*/
				RstGetCur = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStru->wId, 0, &GradeID);

				if((0 == RstGetOrg)||(0 == RstGetCur))
				{
					/*查询失败*/
					bReturnValue = 0;
					return bReturnValue;
				}

				/*相邻link与当前link的坡度ID不同*/
				if(GradeIDOrg != GradeID)
				{	
					if(0xffff != GradeIDOrg)
					{				
						/*初始化前面相邻坡度*/
						gradeFrntTmp = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[GradeIDOrg];
						*gradeFrnt = gradeFrntTmp;
						bReturnValue = 1;
						return bReturnValue;
					}
					else
					{
						/*数据出错(link表中不为统一坡度,查询得到为统一坡度)*/
						bReturnValue = 0;
						return bReturnValue;
					}
				}
				else
				{
					pLinkStru = pLinkStruOrg;
				}
			}
			else
			{
				/*若相邻link的坡度仍为统一坡度*/
				*gradeFrnt = NULL;
				bReturnValue = 1;
				return bReturnValue;
			}
		}
		else
		{
			/*若当前link无相邻link则为线路终点,起点设为无效值*/
			*gradeFrnt = NULL;
			bReturnValue = 2;
			return bReturnValue;
		}
	}

	/*若循环完成未能找到对应坡度ID*/
	if(i == dsuDataLenStru->wLinkLen)
	{
		*gradeFrnt = NULL;
		bReturnValue = 0;
		return bReturnValue;
	}
}

UINT8 dsuGetGradeFrntExp_CPK(DSU_EMAP_STRU *pDsuEmapStru,UINT16 linkId, DSU_GRADE_STRU** gradeFrnt)
{	
	UINT16 GradeIDOrg = 0;					/*记录前面坡度的ID*/
	UINT16 GradeID = 0;						/*记录当前坡度的ID*/
	UINT8  bReturnValue = 0;				/*函数返回值*/
	DSU_LINK_STRU *pLinkStru=NULL;				/*Link信息结构体指针*/
	DSU_LINK_STRU *pLinkStruOrg=NULL;       		/*link的临时变量*/
	DSU_GRADE_STRU* gradeFrntTmp=NULL;			/*临时坡度变量*/
	UINT16 i = 0;							/*循环计数变量*/
	UINT8 RstGetOrg = 0;					/*查询前面坡度Id返回值*/
	UINT8 RstGetCur = 0;					/*查询当前坡度Id返回值*/
	
	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != gradeFrnt))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据起点Link的有效性*/
	if((linkId>LINKINDEXNUM)||(dsuLinkIndex[linkId] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	
	/*若当前link位置相邻的link在坡度表中可以查询到,则获取对应数据行;*/	
	pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[linkId];
	
	for(i=0;i<dsuDataLenStru->wLinkLen;i++)
	{
		if(0xffff != pLinkStru->wOrgnJointMainLkId)
		{
			pLinkStruOrg = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[pLinkStru->wOrgnJointMainLkId];
			
			/*若相邻link的坡度不为统一坡度*/
			if(0 == pLinkStruOrg->wGrade)
			{
				/*查询起点关联link对应的坡度ID*/
				RstGetOrg = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStruOrg->wId, pLinkStruOrg->dwLength, &GradeIDOrg);
				
				/*查询当前link对应的坡度ID*/
				RstGetCur = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStru->wId, 0, &GradeID);
				
				if((0 == RstGetOrg)||(0 == RstGetCur))
				{
					/*查询失败*/
					bReturnValue = 0;
					return bReturnValue;
				}
				
				/*相邻link与当前link的坡度ID不同*/
				if(GradeIDOrg != GradeID)
				{	
					if(0xffff != GradeIDOrg)
					{				
						/*初始化前面相邻坡度*/
						gradeFrntTmp = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[GradeIDOrg];
						*gradeFrnt = gradeFrntTmp;
						bReturnValue = 1;
						return bReturnValue;
					}
					else
					{
						/*数据出错(link表中不为统一坡度,查询得到为统一坡度)*/
						bReturnValue = 0;
						return bReturnValue;
					}
				}
				else
				{
					pLinkStru = pLinkStruOrg;
				}
			}
			else
			{
				/*若相邻link的坡度仍为统一坡度*/
				*gradeFrnt = NULL;
				bReturnValue = 1;
				return bReturnValue;
			}
		}
		else
		{
			/*若当前link无相邻link则为线路终点,起点设为无效值*/
			*gradeFrnt = NULL;
			bReturnValue = 2;
			return bReturnValue;
		}
	}
	
	/*若循环完成未能找到对应坡度ID*/
	if(i == dsuDataLenStru->wLinkLen)
	{
		*gradeFrnt = NULL;
		bReturnValue = 0;
		return bReturnValue;
	}
	else
	{
		/*不可达分支*/
		bReturnValue=0U;
		return bReturnValue;
	}
}
/*访问接口*/
/*备注：增加对单轨项目标识的处理，modify by qxt 20170726*/
UINT8 dsuGetGradeFrntExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 linkId, DSU_GRADE_STRU **gradeFrnt)
{
	UINT8 rtnValue = 0U;/*函数返回值*/
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if (DQU_CBTC_FAO == cbtcVersionType)
	{
		rtnValue=dsuGetGradeFrntExp_FAO(pDsuEmapStru,linkId, gradeFrnt);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType) || ( DQU_CBTC_HLT == cbtcVersionType) ||(DQU_CBTC_DG == cbtcVersionType))
	{
		rtnValue=dsuGetGradeFrntExp_CPK(pDsuEmapStru,linkId, gradeFrnt);
	}
	else
	{
		rtnValue = 0U;
	}
	return rtnValue; 
}

/*
函数功能：获取后面的坡度
输入参数：UINT16 linkId,当前link
输出参数：gradeRear 坡度 
			Null：  线路终点或后面坡度为统一坡度  
			非Null：后面坡度在坡度表中可查
  返回值：0失败 1成功 2线路终点
*/
UINT8 dsuGetGradeRearExp_FAO(DSU_EMAP_STRU *pDsuEmapStru,UINT16 linkId, DSU_GRADE_STRU** gradeRear)
{
	UINT16 GradeIDNxt = 0;					/*记录后面坡度的ID*/
	UINT16 GradeID = 0;						/*记录当前坡度的ID*/
	UINT8  bReturnValue = 0;				/*函数返回值*/
	DSU_LINK_STRU* pLinkStru=NULL;				/*Link信息结构体指针*/
	DSU_LINK_STRU* pLinkStruNxt=NULL;			/*link的临时变量*/
	DSU_GRADE_STRU* gradeRearTmp=NULL;			/*坡度临时变量*/
	UINT16 i = 0;							/*循环计数变量*/
	UINT8 RstGetNxt = 0;					/*查询前面坡度Id返回值*/
	UINT8 RstGetCur = 0;					/*查询当前坡度Id返回值*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != gradeRear))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据起点Link的有效性*/
	if((linkId>LINKINDEXNUM)||(dsuLinkIndex[linkId] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*若当前link位置相邻的link在坡度表中可以查询到,则获取对应数据行;*/	
	pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[linkId];

	for(i=0;i<dsuDataLenStru->wLinkLen;i++)
	{
		if(0xffff != pLinkStru->wTmnlJointMainLkId)
		{
			pLinkStruNxt = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[pLinkStru->wTmnlJointMainLkId];

			/*若相邻link的坡度不为统一坡度*/
			if(0 == pLinkStruNxt->wGrade)
			{
				/*查询起点关联link对应的坡度ID*/
				RstGetNxt = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStruNxt->wId, 0, &GradeIDNxt);

				/*查询当前link对应的坡度ID*/
				RstGetCur = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStru->wId, pLinkStru->dwLength, &GradeID);

				if((0 == RstGetNxt)||(0 == RstGetCur))
				{
					/*查询失败*/
					bReturnValue = 0;
					return bReturnValue;
				}

				/*相邻link与当前link的坡度ID不同*/
				if(GradeIDNxt != GradeID)
				{
					if(0xffff != GradeIDNxt)
					{
						/*初始化后面相邻坡度*/
						gradeRearTmp = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[GradeIDNxt];
						*gradeRear = gradeRearTmp;
						bReturnValue = 1;
						return bReturnValue;
					}
					else
					{
						/*则数据出错(link表中不为统一坡度,查询得到为统一坡度)*/
						bReturnValue = 0;
						return bReturnValue;
					}
				}
				else
				{
					pLinkStru = pLinkStruNxt;
				}
			}
			else
			{
				/*若相邻link的坡度仍为统一坡度*/
				*gradeRear = NULL;
				bReturnValue = 1;
				return bReturnValue;
			}
		}
		else
		{
			/*若当前link无相邻link则为线路终点*/
			*gradeRear = NULL;
			bReturnValue = 2;
			return bReturnValue;
		}
	}

	/*若循环完成未能找到对应坡度ID*/
	if(i == dsuDataLenStru->wLinkLen)
	{
		*gradeRear = NULL;
		bReturnValue = 0;
	}
	return bReturnValue;
}

UINT8 dsuGetGradeRearExp_CPK(DSU_EMAP_STRU *pDsuEmapStru,UINT16 linkId, DSU_GRADE_STRU** gradeRear)
{
	UINT16 GradeIDNxt = 0;					/*记录后面坡度的ID*/
	UINT16 GradeID = 0;						/*记录当前坡度的ID*/
	UINT8  bReturnValue = 0;				/*函数返回值*/
	DSU_LINK_STRU* pLinkStru=NULL;				/*Link信息结构体指针*/
	DSU_LINK_STRU* pLinkStruNxt=NULL;			/*link的临时变量*/
	DSU_GRADE_STRU* gradeRearTmp=NULL;			/*坡度临时变量*/
	UINT16 i = 0;							/*循环计数变量*/
	UINT8 RstGetNxt = 0;					/*查询前面坡度Id返回值*/
	UINT8 RstGetCur = 0;					/*查询当前坡度Id返回值*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuLinkIndex=NULL;
	UINT16* dsuGradeIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	if ((NULL != pDsuEmapStru) && (NULL != gradeRear))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex=pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuGradeIndex=pDsuEmapStru->dsuEmapIndexStru->dsuGradeIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
		dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		bReturnValue = 0;
		return bReturnValue;
	}

	/*判断入口数据起点Link的有效性*/
	if((linkId>LINKINDEXNUM)||(dsuLinkIndex[linkId] == 0xFFFF))
	{
		/*入口数据无效，数据异常，查询失败，返回错误*/
		bReturnValue = 0;
		return bReturnValue;
	}
	
	/*若当前link位置相邻的link在坡度表中可以查询到,则获取对应数据行;*/	
	pLinkStru = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[linkId];
	
	for(i=0;i<dsuDataLenStru->wLinkLen;i++)
	{
		if(0xffff != pLinkStru->wTmnlJointMainLkId)
		{
			pLinkStruNxt = dsuStaticHeadStru->pLinkStru + dsuLinkIndex[pLinkStru->wTmnlJointMainLkId];
			
			/*若相邻link的坡度不为统一坡度*/
			if(0 == pLinkStruNxt->wGrade)
			{
				/*查询起点关联link对应的坡度ID*/
				RstGetNxt = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStruNxt->wId, 0, &GradeIDNxt);

				/*查询当前link对应的坡度ID*/
				RstGetCur = dsuGetGradeIdbyLocExp(pDsuEmapStru,pLinkStru->wId, pLinkStru->dwLength, &GradeID);
				
				if((0 == RstGetNxt)||(0 == RstGetCur))
				{
					/*查询失败*/
					bReturnValue = 0;
					return bReturnValue;
				}
				
				/*相邻link与当前link的坡度ID不同*/
				if(GradeIDNxt != GradeID)
				{
					if(0xffff != GradeIDNxt)
					{
						/*初始化后面相邻坡度*/
						gradeRearTmp = dsuStaticHeadStru->pGradeStru + dsuGradeIndex[GradeIDNxt];
						*gradeRear = gradeRearTmp;
						bReturnValue = 1;
						return bReturnValue;
					}
					else
					{
						/*则数据出错(link表中不为统一坡度,查询得到为统一坡度)*/
						bReturnValue = 0;
						return bReturnValue;
					}
				}
				else
				{
					pLinkStru = pLinkStruNxt;
				}
			}
			else
			{
				/*若相邻link的坡度仍为统一坡度*/
				*gradeRear = NULL;
				bReturnValue = 1;
				return bReturnValue;
			}
		}
		else
		{
			/*若当前link无相邻link则为线路终点*/
			*gradeRear = NULL;
			bReturnValue = 2;
			return bReturnValue;
		}
	}

	/*若循环完成未能找到对应坡度ID*/
	if(i == dsuDataLenStru->wLinkLen)
	{
		*gradeRear = NULL;
		bReturnValue = 0;
		return bReturnValue;
	}
	else
	{
		/*不可达分支*/
		bReturnValue=0U;
		return bReturnValue;
	}
}
/*访问接口*/
/*备注：增加对单轨项目标识的处理，modify by qxt 20170726*/
UINT8 dsuGetGradeRearExp(DSU_EMAP_STRU *pDsuEmapStru,UINT16 linkId, DSU_GRADE_STRU **gradeRear)
{
	UINT8 rtnValue = 0U;
	UINT8 cbtcVersionType=0U;
	cbtcVersionType=GetCbtcSysType();

	if (DQU_CBTC_FAO == cbtcVersionType)
	{
		rtnValue=dsuGetGradeRearExp_FAO(pDsuEmapStru,linkId, gradeRear);
	} 
	else if ((DQU_CBTC_CPK == cbtcVersionType)||(DQU_CBTC_HLT == cbtcVersionType)||(DQU_CBTC_DG == cbtcVersionType) )
	{
		rtnValue=dsuGetGradeRearExp_CPK(pDsuEmapStru,linkId, gradeRear);
	}
	else
	{
		rtnValue = 0U;
	}
	return rtnValue; 
}

/**
函数功能：获取当前LINK的静态限速个数
输入参数：
@linkId：当前link
输出参数：无
返回值：静态限速个数
*/
UINT8 GetStcLmtSpdCntByLnkIdExp(DSU_EMAP_STRU *pDsuEmapStru,DSU_STC_LIMIT_LINKIDX_STRU *pDsuLimitStcLinkIdx,const UINT16 linkId)
{
	UINT8 ret = 0;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM=0U;
	if ((NULL != pDsuEmapStru) && (NULL !=pDsuLimitStcLinkIdx))
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
	}
	else
	{
		/*电子地图数据指针为空*/
		ret = 0;
	}

	if(linkId <= LINKINDEXNUM)
	{
		if (pDsuLimitStcLinkIdx[linkId].linkId == linkId)
		{
		    /*返回linkId对应静态限速表的限速个数*/
			ret = pDsuLimitStcLinkIdx[linkId].limitStcSpdInfoCount;
		}
		else
		{
			ret = 0;
		}
		
	}
	else
	{
		ret = 0;
	}

	return ret;
}

/**
函数功能：获取制定LINK的的指定下标的静态临时限速的对象指针
输入参数：
@linkId：当前Link编号
@idx：对应Link的第几个限速，下标取值范围0-9
返回值：
@NULL：获取失败 
@非空：对应限速结构体指针
*/
DSU_STATIC_RES_SPEED_STRU *GetStcLmtSpdInfoByLnkIdExp(DSU_EMAP_STRU *pDsuEmapStru,DSU_STC_LIMIT_LINKIDX_STRU *pDsuLimitStcLinkIdx,const UINT16 linkId,const UINT8 idx)
{
	DSU_STATIC_RES_SPEED_STRU *pStcLmtSpdInfo = NULL;

	UINT16 LINKINDEXNUM=0U;
	UINT16* dsuStaticResSpeedIndex=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ( (NULL != pDsuEmapStru) && (NULL != pDsuLimitStcLinkIdx) )
	{
		LINKINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuStaticResSpeedIndex=pDsuEmapStru->dsuEmapIndexStru->dsuStaticResSpeedIndex;
		dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;
	}
	else
	{
		/*电子地图数据指针为空*/
		pStcLmtSpdInfo = NULL;
	}

	if ((idx >= LINK_MAX_LIMIT_SPD) || (idx < 0))
	{
		return pStcLmtSpdInfo;
	}
	if(linkId <= LINKINDEXNUM)
	{
		if(idx < pDsuLimitStcLinkIdx[linkId].limitStcSpdInfoCount)
		{
			/*将linkId对应静态限速表的第idx静态限速取出来*/
			pStcLmtSpdInfo = dsuStaticHeadStru->pStaticResSpeedStru + dsuStaticResSpeedIndex[pDsuLimitStcLinkIdx[linkId].limitStcSpdInfoIdBuf[idx]];
		}
	}
	else
	{
		pStcLmtSpdInfo = NULL;
	}

	return pStcLmtSpdInfo;
}

/*
函数功能：将多开道岔转为虚拟道岔
输入参数：multiPointId 多开道岔编号
          multiPointState 多开道岔状态

输出参数：wVirtualPointIds 拆分后虚拟道岔编号 
          wVirtualPointStates 拆分后虚拟道岔状态
返回值：返回值：拆分后虚拟道岔个数, 0失败  

函数算法：多开道岔包含的虚拟道岔： N位，R1位，L1位，R2位，L2位
            所对应在数组中的索引： 0，  1，   2，   3，   4
		    所对应的多开道岔状态： 1，  2，   3，   4，   5
		   因此当 索引=多开道岔状态multiPointState-1 时，所对应的虚拟道岔保持原值，其余虚拟道岔状态取反（定位<=>反位）

注意事项：输出参数虚拟道岔wVirtualPointIds和状态wVirtualPointStates，对于无效道岔其道岔状态设置为3。如
         
		               / L                                      / L
		              /                                        /
		             /                                        /       101                
		-|------------------------         ===》   ---|------/----------------- N      
		   1         \           N                          102       \
		              \                                                \
					   \                                                \
		              R                                                 R
		           图1.实体三开道岔                            图2.虚拟单开道岔

		   当图1实体三开道岔1的状态为3时，推出图2虚拟单开道岔为L位。此时101为无效道岔，输出其状态为3，返回值道岔个数为2，如下
		   wVirtualPointIds[0]=102;
		   wVirtualPointStates[0]=2;
		   wVirtualPointIds[1]=101;
		   wVirtualPointStates[1]=3;
author:单轨项目 add by qxt 20170622
*/
UINT8 ConvertToVirtualSwitchesExp(DSU_EMAP_STRU *pDsuEmapStru,const UINT16 multiPointId,const UINT8 multiPointState,UINT16 wVirtualPointIds[MAX_VIRTUAL_SWITCH_NUM],UINT8 wVirtualPointStates[MAX_VIRTUAL_SWITCH_NUM])
{
	UINT8 chReturnValue = 0;/*函数返回值*/
	UINT16 i = 0,j=0,k=0;          /*循环用变量*/
	DSU_MULTI_SWITCH_STRU* pMultiPointStru=NULL; /*多开道岔临时变量结结构体*/

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 MULTIPOINTINDEXNUM=0U;
	UINT16 *dsuMultiPointIndex=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
    DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;
	if ((NULL != wVirtualPointIds) && (NULL != wVirtualPointStates))
	{
		/*输出参数初始化为无效值65535*/
		for (i = 0; i < MAX_VIRTUAL_SWITCH_NUM; i++)
		{
			wVirtualPointIds[i] = DSU_NULL_16;
			wVirtualPointStates[i] = DSU_NULL_8;
		}

		if ((NULL != pDsuEmapStru)&&(NULL!=pDsuEmapStru->dsuEmapIndexStru))
		{
			MULTIPOINTINDEXNUM=pDsuEmapStru->dsuEmapIndexStru->MULTIPOINTINDEXNUM;
			dsuMultiPointIndex=pDsuEmapStru->dsuEmapIndexStru->dsuMultiPointIndex;
			dsuDataLenStru=pDsuEmapStru->dsuDataLenStru;
			dsuStaticHeadStru=pDsuEmapStru->dsuStaticHeadStru;

			/*判断入口数据输入的有效性*/
			if ((multiPointId <= MULTIPOINTINDEXNUM) && (dsuMultiPointIndex[multiPointId] != DSU_NULL_16) && (multiPointState <= MAX_VIRTUAL_SWITCH_NUM) && (multiPointState >= 1))
			{
				/*遍历多开道岔表*/
				for (j = 0; j < dsuDataLenStru->wMultiPointLen; j++)
				{
					pMultiPointStru = dsuStaticHeadStru->pMultiPointStru + j;
					if ((pMultiPointStru->wId == multiPointId) && (multiPointState <= pMultiPointStru->wType))
					{
						/*当多开道岔状态是1时，需单独处理，因为N位道岔和R1位道岔属于同一道岔,为防止输出两个相同道岔，遍历虚拟道岔时，数组索引应从1开始*/
						if (1 == multiPointState)
						{
							for (k = 1; k < pMultiPointStru->wType; k++)
							{
								/*虚拟道岔编号赋值*/
								wVirtualPointIds[k - 1] = pMultiPointStru->wSwitchIds[k];
								/*虚拟道岔状态赋值，虚拟道岔状态只与N位相同，其他位道岔状态均取反(2=>1;1=>2*/
								wVirtualPointStates[k - 1] = 0x03 & ~pMultiPointStru->wSwitchStates[k];
							}
						}
						else
						{

							for (k = 1; k < pMultiPointStru->wType; k++)
							{
								/*虚拟道岔编号赋值*/
								wVirtualPointIds[k - 1] = pMultiPointStru->wSwitchIds[k];
								/*虚拟道岔状态赋值*/
								if (k == (multiPointState - 1))
								{
									wVirtualPointStates[k - 1] = pMultiPointStru->wSwitchStates[k];
								}
								/*索引在multiPointState-1之前的虚拟道岔均为无效的*/
								else if (k < (multiPointState - 1))
								{
									wVirtualPointStates[k - 1] = EMAP_POINT_STATUS_LOSE;
								}
								/*索引在multiPointState-1之后的虚拟道岔状态置反*/
								else
								{
									/*道岔状态取反(2=>1;1=>2)*/
									wVirtualPointStates[k - 1] = 0x03 & ~pMultiPointStru->wSwitchStates[k];

								}

							}

						}

						chReturnValue = pMultiPointStru->wType - 1;
					}
				}
			}
			else
			{
				/*入口参数异常，查询失败*/
				chReturnValue = 0;

			}
		}
		else
		{
			/*电子地图数据指针为空*/
			chReturnValue = 0;
		}
	}
	else
	{
		/*虚拟道岔数组指针为空*/
		chReturnValue = 0;
	}
	return chReturnValue;

}

/*
函数功能：将虚拟道岔转为多开道岔
输入参数：wVirtualPointIds[] 虚拟道岔编号 
          wVirtualPointStates[] 虚拟道岔状态
		  wVirtualPointNum    虚拟道岔数量
输出参数：multiPointId 对应多开道岔编号
          multiPointState 对应多开道岔状态
返回值：0失败 1成功

注意事项：输入参数虚拟道岔wVirtualPointIds和状态wVirtualPointStates，对于无效的虚拟道岔，不需要传入。如
           
		 		      /L                                                 L
		             /                                                /
		            /                                                /
		           /                                                /
		---|------/-----------\------ N      =====>        ------------------ N
		          1          2 \                                    \
							    \                                    \
		                          R                                      R
		         图1.虚拟单开道岔                             图2.实体三开道岔
		 
		 当图1虚拟道岔编号1的状态为2时，推出图2多开道岔的状态为L位。此时图一虚拟道岔2为无效的，其输入参数可设置为如下：
         wVirtualPointIds[0]=1;
		 wVirtualPointStates[0]=2;
         wVirtualPointNum=1;
author:单轨项目 add by qxt 20170622
*/
UINT8 ConvertToMultiSwitchExp(DSU_EMAP_STRU *pDsuEmapStru,const UINT16 wVirtualPointIds[MAX_VIRTUAL_SWITCH_NUM],const UINT8 wVirtualPointStates[MAX_VIRTUAL_SWITCH_NUM],const UINT8 wVirtualPointNum,UINT16 *multiPointId,UINT8 *multiPointState)
{
	UINT8 chReturnValue = 0;      /*函数返回值*/
	UINT16 i= 0,j=0,k=0;          /*循环用变量*/
	UINT8 IdCount=0U;              /* 用于计数，输入参数虚拟道岔编号与表中道岔编号相等的个数。*/
	UINT8 StateCount=0U;            /*虚拟道岔状态相等的个数，有且只能有一个*/
	UINT8 tempPointState=0U;        /*多开道岔状态*/ 
	DSU_MULTI_SWITCH_STRU *pMultiPointStru=NULL; /*多开道岔临时变量结结构体*/
	/*全局变量改传参调用涉及的全局变量*/
	UINT16 *dsuMultiPointIndex=NULL;
	DSU_DATA_LEN_STRU *dsuDataLenStru=NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru=NULL;

	if ((NULL == multiPointId) || (NULL == multiPointState)
		|| (NULL == wVirtualPointIds) || (NULL == wVirtualPointStates))
	{
		/*多开道岔指针为空或虚拟道岔数组指针为空*/
		chReturnValue = 0;
	}
	else
	{
		/*输出参数初始化为无效值*/
		*multiPointId = DSU_NULL_16;
		*multiPointState = DSU_NULL_8;

		if ((NULL != pDsuEmapStru) && (NULL != pDsuEmapStru->dsuEmapIndexStru))
		{
			dsuMultiPointIndex = pDsuEmapStru->dsuEmapIndexStru->dsuMultiPointIndex;
			dsuDataLenStru = pDsuEmapStru->dsuDataLenStru;
			dsuStaticHeadStru = pDsuEmapStru->dsuStaticHeadStru;

			/*判断入口数据输入的有效性*/
			if (wVirtualPointNum <= MAX_VIRTUAL_SWITCH_NUM)
			{
				/*遍历多开道岔表*/
				for (i = 0; i < dsuDataLenStru->wMultiPointLen; i++)
				{
					IdCount = 0;
					StateCount = 0;
					pMultiPointStru = dsuStaticHeadStru->pMultiPointStru + i;

					for (k = 0; k < wVirtualPointNum; k++)
					{
						for (j = 0; j < pMultiPointStru->wType; j++)
						{
							if (wVirtualPointIds[k] == pMultiPointStru->wSwitchIds[j])
							{
								IdCount++;
								if (wVirtualPointStates[k] == pMultiPointStru->wSwitchStates[j])
								{
									tempPointState = j; /*多开道岔的状态=该虚拟道岔索引值+1*/

									StateCount++;  /*虚拟道岔状态相等的个数只能有一个，*/
								}
							}
						}

					}
					/*找到所对应的多开道岔满足的条件：
					①当输入的道岔有N位（也是R1位）的道岔时，找到的相等的虚拟道岔数量IdCount等于输入参数虚拟道岔数量wVirtualPointNum+1。（因为N位和R位是相同道岔编号，遍历时会多计一次）；
					  当输入的道岔没有N位（也是R1位）的道岔时，找到的相等的虚拟道岔数量IdCount等于输入参数虚拟道岔数量wVirtualPointNum。
					②输入参数道岔状态和表中虚拟道岔状态相等的个数只能有一个，即StateCount=1
					*/
					if (((wVirtualPointNum == IdCount) || (wVirtualPointNum + 1 == IdCount)) && (1 == StateCount))
					{
						*multiPointId = pMultiPointStru->wId;  /*多开道岔编号*/
						*multiPointState = tempPointState + 1;    /*多开道岔状态(索引值+1)*/
						chReturnValue = 1;
						break;
					}
				}

			}
			else
			{
				/*入口参数异常，查询失败*/
				chReturnValue = 0;
			}
		}
		else
		{
			/*电子地图数据指针为空*/
			chReturnValue = 0;
		}
	}
	return chReturnValue;


}

/**********************************************************************************************
*函数功能:根据既有的路径终点link查找下一个link，若遇到道岔分支则添加为新路径(车车新增接口)
*输入参数:		pDsuEmapStru		数据
*				szLinkQueryDir      link查询方向
*				pPathNum			路径数量
*				szPath				路径数据
*				szLinkNum			每条路径的长度
*输出参数:		pPathNum			路径数量
*				szPath				路径数据
*				szLinkNum			每条路径的长度              
*               cLinkDirChangedNum  link方向变化点个数
*返回值:0:失败 1:查询成功，且各路径未到终点 2：查询成功，且各路径到达终点
*备注： add by lxc 2021-2-28
*修改：by yt 2021年9月11日 删除冗余变量
**********************************************************************************************/
UINT8 dsuPathEndNextLinkExp(DSU_EMAP_STRU *pDsuEmapStru, UINT8 szLinkQueryDir[50], UINT8* pPathNum, UINT16 szPath[50][50], UINT16 szLinkNum[50])
{
	UINT8 cRetVal = 0U;

	/* 用于承接输入数据 */
	UINT8 cPathNum = 0U;

	/* 临时变量 */
	UINT8 i = 0U;
	UINT16 j = 0U;
	UINT8 cTmpPathNum = 0U;
	UINT16 wTmpEndLinkId = 0U;
	UINT16 wTmpEndLinkIndex = 0U;
	DSU_LINK_STRU *pTmpEndLinkStru = NULL;   /*当前Link,获取本地数据使用*/
	UINT8 cFunFlag = 0U;				/* 为0时延申当前路径，为1时延申当前路径并开辟新路径 */
	UINT16 wTmpNextMainLinkId = 0U;	/* 下一段正线link */
	UINT16 wTmpNextSideLinkId = 0U;	/* 下一段侧线link */
	UINT16 wAddLinkId = 0U;
	UINT16 wNewLinkId = 0U;
	UINT16 wTmpPathLinkNum = 0U;
	UINT16 szTmpAddPath[25][50] = { 0U };
	UINT16 szTmpAddLinkNum[25] = { 0U };
	UINT16 wTmpEndPathNum = 0U;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM = 0;
	UINT16* pdsuLinkIndex = NULL;
	DSU_STATIC_HEAD_STRU *pdsuStaticHeadStru = NULL;

	UINT8 cMainQueryDir = 0U;  /*主线路径的查询方向*/
	UINT8 cSideQueryDir = 0U;  /*侧线路径的查询方向*/
	UINT8 cCurLinkDirChanged = LINK_DIRCHANGE_NONE;  /*当前Link方向变化点*/
	UINT8 cNxtLinkDirChanged = LINK_DIRCHANGE_NONE;  /*下一Link方向变化点*/
	UINT8 cTempPathIndex = 0U;

	/* 1.入参检查 */
	if ((NULL != pDsuEmapStru) && (NULL != szLinkQueryDir)
		&& (NULL != pPathNum) && (50U > *pPathNum) && (0U != *pPathNum)
		&& (NULL != szPath) && (NULL != szLinkNum))
	{
		for (i = 0U; i < 50U; i++)
		{
			/*方向检查*/
			if ((EMAP_SAME_DIR == szLinkQueryDir[i]) || (EMAP_CONVER_DIR == szLinkQueryDir[i]))
			{
				cRetVal = 1U;
			}
			else
			{
				cRetVal = 0U;
				break;
			}
		}

		/* 入参承接 */
		cPathNum = *pPathNum;

		/* 全局变量透传 */
		LINKINDEXNUM = pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		pdsuLinkIndex = pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		pdsuStaticHeadStru = pDsuEmapStru->dsuStaticHeadStru;
	}

	/* 2.查询所有路径最后一个link：
	*	1）值为0xff，证明路径已到线路终点，或存储数据空间不够，跳过本条路径继续查询下一条路径；
	*	2）沿查询方向上获取端点类型：
	*				a）若为终点记录终点为0xFF；
	*				b）若为计轴点则获取下一个link并延申该路径；
	*				c）若为道岔点且本link为汇合link，则路径分叉，根据定位link与反位link添加新路径；
	*				d）若为道岔点且本link为非汇合link，获取起点连接正线link并延申该路径；
	*/
	if (1u == cRetVal)
	{
		cTmpPathNum = 0u;
		for (i = 0u; i < cPathNum; i++)
		{
			wTmpEndLinkId = szPath[i][(szLinkNum[i] - 1U)];
			cMainQueryDir = szLinkQueryDir[i];
			cSideQueryDir = szLinkQueryDir[i];

			/* 1） */
			if (DSU_NULL_16 != wTmpEndLinkId)
			{	 
				cCurLinkDirChanged = pdsuStaticHeadStru->pLinkStru[pdsuLinkIndex[wTmpEndLinkId]].wLogicDirChanged;		/*获取当前link的方向变化点*/
				/*根据LinkID获取当前link结构体*/
				wTmpEndLinkIndex = pdsuLinkIndex[wTmpEndLinkId];
				pTmpEndLinkStru = pdsuStaticHeadStru->pLinkStru + wTmpEndLinkIndex;

				wTmpNextMainLinkId = DSU_NULL_16;
				wTmpNextSideLinkId = DSU_NULL_16;

				/* 获取查询方向上的端点类型,与查询方向上的下一个link */
				if (EMAP_SAME_DIR == cMainQueryDir)
				{
					wTmpNextMainLinkId = pTmpEndLinkStru->wTmnlJointMainLkId;
					wTmpNextSideLinkId = pTmpEndLinkStru->wTmnlJointSideLkId;
				}
				else
				{
					wTmpNextMainLinkId = pTmpEndLinkStru->wOrgnJointMainLkId;
					wTmpNextSideLinkId = pTmpEndLinkStru->wOrgnJointSideLkId;
				}

				/* 2） */
				cFunFlag = 0U;/* 路径需要延申 */
				wAddLinkId = wTmpNextMainLinkId;
				wNewLinkId = wTmpNextSideLinkId;

				if (DSU_NULL_16 != wNewLinkId)
				{
					cFunFlag = 1u;/* 需要新建路径 */
				}

				/*判断是否存在方向变化点*/


				/* 处理路径 */
				wTmpPathLinkNum = szLinkNum[i];

				/* 延申当前路径,判断当前路径link容量是否达到上限 */
				if (49u == szLinkNum[i])
				{
					/* 容量未达上限，但最后一个link只能存为终点 */
					szPath[i][wTmpPathLinkNum] = DSU_NULL_16;
					szLinkNum[i]++;
				}
				else
				{

					/* 可以延申 */
					szPath[i][wTmpPathLinkNum] = wAddLinkId;
					szLinkNum[i]++;

					if (DSU_NULL_16 != wAddLinkId)
					{
						/*判断是否存在方向变化点*/
						cNxtLinkDirChanged = pdsuStaticHeadStru->pLinkStru[pdsuLinkIndex[wAddLinkId]].wLogicDirChanged;
						if (((LINK_DIRCHANGE_BEGIN == cNxtLinkDirChanged) || (LINK_DIRCHANGE_END == cNxtLinkDirChanged))
							&& (cNxtLinkDirChanged == cCurLinkDirChanged))
						{
							/*存在方向变化点*/
							cMainQueryDir = ~cMainQueryDir;
						}
						else
						{
							/*不存在方向变化点，不处理*/
						}

						szLinkQueryDir[i] = cMainQueryDir;  /*存储此路径下的查询方向*/
					}
				}

				if (1u == cFunFlag)
				{
					/* 生成一条新路径 */
					/* 1.判断当前路径link容量是否达到上限 */
					if (49u == wTmpPathLinkNum)
					{
						/* 容量未达上限，但最后一个link只能存为终点，新开辟路径也没有意义 */
					}
					else
					{
						/* 2.判断路径数量是否达到上限 */
						if ((25u > cTmpPathNum) && (DSU_NULL_16 != wNewLinkId))
						{
							/*为新增路径添加查询方向*/
							cTempPathIndex = cTmpPathNum + cPathNum;  /*当前路径与新增路径总数索引*/
							if (50U > cTempPathIndex)
							{
								/*判断是否存在方向变化点*/
								cNxtLinkDirChanged = pdsuStaticHeadStru->pLinkStru[pdsuLinkIndex[wNewLinkId]].wLogicDirChanged;
								if (((LINK_DIRCHANGE_BEGIN == cNxtLinkDirChanged) || (LINK_DIRCHANGE_END == cNxtLinkDirChanged))
									&& (cNxtLinkDirChanged == cCurLinkDirChanged))
								{
									/*存在方向变化点*/
									cSideQueryDir = ~cSideQueryDir;
								}
								else
								{
									/*不存在方向变化点，不处理*/
								}
								szLinkQueryDir[cTempPathIndex] = cSideQueryDir;  /*存储新增路径下的查询方向*/
							}
							else
							{
								/*路径达到上限，不处理*/
							}

							/* 新增一条路径 */
							szTmpAddLinkNum[cTmpPathNum] = wTmpPathLinkNum;
							for (j = 0u; j < wTmpPathLinkNum; j++)
							{
								szTmpAddPath[cTmpPathNum][j] = szPath[i][j];
							}
							szTmpAddPath[cTmpPathNum][wTmpPathLinkNum] = wNewLinkId;
							szTmpAddLinkNum[cTmpPathNum]++;
							cTmpPathNum++;
						}
					}
				}
			}
			else
			{
				/* 记录查到终点的路径数量，用于判断每条路径是否都查到终点 */
				wTmpEndPathNum++;
			}
		}

		/* 拷贝路径，输出 */
		for (i = 0u; i < cTmpPathNum; i++)
		{
			if (cPathNum >= 50U)
			{
				/* 先判断是否超出路径容量 */
				break;
			}

			for (j = 0u; j < szTmpAddLinkNum[i]; j++)
			{
				szPath[cPathNum][j] = szTmpAddPath[i][j];
			}

			szLinkNum[cPathNum] = szTmpAddLinkNum[i];
			cPathNum++;
		}

		*pPathNum = cPathNum;
	}

	if ((1u == cRetVal) && (cPathNum == wTmpEndPathNum))
	{
		cRetVal = 2U;
	}

	return cRetVal;
}

/*********************************************************************************************
*函数功能:判断两个路径终点是否为同一link，若为同一link则输出这条路径(车车通信新增接口)
*输入参数: cPathANum A路径的数量
           szPathA A路径数据
           szLinkANum A路径的link数量
           cPathBNum B路径的数量
           szPathB B路径数据
           szLinkBNum B路径的link数量
		   cABPathDir A/B路径的查询方向
*输出参数: szPath 找到路径数据
           pPathLinkNum 找到路径数量
		   pLinkDirChangedNum link序列中的方向变化点数
*返回值:终点无相同link:0
终点存在相同link:1
*备注： add by lxc 2021-2-28
*********************************************************************************************/
UINT8 dsuPathSameEndLinkExp(UINT8 cPathANum, UINT16 szPathA[50][50], UINT16 szLinkANum[50], UINT8 cPathBNum
	, UINT16 szPathB[50][50], UINT16 szLinkBNum[50], UINT16 szPath[100], UINT16* pPathLinkNum, UINT8* pLinkDirChangedNum, UINT8 cABPathDir, DSU_EMAP_STRU *pDsuEmapStru)
{
	UINT8 retVal = 0U;
	UINT8 cKeepWorkFlag = 0U;
	UINT8 cFunCreatPathFlag = 0U;
	UINT8 i = 0U;
	UINT8 j = 0U;
	UINT16 x = 0U;

	UINT16 wTmpPathA1LinkNum = 0U;
	UINT16 wTmpPathB1LinkNum = 0U;
	UINT16 wTmpPathA2LinkNum = 0U;
	UINT16 wTmpPathB2LinkNum = 0U;

	UINT16 wTmpPathALinkNum = 0U;
	UINT16 wTmpPathBLinkNum = 0U;

	/* 最后一个link */
	UINT16 wTmpPathAEnd1LinkId = 0U;
	UINT16 wTmpPathBEnd1LinkId = 0U;

	/* 倒数第二个link */
	UINT16 wTmpPathAEnd2LinkId = 0U;
	UINT16 wTmpPathBEnd2LinkId = 0U;

	UINT16 wTmpPathLinkNum = 0U;
	UINT16 wTmpLinkIndex = 0U;

	UINT8 cCurLinkDirChanged = LINK_DIRCHANGE_NONE;  /*当前Link方向变化点*/
	UINT8 cNxtLinkDirChanged = LINK_DIRCHANGE_NONE;  /*下一Link方向变化点*/
	UINT8 cLinkDirChangedNum = 0U;  /*link序列方向变化点数量*/
	UINT8 cResiDue = 0U;

	if ((NULL == szPathA) || (NULL == szLinkANum) || (NULL == szPathB) || (NULL == szLinkBNum)
		|| (NULL == szPath) || (NULL == pPathLinkNum) || (NULL == pLinkDirChangedNum) 
		|| ((EMAP_PATH_SAME_DIR != cABPathDir) && (EMAP_PATH_CONVER_DIR != cABPathDir)))
	{
		;
	}
	else
	{
		cKeepWorkFlag = 1u;
	}

	if (1u == cKeepWorkFlag)
	{
		for (i = 0U; i < cPathANum; i++)
		{
			for (j = 0U; j < cPathBNum; j++)
			{
				wTmpPathA1LinkNum = szLinkANum[i] - 1u;
				wTmpPathA2LinkNum = szLinkANum[i] - 2U;

				wTmpPathB1LinkNum = szLinkBNum[j] - 1u;
				wTmpPathB2LinkNum = szLinkBNum[j] - 2U;

				wTmpPathAEnd1LinkId = szPathA[i][wTmpPathA1LinkNum];
				wTmpPathAEnd2LinkId = szPathA[i][wTmpPathA2LinkNum];

				wTmpPathBEnd1LinkId = szPathB[j][wTmpPathB1LinkNum];
				wTmpPathBEnd2LinkId = szPathB[j][wTmpPathB2LinkNum];

				/* 以下三种情况为查询到相交路径，但需要区别处理 */
				if ((wTmpPathAEnd1LinkId == wTmpPathBEnd1LinkId) && (DSU_NULL_16 != wTmpPathAEnd1LinkId))
				{
					wTmpPathALinkNum = wTmpPathA1LinkNum;
					wTmpPathBLinkNum = wTmpPathB1LinkNum;
					cFunCreatPathFlag = 1u;
				}
				else if (wTmpPathAEnd2LinkId == wTmpPathBEnd1LinkId)
				{
					wTmpPathALinkNum = wTmpPathA2LinkNum;
					wTmpPathBLinkNum = wTmpPathB1LinkNum;
					cFunCreatPathFlag = 1u;
				}
				else if (wTmpPathAEnd2LinkId == wTmpPathBEnd2LinkId)
				{
					wTmpPathALinkNum = wTmpPathA2LinkNum;
					wTmpPathBLinkNum = wTmpPathB2LinkNum;
					cFunCreatPathFlag = 1u;
				}
				else if (wTmpPathAEnd1LinkId == wTmpPathBEnd2LinkId)
				{
					wTmpPathALinkNum = wTmpPathA1LinkNum;
					wTmpPathBLinkNum = wTmpPathB2LinkNum;
					cFunCreatPathFlag = 1u;
				}
				else
				{
					/*do nothing*/
				}


				if (1u == cFunCreatPathFlag)
				{
					break;
				}
			}
			if (1u == cFunCreatPathFlag)
			{
				break;
			}
		}

		wTmpPathALinkNum++;
		wTmpPathBLinkNum++;
		if ((1u == cFunCreatPathFlag) && (100U >= (wTmpPathALinkNum + wTmpPathBLinkNum)))
		{

			/* 存储前半段路径,不存储最后一个link */
			wTmpPathALinkNum--;
			for (x = 0U; x < wTmpPathALinkNum; x++)
			{
				szPath[wTmpPathLinkNum] = szPathA[i][x];
				wTmpPathLinkNum++;
			}

			/* 存储后半段路径,不存储端点 */
			for (x = 0U; x < wTmpPathBLinkNum; x++)
			{
				wTmpLinkIndex = wTmpPathBLinkNum - x;
				wTmpLinkIndex--;
				szPath[wTmpPathLinkNum] = szPathB[j][wTmpLinkIndex];
				wTmpPathLinkNum++;
			}

			/*查找link序列中的方向变化点*/
			for (x = 0U; x < (wTmpPathLinkNum - 1U); x++)
			{
				if ((UINT16_MAX != szPath[x]) && (UINT16_MAX != szPath[x + 1U]))
				{
					cCurLinkDirChanged = pDsuEmapStru->dsuStaticHeadStru->pLinkStru[pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex[szPath[x]]].wLogicDirChanged;
					cNxtLinkDirChanged = pDsuEmapStru->dsuStaticHeadStru->pLinkStru[pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex[szPath[x + 1U]]].wLogicDirChanged;
					if (((LINK_DIRCHANGE_BEGIN == cNxtLinkDirChanged) || (LINK_DIRCHANGE_END == cNxtLinkDirChanged))
						&& (cNxtLinkDirChanged == cCurLinkDirChanged))
					{
						/*存在方向变化点*/
						cLinkDirChangedNum++;
					}
					else
					{
						/*不存在方向变化点，不处理*/
					}
				}
			}

			cResiDue = cLinkDirChangedNum % 2U;

			if (((0U == cResiDue) && (EMAP_PATH_CONVER_DIR == cABPathDir)) || ((0U != cResiDue) && (EMAP_PATH_SAME_DIR == cABPathDir)))
			{
				*pPathLinkNum = wTmpPathLinkNum;
				*pLinkDirChangedNum = cLinkDirChangedNum;
				retVal = 1;
			}
			else
			{
				/*查询失败，返回失败*/
			}
		}
	}

	return retVal;
}

/************************************************
*函数功能:查询AB两端之间的距离
*输入参数:		pDsuEmapStru 电子地图数据
*				pLODAStru	A点
*				pLODBStru	B点
*输出参数:		pLinkNum	输出路径的link数量
*				szLinkId	输出路径的linkId序列
*				pDir		输出A->B的方向
*               pLinkDirChangedNum  方向变化点数量
*返回值:失败:DSU_NULL_32
*		成功:距离
*备注： add by lxc 2021-2-28
************************************************/
UINT32 dsuLenByPointExp(DSU_EMAP_STRU *pDsuEmapStru, const LOD_STRU *pLODAStru, const LOD_STRU *pLODBStru, UINT16* pLinkNum, UINT16 szLinkId[100], UINT8 *pDir, UINT8* pLinkDirChangedNum)
{
	UINT32 reLen = DSU_NULL_32;
	UINT8 cFunRetVal = 0U;
	UINT8 cFun1RetVal = 0U;
	UINT8 cFun2RetVal = 0U;
	UINT8 cFun3RetVal = 0U;
	UINT8 cFun4RetVal = 0U;
	UINT8 cFun5RetVal = 0U;
	UINT8 cKeepWorkFlag = 0U;
	UINT16 dwCycle = 0U;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM = 0;
	UINT16* dsuLinkIndex = NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru = NULL;

	/* 两点沿两个方向上的所有路径数据 */
	UINT16 szSameDirPathA[50][50] = { 0U };
	UINT16 szPathASameDirLinkNum[50] = { 0U };
	UINT8 wPathASameDirNum = 0U;

	UINT16 szConverDirPathA[50][50] = { 0U };
	UINT16 szPathAConverDirLinkNum[50] = { 0U };
	UINT8 wPathAConverDirNum = 0U;

	UINT16 szSameDirPathB[50][50] = { 0U };
	UINT16 szPathBSameDirLinkNum[50] = { 0U };
	UINT8 wPathBSameDirNum = 0U;

	UINT16 szConverDirPathB[50][50] = { 0U };
	UINT16 szPathBConverDirLinkNum[50] = { 0U };
	UINT8 wPathBConverDirNum = 0U;

	/* 临时变量 */
	UINT16 i = 0U;
	UINT16 wTmpLinkId = 0U;
	UINT16 wTmpLinkIndex = 0U;
	DSU_LINK_STRU *pTmpLinkStru = NULL;
	UINT16 szOutputPath[100] = { 0U };
	UINT16 wOutputLinkNum = 0U;
	UINT32 wTmpLen = 0U;
	UINT8 cQueryADir = EMAP_SAME_DIR;
	UINT8 cQueryBDir = EMAP_SAME_DIR;

	UINT8 szASameQueryDir[50] = { 0U };     /*点A同向查询各路径的方向*/
	UINT8 szAConvertQueryDir[50] = { 0U };  /*点A反向查询各路径的方向*/
	UINT8 szBSameQueryDir[50] = { 0U };     /*点B同向查询各路径的方向*/
	UINT8 szBConvertQueryDir[50] = { 0U };  /*点B反向查询各路径的方向*/
	UINT8 cTmepDirChangedNum = 0U;   /*最终路径包含的方向变化点数量*/

	memset(szASameQueryDir, EMAP_SAME_DIR, sizeof(UINT8) * 50);
	memset(szAConvertQueryDir, EMAP_CONVER_DIR, sizeof(UINT8) * 50);
	memset(szBSameQueryDir, EMAP_SAME_DIR, sizeof(UINT8) * 50);
	memset(szBConvertQueryDir, EMAP_CONVER_DIR, sizeof(UINT8) * 50);

	if ((NULL != pLODAStru) && (NULL != pLODBStru) && (NULL != pDsuEmapStru) && (NULL != szLinkId)
		&& (NULL != pLinkNum) && (NULL != pDir) && (NULL != szLinkId) && (NULL != pDir)
		&& (0U != pLODAStru->Lnk) && (0U != pLODBStru->Lnk) && (NULL != pLinkDirChangedNum))
	{
		cKeepWorkFlag = 1u;
		*pLinkNum = 0U;
		*pDir = EMAP_SAME_DIR;

		/* 全局变量透传 */
		LINKINDEXNUM = pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex = pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru = pDsuEmapStru->dsuStaticHeadStru;
	}

	if (1u == cKeepWorkFlag)
	{
		if ((LINKINDEXNUM < pLODAStru->Lnk) || (LINKINDEXNUM < pLODBStru->Lnk))
		{
			cKeepWorkFlag = 0U;
		}
		else
		{
			/* 偏移量检查 */
			wTmpLinkId = pLODAStru->Lnk;
			wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
			pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
			if (pTmpLinkStru->dwLength < pLODAStru->Off)
			{
				cKeepWorkFlag = 0U;
			}

			wTmpLinkId = pLODBStru->Lnk;
			wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
			pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
			if (pTmpLinkStru->dwLength < pLODBStru->Off)
			{
				cKeepWorkFlag = 0U;
			}
		}
	}


	if (1u == cKeepWorkFlag)
	{
		if (pLODAStru->Lnk == pLODBStru->Lnk)
		{
			/* 两点在同一link */
			if (pLODAStru->Off > pLODBStru->Off)
			{
				cQueryADir = EMAP_CONVER_DIR;
				reLen = pLODAStru->Off - pLODBStru->Off;
			}
			else
			{
				cQueryADir = EMAP_SAME_DIR;
				reLen = pLODBStru->Off - pLODAStru->Off;
			}

			szLinkId[wOutputLinkNum] = pLODAStru->Lnk;
			wOutputLinkNum++;
			*pLinkDirChangedNum = 0U;
			*pLinkNum = wOutputLinkNum;
		}
		else
		{
			/* 两点不在同一link */
			/* 初始化路径 */
			szSameDirPathA[0][0] = pLODAStru->Lnk;
			szPathASameDirLinkNum[0] = 1u;
			wPathASameDirNum = 1u;

			szConverDirPathA[0][0] = pLODAStru->Lnk;
			szPathAConverDirLinkNum[0] = 1u;
			wPathAConverDirNum = 1u;

			szSameDirPathB[0][0] = pLODBStru->Lnk;
			szPathBSameDirLinkNum[0] = 1u;
			wPathBSameDirNum = 1u;

			szConverDirPathB[0][0] = pLODBStru->Lnk;
			szPathBConverDirLinkNum[0] = 1u;
			wPathBConverDirNum = 1u;

			cFunRetVal = 1u;
			cFun1RetVal = 1u;
			cFun2RetVal = 1u;
			cFun3RetVal = 1u;
			cFun4RetVal = 1u;

			dwCycle = 1u;
			while (1u == cFunRetVal)
			{
				cFunRetVal = 0U;

				/* 1.调用函数向，向两个点的两个方向分别查询下一个link，生成新的路径 */
				if (2U != cFun1RetVal)
				{
					cFun1RetVal = dsuPathEndNextLinkExp(pDsuEmapStru, szASameQueryDir, &wPathASameDirNum, szSameDirPathA, szPathASameDirLinkNum);
				}

				if (2U != cFun2RetVal)
				{
					cFun2RetVal = dsuPathEndNextLinkExp(pDsuEmapStru, szAConvertQueryDir, &wPathAConverDirNum, szConverDirPathA, szPathAConverDirLinkNum);
				}

				if (2U != cFun3RetVal)
				{
					cFun3RetVal = dsuPathEndNextLinkExp(pDsuEmapStru, szBSameQueryDir, &wPathBSameDirNum, szSameDirPathB, szPathBSameDirLinkNum);
				}

				if (2U != cFun4RetVal)
				{
					cFun4RetVal = dsuPathEndNextLinkExp(pDsuEmapStru, szBConvertQueryDir, &wPathBConverDirNum, szConverDirPathB, szPathBConverDirLinkNum);
				}

				if (((2U == cFun1RetVal) && (cFun1RetVal == cFun2RetVal) && (cFun2RetVal == cFun3RetVal) && (cFun3RetVal == cFun4RetVal))
					|| ((cFun1RetVal == 0U) || (cFun2RetVal == 0U) || (cFun3RetVal == 0U) || (cFun4RetVal == 0U)))
				{
					/* 都查询到了终点，或查询失败，退出循环 */
					cFunRetVal = 0U;
				}
				else
				{
					/* 存在新的路径或者路径未到终点 */
					cFunRetVal = 1u;
				}

				cFun5RetVal = 0U;
				/* 2.判断两个点的发散路径最后的link是否存在相交link,并输出路径 */
				if (1u == cFunRetVal)
				{
					cQueryADir = EMAP_SAME_DIR;
					cQueryBDir = EMAP_CONVER_DIR;
					cFun5RetVal = dsuPathSameEndLinkExp(wPathASameDirNum, szSameDirPathA, szPathASameDirLinkNum
						, wPathBConverDirNum, szConverDirPathB, szPathBConverDirLinkNum, szOutputPath, &wOutputLinkNum, &cTmepDirChangedNum, EMAP_PATH_CONVER_DIR, pDsuEmapStru);

					if (0U == cFun5RetVal)
					{
						cQueryADir = EMAP_CONVER_DIR;
						cQueryBDir = EMAP_SAME_DIR;
						cFun5RetVal = dsuPathSameEndLinkExp(wPathAConverDirNum, szConverDirPathA, szPathAConverDirLinkNum
							, wPathBSameDirNum, szSameDirPathB, szPathBSameDirLinkNum, szOutputPath, &wOutputLinkNum, &cTmepDirChangedNum, EMAP_PATH_CONVER_DIR, pDsuEmapStru);
					}
					if (0U == cFun5RetVal)
					{
						cQueryADir = EMAP_SAME_DIR;
						cQueryBDir = EMAP_SAME_DIR;
						cFun5RetVal = dsuPathSameEndLinkExp(wPathASameDirNum, szSameDirPathA, szPathASameDirLinkNum
							, wPathBSameDirNum, szSameDirPathB, szPathBSameDirLinkNum, szOutputPath, &wOutputLinkNum, &cTmepDirChangedNum, EMAP_PATH_SAME_DIR, pDsuEmapStru);
					}
					if (0U == cFun5RetVal)
					{
						cQueryADir = EMAP_CONVER_DIR;
						cQueryBDir = EMAP_CONVER_DIR;
						cFun5RetVal = dsuPathSameEndLinkExp(wPathAConverDirNum, szConverDirPathA, szPathAConverDirLinkNum
							, wPathBConverDirNum, szConverDirPathB, szPathBConverDirLinkNum, szOutputPath, &wOutputLinkNum, &cTmepDirChangedNum, EMAP_PATH_SAME_DIR, pDsuEmapStru);
					}
				}

				if ((1u == cFunRetVal) && (1u == cFun5RetVal))
				{
					/* 4.计算距离 */
					/* 查询到了一条路径，输出本条路径与距离,终止查询 */
					cFunRetVal = 0U;
					*pLinkNum = wOutputLinkNum;
					for (i = 0U; i < wOutputLinkNum; i++)
					{
						szLinkId[i] = szOutputPath[i];

						wTmpLinkId = szLinkId[i];
						wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
						pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;

						if ((wTmpLinkId != pLODAStru->Lnk) && (wTmpLinkId != pLODBStru->Lnk))
						{
							/* 累加距离 */
							wTmpLen += pTmpLinkStru->dwLength;
						}
					}

					wTmpLinkId = pLODAStru->Lnk;
					wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
					pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
					if (EMAP_SAME_DIR == cQueryADir)
					{
						wTmpLen += (pTmpLinkStru->dwLength - pLODAStru->Off);
					}
					else
					{
						wTmpLen += pLODAStru->Off;
					}

					wTmpLinkId = pLODBStru->Lnk;
					wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
					pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
					if (EMAP_SAME_DIR == cQueryBDir)
					{
						wTmpLen += (pTmpLinkStru->dwLength - pLODBStru->Off);
					}
					else
					{
						wTmpLen += pLODBStru->Off;
					}

					*pLinkDirChangedNum = cTmepDirChangedNum;  /*返回link序列中包含的方向变化点数量*/
					reLen = wTmpLen;
				}

				/* 只允许查询49次 */
				if (dwCycle >= 49u)
				{
					break;
				}
				dwCycle++;
			}
		}

		/* 输出方向 */
		*pDir = cQueryADir;
	}

	return reLen;
}


/**********************************************************************************************
*函数功能:根据既有的路径终点与道岔位置link查找下一个link(车车新增接口)
*输入参数:		pDsuEmapStru		数据
*				cDir				查询方向
*				szPath				路径数据
*				pLinkNum			路径的长度
*				wSwitchSum			道岔数量
*				pSwitchInfo			道岔状态
*输出参数:		szPath				路径数据
*				pLinkNum			路径的长度
*返回值:0:失败 1:查询成功，且各路径未到终点 2：查询成功，且各路径到达终点
*备注： add by lxc 2022-6-17
**********************************************************************************************/
UINT8 dsuPathEndNextLinkBySwitchStateExp(DSU_EMAP_STRU *pDsuEmapStru, UINT8 cDir, UINT16 szPath[50],UINT16 *pLinkNum, const UINT8 cSwitchSum, const DQU_POINT_STATUS_STRU *pSwitchInfo)
{
	UINT8 cRetVal = 0U;

	/* 临时变量 */
	UINT16 j = 0U;
	UINT16 wTmpEndLinkId = 0U;
	UINT8 cFunRetVal = 0U;				/* 为0时延申当前路径，为1时延申当前路径并开辟新路径 */
	UINT16 wTmpNextLinkId = 0U;	/* 下一段正线link */
	UINT16 wTmpLinkNum = 0U;
	UINT16 szTmpAddPath[50] = { 0U };
	UINT16 szTmpAddLinkNum = 0U;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM = 0;
	UINT16* dsuLinkIndex = NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru = NULL;

	/* 1.入参检查 */
	if ((NULL != pDsuEmapStru)
		&& (NULL != szPath) && (NULL != pLinkNum) && (0U != *pLinkNum)
		&& ((EMAP_SAME_DIR == cDir) || (EMAP_CONVER_DIR == cDir)))
	{
		cRetVal = 1u;

		/* 全局变量透传 */
		LINKINDEXNUM = pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex = pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru = pDsuEmapStru->dsuStaticHeadStru;
		wTmpLinkNum = *pLinkNum;
		wTmpEndLinkId = szPath[(wTmpLinkNum - 1u)];
	}

	/* 2.查询所有路径最后一个link：
	*	1）值为0xff，证明路径已到线路终点，或存储数据空间不够，跳过本条路径继续查询下一条路径；
	*	2）沿查询方向上获取端点类型：
	*				a）若为终点记录终点为0xFF；
	*				b）若为计轴点则获取下一个link并延申该路径；
	*				c）若为道岔点且本link为汇合link，则路径分叉，根据定位link与反位link添加新路径；
	*				d）若为道岔点且本link为非汇合link，获取起点连接正线link并延申该路径；
	*/
	if (1u == cRetVal)
	{

		/* 1） */
		if (DSU_NULL_16 != wTmpEndLinkId)
		{
			wTmpNextLinkId = DSU_NULL_16;
			/* 获取查询方向上的端点类型,与查询方向上的下一个link */
			cFunRetVal = dsuGetAdjacentLinkIDExp(pDsuEmapStru,wTmpEndLinkId,cDir,(UCHAR)cSwitchSum, pSwitchInfo,&wTmpNextLinkId);

			/* 判断是否查询成功 */
			if ((0U == wTmpNextLinkId) || (0U == cFunRetVal) || (49u <= wTmpLinkNum))
			{
				/* 查询失败或者到容量上限 */
				wTmpNextLinkId = DSU_NULL_16;

			}

			szPath[wTmpLinkNum] = wTmpNextLinkId;
			wTmpLinkNum++;
			
			/* 输出值 */
			*pLinkNum = wTmpLinkNum;

			if (DSU_NULL_16 == wTmpNextLinkId)
			{
				cRetVal = 2U;
			}
		}
		else
		{
			/* 该路径已经查询到终点 */
			cRetVal = 2U;
		}
		
	}

	return cRetVal;
}

/*********************************************************************************************
*函数功能:判断两个路径终点是否为同一link，若为同一link则输出这条路径(车车通信新增接口)
*输入参数:
*szPathA A路径数据
*szLinkANum A路径的link数量
*szPathB B路径数据
*szLinkBNum B路径的link数量
*输出参数:		szPath 找到路径数据
*pPathLinkNum 找到路径数量
*返回值:终点无相同link:0
*终点存在相同link:1
*备注： add by lxc 2022-6-17
*********************************************************************************************/
UINT8 dsuLinkBufSameEndLinkExp(UINT16 szPathA[50], UINT16 wLinkANum,UINT16 szPathB[50], UINT16 wLinkBNum, UINT16 szPath[100], UINT16* pPathLinkNum)
{
	UINT8 retVal = 0U;
	UINT8 cKeepWorkFlag = 0U;
	UINT8 cFunCreatPathFlag = 0U;
	UINT16 i = 0U;

	UINT16 wTmpPathA1LinkNum = 0U;
	UINT16 wTmpPathB1LinkNum = 0U;
	UINT16 wTmpPathA2LinkNum = 0U;
	UINT16 wTmpPathB2LinkNum = 0U;

	UINT16 wTmpPathALinkNum = 0U;
	UINT16 wTmpPathBLinkNum = 0U;

	/* 最后一个link */
	UINT16 wTmpPathAEnd1LinkId = 0U;
	UINT16 wTmpPathBEnd1LinkId = 0U;

	/* 倒数第二个link */
	UINT16 wTmpPathAEnd2LinkId = 0U;
	UINT16 wTmpPathBEnd2LinkId = 0U;

	UINT16 wTmpPathLinkNum = 0U;
	UINT16 wTmpLinkIndex = 0U;

	if ((NULL == szPathA) || (NULL == szPathB) || (NULL == szPath) || (NULL == pPathLinkNum))
	{
		;
	}
	else
	{
		cKeepWorkFlag = 1u;
	}

	if (1u == cKeepWorkFlag)
	{
		wTmpPathA1LinkNum = wLinkANum - 1u;
		wTmpPathA2LinkNum = wLinkANum - 2U;

		wTmpPathB1LinkNum = wLinkBNum - 1u;
		wTmpPathB2LinkNum = wLinkBNum - 2U;

		wTmpPathAEnd1LinkId = szPathA[wTmpPathA1LinkNum];
		wTmpPathAEnd2LinkId = szPathA[wTmpPathA2LinkNum];

		wTmpPathBEnd1LinkId = szPathB[wTmpPathB1LinkNum];
		wTmpPathBEnd2LinkId = szPathB[wTmpPathB2LinkNum];

		/* 以下三种情况为查询到相交路径，但需要区别处理 */
		if ((wTmpPathAEnd1LinkId == wTmpPathBEnd1LinkId) && (DSU_NULL_16 != wTmpPathAEnd1LinkId))
		{
			wTmpPathALinkNum = wTmpPathA1LinkNum;
			wTmpPathBLinkNum = wTmpPathB1LinkNum;
			cFunCreatPathFlag = 1u;
		}
		else if (wTmpPathAEnd2LinkId == wTmpPathBEnd1LinkId)
		{
			wTmpPathALinkNum = wTmpPathA2LinkNum;
			wTmpPathBLinkNum = wTmpPathB1LinkNum;
			cFunCreatPathFlag = 1u;
		}
		else if (wTmpPathAEnd2LinkId == wTmpPathBEnd2LinkId)
		{
			wTmpPathALinkNum = wTmpPathA2LinkNum;
			wTmpPathBLinkNum = wTmpPathB2LinkNum;
			cFunCreatPathFlag = 1u;
		}
		else if (wTmpPathAEnd1LinkId == wTmpPathBEnd2LinkId)
		{
			wTmpPathALinkNum = wTmpPathA1LinkNum;
			wTmpPathBLinkNum = wTmpPathB2LinkNum;
			cFunCreatPathFlag = 1u;
		}
		else
		{
			/*do nothing*/
		}

		wTmpPathALinkNum++;
		wTmpPathBLinkNum++;
		if ((1U == cFunCreatPathFlag) && (100U >= (wTmpPathALinkNum + wTmpPathBLinkNum)))
		{

			/* 存储前半段路径,不存储最后一个link */
			wTmpPathALinkNum--;
			for (i = 0U; i < wTmpPathALinkNum; i++)
			{
				szPath[wTmpPathLinkNum] = szPathA[i];
				wTmpPathLinkNum++;
			}

			/* 存储后半段路径,不存储端点 */
			for (i = 0U; i < wTmpPathBLinkNum; i++)
			{
				wTmpLinkIndex = wTmpPathBLinkNum - i;
				wTmpLinkIndex--;
				szPath[wTmpPathLinkNum] = szPathB[wTmpLinkIndex];
				wTmpPathLinkNum++;
			}

			*pPathLinkNum = wTmpPathLinkNum;
			retVal = 1;
		}
	}

	return retVal;
}


/************************************************
*函数功能:查询AB两端之间的距离，根据道岔实际位置查找
*输入参数:		pDsuEmapStru 电子地图数据
*				pLODAStru	A点
*				pLODBStru	B点
*				cSwitchSum 道岔数量
*				pSwitchInfo 道岔信息
*输出参数:		pLinkNum	输出路径的link数量
*				szLinkId	输出路径的linkId序列
*				pDir		输出A->B的方向
*返回值:失败:DSU_NULL_32
*		成功:距离
*备注： add by lxc 2022-6-17
************************************************/
UINT32 dsuLenByPointBySwitchStateExp(DSU_EMAP_STRU *pDsuEmapStru, const LOD_STRU *pLODAStru, const LOD_STRU *pLODBStru, const UINT8 cSwitchSum, const DQU_POINT_STATUS_STRU *pSwitchInfo, UINT16* pLinkNum, UINT16 szLinkId[100], UINT8 *pDir)
{
	UINT32 reLen = DSU_NULL_32;
	UINT8 cFunRetVal = 0U;
	UINT8 cFun1RetVal = 0U;
	UINT8 cFun2RetVal = 0U;
	UINT8 cFun3RetVal = 0U;
	UINT8 cFun4RetVal = 0U;
	UINT8 cFun5RetVal = 0U;
	UINT8 cKeepWorkFlag = 0U;
	UINT16 dwCycle = 0U;

	/*全局变量改传参调用涉及的全局变量*/
	UINT16 LINKINDEXNUM = 0;
	UINT16* dsuLinkIndex = NULL;
	DSU_STATIC_HEAD_STRU *dsuStaticHeadStru = NULL;

	/* 两点沿两个方向上的所有路径数据 */
	UINT16 szSameDirPathA[50] = { 0U };
	UINT16 wPathASameDirLinkNum = 0U;

	UINT16 szConverDirPathA[50] = { 0U };
	UINT16 wPathAConverDirLinkNum = 0U;

	UINT16 szSameDirPathB[50] = { 0U };
	UINT16 wPathBSameDirLinkNum = 0U;

	UINT16 szConverDirPathB[50] = { 0U };
	UINT16 wPathBConverDirLinkNum = 0U;

	/* 临时变量 */
	UINT16 i = 0U;
	UINT16 wTmpLinkId = 0U;
	UINT16 wTmpLinkIndex = 0U;
	DSU_LINK_STRU *pTmpLinkStru = NULL;
	UINT16 szOutputPath[100] = { 0U };
	UINT16 wOutputLinkNum = 0U;
	UINT32 wTmpLen = 0U;
	UINT8 cQueryADir = EMAP_SAME_DIR;
	UINT8 cQueryBDir = EMAP_SAME_DIR;

	if ((NULL != pLODAStru) && (NULL != pLODBStru) && (NULL != pDsuEmapStru) && (NULL != szLinkId)
		&& (NULL != pLinkNum) && (NULL != pDir) && (NULL != szLinkId) && (NULL != pDir) && (NULL != pSwitchInfo)
		&& (0U != pLODAStru->Lnk) && (0U != pLODBStru->Lnk))
	{
		cKeepWorkFlag = 1u;
		*pLinkNum = 0U;
		*pDir = EMAP_SAME_DIR;

		/* 全局变量透传 */
		LINKINDEXNUM = pDsuEmapStru->dsuEmapIndexStru->LINKINDEXNUM;
		dsuLinkIndex = pDsuEmapStru->dsuEmapIndexStru->dsuLinkIndex;
		dsuStaticHeadStru = pDsuEmapStru->dsuStaticHeadStru;
	}

	if (1u == cKeepWorkFlag)
	{
		if ((LINKINDEXNUM < pLODAStru->Lnk) || (LINKINDEXNUM < pLODBStru->Lnk))
		{
			cKeepWorkFlag = 0U;
		}
		else
		{
			/* 偏移量检查 */
			wTmpLinkId = pLODAStru->Lnk;
			wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
			pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
			if (pTmpLinkStru->dwLength < pLODAStru->Off)
			{
				cKeepWorkFlag = 0U;
			}

			wTmpLinkId = pLODBStru->Lnk;
			wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
			pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
			if (pTmpLinkStru->dwLength < pLODBStru->Off)
			{
				cKeepWorkFlag = 0U;
			}
		}
	}


	if (1u == cKeepWorkFlag)
	{
		if (pLODAStru->Lnk == pLODBStru->Lnk)
		{
			/* 两点在同一link */
			if (pLODAStru->Off > pLODBStru->Off)
			{
				cQueryADir = EMAP_CONVER_DIR;
				reLen = pLODAStru->Off - pLODBStru->Off;
			}
			else
			{
				cQueryADir = EMAP_SAME_DIR;
				reLen = pLODBStru->Off - pLODAStru->Off;
			}

			szLinkId[wOutputLinkNum] = pLODAStru->Lnk;
			wOutputLinkNum++;
			*pLinkNum = wOutputLinkNum;
		}
		else
		{
			/* 两点不在同一link */
			/* 初始化路径 */
			szSameDirPathA[0] = pLODAStru->Lnk;
			wPathASameDirLinkNum= 1u;

			szConverDirPathA[0] = pLODAStru->Lnk;
			wPathAConverDirLinkNum = 1u;

			szSameDirPathB[0] = pLODBStru->Lnk;
			wPathBSameDirLinkNum = 1u;

			szConverDirPathB[0] = pLODBStru->Lnk;
			wPathBConverDirLinkNum = 1u;

			cFunRetVal = 1u;
			cFun1RetVal = 1u;
			cFun2RetVal = 1u;
			cFun3RetVal = 1u;
			cFun4RetVal = 1u;

			dwCycle = 1u;
			while (1u == cFunRetVal)
			{

				cFunRetVal = 0U;

				/* 1.调用函数向，向两个点的两个方向分别查询下一个link，生成新的路径 */
				if (2U != cFun1RetVal)
				{
					cFun1RetVal = dsuPathEndNextLinkBySwitchStateExp(pDsuEmapStru, EMAP_SAME_DIR, szSameDirPathA, &wPathASameDirLinkNum,cSwitchSum, pSwitchInfo);
				}

				if (2U != cFun2RetVal)
				{
					cFun2RetVal = dsuPathEndNextLinkBySwitchStateExp(pDsuEmapStru, EMAP_CONVER_DIR, szConverDirPathA, &wPathAConverDirLinkNum,cSwitchSum, pSwitchInfo);
				}

				if (2U != cFun3RetVal)
				{
					cFun3RetVal = dsuPathEndNextLinkBySwitchStateExp(pDsuEmapStru, EMAP_SAME_DIR, szSameDirPathB, &wPathBSameDirLinkNum,cSwitchSum, pSwitchInfo);
				}

				if (2U != cFun4RetVal)
				{
					cFun4RetVal = dsuPathEndNextLinkBySwitchStateExp(pDsuEmapStru, EMAP_CONVER_DIR, szConverDirPathB, &wPathBConverDirLinkNum, cSwitchSum, pSwitchInfo);
				}

				if (((2U == cFun1RetVal) && (cFun1RetVal == cFun2RetVal) && (cFun2RetVal == cFun3RetVal) && (cFun3RetVal == cFun4RetVal))
					|| ((cFun1RetVal == 0U) || (cFun2RetVal == 0U) || (cFun3RetVal == 0U) || (cFun4RetVal == 0U)))
				{
					/* 都查询到了终点，或查询失败，退出循环 */
					cFunRetVal = 0U;
				}
				else
				{
					/* 存在新的路径或者路径未到终点 */
					cFunRetVal = 1u;
				}

				cFun5RetVal = 0U;
				/* 2.判断两个点的发散路径最后的link是否存在相交link,并输出路径 */
				if (1u == cFunRetVal)
				{

					cQueryADir = EMAP_SAME_DIR;
					cQueryBDir = EMAP_CONVER_DIR;
					cFun5RetVal = dsuLinkBufSameEndLinkExp(szSameDirPathA, wPathASameDirLinkNum,szConverDirPathB, wPathBConverDirLinkNum, szOutputPath, &wOutputLinkNum);

					if (0U == cFun5RetVal)
					{
						cQueryADir = EMAP_CONVER_DIR;
						cQueryBDir = EMAP_SAME_DIR;
						cFun5RetVal = dsuLinkBufSameEndLinkExp(szConverDirPathA, wPathAConverDirLinkNum,szSameDirPathB, wPathBSameDirLinkNum, szOutputPath, &wOutputLinkNum);
					}

				}

				if ((1u == cFunRetVal) && (1u == cFun5RetVal))
				{
					/* 4.计算距离 */
					/* 查询到了一条路径，输出本条路径与距离,终止查询 */
					cFunRetVal = 0U;
					*pLinkNum = wOutputLinkNum;
					for (i = 0U; i < wOutputLinkNum; i++)
					{
						szLinkId[i] = szOutputPath[i];

						wTmpLinkId = szLinkId[i];
						wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
						pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;

						if ((wTmpLinkId != pLODAStru->Lnk) && (wTmpLinkId != pLODBStru->Lnk))
						{
							/* 累加距离 */
							wTmpLen += pTmpLinkStru->dwLength;
						}
					}

					wTmpLinkId = pLODAStru->Lnk;
					wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
					pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
					if (EMAP_SAME_DIR == cQueryADir)
					{
						wTmpLen += (pTmpLinkStru->dwLength - pLODAStru->Off);
					}
					else
					{
						wTmpLen += pLODAStru->Off;
					}

					wTmpLinkId = pLODBStru->Lnk;
					wTmpLinkIndex = dsuLinkIndex[wTmpLinkId];
					pTmpLinkStru = dsuStaticHeadStru->pLinkStru + wTmpLinkIndex;
					if (EMAP_SAME_DIR == cQueryBDir)
					{
						wTmpLen += (pTmpLinkStru->dwLength - pLODBStru->Off);
					}
					else
					{
						wTmpLen += pLODBStru->Off;
					}

					reLen = wTmpLen;
				}

				/* 只允许查询49次 */
				if (dwCycle >= 49u)
				{
					break;
				}
				dwCycle++;
			}
		}

		/* 输出方向 */
		*pDir = cQueryADir;
	}


	return reLen;
}

/**
* @brief  获取LINK端点信息
* @param chDir 方向
* @param wLinkId LINK编号
* @param pLinkPoint 端点信息
* @return CI_SUCCESS:成功；CI_ERROR:失败
*/
UINT8 dsuLinkPointInfo(UINT8 chDir, UINT16 wLinkId, LINK_POINT_DATA_STRU *pLinkPoint)
{
	UINT8 rtnValue = 0U;
	DSU_LINK_STRU * pLinkDataTemp = NULL;

	pLinkDataTemp = g_dsuEmapStru->dsuStaticHeadStru->pLinkStru + g_dsuEmapStru->dsuEmapIndexStru->dsuLinkIndex[wLinkId];

	if ((NULL == pLinkPoint) || (NULL == pLinkDataTemp))
	{
		/* 出口指针为空或link编号有误 */
	}
	else if ((EMAP_SAME_DIR != chDir) && (EMAP_CONVER_DIR != chDir))
	{
		/* 方向不合法 */
	}
	else
	{
		pLinkPoint->wLinkId = pLinkDataTemp->wId;
		pLinkPoint->wPointType = UINT16_MAX;
		pLinkPoint->wPointId = UINT16_MAX;
		pLinkPoint->wMainLinkId = UINT16_MAX;
		pLinkPoint->wSideLinkId = UINT16_MAX;

		/* 与逻辑方向相同 */
		if (EMAP_SAME_DIR == chDir)
		{
			pLinkPoint->wPointType = pLinkDataTemp->wTmnlPointType;		/* 获取终点端点类型 */
			pLinkPoint->wPointId = pLinkDataTemp->wTmnlPointId;			/* 获取终点端点编号 */
			pLinkPoint->wMainLinkId = pLinkDataTemp->wTmnlJointMainLkId;/* 获取终点相邻正线LINK编号 */
			pLinkPoint->wSideLinkId = pLinkDataTemp->wTmnlJointSideLkId;/* 获取终点相邻侧线LINK编号 */
		}
		else
		{
			/* 与逻辑方向相反 */
			pLinkPoint->wPointType = pLinkDataTemp->wOrgnPointType;		/* 获取起点端点类型 */
			pLinkPoint->wPointId = pLinkDataTemp->wOrgnPointId;			/* 获取起点端点编号 */
			pLinkPoint->wMainLinkId = pLinkDataTemp->wOrgnJointMainLkId;/* 获取起点相邻正线LINK编号 */
			pLinkPoint->wSideLinkId = pLinkDataTemp->wOrgnJointSideLkId;/* 获取起点相邻侧线LINK编号 */
		}

		rtnValue = 1U;
	}
	return rtnValue;
}

/**
* @brief 查询link属于道岔的位置。
* @param UINT16 wLinkID
* @param UINT16 wSwitchId
* @param UINT8 *p_LinkInSW
* @return CI_ERROR:查询失败；CI_SUCCESS:查询成功
*/
UINT8 dsuLinkofSwitPos(UINT16 wLinkID, UINT16 wSwitchId, UINT8 *p_LinkInSW)
{
	UINT8 chRtn = 0U;		/*函数返回值*/
	DSU_POINT_STRU * pSwitchTemp = NULL;

	if (NULL != p_LinkInSW)
	{
		pSwitchTemp = g_dsuEmapStru->dsuStaticHeadStru->pPointStru + g_dsuEmapStru->dsuEmapIndexStru->dsuPointIndex[wSwitchId];

		if (NULL != pSwitchTemp)
		{
			if (wLinkID == pSwitchTemp->wConfluentLkId)
			{
				/*link为道岔的汇合link*/
				*p_LinkInSW = SW_LINK_CON;
			}
			else if (wLinkID == pSwitchTemp->wMainLkId)
			{
				/*link为道岔的定位link*/
				*p_LinkInSW = SW_LINK_MAIN;
			}
			else if (wLinkID == pSwitchTemp->wSideLkId)
			{
				/*link为道岔的反位link*/
				*p_LinkInSW = SW_LINK_SIDE;
			}
			else
			{
				*p_LinkInSW = SW_LINK_DEFAUT;
			}
			chRtn = 1U;
		}
		else
		{
			; /*查询错误，返回*/
		}
	}
	else
	{
		; /* 返回失败 */
	}

	return chRtn;
}

/**
* @brief 获取道岔区域相邻两Link连接时期望的道岔状态
* @param UINT16 wSwitchID
* @param UINT16 wlinkA
* @param UINT16 wlinkB
* @param UINT8 *exSwitchStatus
* @return 失败：CI_ERROR；成功：CI_SUCCESS
*/
UINT8 dsuSwitStatusBtwLink(UINT16 wSwitchID, UINT16 wlinkA, UINT16 wlinkB, UINT8 *exSwitchStatus)
{
	UINT8 chRtn = 0U;
	UINT8 linkAInSwType = SW_LINK_DEFAUT;
	UINT8 linkBInSwType = SW_LINK_DEFAUT;
	UINT8 chFunRtnA = 0U;
	UINT8 chFunRtnB = 0U;

	/*获取link在道岔区域的类型*/
	chFunRtnA = dsuLinkofSwitPos(wlinkA, wSwitchID, &linkAInSwType);
	chFunRtnB = dsuLinkofSwitPos(wlinkB, wSwitchID, &linkBInSwType);

	if ((1U == chFunRtnA) && (1U == chFunRtnB) && (NULL != exSwitchStatus ))
	{
		if (((SW_LINK_CON == linkAInSwType) && (SW_LINK_MAIN == linkBInSwType)) ||
			((SW_LINK_CON == linkBInSwType) && (SW_LINK_MAIN == linkAInSwType)))
		{
			/*设置道岔为定位*/
			(*exSwitchStatus) = EMAP_POINT_STATUS_MAIN;
			chRtn = 1U;
		}
		else if (((SW_LINK_CON == linkAInSwType) && (SW_LINK_SIDE == linkBInSwType)) ||
			((SW_LINK_CON == linkBInSwType) && (SW_LINK_SIDE == linkAInSwType)))
		{
			/*设置道岔为反位*/
			(*exSwitchStatus) = EMAP_POINT_STATUS_SIDE;
			chRtn = 1U;
		}
		else
		{
			;/*查询错误*/
		}
	}
	else
	{
		/*查询错误*/
		;
	}
	return chRtn;
}

/**
* @brief 通过起终点link和两link中link序列信息查询两link间的道岔信息。
* @param UINT16 linkA
* @param UINT16 linkB
* @param UINT8 chDir
* @param IN p_StrPathLinkInfo pLinkSeq
* @param OUT p_strPointInArea pSwInfo
* @return CI_ERROR:失败；CI_SUCCESS:成功
*/
UINT8 dsuSwitInfoBtwLinkBaseLinkSeq(UINT16 linkA, UINT16 linkB, UINT8 chDir, IN PATH_LINK_STRU *pLinkSeq, OUT LOGSEC_SWITCH_STRU *pSwInfo)
{
	UINT8 chRtn = 0U;    /*返回返回值*/
	UINT8 chFunRtn = 0U;  /*查询函数返回值*/
	UINT8 chCycle = 0U;    /*遍历link序列*/
	UINT16 currentLinkID = UINT16_MAX;   /*当前link*/
	UINT16 nextLinkID = UINT16_MAX;     /*next link*/
	UINT8 exStatus = 0U;    /*两link之间的道岔状态*/
	LINK_POINT_DATA_STRU pathTree = { 0U };         /*link端点信息*/
	UINT8 chBreakRtn = 0xaau;
	UINT8 cTmpIndex = 0U;

	/*入口参数检查*/
	if ((NULL == pLinkSeq) || (NULL == pSwInfo))
	{
		/*入口函数非法，返回失败*/
	}
	else if ((EMAP_SAME_DIR != chDir) && (EMAP_CONVER_DIR != chDir))
	{
		/*入口函数非法，返回失败*/
	}
	else if ((0U == pLinkSeq->cLinkCnt) ||
		(linkA != pLinkSeq->szLinkId[0]) ||
		(linkB != pLinkSeq->szLinkId[pLinkSeq->cLinkCnt - 1]))
	{
		/*起点linkID与终点linkID与计划的起终点不相符合，入口函数非法，返回失败*/
		;
	}
	else
	{
		/*初始化道岔信息*/
		CommonMemSet(pSwInfo, sizeof(LOGSEC_SWITCH_STRU), 0U, sizeof(LOGSEC_SWITCH_STRU));


		cTmpIndex = pLinkSeq->cLinkCnt - 1u;


		/*依次遍历所有的link序列*/
		for (chCycle = 0U; chCycle < pLinkSeq->cLinkCnt; chCycle++)
		{
			/*周期设置返回值为失败*/
			chRtn = 0U;

			/*缓存端点link*/
			currentLinkID = pLinkSeq->szLinkId[chCycle];
			/* 获取当前link端点信息 */
			chFunRtn = dsuLinkPointInfo(chDir, pLinkSeq->szLinkId[chCycle], &pathTree);

			if ((chCycle == cTmpIndex) && (1U == chFunRtn))
			{
				/*设置查询成功*/
				chRtn = 1U;
			}
			else if ((chCycle != cTmpIndex) && (1U == chFunRtn))
			{
				if (EMAP_POINT_DOT == pathTree.wPointType)
				{
					nextLinkID = pLinkSeq->szLinkId[chCycle + 1];
					chFunRtn = dsuSwitStatusBtwLink(pathTree.wPointId, currentLinkID, nextLinkID, &exStatus);

					if (0U == chFunRtn)
					{
						/*查询错误，返回*/
						chBreakRtn = 0x55u;
					}
					else
					{
						pSwInfo->SwitchId[pSwInfo->SwitchNum] = pathTree.wPointId;
						pSwInfo->SwitchPosition[pSwInfo->SwitchNum] = exStatus;
						pSwInfo->SwitchNum++;
					}

				}
				else
				{
					/*继续查询*/
				}

				/*设置查询成功*/
				chRtn = 1U;
			}
			else
			{
				/*查询失败，跳出*/
				chBreakRtn = 0x55u;
			}

			if (0x55u == chBreakRtn)
			{
				chRtn = 0U;
				break;
			}
			else
			{
			}
		}

		if (1U == chRtn)
		{
			/*查询成功*/
		}
		else
		{
			/*查询不成功，清空*/
			CommonMemSet(pSwInfo, sizeof(LOGSEC_SWITCH_STRU), 0U, sizeof(LOGSEC_SWITCH_STRU));
		}
	}

	return chRtn;
}