directionsframe.cpp
来自「roadnav 内含一个基于wxWindows库的车载导航系统。编译后」· C++ 代码 · 共 703 行 · 第 1/2 页
CPP
703 行
/* * Roadnav * DirectionsFrame.cpp * * Copyright (c) 2004 - 2006 Richard L. Lynch <rllynch@users.sourceforge.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ ///////////////////////////////////////////////////////////////////////////////// \file////// This frame is responsible for showing and verbalizing real time/// directions to a place the user specifies./////////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifdef _MSC_VER#pragma warning(disable: 4786)#pragma warning(disable: 4800)#endif#include <wx/wx.h>#include "DirectionsFrame.h"#include "Frame.h"#include "LocationDialog.h"#include "libroadnav/Map.h"#include "libroadnav/MapRepresentations.h"#include "libroadnav/MapControlDataImporter_GNISDECI.h"#include "libroadnav/MapControlDataImporter_TigerLine.h"#include "libroadnav/MapState.h"#include "libroadnav/Debug.h"#include "TTS.h"#include "App.h"using namespace std;//////////////////////////////////////////////////////////////////////////////////// DirectionsFrame event table/////////////////////////////////////////////////////////////////////////////////BEGIN_EVENT_TABLE(DirectionsFrame, wxFrame) EVT_CLOSE(DirectionsFrame::OnClose)END_EVENT_TABLE()//////////////////////////////////////////////////////////////////////////////////// \brief DirectionsFrame construct - create children, set up timer////////////////////////////////////////////////////////////////////////////////DirectionsFrame::DirectionsFrame ( class MapFrame * pfrmMap ) : wxFrame ( (wxFrame *) pfrmMap, -1, wxT("Directions"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE ), m_fntText(16, wxDEFAULT, wxNORMAL, wxNORMAL){ wxBoxSizer * psizerWnd; m_pfrmMap = pfrmMap; m_bLockOutGPSUpdate = false; psizerWnd = new wxBoxSizer(wxVERTICAL); ////////////////////////////////////////////////////////////////////////// // Label ////////////////////////////////////////////////////////////////////////// m_pctlText = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(300, 100), wxTE_MULTILINE | wxTE_RICH), psizerWnd->Add( m_pctlText, 1, wxGROW, 0 ); wxTextAttr taEdit(*wxBLACK, wxNullColour, m_fntText); m_pctlText->SetDefaultStyle(taEdit); ////////////////////////////////////////////////////////////////////////// // Set up the sizer ////////////////////////////////////////////////////////////////////////// //psizerWnd->Fit(this); SetSizer(psizerWnd); Layout(); psizerWnd->SetSizeHints(this); m_pcRecords = new MapControlData_Tiles;}//////////////////////////////////////////////////////////////////////////////////// \brief DirectionsFrame destructor - doesn't do anything/////////////////////////////////////////////////////////////////////////////////DirectionsFrame::~DirectionsFrame(){ delete m_pcRecords;}//////////////////////////////////////////////////////////////////////////////////// \brief User wants to bring up directions window - get destination address /// and make sure everything is okay before letting the window appear./// /// If there's no GPS lock, then get the starting address too./////////////////////////////////////////////////////////////////////////////////bool DirectionsFrame::Setup(){ wxFont fntThis = GetFont(); LocationDialog dlgAddress(m_pfrmMap, m_pfrmMap->GetMapControl(), ADFLAG_CANCELBUTTON, &fntThis); dlgAddress.m_bRoadsOnly = true; Address sAddr; Address sEnd; wxString strStartName; wxString strStartIcon; bool bStartCalloutBox; wxString strEndName; wxString strEndIcon; bool bEndCalloutBox; bStartCalloutBox = false; m_bLockOutGPSUpdate = true; ////////////////////////////////////////////////////////////////////////// // GPS lock required first ////////////////////////////////////////////////////////////////////////// m_bLiveMode = m_bGPSLock; ////////////////////////////////////////////////////////////////////////// // Get starting address ////////////////////////////////////////////////////////////////////////// if (m_bLiveMode) { if (!m_bGPSLock) { // obviously, this can't happen right now .. this is more for future purposes wxMessageDialog dlgError(this, wxT("GPS lock required for live directions"), wxT("Error"), wxOK | wxICON_ERROR); dlgError.ShowModal(); return true; } } else { dlgAddress.m_strTitle = wxT("Enter the starting address"); dlgAddress.m_strName = wxT("Starting Address"); sAddr.m_bValid = false; while (!sAddr.m_bValid) { wxString strErrorMsg; if (dlgAddress.ShowModal() == wxID_CANCEL) return true; sAddr = dlgAddress.GetAddress(&strErrorMsg); if (!sAddr.m_bValid) { wxMessageDialog dlgError(this, strErrorMsg, wxT("Error"), wxOK | wxICON_ERROR); dlgError.ShowModal(); } } m_sStart = sAddr; strStartName = dlgAddress.m_strName; if (strStartName == wxT("")) strStartName = wxT("Starting Address"); strStartIcon = dlgAddress.m_strIconFilename; bStartCalloutBox = dlgAddress.m_bShowCalloutBox; } ////////////////////////////////////////////////////////////////////////// // Get destination address ////////////////////////////////////////////////////////////////////////// dlgAddress.m_strTitle = wxT("Enter the destination address"); dlgAddress.m_strName = wxT("Ending Address"); sAddr.m_bValid = false; while (!sAddr.m_bValid) { wxString strErrorMsg; if (dlgAddress.ShowModal() == wxID_CANCEL) return true; sAddr = dlgAddress.GetAddress(&strErrorMsg); if (!sAddr.m_bValid) { wxMessageDialog dlgError(this, strErrorMsg, wxT("Error"), wxOK | wxICON_ERROR); dlgError.ShowModal(); } } m_sEnd = sAddr; strEndName = dlgAddress.m_strName; if (strEndName == wxT("")) strEndName = wxT("Ending Address"); strEndIcon = dlgAddress.m_strIconFilename; bEndCalloutBox = dlgAddress.m_bShowCalloutBox; ////////////////////////////////////////////////////////////////////////// // Is it possible to get there at all? ////////////////////////////////////////////////////////////////////////// if (ComputePath()) { wxMessageDialog dlgError(this, wxT("Unable to determine route!"), wxT("Error"), wxOK | wxICON_ERROR); dlgError.ShowModal(); return true; } ////////////////////////////////////////////////////////////////////////// // write out directions ////////////////////////////////////////////////////////////////////////// m_pctlText->SetValue(m_pcRecords->TranslateRecordsToDirections(m_vrPath)); m_strLastNext = wxT(""); ////////////////////////////////////////////////////////////////////////// // update font ////////////////////////////////////////////////////////////////////////// wxTextAttr taEdit(*wxBLACK, wxNullColour, m_fntText); m_pctlText->SetDefaultStyle(taEdit); m_pctlText->SetStyle(0, m_pctlText->GetLastPosition(), taEdit); if (!m_bLiveMode) { MapMarker cStartMarker(strStartName, &m_sStart, -1, bStartCalloutBox, strStartIcon); m_pfrmMap->GetMapControl()->SetMarker(cStartMarker); } MapMarker cEndMarker(strEndName, &m_sEnd, -1, bEndCalloutBox, strEndIcon); m_pfrmMap->GetMapControl()->SetMarker(cEndMarker); m_pfrmMap->GetMapControl()->SetCenterCoordinates((m_sStart.m_ptCoordinates + m_sEnd.m_ptCoordinates) / 2); m_pfrmMap->GetMapControl()->SetDetailLevel( m_pfrmMap->GetMapControlData().GetNumRecordTypes()-1 ); m_pfrmMap->GetMapControl()->AutoScale(); m_bLockOutGPSUpdate = false; return false;}//////////////////////////////////////////////////////////////////////////////////// \brief Compute the shortest path from m_ptGPS to m_sEnd////// Updates m_sStart (address of m_ptGPS), m_vrPath (path in record numbers),/// m_vptPath (path in long/lat coordinates) in the process/////////////////////////////////////////////////////////////////////////////////bool DirectionsFrame::ComputePath(){ int iAutoDownloadMaps = 1; g_pConfig->Read(wxT("AutoDownloadMaps"), &iAutoDownloadMaps, 1); LibRoadnavDebug2(wxT("Routing"), wxT("ComputePath called - iAutoDownloadMaps = %d, m_bLiveMode = %d"), iAutoDownloadMaps, m_bLiveMode); // determine the path if (m_bLiveMode) { int iRT; vector<bool> bVisibility; for (iRT = FIRST_RECORD_TYPE; iRT <= LAST_RECORD_TYPE; iRT++) { bVisibility.push_back(iRT >= FIRST_RECORD_TYPE_ROAD && iRT <= LAST_RECORD_TYPE_ROAD); } LibRoadnavDebug2(wxT("Routing"), wxT("Trying FindCoordinates for %.7f, %.7f"), m_ptGPS.m_fLong, m_ptGPS.m_fLat); m_sStart = FindCoordinates(m_ptGPS, bVisibility); LibRoadnavDebug1(wxT("Routing"), wxT("m_sStart.m_bValid = %d"), m_sStart.m_bValid); if (!m_sStart.m_bValid) return true; } if (iAutoDownloadMaps) { vector<bool> bVisibility; int iRec; int iCount; map<int,bool> mapCounties; map<int,bool>::iterator iCounties; int iRT; // only load county boundaries for (iRT = FIRST_RECORD_TYPE; iRT <= LAST_RECORD_TYPE; iRT++) { bVisibility.push_back(((ERecordType) iRT) == RecordTypeCountyBoundary); } // calculate top-left and bottom-right coordinates Point ptTopLeft; Point ptBottomRight; ptTopLeft = m_sStart.m_ptCoordinates; ptBottomRight = m_sEnd.m_ptCoordinates; if (ptTopLeft.m_fLong > ptBottomRight.m_fLong) { double fTmp; fTmp = ptTopLeft.m_fLong; ptTopLeft.m_fLong = ptBottomRight.m_fLong; ptBottomRight.m_fLong = fTmp; } if (ptTopLeft.m_fLat > ptBottomRight.m_fLat) { double fTmp;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?