测量学用C语言编程求子午线弧长,GPS数据解析 数据拆分 坐标转换 显示线路图源代码...

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

{

iStart = str.Find(cFlag , iStart+1);

}

return   str.Mid(iStart+1 , str.GetLength()-iStart-1);

}

else

{

//do nothing

}

for (; 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

{

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

{

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

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值