// 秒寻科技
// 计算定位坐标。根据第一径数据组，计算定位坐标点。
// zt
// 2023-03-25

#include "../../includes/includes.h"
#include "./lct_public.h"

// 定义本模块使用的全局变量
COORD_T gLct_astLocationRefPoint[LCT_REF_POINT_MATRIX_LEN * LCT_REF_POINT_MATRIX_LEN] = {0}; // 定位参考点
flt32 gLct_fDelayDeviationMatrix[LCT_REF_POINT_MATRIX_LEN * LCT_REF_POINT_MATRIX_LEN] = {0}; // 定位参考点时延误差
int8 gLct_byDirectionX = 0;
int8 gLct_byDirectionY = 0;
int32 gLct_dwSpeedX = 0; // X平均位移速度
int32 gLct_dwSpeedY = 0; // Y平均位移速度

// 导入全局变量
extern LCT_COORDCAL_PARAM_T gg_stLctCoordcalParam;
extern LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T gLct_astPredictionDirectionDataList[PUB_SYS_CARRIER_NUM];
extern PUB_SYS_STATUS_T gg_stSysStatus;
extern LCT_COORDSEL_MEAN_COORD_T gLct_stMeanLctCoordList;
extern LCT_COORDSEL_ORIGINAL_COORD_T gLct_stOriginalLctCoordList;

// 模块初始化
void lct_coordcal_init(LCT_COORDCAL_PARAM_T stLctCoordcalParam)
{
    // 初始化全局变量
    memset(gLct_astLocationRefPoint, 0, sizeof(COORD_T) * LCT_REF_POINT_MATRIX_LEN * LCT_REF_POINT_MATRIX_LEN);
    memset(gLct_fDelayDeviationMatrix, 0, sizeof(flt32) * LCT_REF_POINT_MATRIX_LEN * LCT_REF_POINT_MATRIX_LEN);

    gg_stLctCoordcalParam.dwAudioSpeed = stLctCoordcalParam.dwAudioSpeed;
    gg_stLctCoordcalParam.dwPhoneCoordZ = stLctCoordcalParam.dwPhoneCoordZ;

    gg_stLctCoordcalParam.dwCoordExpendLen = stLctCoordcalParam.dwCoordExpendLen;
    gg_stLctCoordcalParam.dwIntervalDistance = stLctCoordcalParam.dwIntervalDistance;

    gg_stLctCoordcalParam.dwTrackCoordExpendLen = stLctCoordcalParam.dwTrackCoordExpendLen;
    gg_stLctCoordcalParam.dwTrackIntervalDistance = stLctCoordcalParam.dwTrackIntervalDistance;

    gg_stLctCoordcalParam.dwMinimumValueNum = stLctCoordcalParam.dwMinimumValueNum;

    gg_stLctCoordcalParam.dwFirstPahtValueThres = stLctCoordcalParam.dwFirstPahtValueThres;
    gg_stLctCoordcalParam.dwFirstPahtSnrThres = stLctCoordcalParam.dwFirstPahtSnrThres;
    gg_stLctCoordcalParam.dwFirstPathIndexJumpThres = stLctCoordcalParam.dwFirstPathIndexJumpThres;

    gg_stLctCoordcalParam.dwOneFirstPahtValueThres = stLctCoordcalParam.dwOneFirstPahtValueThres;
    gg_stLctCoordcalParam.dwOneFirstPahtSnrThres = stLctCoordcalParam.dwOneFirstPahtSnrThres;
    gg_stLctCoordcalParam.dwOneFirstPathIndexJumpThres = stLctCoordcalParam.dwOneFirstPathIndexJumpThres;

    gg_stLctCoordcalParam.dwBtsEdgeExpendLen = stLctCoordcalParam.dwBtsEdgeExpendLen;
    gg_stLctCoordcalParam.dwOneDimensionExpendLen = stLctCoordcalParam.dwOneDimensionExpendLen;
    gg_stLctCoordcalParam.dwOneDimensionSquareExpendLen = stLctCoordcalParam.dwOneDimensionSquareExpendLen;
    return;
}

// 计算定位点坐标
// pstLctBtsList:定位基站队列
// pstLctDataList:定位数据队列
// pstFirstPathList:第一径数据队列
// pbyPredictionFlag:预测标识符，0：预测失败，1：预测成功
// pstPredictionCoord:预测坐标
// pstMinimumValueGroup:极小值数据组(返回参数)
// pwMinmumValueNum:极小值数量
void lct_coordcal_main(PUB_LCT_BTS_LIST_T *pstLctBtsList, PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_LIST_T *pstFirstPathList, uint8 *pbyPredictionFlag, COORD_T *pstPredictionCoord, LCT_MINIMUM_VALUE_GROUP_T *pstMinimumValueGroup, uint16 *pwMinmumValueNum)
{
    LCT_FIRSTPATH_T *pstFirstPathDataList = pstFirstPathList->astFirstPath; // 第一径队列
    uint8 byFirstPathDataListLen = pstFirstPathList->byBtsNum;              // 第一径队列长度

    LCT_FIRSTPATH_T astValidCalPathBtsList[PUB_LCT_BTS_MAX_NUM];   // 有效计算径基站队列
    uint8 byValidCalPathBtsListLen = 0;                            // 有效计算径基站队列长度
    LCT_FIRSTPATH_T astValidTrackPathBtsList[PUB_LCT_BTS_MAX_NUM]; // 有效跟踪径基站队列
    uint8 byValidTrackPathBtsListLen = 0;                          // 有效跟踪径基站队列长度

    // 基站所在大楼编号和楼层
    int32 dwBuildId = 0;
    int32 dwLayerId = 0;

    uint8 byPredictionFlag = 0; // 预测成功标识符
    COORD_T stPredictionCoord = {0};
    COORD_T stAheadPointCoord = {0};
    uint8 byChangeXY = 0; // 在XY轴上变化大小趋势，1：X轴变化大，2：Y轴变化大

    LCT_MINIMUM_VALUE_GROUP_T stMinmumValueGroup = {0}; // 极小值点组
    uint16 wMinmumValueNum = 0;                         // 极小值个数

    // 根据第一径和幅度选择有效基站(过滤第一径跳变和信噪比差的基站)
    lct_coordcal_select_valid_bts_by_fp_and_ampl(pstLctDataList, pstFirstPathDataList, byFirstPathDataListLen, astValidCalPathBtsList, &byValidCalPathBtsListLen, astValidTrackPathBtsList, &byValidTrackPathBtsListLen, &dwBuildId, &dwLayerId);

    // 预测定位坐标
    gLct_dwSpeedX = 0; // x轴移动速度
    gLct_dwSpeedY = 0; // y轴移动速度
    // lct_coordcal_prediction_coord(&stPredictionCoord, &byPredictionFlag, &stAheadPointCoord, dwBuildId, dwLayerId);
    lct_prediction_current_coord_by_history(dwBuildId, dwLayerId, &stPredictionCoord, &byPredictionFlag, &stAheadPointCoord, &gLct_dwSpeedX, &gLct_dwSpeedY, &byChangeXY);

    // 预测手机相对于基站的移动趋势，1：靠近趋势，2：远离趋势，0：趋势不确定
    lct_prediction_prediction_phone_move_tendency(gLct_astPredictionDirectionDataList);

    // 预测定位坐标失败
    if (!byPredictionFlag)
    {
        ////1维定位
        // 计算径
        lct_coordcal_one_dimension_location(pstLctDataList, byPredictionFlag, stPredictionCoord, pstFirstPathDataList, byFirstPathDataListLen, CAL_PATH, &stMinmumValueGroup);
        // 跟踪径
        lct_coordcal_one_dimension_location(pstLctDataList, byPredictionFlag, stPredictionCoord, pstFirstPathDataList, byFirstPathDataListLen, TRACK_PATH, &stMinmumValueGroup);

        ////2维定位
        // 计算径
        lct_coordcal_two_dimension_location(pstLctBtsList, astValidCalPathBtsList, byValidCalPathBtsListLen, byPredictionFlag, stPredictionCoord, CAL_PATH, &stMinmumValueGroup);
        // 跟踪径
        lct_coordcal_two_dimension_location(pstLctBtsList, astValidTrackPathBtsList, byValidTrackPathBtsListLen, byPredictionFlag, stPredictionCoord, TRACK_PATH, &stMinmumValueGroup);
    }
    // 预测定位坐标成功
    else
    {
        *pbyPredictionFlag = byPredictionFlag;
        *pstPredictionCoord = stPredictionCoord;

        // 校验手机与基站间的位置变化趋势
        lct_coordcal_check_move_tendency(pstFirstPathDataList, byFirstPathDataListLen, gLct_astPredictionDirectionDataList, &stPredictionCoord, &stAheadPointCoord);

        // 预测手机分别在x轴和y轴上的移动方向
        gLct_byDirectionX = 0; // x轴移动方向，1：向右移动，-1向左移动
        gLct_byDirectionY = 0; // y轴移动方向，1：向上移动，-1向下移动
        lct_coordcal_prediction_x_y_move_direction(pstFirstPathDataList, byFirstPathDataListLen, gLct_astPredictionDirectionDataList, &stAheadPointCoord, byChangeXY, &gLct_byDirectionX, &gLct_byDirectionY);
        // lct_prediction_prediction_phone_x_y_move_direction(gLct_astPredictionDirectionDataList, stAheadPointCoord, &gLct_byDirectionX, &gLct_byDirectionY);

        // 根据手机移动方向修正预测坐标
        lct_coordcal_check_prediction_coord_by_xy_move_tendency(&stPredictionCoord, &stAheadPointCoord, gLct_byDirectionX, gLct_byDirectionY, gLct_dwSpeedX, gLct_dwSpeedY);

        ////一维定位
        // 计算径
        lct_coordcal_check_valid_bts_by_move_direction(CAL_PATH, pstFirstPathDataList, byFirstPathDataListLen, pstLctDataList, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY, &byFirstPathDataListLen);
        lct_coordcal_one_dimension_location(pstLctDataList, byPredictionFlag, stPredictionCoord, pstFirstPathDataList, byFirstPathDataListLen, CAL_PATH, &stMinmumValueGroup);
        // 跟踪径
        lct_coordcal_check_valid_bts_by_move_direction(TRACK_PATH, pstFirstPathDataList, byFirstPathDataListLen, pstLctDataList, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY, &byFirstPathDataListLen);
        lct_coordcal_one_dimension_location(pstLctDataList, byPredictionFlag, stPredictionCoord, pstFirstPathDataList, byFirstPathDataListLen, TRACK_PATH, &stMinmumValueGroup);

        ////二维定位
        // 计算径
        lct_coordcal_check_valid_bts_by_move_direction(CAL_PATH, astValidCalPathBtsList, byValidCalPathBtsListLen, pstLctDataList, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY, &byValidCalPathBtsListLen);
        lct_coordcal_two_dimension_location(pstLctBtsList, astValidCalPathBtsList, byValidCalPathBtsListLen, byPredictionFlag, stPredictionCoord, 0, &stMinmumValueGroup);
        // 跟踪径
        lct_coordcal_check_valid_bts_by_move_direction(TRACK_PATH, astValidTrackPathBtsList, byValidTrackPathBtsListLen, pstLctDataList, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY, &byValidTrackPathBtsListLen);
        lct_coordcal_two_dimension_location(pstLctBtsList, astValidTrackPathBtsList, byValidTrackPathBtsListLen, byPredictionFlag, stPredictionCoord, 1, &stMinmumValueGroup);

        // TODO 校验二维定位的极小值
        lct_coordcal_two_dimension_check(&stMinmumValueGroup, &stPredictionCoord, &stAheadPointCoord, byChangeXY, gLct_byDirectionX, gLct_byDirectionY);
    }

    // 没有极小值，则使用预测坐标
    wMinmumValueNum = stMinmumValueGroup.byLinearCalMinimumListLen + stMinmumValueGroup.byLinearTrackMinimumListLen + stMinmumValueGroup.byCalMinimumListLen + stMinmumValueGroup.byTrackMinimumListLen;
    if (wMinmumValueNum <= 0)
    {
        if (byPredictionFlag)
        {
            stMinmumValueGroup.stPredicMinimumList.stCoord = stPredictionCoord;
            stMinmumValueGroup.byPredicMinimumListLen = 1;
        }
    }

    // 保存极小值组
    *pstMinimumValueGroup = stMinmumValueGroup;
    *pwMinmumValueNum = wMinmumValueNum + stMinmumValueGroup.byPredicMinimumListLen;

    return;
}

// 根据第一径和幅度选择有效基站列表（去除第一径有跳变情况的基站，前后两次第一径索引差超过跳变门限即为跳变，该基站不可用）
// pstFirstPathList:第一径参数列表
// byFirstPathListLen：第一径参数列表长度
// pstValidBtsList:有效基站第一径参数列表(返回参数)
// pbyValidBtsListLen:有效基站参数列表长度(返回参数)
// 返回值，1：成功，0：失败
void lct_coordcal_select_valid_bts_by_fp_and_ampl(PUB_LOCATION_DATA_T *pstLctDataList, LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_T *pstValidCalBtsList, uint8 *pbyValidCalBtsListLen, LCT_FIRSTPATH_T *pstValidTrackBtsList, uint8 *pbyValidTrackBtsListLen, int32 *pdwBulidId, int32 *pdwLayerId)
{
    LCT_FIRSTPATH_T stBtsFirstPath = {0};
    LCT_FIRSTPATH_T *pststBtsFirstPath = NULL;
    LCT_FIRSTPATH_T *pststTmpFirstPath = NULL;

    PUB_LOCATION_DATA_T *pstLctData = NULL;
    uint8 byFreqIndex = 0;
    uint16 wIndexGap = 0;
    flt32 fFirstPathValueThres = (flt32)gg_stLctCoordcalParam.dwFirstPahtValueThres;
    flt32 fFirstPathSnrThres = (flt32)gg_stLctCoordcalParam.dwFirstPahtSnrThres / 10;
    uint16 wFirstPathIndexJumpThres = gg_stLctCoordcalParam.dwFirstPathIndexJumpThres;

    uint8 byCalPathFlag = 0;
    uint8 byTrackPathFlag = 0;
    uint8 byCalCounter = 0;   // 计算径有效基站参数个数
    uint8 byTrackCounter = 0; // 跟踪径有效基站参数个数

    uint8 byMainBtsFindFalg = 0; // 主站标识符
    uint32 dwCalMainBtsId = 0;   // 计算径主站编号
    uint32 dwTrackMainBtsId = 0; // 跟踪径主站编号

    for (uint8 i = 0; i < byFirstPathListLen; i++)
    {
        stBtsFirstPath = pstFirstPathList[i];
        stBtsFirstPath.byMainFlag = 0;

        byFreqIndex = stBtsFirstPath.byFreqIndex;
        pstLctData = &pstLctDataList[byFreqIndex];

        byCalPathFlag = 0;
        byTrackPathFlag = 0;

        // 检查计算径基站Snr是否符合定位要求
        if (stBtsFirstPath.fCalPathIndexSnr > fFirstPathSnrThres && stBtsFirstPath.fFrameCalPathValue > fFirstPathValueThres)
        {
            if (pstLctData->wAheadFrameCalPahtIndex > 0 && !gg_stSysStatus.byReLocationFlag)
            {
                // 第一径跳变检查
                wIndexGap = abs(stBtsFirstPath.wFrameCalIndex - pstLctData->wAheadFrameCalPahtIndex);
                if (wIndexGap < wFirstPathIndexJumpThres)
                {
                    memcpy(&pstValidCalBtsList[byCalCounter], &stBtsFirstPath, sizeof(LCT_FIRSTPATH_T));
                    byCalCounter++;
                    byCalPathFlag = 1;
                }
            }
            else
            {
                memcpy(&pstValidCalBtsList[byCalCounter], &stBtsFirstPath, sizeof(LCT_FIRSTPATH_T));
                byCalCounter++;
                byCalPathFlag = 1;
            }
        }

        // 检查跟踪径基站Snr是否符合定位要求
        if (stBtsFirstPath.fTrackPathIndexSnr > fFirstPathSnrThres && stBtsFirstPath.fFrameTrackPathValue > fFirstPathValueThres)
        {
            if (pstLctData->wAheadFrameTrackPathIndex > 0 && !gg_stSysStatus.byReLocationFlag)
            {
                // 第一径跳变检查
                wIndexGap = abs(stBtsFirstPath.wFrameTrackIndex - pstLctData->wAheadFrameTrackPathIndex);
                if (wIndexGap < wFirstPathIndexJumpThres)
                {
                    memcpy(&pstValidTrackBtsList[byTrackCounter], &stBtsFirstPath, sizeof(LCT_FIRSTPATH_T));
                    byTrackCounter++;
                    byTrackPathFlag = 1;
                }
            }
            else
            {
                memcpy(&pstValidTrackBtsList[byTrackCounter], &stBtsFirstPath, sizeof(LCT_FIRSTPATH_T));
                byTrackCounter++;
                byTrackPathFlag = 1;
            }
        }

        // 计算和跟踪索引都无效，复位定位数据中的第一径索引值
        if (!byCalPathFlag && !byTrackPathFlag)
        {
            pstLctData->wAheadFrameTrackPathIndex = 0;
        }
    }

    // 对计算径信噪比排序，更新计算径主站标识符
    for (uint8 i = 0; i < byCalCounter; i++)
    {
        for (uint8 j = i + 1; j < byCalCounter; j++)
        {
            if (pstValidCalBtsList[j].fCalPathIndexSnr > pstValidCalBtsList[i].fCalPathIndexSnr)
            {
                stBtsFirstPath = pstValidCalBtsList[i];
                pstValidCalBtsList[i] = pstValidCalBtsList[j];
                pstValidCalBtsList[j] = stBtsFirstPath;
            }
        }
    }
    if (byCalCounter > 0)
    {
        pstValidCalBtsList[0].byMainFlag = 1;
    }

    // 对跟踪径信噪比排序，更新跟踪径主站标识符
    for (uint8 i = 0; i < byTrackCounter; i++)
    {
        for (uint8 j = i + 1; j < byTrackCounter; j++)
        {
            if (pstValidTrackBtsList[j].fTrackPathIndexSnr > pstValidTrackBtsList[i].fTrackPathIndexSnr)
            {
                stBtsFirstPath = pstValidTrackBtsList[i];
                pstValidTrackBtsList[i] = pstValidTrackBtsList[j];
                pstValidTrackBtsList[j] = stBtsFirstPath;
            }
        }
    }
    if (byTrackCounter > 0)
    {
        pstValidTrackBtsList[0].byMainFlag = 1;
    }

    // 调整计算径定位基站数量
    if (byCalCounter > 5)
    {
        byCalCounter = 5;
    }
    *pbyValidCalBtsListLen = byCalCounter;

    // 调整跟踪径定位基站数量
    if (byTrackCounter > 5)
    {
        byTrackCounter = 5;
    }
    *pbyValidTrackBtsListLen = byTrackCounter;

    // 修改第一径数据队列主站标识符
    if (byCalCounter || byTrackCounter)
    {
        dwCalMainBtsId = pstValidCalBtsList[0].dwBtsId;
        dwTrackMainBtsId = pstValidTrackBtsList[0].dwBtsId;

        // 遍历队列
        for (uint8 i = 0; i < byFirstPathListLen; i++)
        {
            pststBtsFirstPath = &pstFirstPathList[i];
            pststBtsFirstPath->byMainFlag = 0;

            // 找到主站
            if (!byMainBtsFindFalg && (pststBtsFirstPath->dwBtsId == dwCalMainBtsId || pststBtsFirstPath->dwBtsId == dwTrackMainBtsId))
            {
                pststBtsFirstPath->byMainFlag = 1;
                *pdwBulidId = pststBtsFirstPath->dwBuildId;
                *pdwLayerId = pststBtsFirstPath->dwLayerId;
                byMainBtsFindFalg = 1;
            }
        }
    }

    return;
}

// 根据移动方向校验有效绩效
// byFirstPathType:第一径类型
// pstValidBtsList:有效基站队列
// byValidBtsListLen:有效基站队列长度
// pstAheadCoord:前一点定位坐标
// byChangeXY:在XY轴上变化大小趋势，1：X轴变化大，2：Y轴变化大
// byDirectionX:在X轴上的移动方向，1：向右，-1：向左
// byDirectionY:在Y轴上的移动方向，1：向上，-1：向下
// pbyValidBtsListLen:返回值，有效基站队列长度
void lct_coordcal_check_valid_bts_by_move_direction(uint8 byFirstPathType, LCT_FIRSTPATH_T *pstValidBtsList, uint8 byValidBtsListLen, PUB_LOCATION_DATA_T *pstLctDataList, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 byDirectionX, int8 byDirectionY, uint8 *pbyValidBtsListLen)
{
    LCT_FIRSTPATH_T *pstBtsFirstPath = NULL;
    uint8 byFreqIndex = 0;
    PUB_LOCATION_DATA_T *pstBtsLctData = NULL;
    int32 dwGap = 0;

    if (byDirectionX != 0 || byDirectionY != 0)
    {
        for (uint8 i = 0; i < byValidBtsListLen; i++)
        {
            pstBtsFirstPath = &pstValidBtsList[i];        // 第一径数据
            byFreqIndex = pstBtsFirstPath->byFreqIndex;   // 基站频率
            pstBtsLctData = &pstLctDataList[byFreqIndex]; // 定位数据

            // 在X轴上变化趋势较大
            if (byChangeXY == 1)
            {
                // 定位点在基站右侧
                if (pstAheadCoord->dwX > pstBtsFirstPath->dwCoordX)
                {
                    // 向右移动，远离基站
                    if (byDirectionX == 1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            // 100点，表示有70cm的变动
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                    }
                    // 向左移动，靠近基站
                    else if (byDirectionX == -1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                    }
                }
                // 定位点在基站左侧
                else
                {
                    // 向右移动，靠近基站
                    if (byDirectionX == 1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                    }
                    // 向左移动，远离基站
                    else if (byDirectionX == -1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                    }
                }
            }
            // 在Y轴上变化趋势较大
            else if (byChangeXY == 2)
            {
                // 定位点在基站上方
                if (pstAheadCoord->dwY > pstBtsFirstPath->dwCoordY)
                {
                    // 向上移动，远离基站
                    if (byDirectionY == 1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                    }
                    // 向下移动，靠近基站
                    else if (byDirectionY == -1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                    }
                }
                // 定位点在基站下方
                else
                {
                    // 向上移动，靠近基站
                    if (byDirectionY == 1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex > pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex -= dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex - dwGap;
                                }
                            }
                        }
                    }
                    // 向下移动，远离基站
                    else if (byDirectionY == -1)
                    {
                        if (byFirstPathType == CAL_PATH)
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameCalIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameCalIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwCalPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameCalIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                        else
                        {
                            if (pstBtsLctData->wAheadFrameTrackPathIndex && pstBtsFirstPath->wFrameTrackIndex < pstBtsLctData->wAheadFrameTrackPathIndex)
                            {
                                dwGap = pstBtsFirstPath->wFrameTrackIndex - pstBtsLctData->wAheadFrameTrackPathIndex;
                                dwGap = abs(dwGap);
                                if (dwGap > LCT_COORDCAL_FIRSTPATH_ADJUST_THRES)
                                {
                                    dwGap = LCT_COORDCAL_FIRSTPATH_ADJUST_VALUE;
                                    pstBtsFirstPath->dwTrackPathIndex += dwGap;
                                    pstBtsFirstPath->wFrameTrackIndex = pstBtsLctData->wAheadFrameTrackPathIndex + dwGap;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    *pbyValidBtsListLen = byValidBtsListLen; // 有效基站数量

    return;
}

// 预测坐标
// pstPredictionCoord:预测坐标
// pbyPredictionFlag:预测标识，0：预测失败，1：预测成功
// pstAheadPointCoord:前一个点坐标
// dwBulidId:大楼编号
// dwLayerId:楼层编号
void lct_coordcal_prediction_coord(COORD_T *pstPredictionCoord, uint8 *pbyPredictionFlag, COORD_T *pstAheadPointCoord, int32 dwBulidId, int32 dwLayerId)
{
    LCT_COORDSEL_MEAN_COORD_T *pstData = (LCT_COORDSEL_MEAN_COORD_T *)&gLct_stMeanLctCoordList; // 定位点队列
    uint8 byMeanListLen = pstData->byListLen;                                                   // 定位点队列长度
    LCT_COORDSEL_ORIGINAL_COORD_T *pstOriginalLctCoordList = &gLct_stOriginalLctCoordList;
    uint8 byOriginalListLen = pstOriginalLctCoordList->byListLen;

    flt32 fDisX = 0;
    flt32 fDisY = 0;

    COORD_T stPrediction = {0};
    COORD_T stAheadCoord = {0};

    // 处于同一大楼和楼层
    if (dwBulidId == gg_stSysStatus.dwBuildId && dwLayerId == gg_stSysStatus.dwLayerId)
    {
        if (gg_stSysStatus.byReLocationFlag)
        {
            memset(&gLct_stOriginalLctCoordList, 0, sizeof(LCT_COORDSEL_ORIGINAL_COORD_T)); // 原始坐标队列
            memset(&gLct_stMeanLctCoordList, 0, sizeof(LCT_COORDSEL_MEAN_COORD_T));         // 平滑坐标队列
            gg_stSysStatus.byBtsCaptureFlag = 0;                                            // 系统处于捕获基站状态

            *pbyPredictionFlag = 0; // 预测失败
            return;
        }

        if (byMeanListLen < LCT_COORDSEL_MEAN_COORD_LIST_LEN)
        {
            *pbyPredictionFlag = 0;
            return;
        }

        // 计算平均位移
        for (uint8 i = 1; i < byMeanListLen; i++)
        {
            // 计算X轴与Y轴上的加权位移(每秒移动距离，单位厘米)
            fDisX += pstData->astCoordList[i].dwX - pstData->astCoordList[i - 1].dwX;
            fDisY += pstData->astCoordList[i].dwY - pstData->astCoordList[i - 1].dwY;
        }
        fDisX /= byMeanListLen - 1;
        fDisY /= byMeanListLen - 1;
        gLct_dwSpeedX = (int32)fDisX; // 位移速度
        gLct_dwSpeedY = (int32)fDisY; // 位移速度

        // 保存上一个定位点
        stAheadCoord = pstData->astCoordList[byMeanListLen - 1];
        *pstAheadPointCoord = stAheadCoord;

        // 计算预测坐标
        stPrediction.dwX = stAheadCoord.dwX + fDisX;
        stPrediction.dwY = stAheadCoord.dwY + fDisY;
        stPrediction.dwZ = 120;

        // 保存参数
        *pstPredictionCoord = stPrediction;
        *pbyPredictionFlag = 1; // 预测成功
    }
    // 不在同一大楼和楼层
    else
    {
        memset(&gLct_stOriginalLctCoordList, 0, sizeof(LCT_COORDSEL_ORIGINAL_COORD_T)); // 原始坐标队列
        memset(&gLct_stMeanLctCoordList, 0, sizeof(LCT_COORDSEL_MEAN_COORD_T));         // 平滑坐标队列
        gg_stSysStatus.byBtsCaptureFlag = 0;                                            // 系统处于捕获基站状态

        *pbyPredictionFlag = 0; // 预测失败
    }

    return;
}

// 检验手机移动趋势，用基站到预测点与上一个定位点的距离来校验手机的移动趋势
// pstFirstPathList:
// byFirstPathListLen:
// pstPredictionDirectionDataList:
// pstPredictionCoord:
// pstAheadCoord:
void lct_coordcal_check_move_tendency(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord)
{
    LCT_FIRSTPATH_T *pstFirstPathData = NULL; // 主站
    uint8 byFreqIndex = 0;

    LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstBtsDirectionData = NULL; // 当前基站方向预测数据

    flt32 fDistancP = 0; // 预测点到基站的距离
    flt32 fDistancA = 0; // 上一点到基站的距离

    for (uint8 i = 0; i < byFirstPathListLen; i++)
    {
        pstFirstPathData = &pstFirstPathList[i];
        byFreqIndex = pstFirstPathData->byFreqIndex;
        pstBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex]; // 方向数据

        fDistancP = util_distance_cal_p2p_distance(pstFirstPathData->dwCoordX, pstFirstPathData->dwCoordY, pstPredictionCoord->dwX, pstPredictionCoord->dwY);
        fDistancA = util_distance_cal_p2p_distance(pstFirstPathData->dwCoordX, pstFirstPathData->dwCoordY, pstAheadCoord->dwX, pstAheadCoord->dwY);

        // 预测点更接近基站
        if (fDistancP < fDistancA)
        {
            if (pstBtsDirectionData->byDirectionTendency != 1)
            {
                pstBtsDirectionData->byValidFlag = 0;
            }
        }
        // 预测点更远离基站
        else if (fDistancP > fDistancA)
        {
            if (pstBtsDirectionData->byDirectionTendency != 2)
            {
                pstBtsDirectionData->byValidFlag = 0;
            }
        }
        else
        {
            pstBtsDirectionData->byValidFlag = 0;
        }
    }
}

// // 预测XY轴移动方向
// // pstFirstPathList:第一径数据队列
// // byFirstPathListLen:第一径数据队列长度
// // pstPredictionDirectionDataList:预测移动方向的数据队列
// // pbyDirectionX:X轴预测方向，返回参数，1：向右，-1：向左
// // pbyDirectionY:Y轴预测方向，返回参数，1：向上，-1：向下
// void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, int8 *pbyDirectionX, int8 *pbyDirectionY)
// {
//     LCT_COORDSEL_MEAN_COORD_T *pstMeanLctCoordList = &gLct_stMeanLctCoordList;
//     uint8 byListLen = pstMeanLctCoordList->byListLen;
//     COORD_T stAheadCoord = {0};

//     LCT_FIRSTPATH_T *pstFirstPathData = NULL;
//     uint8 byFreqIndex = 0;
//     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstCurrentBtsDirectionData = NULL; // 当前基站方向预测数据

//     LCT_FIRSTPATH_T *pstOtherFirstPathData = NULL;
//     uint8 byOtherFreqIndex = 0;
//     LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstOtherBtstDirectionData = NULL; // 其它基站方向预测数据

//     int32 dwCurrentX = 0;
//     int32 dwCurrentY = 0;
//     uint32 dwCurrentIndex = 0;

//     int32 dwOtherX = 0;
//     int32 dwOtherY = 0;
//     uint32 dwOtherIndex = 0;

//     int8 byDirectionX = 0; // X轴预测标识符
//     int8 byDirectionY = 0; // Y轴预测标识符

//     // 方向预测次数
//     uint8 byCounterPlusX = 0;
//     uint8 byCounterMinusX = 0;
//     uint8 byCounterPlusY = 0;
//     uint8 byCounterMinusY = 0;

//     // 参数容错
//     if (byListLen < 1)
//     {
//         return;
//     }
//     stAheadCoord = pstMeanLctCoordList->astCoordList[byListLen - 1];

//     // 预测方向
//     for (uint8 i = 0; i < byFirstPathListLen; i++)
//     {
//         pstFirstPathData = &pstFirstPathList[i];
//         byFreqIndex = pstFirstPathData->byFreqIndex; // 基站频率索引

//         // 当前基站预测数据
//         pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
//         dwCurrentX = pstCurrentBtsDirectionData->dwCoordX;
//         dwCurrentY = pstCurrentBtsDirectionData->dwCoordY;
//         dwCurrentIndex = pstCurrentBtsDirectionData->dwCalPathIndex;

//         // 当前站方向趋势有效
//         if (pstCurrentBtsDirectionData->byValidFlag == 1)
//         {
//             for (uint8 j = i + 1; j < byFirstPathListLen; j++)
//             {
//                 // 其它基站预测数据
//                 pstOtherFirstPathData = &pstFirstPathList[j];
//                 byOtherFreqIndex = pstOtherFirstPathData->byFreqIndex; // 基站频率索引
//                 pstOtherBtstDirectionData = &pstPredictionDirectionDataList[byOtherFreqIndex];

//                 // 其它站方向趋势有效
//                 if (pstOtherBtstDirectionData->byValidFlag == 1)
//                 {
//                     dwOtherX = pstOtherBtstDirectionData->dwCoordX;
//                     dwOtherY = pstOtherBtstDirectionData->dwCoordY;
//                     dwOtherIndex = pstOtherBtstDirectionData->dwCalPathIndex;

//                     // 靠近当前站
//                     if (pstCurrentBtsDirectionData->byDirectionTendency == 1)
//                     {
//                         // 靠近当前站，同时也靠近其它基站
//                         if (pstOtherBtstDirectionData->byDirectionTendency == 1)
//                         {
//                             // 其它基站在当前基站右侧
//                             if (dwOtherX > dwCurrentX)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterPlusX++;
//                                 }
//                                 else
//                                 {
//                                     byCounterMinusX++;
//                                 }
//                             }
//                             // 其它基站在当前基站左侧
//                             else if (dwOtherX < dwCurrentX)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterMinusX++;
//                                 }
//                                 else
//                                 {
//                                     byCounterPlusX++;
//                                 }
//                             }

//                             // 其它基站在当前基站上方
//                             if (dwOtherY > dwCurrentY)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterPlusY++;
//                                 }
//                                 else
//                                 {
//                                     byCounterMinusY++;
//                                 }
//                             }
//                             // 其它基站在当前基站下方
//                             else if (dwOtherY < dwCurrentY)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterMinusY++;
//                                 }
//                                 else
//                                 {
//                                     byCounterPlusY++;
//                                 }
//                             }
//                             // 其它基站与当前基站Y坐标相同
//                             else
//                             {
//                                 byDirectionY = 0; // 错误
//                             }
//                         }
//                         // 靠近当前站，远离其它基站
//                         else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
//                         {
//                             // 其它基站在当前基站右侧
//                             if (dwOtherX > dwCurrentX)
//                             {
//                                 byCounterMinusX++;
//                             }
//                             // 其它基站在当前基站左侧
//                             else if (dwOtherX < dwCurrentX)
//                             {
//                                 byDirectionX = 1;
//                             }
//                             // 其它基站与当前基站X坐标相同
//                             else
//                             {
//                                 byDirectionX = 0; // 错误
//                             }

//                             // 其它基站在当前基站上方
//                             if (dwOtherY > dwCurrentY)
//                             {
//                                 byCounterMinusY++;
//                             }
//                             // 其它基站在当前基站下方
//                             else if (dwOtherY < dwCurrentY)
//                             {
//                                 byCounterPlusY++;
//                             }
//                             // 其它基站与当前基站Y坐标相同
//                             else
//                             {
//                                 byDirectionY = 0; // 错误
//                             }
//                         }
//                     }
//                     // 远离当前站
//                     else if (pstCurrentBtsDirectionData->byDirectionTendency == 2)
//                     {
//                         // 远离当前站，靠近其它基站
//                         if (pstOtherBtstDirectionData->byDirectionTendency == 1)
//                         {
//                             // 其它基站在当前基站右侧
//                             if (dwOtherX > dwCurrentX)
//                             {
//                                 byCounterPlusX++;
//                             }
//                             // 其它基站在当前基站左侧
//                             else if (dwOtherX < dwCurrentX)
//                             {
//                                 byCounterMinusX++;
//                             }
//                             // 其它基站与当前基站X坐标相同
//                             else
//                             {
//                                 byDirectionX = 0; // 错误
//                             }

//                             // 其它基站在当前基站上方
//                             if (dwOtherY > dwCurrentY)
//                             {
//                                 byCounterPlusY++;
//                             }
//                             // 其它基站在当前基站下方
//                             else if (dwOtherY < dwCurrentY)
//                             {
//                                 byCounterMinusY++;
//                             }
//                             // 其它基站与当前基站Y坐标相同
//                             else
//                             {
//                                 byDirectionY = 0; // 错误
//                             }
//                         }
//                         // 远离当前站，同时远离其它基站
//                         else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
//                         {
//                             // 其它基站在当前基站右侧
//                             if (dwOtherX > dwCurrentX)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterMinusX++;
//                                 }
//                                 else
//                                 {
//                                     byCounterPlusX++;
//                                 }
//                             }
//                             // 其它基站在当前基站左侧
//                             else if (dwOtherX < dwCurrentX)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterPlusX++;
//                                 }
//                                 else
//                                 {
//                                     byCounterMinusX++;
//                                 }
//                             }
//                             // 其它基站与当前基站X坐标相同
//                             else
//                             {
//                                 byDirectionX = 0; // 错误
//                             }

//                             // 其它基站在当前基站上方
//                             if (dwOtherY > dwCurrentY)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterMinusY++;
//                                 }
//                                 else
//                                 {
//                                     byCounterPlusY++;
//                                 }
//                             }
//                             // 其它基站在当前基站下方
//                             else if (dwOtherY < dwCurrentY)
//                             {
//                                 if (dwOtherIndex > dwCurrentIndex)
//                                 {
//                                     byCounterPlusY++;
//                                 }
//                                 else
//                                 {
//                                     byCounterMinusY++;
//                                 }
//                             }
//                             // 其它基站与当前基站Y坐标相同
//                             else
//                             {
//                                 byDirectionY = 0; // 错误
//                             }
//                         }
//                     }
//                 }
//             }

//             if (byCounterPlusX != 0 || byCounterMinusX != 0 || byCounterPlusY != 0 || byCounterMinusY != 0)
//             {
//                 break;
//             }
//         }
//     }

//     // 方向预测失败
//     if (byCounterPlusX == 0 && byCounterMinusX == 0 && byCounterPlusY == 0 && byCounterMinusY == 0)
//     {
//         *pbyDirectionX = 0;
//         *pbyDirectionY = 0;
//     }
//     else
//     {
//         if (byCounterPlusX > byCounterMinusX)
//         {
//             byDirectionX = 1;
//         }
//         else if (byCounterPlusX < byCounterMinusX)
//         {
//             byDirectionX = -1;
//         }
//         else
//         {
//             byDirectionX = 0; // 不成功
//         }

//         if (byCounterPlusY > byCounterMinusY)
//         {
//             byDirectionY = 1;
//         }
//         else if (byCounterPlusY < byCounterMinusY)
//         {
//             byDirectionY = -1;
//         }
//         else
//         {
//             byDirectionY = 0; // 不成功
//         }

//         *pbyDirectionX = byDirectionX;
//         *pbyDirectionY = byDirectionY;
//     }

//     // // 修正移动方向
//     // if (byDirectionX == 0 && byDirectionY == 0)
//     // {
//     //     if (gLct_dwSpeedX < 0)
//     //     {
//     //         byDirectionX = -1;
//     //     }
//     //     else if (gLct_dwSpeedX > 0)
//     //     {
//     //         byDirectionX = 1;
//     //     }

//     //     if (gLct_dwSpeedY < 0)
//     //     {
//     //         byDirectionY = -1;
//     //     }
//     //     else if (gLct_dwSpeedY > 0)
//     //     {
//     //         byDirectionY = 1;
//     //     }

//     //     *pbyDirectionX = byDirectionX;
//     //     *pbyDirectionY = byDirectionY;
//     // }

//     return;
// }

// 预测XY轴移动方向
// pstFirstPathList:第一径数据队列
// byFirstPathListLen:第一径数据队列长度
// pstPredictionDirectionDataList:预测移动方向的数据队列
// byChangeXY:在XY轴上变化大小趋势，1：X轴变化大，2：Y轴变化大
// pbyDirectionX:X轴预测方向，返回参数，1：向右，-1：向左
// pbyDirectionY:Y轴预测方向，返回参数，1：向上，-1：向下
void lct_coordcal_prediction_x_y_move_direction(LCT_FIRSTPATH_T *pstFirstPathList, uint8 byFirstPathListLen, LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstPredictionDirectionDataList, COORD_T *pstAheadCoord, uint8 byChangeXY, int8 *pbyDirectionX, int8 *pbyDirectionY)
{
    LCT_FIRSTPATH_T *pstFirstPathData = NULL;
    uint8 byFreqIndex = 0;
    LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstCurrentBtsDirectionData = NULL; // 当前基站方向预测数据

    LCT_FIRSTPATH_T *pstOtherFirstPathData = NULL;
    uint8 byOtherFreqIndex = 0;
    LCT_FIRSTPATH_PREDICTION_DIRECTION_DATA_T *pstOtherBtstDirectionData = NULL; // 其它基站方向预测数据

    // 主站
    int32 dwCurrentX = 0;
    int32 dwCurrentY = 0;
    int8 byMainDirectionX = 0;         // 主站X轴预测标识符，-1：向左，1：向右，0：不确定
    int8 byMainDirectionY = 0;         // 主站Y轴预测标识符，-1：向下，1：向上，0：不确定
    uint8 byMainDirectionXCounter = 0; // 主站方向预测正确计数器
    uint8 byMainDirectionYCounter = 0; // 主站方向预测正确计数器
    uint8 byFirstPathIndexX = 0;
    uint8 byFirstPathIndexY = 0;

    // 从站
    int32 dwOtherX = 0;
    int32 dwOtherY = 0;

    // 预测方向
    for (uint8 i = 0; i < byFirstPathListLen; i++)
    {
        pstFirstPathData = &pstFirstPathList[i];     // 第一径数据
        byFreqIndex = pstFirstPathData->byFreqIndex; // 基站频率索引

        // 当前基站预测数据
        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
        pstCurrentBtsDirectionData->byDirectionX = 0;
        pstCurrentBtsDirectionData->byDirectionY = 0;
        pstCurrentBtsDirectionData->byDirectionXCounter = 0;
        pstCurrentBtsDirectionData->byDirectionYCounter = 0;
        dwCurrentX = pstCurrentBtsDirectionData->dwCoordX;
        dwCurrentY = pstCurrentBtsDirectionData->dwCoordY;

        // 当前站方向趋势有效
        if (pstCurrentBtsDirectionData->byValidFlag == 1)
        {
            // 基站手机相对于主站在x和y轴上的移动方向
            lct_coordcal_cal_bts_move_direction(pstCurrentBtsDirectionData->byDirectionTendency, dwCurrentX, dwCurrentY, pstAheadCoord, &byMainDirectionX, &byMainDirectionY);

            // 利用从站校验主站的移动方向正确性
            for (uint8 j = 0; j < byFirstPathListLen; j++)
            {
                if (i != j)
                {
                    // 其它基站预测数据
                    pstOtherFirstPathData = &pstFirstPathList[j];
                    byOtherFreqIndex = pstOtherFirstPathData->byFreqIndex; // 基站频率索引
                    pstOtherBtstDirectionData = &pstPredictionDirectionDataList[byOtherFreqIndex];

                    // 其它站方向趋势有效
                    if (pstOtherBtstDirectionData->byValidFlag == 1)
                    {
                        dwOtherX = pstOtherBtstDirectionData->dwCoordX;
                        dwOtherY = pstOtherBtstDirectionData->dwCoordY;

                        //// 用从站的趋势校验主站的运动方向
                        // 主站X轴向右移动
                        if (byMainDirectionX == 1)
                        {
                            // 手机靠近从站
                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherX > dwCurrentX && pstAheadCoord->dwX < dwOtherX) || (dwOtherX <= dwCurrentX && pstAheadCoord->dwX < dwOtherX))
                                {
                                    byMainDirectionXCounter++;
                                }
                            }
                            // 手机远离从站
                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherX < dwCurrentX && pstAheadCoord->dwX >= dwOtherX) || (dwOtherX >= dwCurrentX && pstAheadCoord->dwX >= dwOtherX))
                                {
                                    byMainDirectionXCounter++;
                                }
                            }
                        }
                        // 主站X轴向左移动
                        else if (byMainDirectionX == -1)
                        {
                            // 手机靠近从站
                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherX < dwCurrentX && pstAheadCoord->dwX > dwOtherX) || (dwOtherX >= dwCurrentX && pstAheadCoord->dwX > dwOtherX))
                                {
                                    byMainDirectionXCounter++;
                                }
                            }
                            // 手机远离从站
                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherX >= dwCurrentX && pstAheadCoord->dwX <= dwOtherX) || (dwOtherX <= dwCurrentX && pstAheadCoord->dwX <= dwOtherX))
                                {
                                    byMainDirectionXCounter++;
                                }
                            }
                        }

                        // 主站Y轴向上移动
                        if (byMainDirectionY == 1)
                        {
                            // 手机靠近从站
                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherY > dwCurrentY && pstAheadCoord->dwY < dwOtherY) || (dwOtherY <= dwCurrentY && pstAheadCoord->dwY < dwOtherY))
                                {
                                    byMainDirectionYCounter++;
                                }
                            }
                            // 手机远离从站
                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherY <= dwCurrentY && pstAheadCoord->dwY >= dwOtherY) || (dwOtherY >= dwCurrentY && pstAheadCoord->dwY >= dwOtherY))
                                {
                                    byMainDirectionYCounter++;
                                }
                            }
                        }
                        // 主站Y轴向下移动
                        else if (byMainDirectionY == -1)
                        {
                            // 手机靠近从站
                            if (pstOtherBtstDirectionData->byDirectionTendency == 1)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherY >= dwCurrentY && pstAheadCoord->dwY > dwOtherY) || (dwOtherY < dwCurrentY && pstAheadCoord->dwY > dwOtherY))
                                {
                                    byMainDirectionYCounter++;
                                }
                            }
                            // 手机远离从站
                            else if (pstOtherBtstDirectionData->byDirectionTendency == 2)
                            {
                                // TODO,条件已经检查过，不需要再修改
                                if ((dwOtherY > dwCurrentY && pstAheadCoord->dwY <= dwOtherY) || (dwOtherY <= dwCurrentY && pstAheadCoord->dwY <= dwOtherY))
                                {
                                    byMainDirectionYCounter++;
                                }
                            }
                        }
                    }
                }
            }

            // 保存主站方向预判信息
            pstCurrentBtsDirectionData->byDirectionX = byMainDirectionX;
            pstCurrentBtsDirectionData->byDirectionY = byMainDirectionY;
            pstCurrentBtsDirectionData->byDirectionXCounter = byMainDirectionXCounter;
            pstCurrentBtsDirectionData->byDirectionYCounter = byMainDirectionYCounter;

            // 变量复位
            byMainDirectionX = 0;
            byMainDirectionY = 0;
            byMainDirectionXCounter = 0;
            byMainDirectionYCounter = 0;
        }
    }

    // 统计XY轴移动方向正确校验最多的方向
    for (uint8 i = 0; i < byFirstPathListLen; i++)
    {
        pstFirstPathData = &pstFirstPathList[i];     // 第一径数据
        byFreqIndex = pstFirstPathData->byFreqIndex; // 基站频率索引
        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
        if (pstCurrentBtsDirectionData->byDirectionXCounter > byMainDirectionXCounter)
        {
            byMainDirectionXCounter = pstCurrentBtsDirectionData->byDirectionXCounter;
            byFirstPathIndexX = i;
        }

        if (pstCurrentBtsDirectionData->byDirectionYCounter > byMainDirectionYCounter)
        {
            byMainDirectionYCounter = pstCurrentBtsDirectionData->byDirectionYCounter;
            byFirstPathIndexY = i;
        }
    }

    // 选择一个轴向，X轴或者Y轴
    if (byMainDirectionXCounter > byMainDirectionYCounter)
    {
        // X轴
        pstFirstPathData = &pstFirstPathList[byFirstPathIndexX]; // 第一径数据
        byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
        byMainDirectionX = pstCurrentBtsDirectionData->byDirectionX;
    }
    else if (byMainDirectionXCounter < byMainDirectionYCounter)
    {
        // Y轴
        pstFirstPathData = &pstFirstPathList[byFirstPathIndexY]; // 第一径数据
        byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
        pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
        byMainDirectionY = pstCurrentBtsDirectionData->byDirectionY;
    }
    else
    {
        // 在X轴移动较大
        if (byChangeXY == 1)
        {
            // X轴
            pstFirstPathData = &pstFirstPathList[byFirstPathIndexX]; // 第一径数据
            byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
            pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
            byMainDirectionX = pstCurrentBtsDirectionData->byDirectionX;
        }
        // 在Y轴移动较大
        else
        {
            // Y轴
            pstFirstPathData = &pstFirstPathList[byFirstPathIndexY]; // 第一径数据
            byFreqIndex = pstFirstPathData->byFreqIndex;             // 基站频率索引
            pstCurrentBtsDirectionData = &pstPredictionDirectionDataList[byFreqIndex];
            byMainDirectionY = pstCurrentBtsDirectionData->byDirectionY;
        }
    }

    // 保存参数
    *pbyDirectionX = byMainDirectionX;
    *pbyDirectionY = byMainDirectionY;

    return;
}

// 计算手机相对于基站的移动方向
// byDirectionTendency:手机相对于基站的运动趋势
// dwBtsCoordX:基站X坐标
// dwBtsCoordY:基站Y坐标
// pstAheadCoord:前一个定位点
// pbyDirectionX:X轴预测方向，返回参数，1：向右，-1：向左
// pbyDirectionY:Y轴预测方向，返回参数，1：向上，-1：向下
void lct_coordcal_cal_bts_move_direction(uint8 byDirectionTendency, int32 dwBtsCoordX, int32 dwBtsCoordY, COORD_T *pstAheadCoord, int8 *pbyDirectionX, int8 *pbyDirectionY)
{
    int8 byDirectionX = 0;
    int8 byDirectionY = 0;

    //// 预判当前手机相对于当前基站在x和y轴上的移动方向
    // 手机靠近当前站
    if (byDirectionTendency == 1)
    {
        // 从右侧靠近
        if (pstAheadCoord->dwX > dwBtsCoordX)
        {
            byDirectionX = -1;
        }
        // 从左侧靠近
        else if (pstAheadCoord->dwX < dwBtsCoordX)
        {
            byDirectionX = 1;
        }

        // 从上方靠近
        if (pstAheadCoord->dwY > dwBtsCoordY)
        {
            byDirectionY = -1;
        }
        // 从下方靠近
        else if (pstAheadCoord->dwY < dwBtsCoordY)
        {
            byDirectionY = 1;
        }
    }
    // 手机远离当前站
    else if (byDirectionTendency == 2)
    {
        // 从右侧远离
        if (pstAheadCoord->dwX > dwBtsCoordX)
        {
            byDirectionX = 1;
        }
        // 从左侧远离
        else if (pstAheadCoord->dwX < dwBtsCoordX)
        {
            byDirectionX = -1;
        }

        // 从上方远离
        if (pstAheadCoord->dwY > dwBtsCoordY)
        {
            byDirectionY = 1;
        }
        // 从下方远离
        else if (pstAheadCoord->dwY < dwBtsCoordY)
        {
            byDirectionY = -1;
        }
    }

    *pbyDirectionX = byDirectionX;
    *pbyDirectionY = byDirectionY;

    return;
}

// 根据X轴和Y轴移动趋势，校验预测坐标
void lct_coordcal_check_prediction_coord_by_xy_move_tendency(COORD_T *pstPredictionCoord, COORD_T *pstAheadCoord, int8 byDirectionX, int8 byDirectionY, int32 dwSpeedX, int32 dwSpeedY)
{
    // X轴向右移动
    if (byDirectionX == 1)
    {
        if (dwSpeedX <= 0)
        {
            pstPredictionCoord->dwX = pstAheadCoord->dwX - dwSpeedX;
        }
    }
    // X轴向左移动
    else if (byDirectionX == -1)
    {
        if (dwSpeedX >= 0)
        {
            pstPredictionCoord->dwX = pstAheadCoord->dwX - dwSpeedX;
        }
    }
    else
    {
        pstPredictionCoord->dwX = pstAheadCoord->dwX + 30;
    }

    // Y轴向上移动
    if (byDirectionY == 1)
    {
        if (dwSpeedY <= 0)
        {
            pstPredictionCoord->dwY = pstAheadCoord->dwY - dwSpeedY;
        }
    }
    else if (byDirectionY == -1)
    {
        if (dwSpeedY >= 0)
        {
            pstPredictionCoord->dwY = pstAheadCoord->dwY - dwSpeedY;
        }
    }
    else
    {
        pstPredictionCoord->dwY = pstAheadCoord->dwY + 30;
    }

    return;
}

// 根据基站围成的搜索矩阵校验预测坐标
void lct_coordcal_check_prediction_coord_by_bts_coord(COORD_T *pstPredicCoord, LCT_FIRSTPATH_T *pstCalBtsList, uint8 byCalBtsListLen, LCT_FIRSTPATH_T *pstTrackBtsList, uint8 byTrackBtsListLen)
{
    int32 dwBtsEdgeExpendLen = gg_stLctCoordcalParam.dwBtsEdgeExpendLen;
    COORD_T stPredicCoord = *pstPredicCoord; // 预测坐标
    int32 dwCalMinValueX = 2147483647;
    int32 dwCalMaxValueX = -2147483648;
    int32 dwCalMinValueY = 2147483647;
    int32 dwCalMaxValueY = -2147483648;

    int32 dwTrackMinValueX = 2147483647;
    int32 dwTrackMaxValueX = -2147483648;
    int32 dwTrackMinValueY = 2147483647;
    int32 dwTrackMaxValueY = -2147483648;

    int32 dwTmp = 0;

    LCT_FIRSTPATH_T *pstFirstpath = NULL;

    // 计算计算径坐标最大最小值
    for (uint8 i = 0; i < byCalBtsListLen; i++)
    {
        pstFirstpath = &pstCalBtsList[i];

        // X坐标
        if (pstFirstpath->dwCoordX < dwCalMinValueX)
        {
            dwCalMinValueX = pstFirstpath->dwCoordX;
        }
        if (pstFirstpath->dwCoordX > dwCalMaxValueX)
        {
            dwCalMaxValueX = pstFirstpath->dwCoordX;
        }

        // Y坐标
        if (pstFirstpath->dwCoordY < dwCalMinValueY)
        {
            dwCalMinValueY = pstFirstpath->dwCoordY;
        }
        if (pstFirstpath->dwCoordY > dwCalMaxValueY)
        {
            dwCalMaxValueY = pstFirstpath->dwCoordY;
        }
    }

    // 计算跟踪径坐标最大最小值
    for (uint8 j = 0; j < byTrackBtsListLen; j++)
    {
        pstFirstpath = &pstTrackBtsList[j];

        // X坐标
        if (pstFirstpath->dwCoordX < dwTrackMinValueX)
        {
            dwTrackMinValueX = pstFirstpath->dwCoordX;
        }
        if (pstFirstpath->dwCoordX > dwTrackMaxValueX)
        {
            dwTrackMaxValueX = pstFirstpath->dwCoordX;
        }

        // Y坐标
        if (pstFirstpath->dwCoordY < dwTrackMinValueY)
        {
            dwTrackMinValueY = pstFirstpath->dwCoordY;
        }
        if (pstFirstpath->dwCoordY > dwTrackMaxValueY)
        {
            dwTrackMaxValueY = pstFirstpath->dwCoordY;
        }
    }

    dwCalMinValueX = dwCalMinValueX < dwTrackMinValueX ? dwCalMinValueX : dwTrackMinValueX;
    dwCalMaxValueX = dwCalMaxValueX > dwTrackMaxValueX ? dwCalMaxValueX : dwTrackMaxValueX;
    dwCalMinValueY = dwCalMinValueY < dwTrackMinValueY ? dwCalMinValueY : dwTrackMinValueY;
    dwCalMaxValueY = dwCalMaxValueY > dwTrackMaxValueY ? dwCalMaxValueY : dwTrackMaxValueY;

    // 二次校验预测坐标
    dwTmp = dwCalMinValueX - dwBtsEdgeExpendLen;
    if (stPredicCoord.dwX < dwTmp)
    {
        stPredicCoord.dwX = dwTmp;
    }

    dwTmp = dwCalMaxValueX + dwBtsEdgeExpendLen;
    if (stPredicCoord.dwX > dwTmp)
    {
        stPredicCoord.dwX = dwTmp;
    }
    dwTmp = dwCalMinValueY - dwBtsEdgeExpendLen;
    if (stPredicCoord.dwY < dwTmp)
    {
        stPredicCoord.dwY = dwTmp;
    }

    dwTmp = dwCalMaxValueY + dwBtsEdgeExpendLen;
    if (stPredicCoord.dwY > dwTmp)
    {
        stPredicCoord.dwY = dwTmp;
    }

    *pstPredicCoord = stPredicCoord;

    return;
}
