gpsinfo.cpp

来自「GPS信号强度」· C++ 代码 · 共 351 行

CPP
351
字号
// GpsInfo.cpp: implementation of the CGpsInfo class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "gpsdemo.h"
#include "GpsInfo.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGpsInfo::CGpsInfo()
{
	m_strGpsInfo = _T("");
	m_strGpsOutput = _T("");

	m_dUtcTime = 0;
	m_dUtcDate = 0;
	m_dLatitude = 0;
	m_dLongitude = 0;
	m_dAltitude = 0;
	m_dGeoidSeparation = 0;
	m_dSpeedGnd = 0;
	m_dCourseGnd = 0;
	m_iNumSatUsed = 0;
	m_bPositionFix = FALSE;
	m_iInfoMask = 0;
	
	for (int i=0; i<GPS_TOTAL_CHANNEL_NUM; i++)
	{
		m_ChannelInfo[i].iSatId = 0;
		m_ChannelInfo[i].iElevation = 0;
		m_ChannelInfo[i].iAzimuth = 0;
		m_ChannelInfo[i].iSNR = 0;
	}

	m_iCountSatsGot = 0;
	m_iTotalMsgs = 0;
	m_bGsvMsgStarted = FALSE;
}

CGpsInfo::~CGpsInfo()
{

}

int CGpsInfo::GetInfoType()
{
	if (m_strGpsInfo.Left(3) == _T("$GP"))
		return GPS_NMEA_INFO;
	else if (m_strGpsInfo.Left(5) == _T("$PPLM"))		// propriety ID for Palmmicro
		return GPS_DEBUG_INPUT;
	else
		return GPS_UNKNOWN_INPUT;
}

void CGpsInfo::SetInfoLine(CString strInfo)
{
	m_strGpsInfo = strInfo;
	m_strGpsInfo.TrimLeft();
	m_strGpsInfo.TrimRight();
	m_iInfoMask = 0;
	switch (GetInfoType()) 
	{
	case GPS_NMEA_INFO:
		ParseNmeaInfo(m_strGpsInfo);
		break;
	case GPS_DEBUG_INPUT:
		ParseDebugInfo(m_strGpsInfo);
		break;
	default:
		break;
	}

};

void CGpsInfo::SetOutputLine(CString strInfo)
{
	m_strGpsOutput = strInfo;
	m_strGpsOutput.TrimLeft();
	m_strGpsOutput.TrimRight();
}

void CGpsInfo::ParseNmeaInfo(CString strInfo)
{
	int i, j;
//	BOOL bChannelChanged;
	CArray <CString, CString&> FieldArray;
	GetGpsFields(FieldArray, strInfo);
//	TRACE("Got %s fields %d\n", FieldArray[0], FieldArray.GetSize());
	
	if (FieldArray.GetSize() <= 0)
		return;

	switch (NmeaTypeId(FieldArray[0])) 
	{
	case GPS_NMEA_TYPE_GPGGA:
		if (FieldArray.GetSize() != 15)
		{
			TRACE("Wrong GGA sentence\n");
			return;
		}

		if (FieldArray[6].IsEmpty() || FieldArray[6] == "0")	// position not fixed
		{
			if (m_bPositionFix)
			{
				m_bPositionFix = FALSE;
				m_iInfoMask |= GPS_INFOMASK_SATELLITE_VALID;	// enable display
			}
			return;
		}

		if (!m_bPositionFix)
		{
			m_bPositionFix = TRUE;
			m_iInfoMask |= GPS_INFOMASK_SATELLITE_VALID;
		}

		m_dUtcTime = (double)atof(FieldArray[1]);
		m_dLatitude = (double)atof(FieldArray[2]);
		if (FieldArray[3] == "S")
			m_dLatitude = -m_dLatitude;
		m_dLongitude  = (double)atof(FieldArray[4]);
		if (FieldArray[5] == "W")
			m_dLongitude = -m_dLongitude;
		m_iNumSatUsed = atoi(FieldArray[7]);
		m_dAltitude = (double)atof(FieldArray[9]);
		m_dGeoidSeparation = (double)atof(FieldArray[11]);
		m_iInfoMask |= GPS_INFOMASK_POSITION_VALID;

		break;

	case GPS_NMEA_TYPE_GPGLL:
		if (FieldArray.GetSize() < 7)
		{
			TRACE("Wrong GLL sentence\n");
			return;
		}

		if (FieldArray[6].IsEmpty() || FieldArray[6] == "V")	// position invalid
			return;

		m_dLatitude = (double)atof(FieldArray[1]);
		if (FieldArray[2] == "S")
			m_dLatitude = -m_dLatitude;
		m_dLongitude  = (double)atof(FieldArray[3]);
		if (FieldArray[4] == "W")
			m_dLongitude = -m_dLongitude;
		m_dUtcTime = (double)atof(FieldArray[5]);

		m_iInfoMask |= GPS_INFOMASK_POSITION_VALID;

		break;

	case GPS_NMEA_TYPE_GPGSA:
		if (FieldArray.GetSize() != 18)
		{
			TRACE("Wrong SA sentence\n");
			return;
		}
// bypass GPGSA at the moment, I don't understand the use of it
		
//		TRACE("GPGSA sentence bypassed\n");
/*
		bChannelChanged = FALSE;

		for (i=0; i<GPS_TOTAL_CHANNEL_NUM; i++)
		{
			int iNewSatId = atoi(FieldArray[i+3]);
			if (iNewSatId != m_ChannelInfo[i].iSatId)
			{
				m_ChannelInfo[i].iSatId = iNewSatId;
				m_ChannelInfo[i].iElevation = 0;
				m_ChannelInfo[i].iAzimuth = 0;
				m_ChannelInfo[i].iSNR = 0;
				bChannelChanged = TRUE;
			}
		}
		
		if (bChannelChanged)
		{
			m_iInfoMask |= GPS_INFOMASK_SATELLITE_VALID;
		}
*/
		
		break;

	case GPS_NMEA_TYPE_GPGSV:
		if (FieldArray.GetSize() <= 4)		// GPGSV can be shorter, in Surf system
		{
			TRACE("Wrong GSV sentence\n");
			return;
		}

		if (atoi(FieldArray[2]) == 1)	
		{
			// if this is the first message in sequence, clear all the satellite IDs 
			for (j=0; j<GPS_TOTAL_CHANNEL_NUM; j++)
				m_ChannelInfo[j].iSatId = 0;
			m_iCountSatsGot = 0;
			m_iTotalMsgs = atoi(FieldArray[1]);
			if (atoi(FieldArray[2]) == m_iTotalMsgs)
			{
				m_bGsvMsgStarted = FALSE;
				m_iInfoMask |= GPS_INFOMASK_SATELLITE_VALID;
			}
			else
			{
				m_bGsvMsgStarted = FALSE;
			}
		}
		else if (!m_bGsvMsgStarted)	// the first message not received, bypass the rest ones
			break;
		else if (atoi(FieldArray[2]) == m_iTotalMsgs)	// the last messages
		{
			m_bGsvMsgStarted = FALSE;
			m_iInfoMask |= GPS_INFOMASK_SATELLITE_VALID;
		}

		for (i=0; i<(FieldArray.GetSize()-4)/4; i++)
		{
			if (m_iCountSatsGot >= GPS_TOTAL_CHANNEL_NUM)
				break;

			int iSatId = atoi(FieldArray[i*4+4]);
			if (iSatId == 0)
				continue;

			
			m_ChannelInfo[m_iCountSatsGot].iSatId = iSatId;
			m_ChannelInfo[m_iCountSatsGot].iElevation = atoi(FieldArray[i*4+5]);
			m_ChannelInfo[m_iCountSatsGot].iAzimuth = atoi(FieldArray[i*4+6]);
			m_ChannelInfo[m_iCountSatsGot].iSNR = atoi(FieldArray[i*4+7]);
			m_iCountSatsGot++;

/*
			for (j=0; j<GPS_TOTAL_CHANNEL_NUM; j++)
			{
				if (m_ChannelInfo[j].iSatId == iSatId)
				{
					m_ChannelInfo[j].iElevation = atoi(FieldArray[i*4+5]);
					m_ChannelInfo[j].iAzimuth = atoi(FieldArray[i*4+6]);
					m_ChannelInfo[j].iSNR = atoi(FieldArray[i*4+7]);
					break;
				}
			}
*/
		}


		break;

	case GPS_NMEA_TYPE_GPRMC:
		if (FieldArray.GetSize() < 12)
		{
			TRACE("Wrong RMC sentence\n");
			return;
		}

		if (FieldArray[2].IsEmpty() || FieldArray[6] == "V")	// position invalid
			return;

		m_dUtcTime = (double)atof(FieldArray[1]);
		m_dLatitude = (double)atof(FieldArray[3]);
		if (FieldArray[4] == "S")
			m_dLatitude = -m_dLatitude;
		m_dLongitude  = (double)atof(FieldArray[5]);
		if (FieldArray[6] == "W")
			m_dLongitude = -m_dLongitude;

//		TRACE ("LONGITUDE %f \n", m_dLongitude/100);
		m_dSpeedGnd = (double)atof(FieldArray[7]);
		m_dCourseGnd = (double)atof(FieldArray[8]);
		m_dUtcDate = atoi(FieldArray[9]);

		m_iInfoMask |= GPS_INFOMASK_POSITION_VALID;

		break;
	
	default:
		TRACE ("NMEA type %s is unknown\n", NmeaTypeId(FieldArray[0]));
	}
}

void CGpsInfo::ParseDebugInfo(CString strInfo)
{

}

// 
void CGpsInfo::GetGpsFields(CArray <CString, CString&> &FieldsArr, CString strInfo)
{

	CString strField;
	int iPos = 0;

	FieldsArr.RemoveAll();

	while((iPos = strInfo.Find(",")) >= 0)
	{
		strField = strInfo.Left(iPos);
		strField.TrimLeft();
		strField.TrimRight();
		FieldsArr.Add(strField);
		strInfo = strInfo.Mid(iPos+1);
		if (strInfo.IsEmpty())
			break;
	}
	
	if (!strInfo.IsEmpty())
	{
		iPos = strInfo.Find("*");
		if (iPos == 0)
			strInfo.Empty();
		else if (iPos > 0)
			strInfo = strInfo.Left(iPos);

		strInfo.TrimLeft();
		strInfo.TrimRight();

		FieldsArr.Add(strInfo);
	}

}

int CGpsInfo::NmeaTypeId(CString strNmeaId)
{
//	TRACE ("Got NMEA type %s\n", strNmeaId);

	if (strNmeaId == _T("$GPGGA"))
		return GPS_NMEA_TYPE_GPGGA;
	else if (strNmeaId == _T("$GPGLL"))
		return GPS_NMEA_TYPE_GPGLL;
	else if (strNmeaId == _T("$GPGSA"))
		return GPS_NMEA_TYPE_GPGSA;
	else if (strNmeaId == _T("$GPGSV"))
		return GPS_NMEA_TYPE_GPGSV;
	else if (strNmeaId == _T("$GPRMC"))
		return GPS_NMEA_TYPE_GPRMC;
	else
		return GPS_NMEA_TYPE_OTHERS;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?