各种通信(三):GPS模块数据解析

cpp 复制代码
#ifndef _GPS_PARSE_H
#define _GPS_PARSE_H

#define USE_BEIJING_TIMEZONE
#define NMEA_VER_300

#define SECOND_PER_COMMONYEAR		60 * 60 * 24 * 365UL
#define SECOND_PER_LEAPYEAR			60 * 60 * 24 * 366UL

#define SECOND_PER_BIG_MONTH		60 * 60 * 24 * 31UL
#define SECOND_PER_SMALL_MONTH		60 * 60 * 24 * 30UL
#define SECOND_LEAP_YEAR_MONTH		60 * 60 * 24 * 29UL
#define SECOND_NOLEAP_YEAR_MONTH	60 * 60 * 24 * 28UL

#define SECOND_PER_DAY				60 * 60 * 24UL

#pragma pack( 1 )

class CGpsParseWx
{
public:
	CGpsParseWx();
	virtual ~CGpsParseWx();
	wxCriticalSection m_critsect;
public:
	/* GPRMC */
	typedef struct GpsGprmcData
	{
		//8byte
		time_t			tmTime;							//定位时间
		//8byte
		float			Latitude;						//纬度
		float			Longitude;						//经度

		//4byte
		unsigned int	Speed			:10;			//地面速度(单位节:1Knots = 1.852Km/h)
		unsigned int	Azimuth			:9;				//地面航向
		unsigned int	SolarAzimuth	:9;				//太阳方位		
		unsigned int	Status			:1;				//状态 A:1定位;V:0导航		
		unsigned int	NS				:1;				//北纬或南纬(N:0  S:1)		
		unsigned int	EW				:1;				//东经或西经(E:1  W:0)
		unsigned int	SolarDirection	:1;				//太阳方向
	}TGpsGprmcData;//20byte

	/* GPGGA */
	typedef struct GpsGpggaData
	{
		//8byte
		time_t			tmTime;							//定位时间
		//20byte
		float Latitude;									//纬度
		float Longitude;								//经度
		float HdopFactor;								//HDOP水平精度因子(0.5 - 99.9)
		float ElevationHigh;							//海拔高度(-9999.9 - 99999.9)
		float GeoidalHigh;								//地球椭球面相对大地水准面的高度(-9999.9 - 99999.9)
		//4byte
		unsigned int DifferentialTime;					//差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)

		//4byte
		unsigned int	DifferentialID	:10;			//差分站ID号0000 - 1023
		unsigned int	Satellite		:4;				//使用卫星数量(00 - 12)
		unsigned int	NS				:1;				//北纬或南纬
		unsigned int	EW				:1;				//东经或西经
		unsigned int	Quality			:1;				//定位质量指示(0:定位无效;1:定位有效)
		
	}TGpsGpggaData;//36byte
	
	/* GPGLL */
	typedef struct GpsGpgllData
	{
		//8byte
		time_t	tmTime;								//定位时间
		//8byte
		float Latitude;								//纬度
		float Longitude;							//
		//1byte
		unsigned char	NS			:1;				//北纬或南纬
		unsigned char	EW			:1;				//东经或西经
		unsigned char	Status		:1;				//状态 A:定位;V:导航
	}TGpsGpgllData;//17byte
	/* GPVTG */
	typedef struct GpsGpvtgData
	{
		//8byte
		float			StepLength;						//步长(000.0 - 999.9)
		float			Velocity;						//速率(0000.0 - 1851.8公里/小时)
		//4byte
		unsigned int	RealDirection		:9;			//真实方向(000 - 359度)以真北为参考基准的地面航向
		unsigned int	RelativeDirection	:9;			//相对方向(000 - 359度)以磁北为参考基准的地面航向

#ifdef NMEA_VER_300
		unsigned int	Mode				:3;			//模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
#endif
	}TGpsGpvtgData;//12byte

	/* GPGSV */
	typedef struct GpsGpgsvData
	{
		unsigned short	GsvTotalNum			:3;				//本次GSV语句的总数目(1 - 4)
		unsigned short	GsvNo				:3;				//本条GSV语句是本次GSV语句的第几条(1 - 4)
		unsigned short	VisibleSatelliteNum	:5;				//当前可见卫星总数(00 - 16)
	}TGpsGpgsvData;//2byte

	/* 用于显示GPS信息的数据 */
	typedef struct GpsInfo
	{
		//392byte
		unsigned int SatelliteId[24];						//卫星ID(0 - 32)
		unsigned int SatelliteElevation[24];				//卫星仰角(0°- 90°)
		unsigned int SatelliteAzimuth[24];					//卫星方位角(0°- 360°)
		unsigned int SignalNoiseRatio[24];					//信噪比(00-99)dbHz

		time_t	tmTime;	
		//8byte
		float			Latitude;							//纬度
		float			Longitude;							//经度
		//8byte
		unsigned int	ElevationHigh	:11;				//GPS接收机海拔(米)[0,2047]
		unsigned int	GsvTotalNum		:3;					//本次GSV语句的总数目(1 - 4)
		unsigned int	GsvNo			:3;					//本条GSV语句是本次GSV语句的第几条(1 - 4)
		unsigned int	SatelliteNum	:5;					//卫星颗数(0 - 32)
		unsigned int	Speed			:10;				//GPS接收机速度(公里/小时)
		unsigned int	NS				:1;					//北纬或南纬(N:0  S:1)		
		unsigned int	EW				:1;					//东经或西经(E:1  W:0)
	}TGpsInfo;//396byte

public:
	/* function */
	void GpsDataParse( wxChar *line );
	void ExecFormatChange( float *Latitude,float *Longitude );
	float get_double_number( wxChar *s );
	size_t GetComma( unsigned int num,wxChar *str );
	void UTC2BTC( struct tm *ltime );
	void ReadyToWriteFile( wxChar *line );
	void SetGPSInfo( TGpsInfo *in_Param );
	void GetGPSInfo( TGpsInfo *outParam );
	unsigned int isLeapYear( unsigned int year );
	unsigned long int GetYearSecond( unsigned int year );
	unsigned long int GetMonthSecond( unsigned int year,unsigned int month );
	unsigned long int GetDaySecond( unsigned int day );
	unsigned long int GetCurrentSecond( unsigned int hour,unsigned int minute,unsigned second );
};
#endif
cpp 复制代码
#include "wx/wxprec.h"

#ifdef __BORLANDC__
	#pragma hdrstop
#endif

#ifndef WX_PRECOMP
	#include "wx/wx.h"
#endif
#include "gpsParse.h"
#include "serialWx.h"

#include <deque>
std::deque<int>	sg_gsv_id_queue;//卫星编号		
std::deque<int> sg_gsv_se_queue;//卫星仰角
std::deque<int> sg_gsv_sa_queue;//卫星方向角
std::deque<int>	sg_gsv_sr_queue;//信噪比

extern bool b_isGGA;
extern bool b_isRMC;
extern bool b_isGLL;
extern bool b_isVTG;
extern bool b_isGSV;
extern bool bReadyForSaveParse;

int SatelliteId[4];
int SatelliteElevation[4];
int SatelliteAzimuth[4];
int SignalNoiseRatio[4];

CGpsParseWx::TGpsInfo inParam;

CGpsParseWx::TGpsGpggaData	GpggaData;
CGpsParseWx::TGpsGprmcData	GprmcData;
CGpsParseWx::TGpsGpgllData	GpgllData;
CGpsParseWx::TGpsGpvtgData	GpvtgData;
CGpsParseWx::TGpsGpgsvData	GpgsvData;

CGpsParseWx::TGpsGpggaData	BinGpggaData;
CGpsParseWx::TGpsGprmcData	BinGprmcData;
CGpsParseWx::TGpsGpgllData	BinGpgllData;
CGpsParseWx::TGpsGpvtgData	BinGpvtgData;
CGpsParseWx::TGpsGpgsvData	BinGpgsvData;

wxChar *SignType = NULL;

CGpsParseWx::CGpsParseWx()
{
	memset(&GpggaData,0,sizeof(GpggaData));
	memset(&GprmcData,0,sizeof(GprmcData));
	memset(&GpgllData,0,sizeof(GpgllData));
	memset(&GpvtgData,0,sizeof(GpvtgData));
	memset(&GpgsvData,0,sizeof(GpgsvData));

	memset(&BinGpggaData,0,sizeof(BinGpggaData));
	memset(&BinGprmcData,0,sizeof(BinGprmcData));
	memset(&BinGpgllData,0,sizeof(BinGpgllData));
	memset(&BinGpvtgData,0,sizeof(BinGpvtgData));
	memset(&BinGpgsvData,0,sizeof(BinGpgsvData));
}

CGpsParseWx::~CGpsParseWx()
{

}
/*
*Gps data parsed
*/

void CGpsParseWx::GpsDataParse( wxChar *line )
{
	size_t tmp;
	
	wxChar *buf = line;
	wxChar key_code[7] = wxT("");

	if ( line == NULL )
	{
		return ;
	}
	memcpy( &key_code[0], line, 6 );

	if ( wxStrcmp(&key_code[0],wxT("$GPGGA") ) == 0)//$GPGGA:GPS定位信息
	{
		struct tm ltime;
		//UTC时间
		ltime.tm_hour = (buf[7]-'0')*10+(buf[8]-'0');
		ltime.tm_min = (buf[9]-'0')*10+(buf[10]-'0');
		ltime.tm_sec = (buf[11]-'0')*10+(buf[12]-'0');
		//经纬度方向,纬度,经度
		GpggaData.Latitude = get_double_number(&buf[GetComma(2,buf)]);
		GpggaData.NS = buf[GetComma(3,buf)];
		GpggaData.Longitude = get_double_number(&buf[GetComma(4,buf)]);
		GpggaData.EW = buf[GetComma(5,buf)];
		//定位质量指示
		GpggaData.Quality = buf[GetComma(6,buf)];
		//使用卫星数量
		tmp = GetComma(7,buf);
		GpggaData.Satellite = (buf[tmp]-'0')*10+(buf[tmp+1]-'0');
		//水平精确度
		GpggaData.HdopFactor = get_double_number(&buf[GetComma(8,buf)]);
		//天线离海平面的高度
		GpggaData.ElevationHigh = get_double_number(&buf[GetComma(9,buf)]);
		//大地高度
		tmp = GetComma(11,buf);
		GpggaData.GeoidalHigh = get_double_number(&buf[tmp]);
		//差分时间
		GpggaData.DifferentialTime = get_double_number(&buf[GetComma(13,buf)]);
		//差分站ID
		GpggaData.DifferentialID = get_double_number(&buf[GetComma(14,buf)]);

#ifdef USE_BEIJING_TIMEZONE
		//格林威治时间转换北京时间
		UTC2BTC( &ltime );
		GpggaData.tmTime = GetCurrentSecond( ltime.tm_hour,ltime.tm_min,ltime.tm_sec );
#endif
		//经纬度格式转化(ddmm.mmmm->ddd.ddd)
		ExecFormatChange( &GpggaData.Latitude,&GpggaData.Longitude );

		inParam.ElevationHigh = GpggaData.ElevationHigh;
		inParam.Latitude = GpggaData.Latitude;
		inParam.Longitude = GpggaData.Longitude;
		inParam.NS = GpggaData.NS;
		inParam.EW = GpggaData.EW;

	}

	else if ( wxStrcmp(&key_code[0],wxT("$GPRMC") ) == 0)//GPRMC:定位信息
	{
		struct tm ltime;
		//UTC时间
		ltime.tm_hour = (buf[7]-'0')*10+(buf[8]-'0');
		ltime.tm_min = (buf[9]-'0')*10+(buf[10]-'0');
		ltime.tm_sec = (buf[11]-'0')*10+(buf[12]-'0');

		//状态,经纬度方向,纬度,经度
		GprmcData.Status = buf[GetComma(2,buf)];//定位或者导航
		GprmcData.Latitude = get_double_number(&buf[GetComma(3,buf)]);
		GprmcData.NS = buf[GetComma(4,buf)];
		GprmcData.Longitude = get_double_number(&buf[GetComma(5,buf)]);
		GprmcData.EW = buf[GetComma(6,buf)];
		//速度
		GprmcData.Speed = (((get_double_number(&buf[GetComma(7,buf)])) * 1.852)*1000)/3600;
		//方位角
		GprmcData.Azimuth = get_double_number(&buf[GetComma(8,buf)]);
		//日期
		tmp = GetComma(9,buf);
		ltime.tm_mday = (buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');
		ltime.tm_mon = (buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');
		ltime.tm_year = (buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;

		//太阳方位(000-180)
		GprmcData.SolarAzimuth = get_double_number(&buf[GetComma(10,buf)]);
		//太阳方向:东或者西
		GprmcData.SolarDirection = get_double_number(&buf[GetComma(11,buf)]);

#ifdef USE_BEIJING_TIMEZONE
		//格林威治时间转换北京时间
		UTC2BTC( &ltime );

		GprmcData.tmTime = GetYearSecond( ltime.tm_year ) 
							+ GetMonthSecond( ltime.tm_year,ltime.tm_mon )
							+ GetDaySecond( ltime.tm_mday )
							+ GetCurrentSecond( ltime.tm_hour,ltime.tm_min,ltime.tm_sec );
#endif
		//经纬度格式转化(ddmm.mmmm->ddd.ddd)
		ExecFormatChange( &GprmcData.Latitude,&GprmcData.Longitude );

		//set
		inParam.tmTime = GprmcData.tmTime;
		inParam.Speed =  GprmcData.Speed;
		inParam.Latitude = GprmcData.Latitude;
		inParam.Longitude = GprmcData.Longitude;
		inParam.NS = GprmcData.NS;
		inParam.EW = GprmcData.EW;
	}

	else if ( wxStrcmp(&key_code[0],wxT("$GPGLL")) == 0 )//GPGLL:地理定位信息
	{
		struct tm ltime;
		//纬度,经度
		GpgllData.Latitude = get_double_number(&buf[GetComma(1,buf)]);
		GpgllData.NS = buf[GetComma(2,buf)];
		GpgllData.Longitude = get_double_number(&buf[GetComma(3,buf)]);
		GpgllData.EW = buf[GetComma(4,buf)];
		//UTC时间
		tmp = GetComma(5,buf);
		ltime.tm_hour = (buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');
		ltime.tm_min = (buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');
		ltime.tm_sec = (buf[tmp+4]-'0')*10+(buf[tmp+5]-'0');
		//状态
		GpgllData.Status = buf[GetComma(6,buf)];//定位或者导航

#ifdef USE_BEIJING_TIMEZONE
		//格林威治时间转换北京时间
		UTC2BTC( &ltime );
		GpgllData.tmTime = GetCurrentSecond( ltime.tm_hour,ltime.tm_min,ltime.tm_sec );
#endif
		//经纬度格式转化(ddmm.mmmm->ddd.ddd)
		ExecFormatChange( &GpgllData.Latitude,&GpgllData.Longitude );

		inParam.Latitude = GpgllData.Latitude;
		inParam.Longitude = GpgllData.Longitude;
		inParam.NS = GpgllData.NS;
		inParam.EW = GpgllData.EW;

	}

	else if ( wxStrcmp(&key_code[0],wxT("$GPVTG")) == 0 )//GPVTG:地面速度信息
	{
		//真实方向
		GpvtgData.RealDirection = get_double_number(&buf[GetComma(1,buf)]);
		//相对方向
		GpvtgData.RelativeDirection = get_double_number(&buf[GetComma(3,buf)]);
		//步长
		GpvtgData.StepLength = get_double_number(&buf[GetComma(5,buf)]);
		//速率
		GpvtgData.Velocity = get_double_number(&buf[GetComma(7,buf)]);

#ifdef NMEA_VER_300
		//模式指示
		GpvtgData.Mode = buf[GetComma(9,buf)];
#endif
	}

	else if ( wxStrcmp(&key_code[0],wxT("$GPGSV") ) == 0)//GPGSV:可视卫星状态
	{
		int m_nStep = 0;
		//本次GSV语句的总数目
		GpgsvData.GsvTotalNum = wxAtoi( &buf[GetComma(1,buf)] );
		//本条GSV语句是本次GSV语句的第几条
		GpgsvData.GsvNo = wxAtoi( &buf[GetComma(2,buf)] );
		//当前可见卫星总数
		GpgsvData.VisibleSatelliteNum = wxAtoi( &buf[GetComma(3,buf)] );

		if ( GpgsvData.VisibleSatelliteNum == 0 )
		{
			return;
		}
		static int j = 0;
		for ( int i = 1;i <= 4; i++ )
		{
			size_t m_nComma = GetComma(4*i,buf);
			if ( m_nComma == 0 )
			{
				break;
			}
			else
			{
				//卫星仰角和卫星方位角和信噪比放入到队列中
				sg_gsv_id_queue.push_back( wxAtoi( &buf[GetComma(4+m_nStep,buf)]) );
				sg_gsv_se_queue.push_back( wxAtoi( &buf[GetComma(5+m_nStep,buf)]) );
				sg_gsv_sa_queue.push_back( wxAtoi( &buf[GetComma(6+m_nStep,buf)]) );
				sg_gsv_sr_queue.push_back( wxAtoi( &buf[GetComma(7+m_nStep,buf)]) );
				
				inParam.SatelliteId[j] =  wxAtoi( &buf[GetComma(4+m_nStep,buf)]);
				inParam.SatelliteElevation[j] =  wxAtoi( &buf[GetComma(5+m_nStep,buf)] );
				inParam.SatelliteAzimuth[j] =  wxAtoi( &buf[GetComma(6+m_nStep,buf)] );
				inParam.SignalNoiseRatio[j] =  wxAtoi( &buf[GetComma(7+m_nStep,buf)] );

				j++;
				if ( j == GpgsvData.VisibleSatelliteNum )
				{
					j  = 0;
				}
				m_nStep +=4;
			}
		}
		inParam.SatelliteNum = GpgsvData.VisibleSatelliteNum;
		inParam.GsvTotalNum = GpgsvData.GsvTotalNum;
		inParam.GsvNo = GpgsvData.GsvNo;
	}

	return ;
}

/*
*exec format change
*/
void CGpsParseWx::ExecFormatChange( float *Latitude,float *Longitude )
{
	float m_Latitude,m_Longitude;
	float DecimalLongitudeResult,DecimalLatitudeResult;
	int IntegralLatitudeResult, IntegralLongitudeResult;

	m_Latitude = *Latitude;
	m_Longitude = *Longitude;

	IntegralLatitudeResult = m_Latitude / 100;
	
	if( m_Latitude<100 )
		DecimalLatitudeResult = 0.0;
	else
	{
		DecimalLatitudeResult = m_Latitude - 100;
		while( DecimalLatitudeResult >= 100 )
			DecimalLatitudeResult=DecimalLatitudeResult - 100;
	}

	IntegralLongitudeResult = m_Longitude / 100;
	
	if( m_Longitude<100 )
		DecimalLongitudeResult=0.0;
	else
	{
		DecimalLongitudeResult = m_Longitude-100;
		while( DecimalLongitudeResult >= 100 )
			DecimalLongitudeResult = DecimalLongitudeResult - 100;
	}
	DecimalLatitudeResult = DecimalLatitudeResult / 60;
	DecimalLongitudeResult = DecimalLongitudeResult / 60;

	m_Latitude = IntegralLatitudeResult + DecimalLatitudeResult;
	m_Longitude = IntegralLongitudeResult + DecimalLongitudeResult;

	*Latitude = m_Latitude;
	*Longitude = m_Longitude;

	return ;
}

/*
*get double number
*/
float CGpsParseWx::get_double_number( wxChar *s )
{
	wxChar buf[128] = wxT("");
	size_t i;
	float rev = 0.0;

	i = GetComma( 1,s );
	wxStrncpy( buf,s,i );
	buf[i] = 0;
	rev = wxAtof( buf );

	return rev;
}

/*
*get comma app
*/
size_t CGpsParseWx::GetComma( unsigned int num,wxChar *str )
{
	size_t i,j = 0;

	size_t len = wxStrlen( str );
	for ( i=0; i<len; i++ )
	{
		if ( str[i] == ',' )
			j++;
		if ( j == num )
			return i+1;
	}

	return 0;
}

/*
*world time renderto beijing time
*/
void CGpsParseWx::UTC2BTC( struct tm *ltime )
{
	if( ltime == NULL )
	{
		return;
	}

	
	ltime->tm_sec++;
	if( ltime->tm_sec>59 )
	{
		ltime->tm_sec = 0;
		ltime->tm_min++;
		if( ltime->tm_min>59 )
		{
			ltime->tm_min = 0;
			ltime->tm_hour++;
		}
	}
	
	ltime->tm_hour+=8;
	if( ltime->tm_hour>23 )
	{
		ltime->tm_hour-=24;
		ltime->tm_mday+=1;
		if( ltime->tm_mon==2 || ltime->tm_mon==4 || ltime->tm_mon==6 || ltime->tm_mon==9 || ltime->tm_mon==11 )
		{
			if( ltime->tm_mday>30 )
			{
				ltime->tm_mday = 1;
				ltime->tm_mon++;
			}
		}
		else
		{
			if( ltime->tm_mday>31 )
			{
				ltime->tm_mday = 1;
				ltime->tm_mon++;
			}
		}
		if( ltime->tm_year % 4 == 0 )
		{
			if( ltime->tm_mday > 29 && ltime->tm_mon == 2 )
			{
				ltime->tm_mday = 1;
				ltime->tm_mon++;
			}
		}
		else
		{
			if( ltime->tm_mday>28 && ltime->tm_mon ==2 )
			{
				ltime->tm_mday = 1;
				ltime->tm_mon++;
			}
		}
		if( ltime->tm_mon>12 )
		{
			ltime->tm_mon-=12;
			ltime->tm_year++;
		}
	}
}

/* 
*ready to write file
*/
void CGpsParseWx::ReadyToWriteFile( wxChar *line )
{
	if( line == NULL )
	{
		return ;
	}
	
	wxChar key_code[7] = wxT("");
	memcpy( &key_code[0],line,6 );

	if ( wxStrcmp(&key_code[0],wxT("$GPGGA")) == 0 )
	{
		m_critsect.Enter();
		SignType = wxT("$GPGGA");
		BinGpggaData = GpggaData;
		bReadyForSaveParse = true;
		b_isGGA = true;
		b_isRMC = false;
		b_isGLL = false;
		b_isVTG = false;
		b_isGSV = false;
		m_critsect.Leave();
	}
	else if ( wxStrcmp(&key_code[0],wxT("$GPRMC")) == 0 )
	{
		m_critsect.Enter();
		SignType = wxT("$GPRMC");
		BinGprmcData = GprmcData;
		bReadyForSaveParse = true;
		b_isRMC = true;
		b_isGGA = false;
		b_isGLL = false;
		b_isVTG = false;
		b_isGSV = false;
		m_critsect.Leave();
	}
	else if ( wxStrcmp(&key_code[0],wxT("$GPGLL")) == 0 )
	{
		m_critsect.Enter();
		SignType = wxT("$GPGLL");
		BinGpgllData = GpgllData;
		bReadyForSaveParse = true;
		b_isGLL = true;
		b_isGGA = false;
		b_isRMC = false;
		b_isVTG = false;
		b_isGSV = false;
		m_critsect.Leave();
	}
	else if ( wxStrcmp(&key_code[0],wxT("$GPVTG")) == 0 )
	{
		m_critsect.Enter();
		SignType = wxT("$GPVTG");
		BinGpvtgData = GpvtgData;
		bReadyForSaveParse = true;
		b_isVTG = true;
		b_isGGA = false;
		b_isRMC = false;
		b_isGLL = false;
		b_isGSV = false;
		m_critsect.Leave();
	}
	else if ( wxStrcmp(&key_code[0],wxT("$GPGSV")) == 0 )
	{
		m_critsect.Enter();
		int i = 0;
		SignType = wxT("$GPGSV");
		memset( SatelliteId,0,sizeof(SatelliteId) );
		memset( SatelliteElevation,0,sizeof(SatelliteElevation) );
		memset( SatelliteAzimuth,0,sizeof(SatelliteAzimuth) );
		memset( SignalNoiseRatio,0,sizeof(SignalNoiseRatio) );
		//从队列中提取每颗卫星的仰角和方位角和信噪比
		while ( ! sg_gsv_se_queue.empty() && ! sg_gsv_sa_queue.empty() && ! sg_gsv_sr_queue.empty() && ! sg_gsv_id_queue.empty())
		{
			SatelliteId[i] = sg_gsv_id_queue.front();
			SatelliteElevation[i] = sg_gsv_se_queue.front();
			SatelliteAzimuth[i] = sg_gsv_sa_queue.front();
			SignalNoiseRatio[i] = sg_gsv_sr_queue.front();

			i++;
			//清空队列数据
			sg_gsv_id_queue.pop_front();
			sg_gsv_se_queue.pop_front();
			sg_gsv_sa_queue.pop_front();
			sg_gsv_sr_queue.pop_front();
		}
		BinGpgsvData = GpgsvData;
		bReadyForSaveParse = true;
		b_isGSV = true;
		b_isGGA = false;
		b_isRMC = false;
		b_isGLL = false;
		b_isVTG = false;
		m_critsect.Leave();
	}
	else
		return;
}
void CGpsParseWx::GetGPSInfo( TGpsInfo *outParam )
{
	outParam = &inParam;
}

unsigned long int CGpsParseWx::GetCurrentSecond( unsigned int hour,unsigned int minute,unsigned second )
{
	unsigned long int iSecond = 0;

	iSecond = hour * 60 * 60 + minute * 60 + second;

	return iSecond;
}

unsigned long int CGpsParseWx::GetDaySecond( unsigned int day )
{
	unsigned long int second = 0;
	unsigned int iDay;

	for( iDay = 1; iDay < day; iDay++ )
	{
		second += SECOND_PER_DAY;
	}

	return second;
}
unsigned long int CGpsParseWx::GetMonthSecond( unsigned int year,unsigned int month )
{
	unsigned long int second = 0;
	unsigned int iMonth;

	for( iMonth = 1; iMonth < month; iMonth++ )
	{
		if( iMonth == 1 || iMonth == 3 || iMonth == 5 || iMonth == 7 || iMonth == 8 || iMonth == 10 || iMonth == 12 )
		{
			second += SECOND_PER_BIG_MONTH;
		}
		else if( iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11 )
		{
			second += SECOND_PER_SMALL_MONTH;
		}
		else if ( iMonth == 2 && isLeapYear(year) )
		{
			second += SECOND_LEAP_YEAR_MONTH;
		}
		else
		{
			second += SECOND_NOLEAP_YEAR_MONTH;
		}
	}

	return second;
}

unsigned long int CGpsParseWx::GetYearSecond( unsigned int year )
{
	unsigned long int second = 0;
	unsigned int iYear;
	
	for( iYear = 1970; iYear < year; iYear++ )
	{
		if (isLeapYear(iYear))
		{
			second += SECOND_PER_LEAPYEAR;
		}
		else
		{
			second += SECOND_PER_COMMONYEAR;
		}
	}

	return second;//1262304000
}
unsigned int CGpsParseWx::isLeapYear( unsigned int year )
{
	unsigned int leap_year = FALSE;

	if ((year % 4) == 0)
	{
		leap_year = TRUE;
		if ((year % 100) == 0)
		{
			if ((year % 400) != 0)
			{
				leap_year = FALSE;
			}
		}
	}

	return leap_year;
}

感概一下,年轻时候真挺能研究,硬生生自研星历图动态表示出来

相关推荐
量子炒饭大师6 小时前
收集飞花令碎片——C语言字符函数与字符串函数
c语言·开发语言
web安全工具库8 小时前
Makefile 模式规则精讲:从 %.o: %.c 到静态模式规则的终极自动化
linux·运维·c语言·开发语言·数据库·自动化
earthzhang202111 小时前
【1028】字符菱形
c语言·开发语言·数据结构·c++·算法·青少年编程
承渊政道15 小时前
动态内存管理
c语言·c++·经验分享·c#·visual studio
Narcissiffo16 小时前
【C语言】str系列函数
c语言·开发语言
hqyjzsb17 小时前
2025年市场岗位能力重构与跨领域转型路径分析
c语言·人工智能·信息可视化·重构·媒体·改行学it·caie
小莞尔17 小时前
【51单片机】【protues仿真】基于51单片机智能窗帘系统
c语言·stm32·单片机·嵌入式硬件·物联网·51单片机
懒羊羊不懒@17 小时前
Java基础语法—最小单位、及注释
java·c语言·开发语言·数据结构·学习·算法
SundayBear18 小时前
嵌入式进阶:C语言内联汇编
c语言·开发语言·汇编