- GPS数据提取解析源码GPS source data extraction analysis, we can refer to learn from
- GPS数据解析
- 数据拆分 \坐标转换 \显示线路图\源代码
- 逐条读取gps数据 然后进行拆分 解析,坐标转换,绘制线路。。。很好的示例多多交流学习。。
- 本程序是基于VC++ 建立的单文档工程。
- 废话少说,直接上代码
- //获取子字符串个数
- int GetSubStrCount(CString str,char cFlag)
- {
- cFlag = ',';
- int i = 0;
- BOOL isHas = FALSE;
- for (int iStart = -1; -1 != (iStart = str.Find(cFlag,iStart+1)) ; i++)
- {
- isHas = TRUE;
- }
- if (!isHas)
- {
- return 0;
- }
- else
- {
- return i+1;
- }
- }
- //获取子字符串
- // i 序号 0
- CString GetSubStr(CString str,int i,char cFlag)
- {
- cFlag = ',';
- int iStart = -1;
- int iEnd = 0;
- int j = 0;
- int iStrCount;
- iStrCount = GetSubStrCount(str,cFlag);
- if (i>iStrCount -1 || i<0)
- {
- str = "";
- return str;
- }
- else
- {
- //do nothing
- }
- if (i == iStrCount-1)
- {
- i = iStrCount;
- for (;j<i-1;j++)
- {
- iStart = str.Find(cFlag , iStart+1);
- }
- return str.Mid(iStart+1 , str.GetLength()-iStart-1);
- }
- else
- {
- //do nothing
- }
- for (; j<i; j++)
- {
- iStart = str.Find(cFlag , iStart+1);
- }
- iEnd = str.Find(cFlag , iStart+1);
- return str.Mid(iStart+1 , iEnd-iStart-1);
- }
- //数据解析
- CString CGpsDataView::Analyzing(CString str)
- {
- CString subStr[20];
- char cFlag = ',';
- int j = GetSubStrCount(str,cFlag); //得到该行的子字符串个数
- CStdioFile wFile;
- wFile.Open("save.txt",CFile::modeCreate | CFile::modeWrite | CFile::typeText);//将数据写入文件
- for (int i=0;i<j;i++)
- {
- subStr[i] = GetSubStr(str,i,cFlag);
- }
- //GPGGA数据
- if (subStr[0] == "$GPGGA")
- {
- CoordCovert(subStr[2],subStr[4]);
- //提取时间
- subStr[1].Insert(2,':');
- subStr[1].Insert(5,':');
- subStr[1].Insert(0," UTC时间:");
- //提取纬度
- if (subStr[3] == 'N')
- {
- subStr[2].Insert(11,"分");
- subStr[2].Insert(2,"度");
- subStr[2].Insert(0," 北纬");
- }
- else if (subStr[3] == 'S')
- {
- subStr[2].Insert(11,"分");
- subStr[2].Insert(2,"度");
- subStr[2].Insert(0," 南纬");
- }
- //提取经度
- if (subStr[5] == 'E')
- {
- subStr[4].Insert(12,"分");
- subStr[4].Insert(3,"度");
- subStr[4].Insert(0," 东经");
- }
- else if (subStr[5] == 'W')
- {
- subStr[4].Insert(12,"分");
- subStr[4].Insert(3,"度");
- subStr[4].Insert(0," 西经");
- }
- //判断GPS状态
- CString GpsState;
- if (subStr[6] == '0')
- {
- GpsState = " GPS状态:无定位.";
- }
- else if (subStr[6] == '1')
- {
- GpsState = " GPS状态:无差分校正定位.";
- }
- else if (subStr[6] == '2')
- {
- GpsState = " GPS状态:差分校正定位.";
- }
- else if (subStr[6] == '9')
- {
- GpsState = " GPS状态:用星历计算定位.";
- }
- //提取卫星数
- subStr[7].Insert(0," 卫星数:");
- //提取平面位置精度因子
- subStr[8].Insert(0," 平面位置精度因子:");
- //天线海拔高度
- subStr[9].Insert(strlen(subStr[9]),subStr[10]);
- subStr[9].Insert(0," 天线海拔高度:");
- //海平面分离度
- subStr[11].Insert(strlen(subStr[11]),subStr[12]);
- subStr[11].Insert(0," 海平面分离度:");
- subStr[0] += subStr[1];
- subStr[0] += subStr[2];
- subStr[0] += subStr[4];
- subStr[0] += GpsState;
- subStr[0] += subStr[7];
- subStr[0] += subStr[8];
- subStr[0] += subStr[9];
- subStr[0] += subStr[11];
- //MessageBox(subStr[0]);
- wFile.WriteString(subStr[0]);//将数据写入文件
- }
- //GPZDA数据
- else if (subStr[0] == "$GPZDA")
- {
- //提取时间
- subStr[1].Insert(2,':');
- subStr[1].Insert(5,':');
- subStr[1].Insert(0," UTC时间:");
- //提取日期
- subStr[2].Insert(strlen(subStr[2]),"日");
- subStr[2].Insert(0,"月");
- subStr[2].Insert(0,subStr[3]);
- subStr[2].Insert(0,"年");
- subStr[2].Insert(0,subStr[4]);
- subStr[2].Insert(0,' ');
- //当地时域描述
- subStr[5].Insert(strlen(subStr[5]),"小时");
- if (strlen(subStr[6]) > 3)
- {
- subStr[6] = subStr[6].Left(2);
- }
- else
- {
- subStr[6] = '0';
- }
- subStr[6] += "分";
- subStr[6].Insert(0,subStr[5]);
- subStr[6].Insert(0," 当地时域:");
- subStr[0] += subStr[1];
- subStr[0] += subStr[2];
- subStr[0] += subStr[6];
- //MessageBox(subStr[0]);
- wFile.WriteString(subStr[0]);//将数据写入文件
- }
- //GPGSA数据
- else if (subStr[0] == "$GPGSA")
- {
- //卫星捕获模式,以及定位模式
- CString CatchLocation;
- if (subStr[1] == 'M')
- {
- if (subStr[2] == '1')
- {
- CatchLocation = " 手动捕获卫星,未定位!";
- }
- else if (subStr[2] == '2')
- {
- CatchLocation = " 手动捕获卫星,2D定位!";
- }
- else if (subStr[2] == '3')
- {
- CatchLocation = " 手动捕获卫星,3D定位!";
- }
- }
- else if (subStr[1] == 'A')
- {
- if (subStr[2] == '1')
- {
- CatchLocation =" 自动捕获卫星,未定位!";
- }
- else if (subStr[2] == '2')
- {
- CatchLocation =" 自动捕获卫星,2D定位!";
- }
- else if (subStr[2] == '3')
- {
- CatchLocation =" 自动捕获卫星,3D定位!";
- }
- }
- //各卫星定位结果
- subStr[3].Insert(0," 各卫星定位结果:");
- subStr[3] += ' ';
- subStr[4].Insert(0,subStr[3]);
- subStr[4] += ' ';
- subStr[5].Insert(0,subStr[4]);
- subStr[5] += ' ';
- subStr[6].Insert(0,subStr[5]);
- subStr[6] += ' ';
- subStr[7].Insert(0,subStr[6]);
- subStr[7] += ' ';
- subStr[8].Insert(0,subStr[7]);
- subStr[8] += ' ';
- subStr[9].Insert(0,subStr[8]);
- subStr[9] += ' ';
- subStr[10].Insert(0,subStr[9]);
- subStr[10] += ' ';
- subStr[11].Insert(0,subStr[10]);
- subStr[11] += ' ';
- subStr[12].Insert(0,subStr[11]);
- subStr[12] += ' ';
- subStr[13].Insert(0,subStr[12]);
- subStr[13] += ' ';
- subStr[14].Insert(0,subStr[13]);
- subStr[14] += ' ';
- //空间(三维)位置精度因子
- subStr[15].Insert(0," 空间(三维)位置精度因子:");
- //平面位置精度因子
- subStr[16].Insert(0," 平面位置精度因子:");
- //高度位置精度因子
- subStr[17] = subStr[17].Left(3);
- subStr[17].Insert(0," 高度位置精度因子:");
- subStr[0] += CatchLocation;
- subStr[0] += subStr[14];
- subStr[0] += subStr[15];
- subStr[0] += subStr[16];
- subStr[0] += subStr[17];
- /MessageBox(subStr[0]);
- wFile.WriteString(subStr[0]);//将数据写入文件
- }
- //GPGSV数据
- else if (subStr[0] == "$GPGSV")
- {
- ///MessageBox(subStr[0]);
- //卫星编号、卫星仰角(0~90度)、卫星方位角(0~359度)、信噪比
- subStr[4].Insert(0,"卫星编号:");
- subStr[5].Insert(0," 仰角:");
- subStr[6].Insert(0," 方位角:");
- subStr[7].Insert(0," 信噪比:");
- subStr[4] += subStr[5];
- subStr[4] += subStr[6];
- subStr[4] += subStr[7];
- ///MessageBox(subStr[4]);
- subStr[8].Insert(0,"卫星编号:");
- subStr[9].Insert(0," 仰角:");
- subStr[10].Insert(0," 方位角:");
- subStr[11].Insert(0," 信噪比:");
- subStr[8] += subStr[9];
- subStr[8] += subStr[10];
- subStr[8] += subStr[11];
- MessageBox(subStr[8]);
- subStr[12].Insert(0,"卫星编号:");
- subStr[13].Insert(0," 仰角:");
- subStr[14].Insert(0," 方位角:");
- subStr[15].Insert(0," 信噪比:");
- subStr[12] += subStr[13];
- subStr[12] += subStr[14];
- subStr[12] += subStr[15];
- /MessageBox(subStr[12]);
- subStr[16].Insert(0,"卫星编号:");
- subStr[17].Insert(0," 仰角:");
- subStr[18].Insert(0," 方位角:");
- if (strlen(subStr[19]) > 3)
- {
- subStr[19] = subStr[19].Left(2);
- }
- else
- {
- subStr[19] = '0';
- }
- subStr[19].Insert(0," 信噪比:");
- subStr[16] += subStr[17];
- subStr[16] += subStr[18];
- subStr[16] += subStr[19];
- /MessageBox(subStr[16]);
- wFile.WriteString(subStr[16]);//将数据写入文件
- }
- return str;
- }
- //读取文件数据并解析
- void CGpsDataView::OnFileRead()
- {
- // TODO: 在此添加命令处理程序代码
- CStdioFile myFile;
- CString oneLine;
- char cFlag = ',';
- CString subStr[20];
- //读取GPS数据文件
- if(!myFile.Open(("gps.txt"),CFile::modeRead | CFile::typeText))
- {
- AfxMessageBox(_T("打开文件错误!"));
- return;
- }
- else
- {
- /*do nothing*/
- }
- while (myFile.ReadString(oneLine))//读一行
- {
- //MessageBox(oneLine);
- int j = GetSubStrCount(oneLine,cFlag); //得到该行的子字符串个数
- //校验
- if(CheckNum(oneLine))
- {
- MessageBox(_T("数据校验...接收正确!..."));
- for (int i=0;i<j;i++)
- {
- subStr[i] = GetSubStr(oneLine,i,cFlag);
- //MessageBox(subStr[i]);
- }
- Analyzing(oneLine); //解析
- }
- else
- {
- AfxMessageBox(_T("数据校验..接收错误!..."));
- }
- }
- myFile.Close();
- }
- //***********************************************************************************************
- //坐标转换
- //度分秒--弧度
- double Dms2Rad(double Dms)
- {
- double Degree, Miniute;
- double Second;
- int Sign;
- double Rad;
- if(Dms >= 0)
- {
- Sign = 1;
- }
- else
- {
- Sign = -1;
- }
- Dms = fabs(Dms); //绝对值
- Degree = floor(Dms); // 取度 floor(2.800) = 2.0000
- Miniute = floor(fmod(Dms * 100.0, 100.0)); //fmod 计算余数
- Second = fmod(Dms * 10000.0, 100.0);
- Rad = Sign * (Degree + Miniute / 60.0 + Second / 3600.0) * PI / 180.0;
- return Rad;
- }
- double Rad2Dms(double Rad)
- {
- double Degree, Miniute;
- double Second;
- int Sign;
- double Dms;
- if(Rad >= 0)
- {
- Sign = 1;
- }
- else
- {
- Sign = -1;
- }
- Rad = fabs(Rad * 180.0 / PI);
- Degree = floor(Rad);
- Miniute = floor(fmod(Rad * 60.0, 60.0));
- Second = fmod(Rad * 3600.0, 60.0);
- Dms = Sign * (Degree + Miniute / 100.0 + Second / 10000.0);
- return Dms;
- }
- //正算公式
- bool GpsPoint::BL2xy()
- {
- //大地测量学基础 (吕志平 乔书波 北京:测绘出版社 2010.03)
- double X; //由赤道至纬度为B的子午线弧长 (P106 5-41)
- double N; //椭球的卯酉圈曲率半径
- double t;
- double t2;
- double m;
- double m2;
- double ng2;
- double cosB;
- double sinB;
- X = A1 * B * 180.0 / PI + A2 * sin(2 * B)
- + A3 * sin(4 * B) + A4 * sin(6 * B);
- sinB = sin(B);
- cosB = cos(B);
- t = tan(B);
- t2 = t * t;
- N = a /sqrt(1 - e2 * sinB * sinB);
- m = cosB * (L - L0);
- m2 = m * m;
- ng2 = cosB * cosB * e2 / (1 - e2);
- //P156 (6-63公式)
- x = X + N * t *(( 0.5 + ( (5 - t2 + 9 * ng2 + 4 * ng2 * ng2)
- / 24.0 + (61 - 58 * t2 + t2 * t2) * m2 / 720.0) * m2)* m2);
- y = N * m * ( 1 + m2 * ( (1 - t2 + ng2) / 6.0 + m2 * ( 5 - 18 * t2 + t2 * t2
- + 14 * ng2 - 58 * ng2 * t2 ) / 120.0));
- //y += 500000;
- return true;
- }
- //反算公式
- bool GpsPoint::xy2BL()
- {
- double sinB;
- double cosB;
- double t;
- double t2;
- double N; //椭球的卯酉圈曲率半径
- double ng2;
- double V;
- double yN;
- double preB0;
- double B0;
- double eta;
- //y -= 500000;
- B0 = x / A1;
- do
- {
- preB0 = B0;
- B0 = B0 * PI / 180.0;
- B0 = (x - (A2 * sin(2 * B0) + A3 * sin(4 * B0) + A4 * sin(6 * B0))) / A1;
- eta = fabs(B0 - preB0);
- }while(eta > 0.000000001);
- B0 = B0 * PI / 180.0;
- B = Rad2Dms(B0);
- sinB = sin(B0);
- cosB = cos(B0);
- t = tan(B0);
- t2 = t * t;
- N = a / sqrt(1 - e2 * sinB * sinB);
- ng2 = cosB * cosB * e2 / (1 - e2);
- V = sqrt(1 + ng2);
- yN = y / N;
- B = B0 - (yN * yN - (5 + 3 * t2 + ng2 - 9 * ng2 * t2) * yN * yN * yN * yN
- / 12.0 + (61 + 90 * t2 + 45 * t2 * t2) * yN * yN * yN * yN * yN * yN / 360.0)
- * V * V * t / 2;
- L = L0 + (yN - (1 + 2 * t2 + ng2) * yN * yN * yN / 6.0 + (5 + 28 * t2 + 24
- * t2 * t2 + 6 * ng2 + 8 * ng2 * t2) * yN * yN * yN * yN * yN / 120.0) / cosB;
- return true;
- }
- //设置中央子午线
- bool GpsPoint::SetL0(double dL0)
- {
- L0 = Dms2Rad(dL0);
- return true;
- }
- //将度分秒经纬度转换为弧度后再转换为平面坐标
- bool GpsPoint::SetBL(double dB, double dL)
- {
- B = Dms2Rad(dB);
- L = Dms2Rad(dL);
- BL2xy();
- return true;
- }
- bool GpsPoint::GetBL(double *dB, double *dL)
- {
- *dB = Rad2Dms(B);
- *dL = Rad2Dms(L);
- return true;
- }
- //将平面坐标转换为(弧度)经纬度
- bool GpsPoint::Setxy(double dx, double dy)
- {
- x = dx;
- y = dy;
- xy2BL();
- return true;
- }
- bool GpsPoint::Getxy(double *dx, double *dy)
- {
- *dx = x;
- *dy = y;
- return true;
- }
- GpsPoint_Krasovsky::GpsPoint_Krasovsky()
- {
- a = 6378245; //长半径
- f = 298.3; //扁率的倒数 (扁率:(a-b)/a)
- e2 = 1 - ((f - 1) / f) * ((f - 1) / f); //第一偏心率的平方
- e12 = (f / (f - 1)) * (f / (f - 1)) - 1; //第二偏心率的平方
- // 克拉索夫斯基椭球
- A1 = 111134.8611;
- A2 = -16036.4803;
- A3 = 16.8281;
- A4 = -0.0220;
- }
- //*************坐标转换
- bool CGpsDataView::CoordCovert(CString latitude, CString longitude)
- {
- double bbb = atof(latitude);
- double lll = atof(longitude);
- //度分格式转换为度分秒格式
- bbb = Dm2Dms(bbb);
- lll = Dm2Dms(lll);
- double MyL0 ; //中央子午线
- double MyB = bbb ; //33 d 44 m 55.6666 s
- double MyL = lll ; //3度带,109 d 22 m 33.4444 s
- //计算当地中央子午线 ,3度带
- MyL0 = fabs(MyL);
- MyL0 = floor(MyL);
- MyL0 = 3 * floor(MyL0 / 3 );
- GpsPoint_Krasovsky MyPrj;
- MyPrj.SetL0(MyL0);
- MyPrj.SetBL(MyB, MyL);
- double OutMyX;
- double OutMyY;
- OutMyX = MyPrj.x; //正算结果:坐标x
- OutMyY = MyPrj.y; //结果:坐标y
- CString strTemp1;
- CString strTemp2;
- CString strTemp3;
- CString strTemp4;
- strTemp1.Format("%f",OutMyX);
- strTemp2.Format("%f",OutMyY);
- strTemp1.Insert(0,"x = ");
- strTemp2.Insert(0," , y = ");
- strTemp2.Insert(0,strTemp1);
- strTemp2.Insert(0," 坐标转换: ");
- strTemp3.Format("%f12",MyB);
- strTemp4.Format("%f12",MyL);
- strTemp3.Insert(0,"B = ");
- strTemp4.Insert(0," L = ");
- strTemp4.Insert(0,strTemp3);
- strTemp2.Insert(0,strTemp4);
- //MessageBox(strTemp2);
- DrawPoint(MyPrj.x,MyPrj.y);
- return true;
- }
- //==================================
- //度分格式转换为度分秒格式
- double CGpsDataView::Dm2Dms(double Dm)
- {
- double Dms;
- double temp;
- temp = Dm - floor(Dm);
- temp = (temp * 60) / 100;
- Dm = floor(Dm);
- Dm += temp;
- Dm = Dm /100;
- Dms = Dm;
- return Dms;
- }
- //*************绘制线路 显示出路线
- int count1=0;
- bool bFirst = true;
- double xTemp;
- double yTemp;
- void CGpsDataView::DrawPoint(double X, double Y)
- {
- Sleep(100);
- //X = (X - floor(X))*100;
- //Y = (Y - floor(Y))*100;
- if (bFirst)
- {
- xTemp=X;
- yTemp=Y;
- bFirst=false;
- }
- CDC *pDC=GetDC();
- CPen pen(PS_SOLID,3,RGB(255,20,20));
- CPen *pOldPen;
- CBrush *pOldBrush;
- CBrush *pBrush=CBrush::FromHandle( (HBRUSH)GetStockObject(NULL_BRUSH) );
- pOldPen=pDC->SelectObject(&pen);
- pOldBrush=pDC->SelectObject(pBrush);
- int a=(int)(100.0-(X-xTemp)*800.0);
- int b=(int)(100.0+(Y-yTemp)*800.0);
- //绘制点显示路径
- pDC->Ellipse(a,b,a+5,b+5);
- //计数
- count1=count1+1;
- pDC->SelectObject( pOldBrush );
- pDC->SelectObject( pOldPen );
- CString str;
- str.Format("%.1f,%.1f,%d,%d,%d",X-xTemp,Y-yTemp,a,b,count1);
- pDC->TextOut(10,10,str);
- }