#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; i14) || (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; iGetCount(); 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