📄 gps.cpp
字号:
// Gps.cpp: implementation of the CGps class.
//
//////////////////////////////////////////////////////////////////////
//GPS数据处理类
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Gps.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include "CommFun.h"
//地球常量
const double D2R = 0.017453;
const double R2D = 57.295781;
const double a = 6378137.0;//地球长半径
const double b = 6356752.314245;//短半径
const double e2 = 0.006739496742337;//偏心率平方
const double f = 0.003352810664747;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGps::CGps()
{
}
CGps::~CGps()
{
}
//根据两点经纬度计算距离
double CGps::GetDis(double StartLat, double StartLong, double EndLat, double EndLong)
{
if(StartLong==EndLong && StartLat==EndLat){
return 0;
}
double fPhimean;
double fdLambda;
double fdPhi;
double fAlpha;
double fNu;
double fR;
double fz;
double fTemp;
double Distance;
double fRho;
//long br;
fdLambda = (StartLong - EndLong) * D2R;
fdPhi = (StartLat - EndLat) * D2R;
fPhimean = ((StartLat + EndLat) / 2.0) * D2R;
fTemp = 1 - e2 * (pow(sin(fPhimean),2));
fRho = (a * (1 - e2)) / pow(fTemp, 1.5);
fNu = a / (sqrt(1 - e2 * (sin(fPhimean) * sin(fPhimean))));
fz = sqrt(pow(sin(fdPhi/2.0),2)+cos(EndLat*D2R)*cos(StartLat*D2R)*pow(sin(fdLambda/2.0),2)) ;
fz = 2 * asin(fz);
fAlpha = cos(EndLat * D2R) * sin(fdLambda) * 1 / sin(fz);
fAlpha = asin(fAlpha);
fR = (fRho * fNu) / ((fRho * pow(sin(fAlpha),2)) + (fNu * pow(cos(fAlpha),2)));
Distance = (fz * fR);
/*br=(long)(fAlpha * R2D);
if((StartLat <= EndLat) && (StartLong <= EndLong))
*Bearing = abs(br);
else if ((StartLat <= EndLat) && (StartLong >= EndLong))
*Bearing = 360 - abs(br);
else if ((StartLat >= EndLat) && (StartLong >= EndLong))
*Bearing = 180 + abs(br);
else if ((StartLat >= EndLat) && (StartLong <= EndLong))
*Bearing = 180 - abs(br);*/
return Distance;
}
//把GPS原始纬度数据转换成度数
double CGps::TransLat(CString strLat, CString NS)
{ //北纬为正,南纬为负
double dLat;
int iDot;//小数点位置
iDot=strLat.Find(".");
dLat=atof(strLat.Left(iDot-2))+atof(strLat.Mid(iDot-2))/60;
if(NS=="S"){//南纬为负
dLat=-1*dLat;
}
//输出
return dLat;
}
//把GPS原始经度数据转换成度数
double CGps::TransLong(CString strLong, CString EW)
{ //东经为正,西经为负
double dLong;
int iDot;//小数点位置
iDot=strLong.Find(".");
dLong=atof(strLong.Left(iDot-2))+atof(strLong.Mid(iDot-2))/60;
if(EW=="W"){//南纬为负
dLong=-1*dLong;
}
//输出
return dLong;
}
//原始数据得到经纬度信息
long CGps::FilterLatLong(CString strGPGGA, double *dLat, double *dLong)
{
//初始化返回值
*dLat=0;
*dLong=0;
///////////////
CString GPGGA; //GPGGA数据
int i,j; //位置索引
CString sData[100]; //切分数组
CString strTmp;
GPGGA=strGPGGA;
//检查可用性,卫星个数大于3
//切分,取出信息
i=0;
while(GPGGA.GetLength()>0){//切分
j=GPGGA.Find(",");
if(j==-1){
sData[i]=GPGGA;
GPGGA.Delete(0);
}else{
sData[i]=GPGGA.Left(j);
GPGGA.Delete(0,j+1);
i++;
}
}
if(!CCommFun::IsNumber(sData[7])){//不是数字
return -1;
}else{
if(atoi(sData[7])<3){//正确的数据但不可用卫星个数小于3
return -2;
}else{//正确的可用的gps数据
*dLat=TransLat(sData[2],sData[3]);
*dLong=TransLong(sData[4],sData[5]);
return 0;
}
}
}
//角度和速度
long CGps::FilterFV(CString GPVTG, long *lJiao, double *dV)
{ //$GPVTG,[355],T,358,M,001.2,N,[0002.2],K*70
//初始化返回值
*lJiao=0;
*dV=0;
///////////////
int i,j; //位置索引
CString sData[100]; //切分数组
CString strTmp;
strTmp=GPVTG;
//检查可用性,卫星个数大于3
//切分,取出信息
i=0;
while(strTmp.GetLength()>0){//切分
j=strTmp.Find(",");
if(j==-1){
sData[i]=strTmp;
strTmp.Delete(0);
}else{
sData[i]=strTmp.Left(j);
strTmp.Delete(0,j+1);
i++;
}
}
if(!CCommFun::IsNumber(sData[1])){//不是数字
return -1;
}else{
//正确的可用的gps数据
*lJiao=atol(sData[1]);
*dV=atof(sData[7]);
return 0;
}
}
//校验GPS数据
CString CGps::CheckGps(CString GPS)
{
//判断GPS数据正确性
///////////////
CString strTemp;
int i; //位置索引
char cYZ=0; //校验码
char cTmp;
if(GPS.Find("$")==-1 || GPS.Find("*")==-1){//不是GPS数据
return "";
}else{//验证(逐位异或)
//取出信息主体信息
i=GPS.Find("$");
strTemp=GPS.Mid(i,GPS.Find("*")-i+3);
for(i=0;i<strTemp.GetLength();i++){//验证(逐位异或)
cTmp=strTemp.GetAt(i);
if(cTmp=='*'){//结束
break;
}
if(cTmp!='$' && cTmp!=','){
cYZ^=cTmp;
}
}
if(cYZ==CCommFun::strHexToInt(strTemp.Mid(strTemp.Find("*")+1,2)))
return strTemp;
else
return "";
}
}
BOOL CGps::LLtoXY(double dLate, double dLong, double *dX, double *dY)
{
GpsPos gp;
gp.SetBL(dLate,dLong);
gp.BLtoXY();
*dX=gp.X;
*dY=gp.Y;
return TRUE;
}
//判断两点之间的线段是否与圆相交
BOOL CGps::LineCutRound(double dLate1, double dLong1, double dLate2, double dLong2, double dLate0, double dLong0, long R,long lCutCount)
{
//切点算法
double dX=0,dY=0;
double dL=0;
double dL2=0;
double X=0,Y=0;
double Xl=0,Yl=0;
//如果有一点在圆内,就不用算了
dL=GetDis(dLate1,dLong1,dLate0,dLong0);
if(dL<R){
return TRUE;
}
dL=GetDis(dLate2,dLong2,dLate0,dLong0);
if(dL<R){
return TRUE;
}
//第一步计算线段的夹角
//double A=atan((dLong2-dLong1)/(dLate2-dLate1));
//线段两点的距离,必须大于直径,不然就不用切了
dL=GetDis(dLate1,dLong1,dLate2,dLong2);
if(dL>=2*R){
//计算线段的X Y 坐标递增值,距离递增为小于直径,确保穿过圆
double dX=(dLong2-dLong1)/lCutCount;
double dY=(dLate2-dLate1)/lCutCount;
//递增计算点是否在圆内,有点在圆内就是穿过
for(int i=0;i<lCutCount;i++){
//递增
dLong1+=dX;
dLate1+=dY;
//计算是否在圆内
dL2=GetDis(dLate1,dLong1,dLate0,dLong0);
if(dL2<R){//在圆内
return TRUE;
}
}
return FALSE;
}else{
return FALSE;
}//
}
CString CGps::ftoa(double dData)
{
COleVariant vt;
CString strTmp;
vt.vt=VT_R8;
vt.dblVal=dData;
vt.ChangeType(VT_BSTR);
strTmp=vt.bstrVal;
return strTmp;
}
//根据两点经纬度计算距离和角度
double CGps::GetDis(double StartLat, double StartLong, double EndLat, double EndLong, long *Ljiao)
{
*Ljiao=0;
if(StartLong==EndLong && StartLat==EndLat){
return 0;
}
double fPhimean;
double fdLambda;
double fdPhi;
double fAlpha;
double fNu;
double fR;
double fz;
double fTemp;
double Distance;
double fRho;
long br;
fdLambda = (StartLong - EndLong) * D2R;
fdPhi = (StartLat - EndLat) * D2R;
fPhimean = ((StartLat + EndLat) / 2.0) * D2R;
fTemp = 1 - e2 * (pow(sin(fPhimean),2));
fRho = (a * (1 - e2)) / pow(fTemp, 1.5);
fNu = a / (sqrt(1 - e2 * (sin(fPhimean) * sin(fPhimean))));
fz = sqrt(pow(sin(fdPhi/2.0),2)+cos(EndLat*D2R)*cos(StartLat*D2R)*pow(sin(fdLambda/2.0),2)) ;
fz = 2 * asin(fz);
fAlpha = cos(EndLat * D2R) * sin(fdLambda) * 1 / sin(fz);
fAlpha = asin(fAlpha);
fR = (fRho * fNu) / ((fRho * pow(sin(fAlpha),2)) + (fNu * pow(cos(fAlpha),2)));
Distance = (fz * fR);
br=(long)(fAlpha * R2D);
if((StartLat <= EndLat) && (StartLong <= EndLong))
*Ljiao = abs(br);
else if ((StartLat <= EndLat) && (StartLong >= EndLong))
*Ljiao = 360 - abs(br);
else if ((StartLat >= EndLat) && (StartLong >= EndLong))
*Ljiao = 180 + abs(br);
else if ((StartLat >= EndLat) && (StartLong <= EndLong))
*Ljiao = 180 - abs(br);
return Distance;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -