⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gps.cpp

📁 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 + -