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 + -
显示快捷键?