|
|
#include "stdafx.h"
|
|
|
#include "LineManage.h"
|
|
|
#include "Globe.h"
|
|
|
|
|
|
CLineManage::CLineManage(void)
|
|
|
{
|
|
|
PtStruct pt;
|
|
|
line.AddTail(pt);
|
|
|
line.RemoveAll();
|
|
|
}
|
|
|
|
|
|
|
|
|
CLineManage::~CLineManage(void)
|
|
|
{
|
|
|
//2015.11.27 防止内存泄漏
|
|
|
MakeListNull();
|
|
|
}
|
|
|
|
|
|
void CLineManage::MakeListNull()
|
|
|
{
|
|
|
if (line.GetCount()>0)
|
|
|
{
|
|
|
line.RemoveAll();
|
|
|
}
|
|
|
}
|
|
|
//读取文件中的航线数据
|
|
|
//输入:航线文件名称strFileName
|
|
|
//输出:航线数据集合pLineData
|
|
|
//返回值:true——文件读取成功
|
|
|
// false——文件读取失败
|
|
|
bool CLineManage::ReadLineDataFromFile(DrawLineDataStruct &pLineData, const CString strFileName)
|
|
|
{
|
|
|
int ptNum = 0;
|
|
|
|
|
|
//初始化
|
|
|
memset(&pLineData, 0, sizeof(DrawLineDataStruct));
|
|
|
|
|
|
//存储航线的航点数据
|
|
|
PtStruct pts[257];
|
|
|
memset(pts, 0, sizeof(PtStruct)*257);
|
|
|
|
|
|
FILE *fpReadFlyLine = fopen(strFileName, "r");
|
|
|
|
|
|
if (fpReadFlyLine != NULL)
|
|
|
{
|
|
|
while (!feof(fpReadFlyLine))
|
|
|
{
|
|
|
if (!ReadLinePtAndCheckData(pts[ptNum], fpReadFlyLine))
|
|
|
{
|
|
|
BCGPMessageBox(_T("航线文件不符合要求\r\n或航线号与要显示的航线不一致"));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
ptNum ++;
|
|
|
}
|
|
|
|
|
|
//关闭文件
|
|
|
fclose(fpReadFlyLine);
|
|
|
}
|
|
|
else //空文件,航点数为0
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//对读取的航线数据进行有效性检查
|
|
|
if (CheckFlyLine(pts, ptNum))
|
|
|
{
|
|
|
//航点数据转换成标绘的航线数据集合
|
|
|
LinePoint2DrawLinePoints(pLineData, pts, ptNum);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//功能;航点数据转换成能标绘的航线数据体
|
|
|
void CLineManage::LinePoint2DrawLinePoints(DrawLineDataStruct &lineDataArr, const PtStruct *pLinePoints, const int linePointNum)
|
|
|
{
|
|
|
//航线编号
|
|
|
lineDataArr.lineID = pLinePoints[0].nL;
|
|
|
|
|
|
//判断第一个点是否为原点
|
|
|
if (pLinePoints[0].nPt == 0)
|
|
|
{
|
|
|
//航点个数
|
|
|
lineDataArr.pointNum = linePointNum-1;
|
|
|
|
|
|
//拷贝航点数据
|
|
|
memcpy(lineDataArr.pts, pLinePoints+1, sizeof(PtStruct)*lineDataArr.pointNum);
|
|
|
|
|
|
//航线的航点个数
|
|
|
lineDataArr.linePointNum = linePointNum-1;
|
|
|
|
|
|
//拷贝航线的航点数据
|
|
|
memcpy(lineDataArr.linePts, pLinePoints+1, sizeof(PtStruct)*lineDataArr.pointNum);
|
|
|
|
|
|
//根据航路特征字,判断航线标注的闭合形状,是“闭合航路”还是“返回原点”
|
|
|
if ((pLinePoints[linePointNum-1].ch2 == 0x01)||(pLinePoints[linePointNum-1].ch2 == 0x0B))
|
|
|
{
|
|
|
/*
|
|
|
if (lineDataArr.lineID>11)
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum] = pLinePoints[1];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum] = pLinePoints[linePointNum-1/ *1* /];
|
|
|
}*/
|
|
|
|
|
|
if (pLinePoints[linePointNum-1].ch1 == 0x02)//航线最后一个点的倒数第二位是0x02是为不闭合标志
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum] = pLinePoints[linePointNum - 1];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum] = pLinePoints[1];
|
|
|
}
|
|
|
|
|
|
//标绘的航点数加1
|
|
|
lineDataArr.linePointNum ++;
|
|
|
}
|
|
|
// else if (pLinePoints[linePointNum-1].ch2&0X01 == 0x01) //返回原点
|
|
|
else if (pLinePoints[linePointNum-1].ch2 == 0x00) //返回原点 2016.02.20
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum].dX = g_gcsLon;
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum].dY = g_gcsLat;
|
|
|
|
|
|
//标绘的航点数加1
|
|
|
lineDataArr.linePointNum ++;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//航点个数
|
|
|
lineDataArr.pointNum = linePointNum;
|
|
|
|
|
|
//拷贝航点数据
|
|
|
memcpy(lineDataArr.pts, pLinePoints, sizeof(PtStruct)*lineDataArr.pointNum);
|
|
|
|
|
|
//航线的航点个数
|
|
|
lineDataArr.linePointNum = linePointNum;
|
|
|
|
|
|
//拷贝航线的航点数据
|
|
|
memcpy(lineDataArr.linePts, pLinePoints, sizeof(PtStruct)*lineDataArr.pointNum);
|
|
|
|
|
|
//根据航路特征字,判断航线标注的闭合形状,是“闭合航路”还是“返回原点”
|
|
|
if (pLinePoints[linePointNum-1].ch2 == 0)
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum] = pLinePoints[0];
|
|
|
|
|
|
//标绘的航点数加1
|
|
|
lineDataArr.linePointNum ++;
|
|
|
}
|
|
|
// else if (pLinePoints[linePointNum-1].ch2&0X01 == 1) //返回原点
|
|
|
else if (pLinePoints[linePointNum-1].ch2 == 0x01) //返回原点
|
|
|
{
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum].dX = g_gcsLon;
|
|
|
lineDataArr.linePts[lineDataArr.linePointNum].dY = g_gcsLat;
|
|
|
|
|
|
//标绘的航点数加1
|
|
|
lineDataArr.linePointNum ++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//读取航线某航点 //2017.07.05
|
|
|
int CLineManage::ReadAirLinePoint(FILE *fp, PtStruct &pt)
|
|
|
{
|
|
|
return fscanf(fp, "%d, %d, %lf, %lf, %lf, %d, %02X, %02X\n", &pt.nL,
|
|
|
&pt.nPt, &pt.dX, &pt.dY, &pt.nH, &pt.nV, &pt.ch1, &pt.ch2);
|
|
|
}
|
|
|
|
|
|
|
|
|
//功能:读取航路文件的一行数据,并对该行数据进行检查
|
|
|
//输入:航路文件指针fp
|
|
|
//输出:航点数据体pt
|
|
|
//返回值:true——成功
|
|
|
// false——失败
|
|
|
bool CLineManage::ReadLinePtAndCheckData(PtStruct &pt, FILE *fp)
|
|
|
{
|
|
|
int redFlag = 0; //航路文件是否导入正确的标识
|
|
|
int nums = 8;
|
|
|
|
|
|
redFlag = ReadAirLinePoint(fp, pt);
|
|
|
|
|
|
if (redFlag != nums) //航路文件不对,返回
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//功能:对航路文件进行严格的数据检查
|
|
|
//输入:航路文件数据体pts,航点个数ptNum
|
|
|
//输出:更改航路特征后的航路文件数据体pts
|
|
|
|
|
|
//返回值:true——该航路文件数据正确
|
|
|
// false——该航路文件数据不正确
|
|
|
//检查项:
|
|
|
// 1、所有航点的航线编号是否一样;
|
|
|
// 2、所有航点的航点编号是否不一样;
|
|
|
// 3、除最后一个航点外,其余航点的航路特征字是否为“还有航点”;
|
|
|
// 4、最后一个航点的航路特征字是否为“闭合航路”,若不是更改成“闭合航路”
|
|
|
bool CLineManage::CheckFlyLine(PtStruct *pts, const int ptNum)
|
|
|
{
|
|
|
//航路点个数的有效范围为[0,255]共256个
|
|
|
//检测的有效范围为【2,256】
|
|
|
if ((ptNum>257) || (ptNum<2))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
int i=0;
|
|
|
int j=0;
|
|
|
|
|
|
//对单个航点的数据进行检查
|
|
|
for (i=0; i<ptNum; i++)
|
|
|
{
|
|
|
if (!CheckOnePointValue(pts[i]))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//对航点的航线编号进行严格检查
|
|
|
//当存在航线编号不一样时,返回false
|
|
|
int ptLineID = pts[0].nL;
|
|
|
for (i=1; i<ptNum; i++)
|
|
|
{
|
|
|
if (ptLineID != pts[i].nL)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//对航线的航点编号进行严格检查,判断规则为,起点为0或1,依次递增1
|
|
|
//当存在航点编号不符合规则时,返回false
|
|
|
if ( (pts[0].nPt != 0) && (pts[0].nPt != 1) )
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
int toComparePtId = pts[0].nPt + 1;
|
|
|
for (i=1; i<ptNum; i++)
|
|
|
{
|
|
|
if (pts[i].nPt != toComparePtId)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
toComparePtId++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true; //2016.02.17
|
|
|
|
|
|
//-------------delete in 2016.02.17-------------------//
|
|
|
//不对航点特征字进行判断
|
|
|
/*
|
|
|
// //对除最后一个航点进行验证,看其是否为“还有航点”;
|
|
|
// for (i=0; i<ptNum-1; i++)
|
|
|
// {
|
|
|
// if ((pts[i].ch2 & 0x02) == 0) //“闭合航路”时返回false
|
|
|
// {
|
|
|
// return false;
|
|
|
// }
|
|
|
// }
|
|
|
//
|
|
|
// //对最后一个航点进行验证,看其是否为“航点结束”,且航路结束特征为“闭合航路”
|
|
|
// //若是“航点结束”,但航路结束特征不为“闭合航路”,返回false
|
|
|
// if ((pts[ptNum-1].ch2 & 0x02) == 0)
|
|
|
// {
|
|
|
// //2015.12.02
|
|
|
// // if ((pts[ptNum-1].ch2 & 0x01) != 0) //航路结束特征不是“闭合航路”
|
|
|
// // {
|
|
|
// // return false;
|
|
|
// // }
|
|
|
// // else //航路结束特征为“闭合航路”
|
|
|
// // {
|
|
|
// // return true;
|
|
|
// // }
|
|
|
//
|
|
|
// return true;
|
|
|
// }
|
|
|
// else
|
|
|
// {
|
|
|
// return false;
|
|
|
// }*/
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//功能:对单个航点的数据的有效范围进行检查
|
|
|
//输入:航点数据体pt
|
|
|
//返回值:true——航点数据位于有效范围内
|
|
|
// false——航点数据超限
|
|
|
bool CLineManage::CheckOnePointValue(const PtStruct pt)
|
|
|
{
|
|
|
//航点数据的数据范围进行检查,看其是否符合要求
|
|
|
//对导入的数据进行判读,超限就弹出错误,并返回
|
|
|
if ( (pt.nL<1) || (pt.nL>14)
|
|
|
|| (pt.nPt<0) || (pt.nPt>255)
|
|
|
|| (pt.dX<-180) || (pt.dX>180)
|
|
|
|| (pt.dY<-90) || (pt.dY>90)
|
|
|
|| (pt.nH<-500) || (pt.nH>10000)
|
|
|
|| (pt.nV<0) || (pt.nV>360)
|
|
|
|| (pt.ch1<0) || (pt.ch1>255)
|
|
|
|| (pt.ch2<0) || (pt.ch2>255) )
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//功能:打开无人机航路文件
|
|
|
//输入:航路文件的绝对路径str
|
|
|
// 航线编号nL:1、2、3、4、5
|
|
|
// 航线的来源,是否来自软件安装路径的标识bFromLocalDir:true——是;false——不是
|
|
|
// 其中:1、从软件安装目录下加载的航线文件需要对原点是否存在进行判断;航线导入不需要判断
|
|
|
// 2、从软件安装目录下加载的航线文件需要对航线ID进行检查,航线导入不需要检查
|
|
|
|
|
|
//输出:航点数据存储于类的的成员line中
|
|
|
//返回值:成功——返回true
|
|
|
// 失败——返回false
|
|
|
bool CLineManage::OpenFlyLineFile(const CString &str, const int &nL, const bool &bFromLocalDir)
|
|
|
{
|
|
|
MakeListNull(); //清空已有的数据
|
|
|
FILE* fp;
|
|
|
PtStruct pt;
|
|
|
//读取航线文件
|
|
|
fp = fopen(str, "r");
|
|
|
if (fp == NULL)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
int linePtNum = 0;
|
|
|
while(!feof(fp))
|
|
|
{
|
|
|
if (!ReadLinePtAndCheckData(pt, fp))
|
|
|
{
|
|
|
|
|
|
return WrongLineDataProcess(fp);
|
|
|
}
|
|
|
AddPt(pt);
|
|
|
linePtNum++;
|
|
|
|
|
|
}
|
|
|
//return true;
|
|
|
PtStruct *linePts = new PtStruct[LINEPTNUM];
|
|
|
memset(linePts, 0, sizeof(PtStruct)*LINEPTNUM);
|
|
|
ListData2ArrayData(linePts, linePtNum, 1);
|
|
|
|
|
|
//对航线数据进行严格的检查
|
|
|
if (CheckFlyLine(linePts, linePtNum))
|
|
|
{
|
|
|
if (bFromLocalDir) //本地路径加载的航线文件
|
|
|
{
|
|
|
if (CheckOrgPtIsExisted(linePts, linePtNum) &&
|
|
|
CheckFlyLineIDCorrect(linePts, linePtNum, nL))
|
|
|
{
|
|
|
fclose(fp);
|
|
|
if (linePts != NULL)
|
|
|
{
|
|
|
delete []linePts;
|
|
|
linePts = NULL;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (linePts != NULL)
|
|
|
{
|
|
|
delete []linePts;
|
|
|
linePts = NULL;
|
|
|
}
|
|
|
return WrongLineDataProcess(fp);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//航路文件读取成功,数据验证均正确
|
|
|
if (linePts != NULL)
|
|
|
{
|
|
|
delete []linePts;
|
|
|
linePts = NULL;
|
|
|
}
|
|
|
fclose(fp);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (linePts != NULL)
|
|
|
{
|
|
|
delete []linePts;
|
|
|
linePts = NULL;
|
|
|
}
|
|
|
return WrongLineDataProcess(fp);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//功能:文件读取错误时采取的操作
|
|
|
bool CLineManage::WrongLineDataProcess(FILE *fp)
|
|
|
{
|
|
|
//删除原有的数据
|
|
|
MakeListNull();
|
|
|
//关闭文件
|
|
|
fclose(fp);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//拷贝航线数据
|
|
|
void CLineManage::AddPt(PTLIST *other)
|
|
|
{
|
|
|
MakeListNull();
|
|
|
|
|
|
POSITION pos = other->GetHeadPosition();
|
|
|
for (int i=0; i<other->GetCount(); i++)
|
|
|
{
|
|
|
PtStruct pt = other->GetNext(pos);
|
|
|
//航线编号都置为0
|
|
|
pt.nL = 0;
|
|
|
line.AddTail(pt); //往每块数据里添加航点数据
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//增加航点
|
|
|
void CLineManage::AddPt(PtStruct pt)
|
|
|
{
|
|
|
//拷贝一份数据
|
|
|
line.AddTail(pt); //往每块数据里添加航点数据
|
|
|
}
|
|
|
|
|
|
//增加原点航点
|
|
|
void CLineManage::AddPt(const double &L, const double &B,const float& H, const int &ptId)
|
|
|
{
|
|
|
PtStruct pt;
|
|
|
memset(&pt,0,sizeof(PtStruct));
|
|
|
|
|
|
pt.ch2 = 0x03; //航点特征字为“还有航点”
|
|
|
pt.dX = L;
|
|
|
pt.dY = B;
|
|
|
pt.nPt = ptId;
|
|
|
pt.nH = H;
|
|
|
|
|
|
|
|
|
//WGS84坐标转BJ54坐标
|
|
|
if (ptId == 0) //原点坐标
|
|
|
{
|
|
|
//wgs84AndBj54.Wgs84TransToBj54(&pt.dX, &pt.dY); //WGS84转BJ54坐标
|
|
|
}
|
|
|
|
|
|
line.AddTail(pt); //往每块数据里添加航点数据
|
|
|
}
|
|
|
|
|
|
|
|
|
//功能:将链表里存储的数据转化成指定坐标系的数组存储
|
|
|
// 如coordType=0——输出wgs84坐标系的坐标数组
|
|
|
// 如coordType=1——输出bj54坐标系的坐标数组
|
|
|
|
|
|
//输入:坐标系coordType:0为wgs84;1为bj54坐标系
|
|
|
//输出:航点数组pts,航点总数ptNum
|
|
|
void CLineManage::ListData2ArrayData(PtStruct *pts, int &ptNum, const int &coordType)
|
|
|
{
|
|
|
ptNum = line.GetCount();
|
|
|
int i=0;
|
|
|
POSITION ps = line.GetHeadPosition();
|
|
|
for (i=0; i<ptNum; ++i)
|
|
|
{
|
|
|
pts[i] = line.GetNext(ps);
|
|
|
}
|
|
|
|
|
|
//输出WGS84坐标系的坐标,需进行BJ54到WGS84间的变换
|
|
|
if (coordType == 0)
|
|
|
{
|
|
|
for (i=0; i<ptNum; ++i)
|
|
|
{
|
|
|
//wgs84AndBj54.Bj54TransToWgs84(&pts[i].dX, &pts[i].dY);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//功能:判断航线数据的第一个点是否为原点
|
|
|
//输入:航点数组pts,航点总数ptNum
|
|
|
//返回值:true——存在;
|
|
|
// false——不存在
|
|
|
bool CLineManage::CheckOrgPtIsExisted(const PtStruct *pts, const int &ptNum)
|
|
|
{
|
|
|
if (pts[0].nPt == 0) //原点点号为0
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//功能:判断航线数据的航线编号是否为设置的航线编号
|
|
|
//输入:航点数组pts,航点总数ptNum
|
|
|
//返回值:true——存在;
|
|
|
// false——不存在
|
|
|
bool CLineManage::CheckFlyLineIDCorrect(const PtStruct *pts, const int &ptNum, const int &nL)
|
|
|
{
|
|
|
for (int i=0; i<ptNum; ++i)
|
|
|
{
|
|
|
if (pts[i].nL != nL)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
} |