GPS数据解析 数据拆分 坐标转换 显示线路图源代码

来源:互联网 发布:golang webloop 编辑:程序博客网 时间:2024/05/15 23:06

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);

}

原创粉丝点击