You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

532 lines
12 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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
// 航线的来源是否来自软件安装路径的标识bFromLocalDirtrue——是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坐标系的坐标数组
//输入坐标系coordType0为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;
}