📄 directionsframe.cpp
字号:
/* * Roadnav * DirectionsFrame.cpp * * Copyright (c) 2004 - 2007 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 "Support.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 "libroadnav/MapSupport.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; m_bLiveMode = false; m_bGPSLock = false; m_fGPSHeading = 0; m_fGPSSpeed = 0; 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(m_clrText, m_clrBackground, 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(); MapMarker cStartMarker; MapMarker cEndMarker; wxString strErrorMsg; Address sEnd; ////////////////////////////////////////////////////////////////////////// // 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 { if (QueryAddress( wxT("Enter the starting address"), m_pfrmMap, m_pfrmMap->GetMapControl(), wxT(""), wxT(""), wxT(""), true, &cStartMarker, &strErrorMsg) != wxID_OK) { return true; } if (!cStartMarker.m_cAddress.m_bValid) { wxMessageDialog dlgError(this, strErrorMsg, wxT("Error"), wxOK | wxICON_ERROR); return true; } if (cStartMarker.m_strName == wxT("Selected Address") || cStartMarker.m_strName == wxT("")) cStartMarker.m_strName = wxT("Starting Address"); m_sStart = cStartMarker.m_cAddress; } ////////////////////////////////////////////////////////////////////////// // Get destination address ////////////////////////////////////////////////////////////////////////// if (QueryAddress( wxT("Enter the destination address"), m_pfrmMap, m_pfrmMap->GetMapControl(), wxT(""), wxT(""), wxT(""), true, &cEndMarker, &strErrorMsg) != wxID_OK) { return true; } if (!cEndMarker.m_cAddress.m_bValid) { wxMessageDialog dlgError(this, strErrorMsg, wxT("Error"), wxOK | wxICON_ERROR); return true; } if (cEndMarker.m_strName == wxT("Selected Address") || cEndMarker.m_strName == wxT("")) cEndMarker.m_strName = wxT("Destination Address"); m_sEnd = cEndMarker.m_cAddress; ////////////////////////////////////////////////////////////////////////// // 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(m_clrText, m_clrBackground, m_fntText); m_pctlText->SetDefaultStyle(taEdit); m_pctlText->SetStyle(0, m_pctlText->GetLastPosition(), taEdit); if (!m_bLiveMode) { m_pfrmMap->GetMapControl()->SetMarker(cStartMarker); } 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) { LibRoadnavDebug2(wxT("Routing"), wxT("Trying FindCoordinates for %.7f, %.7f"), m_ptGPS.m_fLong, m_ptGPS.m_fLat); m_sStart = FindCoordinates(m_ptGPS, OnlyRoadsVisibility()); LibRoadnavDebug1(wxT("Routing"), wxT("m_sStart.m_bValid = %d"), m_sStart.m_bValid); if (!m_sStart.m_bValid) return true; } if (iAutoDownloadMaps) { bool bVisibility[LAST_RECORD_TYPE + 1]; int iRec; int iCount; map<int,bool> mapCounties; map<int,bool>::iterator iCounties; int iRT; double fMargin = 1; // only load county boundaries for (iRT = FIRST_RECORD_TYPE; iRT <= LAST_RECORD_TYPE; iRT++) bVisibility[iRT] = (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; fTmp = ptTopLeft.m_fLat; ptTopLeft.m_fLat = ptBottomRight.m_fLat; ptBottomRight.m_fLat = fTmp; } ptTopLeft = ptTopLeft - Point(fMargin, fMargin); ptBottomRight = ptBottomRight + Point(fMargin, fMargin); // load the county boundaries for the region that the route may cover m_pcRecords->LoadRegion(ptTopLeft, ptBottomRight, bVisibility); // enumerate counties present iCount = m_pcRecords->Count(); for (iRec = 0; iRec < iCount; iRec++) { IMapControlDataEntry * pcRec; Point * pptRec; int iCoordinate; pcRec = m_pcRecords->GetRecord(iRec); for (iCoordinate = 0; iCoordinate < pcRec->nCoordinates; iCoordinate++) { pptRec = &pcRec->psCoordinates[iCoordinate]; if (pptRec->m_fLong >= ptTopLeft.m_fLong && pptRec->m_fLong <= ptBottomRight.m_fLong && pptRec->m_fLat >= ptTopLeft.m_fLat && pptRec->m_fLat <= ptBottomRight.m_fLat) { mapCounties[pcRec->CountyCode()] = true; } } } map<int,bool> bDownloadingCounty; map<wxString,bool> bDownloadingState; vector<wxInt32> vDownloadCounties; vector<wxString> vDownloadStates; int iTotal;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -