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

📄 frame.cpp

📁 Powerful and Portable GPS application -- support Linux, Windows, Windows CE GPS navigation and Map m
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{	bool bViewPhotos;	g_pConfig->Read(wxT("AerialPhotosVisible"), &bViewPhotos, false);	if ( bViewPhotos )	{		m_MapAppearanceSettings = m_ThemeManager.GetPhotoTheme();	}	else	{		switch( m_ThemeManager.GetThemeUsage() )		{			case ThemeManager::AutoSwap:				m_SolarTimer.Start();				if ( m_SolarTimer.IsDaytime() || !m_SolarTimer.Valid())					m_MapAppearanceSettings = m_ThemeManager.GetDayTheme();				else					m_MapAppearanceSettings = m_ThemeManager.GetNightTheme();				break;						case ThemeManager::Night:				m_SolarTimer.Stop();				m_MapAppearanceSettings = m_ThemeManager.GetNightTheme();				break;						case ThemeManager::Day:				m_SolarTimer.Stop();				m_MapAppearanceSettings = m_ThemeManager.GetDayTheme();				break;		}	}	//////////////////////////////////////////////////////////////////////////////	// Apply the skin	//////////////////////////////////////////////////////////////////////////////	wxString strSkinPath;	if (m_SolarTimer.IsDaytime())		g_pConfig->Read(wxT("SkinPath-Day"), &strSkinPath, wxT("Default-Day"));	else		g_pConfig->Read(wxT("SkinPath-Night"), &strSkinPath, wxT("Default-Night"));	bool bSkinLoaded = false;	if (strSkinPath != wxT(""))		bSkinLoaded = !LoadSkin(strSkinPath, true);	if (!bSkinLoaded)	{		LoadSkin(wxT("<?xml version=\"1.0\">\<roadnavskin>\	<layout>\		<control name=\"map\">\			<region>\				<topleft>\					<x/>\					<y/>\				</topleft>\				<bottomright>\					<x multiplier=\"1\"/>\					<y multiplier=\"1\"/>\				</bottomright>\			</region>\		</control>\	</layout>\</roadnavskin>"),			false);	}	m_pfrmGPS->SetFont(GetFont());	m_pfrmGPS->SetBackgroundStyle(wxBG_STYLE_COLOUR);		m_pfrmGPS->SetBackgroundColour(m_MapAppearanceSettings.GetMiscColor(MiscColorBackground));	m_pfrmGPS->SetForegroundColour(m_MapAppearanceSettings.GetMiscColor(MiscColorForeground));	m_pfrmGPS->SafeRefresh();	m_pfrmWhatsNearBy->SetFont(GetFont());	m_pfrmWhatsNearBy->SetBackgroundStyle(wxBG_STYLE_COLOUR);		m_pfrmWhatsNearBy->SetBackgroundColour(m_MapAppearanceSettings.GetMiscColor(MiscColorBackground));	m_pfrmWhatsNearBy->SetForegroundColour(m_MapAppearanceSettings.GetMiscColor(MiscColorForeground));		m_pfrmDirections->SetFont(GetFont());	m_pfrmDirections->SetBackgroundColour(m_MapAppearanceSettings.GetMiscColor(MiscColorBackground));	m_pfrmDirections->SetForegroundColour(m_MapAppearanceSettings.GetMiscColor(MiscColorForeground));		UpdateSkinState();}#if defined _WINDOWS//////////////////////////////////////////////////////////////////////////////////// \brief Catches the WM_TIMECHANGE Windows message////// wxWidgets does not support the WM_TIMECHANGE event so we will add it/// here in a non-portable way/////////////////////////////////////////////////////////////////////////////////long MapFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam){   long result = wxFrame::MSWWindowProc(nMsg,wParam,lParam);   if ( nMsg == WM_TIMECHANGE )   {      // user changed the clock in some way... notify the solar timer      wxTimeChangeEvent event;      m_SolarTimer.AddPendingEvent(event);   }   return result;}#endif//////////////////////////////////////////////////////////////////////////////////// \brief Called to process a wxGPSEvent object. This just saves the object/// and lets it get processed in the idle handler./////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdate(wxGPSEvent & event){	wxMutexLocker mlLocker(m_mtxGPS);		m_evGPS = event;	m_bNewGPSData = true;}//////////////////////////////////////////////////////////////////////////////////// \brief Handle speed controlled zooming/////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdleSpeedControlledZooming(wxGPSEvent & event){	double fSpeed = event.m_fSpeed;	//////////////////////////////////////////////////////////////////////////////	// Beginning of speed controlled zooming code	//////////////////////////////////////////////////////////////////////////////	int iDesiredSpeedControlledDetailLevelOffset;	bool bSignificantOffset;	double fHighestExceededCutoff;	vector<double>::iterator iCutoff;	double fHysteresis;		fHysteresis = 5;	iDesiredSpeedControlledDetailLevelOffset = 0;	bSignificantOffset = false;	fHighestExceededCutoff = -1000;	// determine the correct offset due to the current velocity				for (iCutoff = m_vSpeedControlledDetailLevelCutoffs.begin(); iCutoff != m_vSpeedControlledDetailLevelCutoffs.end(); iCutoff++)	{		if (fSpeed > *iCutoff)		{			iDesiredSpeedControlledDetailLevelOffset--;						if (*iCutoff > fHighestExceededCutoff)				fHighestExceededCutoff = *iCutoff;		}	}		if (fSpeed - fHighestExceededCutoff > fHysteresis)		bSignificantOffset = true;		// check for accelerating through auto-zoom cutoff + fHysteresis	if ((m_iSpeedControlledDetailLevelOffset - iDesiredSpeedControlledDetailLevelOffset > 1) ||		(m_iSpeedControlledDetailLevelOffset - iDesiredSpeedControlledDetailLevelOffset == 1 && bSignificantOffset))	{		m_iSpeedControlledDetailLevelOffset--;		m_ctlMap->LessDetail();	}		// check for decelerating through auto-zoom cutoff	if ((iDesiredSpeedControlledDetailLevelOffset - m_iSpeedControlledDetailLevelOffset >= 1))	{		m_iSpeedControlledDetailLevelOffset++;		m_ctlMap->MoreDetail();	}	//////////////////////////////////////////////////////////////////////////////	// End of speed controlled zooming code	//////////////////////////////////////////////////////////////////////////////}//////////////////////////////////////////////////////////////////////////////////// \brief Handle zooming based on road type/////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdleRoadTypeZooming(wxGPSEvent & event){	if (m_adrGPS.m_eRecordType == m_eRoadTypeZoomingCurrentType || 			m_adrGPS.m_eRecordType < FIRST_RECORD_TYPE_ROAD || 			m_adrGPS.m_eRecordType > LAST_RECORD_TYPE_ROAD)	{		// road type has not changed		// or the current road type isn't really a road		m_iRoadTypeZoomingCountdown = -1;		m_eRoadTypeZoomingNextType = m_adrGPS.m_eRecordType;	}	else if (m_adrGPS.m_eRecordType != m_eRoadTypeZoomingNextType)	{		// okay, we just observed the road type change		m_iRoadTypeZoomingCountdown = 2; // add one, and multiply by frequency to determine responsive time		m_eRoadTypeZoomingNextType = m_adrGPS.m_eRecordType;	}	else if (m_iRoadTypeZoomingCountdown > 0)	{		// we have observed the road type has changed for a little while now		// getting ready to switch		m_iRoadTypeZoomingCountdown--;	}	else	{		// alright, time to switch		wxASSERT(m_iRoadTypeZoomingCountdown == 0);				// remember current detail level for old type		m_ariRoadTypeZoomingDetailLevels[m_eRoadTypeZoomingCurrentType] = m_ctlMap->GetDetailLevel() - m_iSpeedControlledDetailLevelOffset;				// set type to new type		m_eRoadTypeZoomingCurrentType = m_adrGPS.m_eRecordType;				// set detail level to new type's detail level		if (m_ariRoadTypeZoomingDetailLevels[m_eRoadTypeZoomingCurrentType] >= 0)			m_ctlMap->SetDetailLevel(m_ariRoadTypeZoomingDetailLevels[m_eRoadTypeZoomingCurrentType] + m_iSpeedControlledDetailLevelOffset);				m_iRoadTypeZoomingCountdown = -1;	}}//////////////////////////////////////////////////////////////////////////////////// \brief Repositions the center of the map so that the current GPS/// coordinates are on the screen./////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdleKeepGPSOnScreen(wxGPSEvent & event){	double fScreenEdge = 0.1;	double fSafety = 0.05;	double fScreenRelativeHeading;	wxPoint ptScreenGPS;	wxSize szMapCtl;	const Point & pt = event.m_pt;	double fHeading = event.m_fHeading;	wxRealPoint ptRelativeScreenGPS;				ptScreenGPS = m_ctlMap->MapLongLatToScreen(pt);	szMapCtl = m_ctlMap->GetSize();		fScreenRelativeHeading = fHeading - m_ctlMap->GetAngle();		ptRelativeScreenGPS.x = (((double) ptScreenGPS.x) / szMapCtl.x);	ptRelativeScreenGPS.y = (((double) ptScreenGPS.y) / szMapCtl.y);	if (!m_ctlMap->IsOnScreen(pt))	{		// yikes, we're really far off		m_ctlMap->SetCenterCoordinates(pt);	}	else if (ptRelativeScreenGPS.x < fScreenEdge)	{		// we're close to the left edge .. slide the screen left		m_ctlMap->MoveCenterLeft(1.0 - ptRelativeScreenGPS.x - fScreenEdge - fSafety);				// move it up/down so the car passes through the center of the screen		m_ctlMap->MoveCenterUp(0.5 - ptRelativeScreenGPS.y - (0.5 - fScreenEdge - fSafety) * sin_deg(fScreenRelativeHeading - 90));	}	else if (ptRelativeScreenGPS.y < fScreenEdge)	{		// we're close to the top edge .. slide the screen up		m_ctlMap->MoveCenterUp(1.0 - ptRelativeScreenGPS.y - fScreenEdge - fSafety);				// move it left/right so the car passes through the center of the screen		m_ctlMap->MoveCenterLeft(0.5 - ptRelativeScreenGPS.x - (0.5 - fScreenEdge - fSafety) * cos_deg(fScreenRelativeHeading - 90));	}	else if (ptRelativeScreenGPS.x > (1.0 - fScreenEdge))	{		// we're close to the right edge .. slide the screen right		m_ctlMap->MoveCenterRight(ptRelativeScreenGPS.x - fScreenEdge - fSafety);				// move it up/down so the car passes through the center of the screen		m_ctlMap->MoveCenterUp(0.5 - ptRelativeScreenGPS.y - (0.5 - fScreenEdge - fSafety) * sin_deg(fScreenRelativeHeading - 90));	}	else if (ptRelativeScreenGPS.y > (1.0 - fScreenEdge))	{		// we're close to the bottom edge .. slide the screen down		m_ctlMap->MoveCenterDown(ptRelativeScreenGPS.y - fScreenEdge - fSafety);				// move it left/right so the car passes through the center of the screen		m_ctlMap->MoveCenterLeft(0.5 - ptRelativeScreenGPS.x - (0.5 - fScreenEdge - fSafety) * cos_deg(fScreenRelativeHeading - 90));	}}//////////////////////////////////////////////////////////////////////////////////// \brief Adjust the angle of the map so the heading is pointing up./////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdlePointGPSHeadingUp(wxGPSEvent & event){	double fDesiredAngle;	double fHeading = event.m_fHeading;	double fAngleDifference;		fDesiredAngle = floor((fHeading + 22.5) / 45) * 45;		fAngleDifference = fabs(m_ctlMap->GetAngle() - fHeading);	if (fAngleDifference > 180)		fAngleDifference = 360 - fAngleDifference;	if (fAngleDifference > 45)		m_ctlMap->SetAngle(fDesiredAngle);}//////////////////////////////////////////////////////////////////////////////////// \brief Appends the current GPS coordinates to the GPS history track./////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdleUpdateGPSTrack(wxGPSEvent & event){	MapTrack * pTrack;	const Point & pt = event.m_pt;	pTrack = m_ctlMap->GetTrack(wxT("GPSHistory"));	if (!pTrack)	{		vector<Point> vptCoords;		vptCoords.push_back(pt);		MapTrack cTrack(wxT("GPSHistory"), vptCoords, wxColour(0, 255, 255), false);		m_ctlMap->SetTrack(cTrack);		pTrack = m_ctlMap->GetTrack(wxT("GPSHistory"));	}	pTrack->m_vptCoordinates.push_back(pt);	m_ctlMap->SetTrack(*pTrack);}///////////////////////////////////////////////////////////////////////////////// /// \brief Called when new GPS coordinates have been received.////// Moves the marker to indicate where the GPS says we are/////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdle(wxGPSEvent & event){	LibRoadnavDebug0(wxT("GPS"), wxT("MapFrame::OnGPSUpdate"));		if (m_bOnGPSInProgress)	{		LibRoadnavDebug0(wxT("GPS"), wxT("MapFrame::OnGPSUpdate already running - exiting"));		return;	}			m_bOnGPSInProgress = true;	if (event.m_strErrorMessage != wxT(""))	{		wxMessageBox(event.m_strErrorMessage, wxT("Error"), wxOK | wxICON_ERROR, this);	}	bool bEnabled = event.m_bEnabled;	bool bActive = event.m_bActive;	bool bLocked = event.m_bLocked;	const Point & pt = event.m_pt;	double fSpeed = event.m_fSpeed;	double fHeading = event.m_fHeading;	const wxString & strLockType = event.m_strLockType;	int nSat = event.m_nSatUsedForLock;		LibRoadnavDebug5(wxT("GPS"), wxT("bEnabled = %d, bActive = %d, bLocked = %d, fSpeed = %.1f, fHeading = %.1f"),								bEnabled,								bActive,								bLocked,								fSpeed,								fHeading);	if (bLocked)	{		double fHeadingChange = fabs(m_fGPSHeading - fHeading);		bool bPositionChange;		bool bAngleChange;		bPositionChange = fabs(m_ptGPS.m_fLong - pt.m_fLong) > 2e-6 || fabs(m_ptGPS.m_fLat - pt.m_fLat) > 2e-6;				if (fHeadingChange > 180)			fHeadingChange = 360 - fHeadingChange;				bAngleChange = fHeadingChange > 5;		if (bPositionChange || bAngleChange)		{			bool bDoRoadTypeZoomingNow = false;			bool bKeepGPSCentered = g_pConfig->Read(wxT("KeepGPSCentered"), (long) true);			if (bPositionChange)			{				Address adrGPS;				if (g_pConfig->Read(wxT("RoadTypeZooming"), (long) false))				{					if (wxDateTime::Now() - m_tLastRoadTypeZoomingCheck > wxTimeSpan(0, 0, 2, 0))					{						bDoRoadTypeZoomingNow = true;

⌨️ 快捷键说明

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