📄 frame.cpp
字号:
{ 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 + -