00001
00002
00003
00004 #include "stdafx.h"
00005 #include "EvolveTraffic.h"
00006 #include "RoadFeaturesDlg.h"
00007 #include "RoadFeature.h"
00008
00009 #include "GridCtrl_src\GridCellCombo.h"
00010 #include "GridCtrl_src\GridCellNumeric.h"
00011
00012 #include "ConfigData.h"
00013 extern CConfigData g_ConfigData;
00014
00015 #ifdef _DEBUG
00016 #define new DEBUG_NEW
00017 #undef THIS_FILE
00018 static char THIS_FILE[] = __FILE__;
00019 #endif
00020
00022
00023
00024
00025 CRoadFeaturesDlg::CRoadFeaturesDlg(CWnd* pParent )
00026 : CDialogExt(CRoadFeaturesDlg::IDD, pParent)
00027 {
00028
00029
00030
00031
00032 MAX_SLOPE = g_ConfigData.Road.RoadFeatures.Gradient.MAX_SLOPE;
00033 SPEEDLIMIT_MIN = g_ConfigData.Road.RoadFeatures.SpeedLimit.SPEEDLIMIT_MIN;
00034 SPEEDLIMIT_MAX = g_ConfigData.Road.RoadFeatures.SpeedLimit.SPEEDLIMIT_MAX;
00035
00036 m_sFeatureTypes.Add("Speed Limit");
00037 m_sFeatureTypes.Add("Gradient");
00038
00039 m_sDirections.Add("Positive x");
00040 m_sDirections.Add("Negative x");
00041
00042 m_sColumnHeaders.Add("Type");
00043 m_sColumnHeaders.Add("Direction");
00044 m_sColumnHeaders.Add("Start (m)");
00045 m_sColumnHeaders.Add("End (m)");
00046 m_sColumnHeaders.Add("Value");
00047
00048 m_nFixCols = FIXED_COLUMNS;
00049 m_nFixRows = FIXED_ROWS;
00050 m_nCols = m_sColumnHeaders.GetSize() + m_nFixCols;
00051 }
00052
00053 void CRoadFeaturesDlg::DoDataExchange(CDataExchange* pDX)
00054 {
00055 CDialogExt::DoDataExchange(pDX);
00056
00057 DDX_Control(pDX, IDC_GRID, m_Grid);
00058
00059 }
00060
00061
00062 BEGIN_MESSAGE_MAP(CRoadFeaturesDlg, CDialogExt)
00063
00064 ON_NOTIFY(GVN_ENDLABELEDIT, IDC_GRID, OnGridEndEdit)
00065 ON_BN_CLICKED(IDC_BTN_ADDFEAT, OnBtnAddfeat)
00066 ON_BN_CLICKED(IDC_BTN_DELFEAT, OnBtnDelfeat)
00067
00068 END_MESSAGE_MAP()
00069
00071
00072
00073 BOOL CRoadFeaturesDlg::OnInitDialog()
00074 {
00075 CDialogExt::OnInitDialog();
00076
00077
00078 m_NoFeatures = m_vRoadFeatures.GetSize();
00079 m_nRows = m_nFixRows + m_NoFeatures;
00080
00081 TRY {
00082 m_Grid.SetRowCount(m_nRows);
00083 m_Grid.SetColumnCount(m_nCols);
00084 m_Grid.SetFixedRowCount(m_nFixRows);
00085 m_Grid.SetFixedColumnCount(m_nFixCols);
00086 }
00087 CATCH (CMemoryException, e)
00088 {
00089 e->ReportError();
00090 return FALSE;
00091 }
00092 END_CATCH
00093
00094 SetGridHeadings();
00095 SetCells(false);
00096 m_Grid.ExpandColumnsToFit();
00097
00098 LoadFeaturesIntoGrid();
00099
00100 return TRUE;
00101 }
00102
00103 void CRoadFeaturesDlg::OnValidate(UINT &nID, CString &strMessage)
00104 {
00105 int nFeats = m_vRoadFeatures.GetSize();
00106
00107 for(int i = 0; i < nFeats; i++)
00108 {
00109 CRoadFeature *pFeat = reinterpret_cast<CRoadFeature*>(m_vRoadFeatures.GetAt(i));
00110
00111
00112 int FeatStart = pFeat->getStart();
00113 int FeatEnd = pFeat->getEnd();
00114 if(FeatStart > FeatEnd)
00115 {
00116 pFeat->setStart(FeatEnd);
00117 pFeat->setEnd(FeatStart);
00118 int temp = FeatStart; FeatStart = FeatEnd; FeatEnd = temp;
00119 }
00120
00121
00122 if(FeatStart > m_RoadLength || FeatEnd > m_RoadLength)
00123 {
00124 strMessage.Format("Feature %d: Starts or ends outside the road length.", i+1);
00125 nID = IDC_GRID;
00126 return;
00127 }
00128
00129 int FeatType = pFeat->getType();
00130
00131 if(FeatType == FEAT_GRADIENT && pFeat->getValue() > MAX_SLOPE)
00132 {
00133 strMessage.Format("Feature %d: Gradient specified is greater \nthan the maximum of %d%%.", i+1, MAX_SLOPE);
00134 nID = IDC_GRID;
00135 return;
00136 }
00137
00138 double speed_limit = pFeat->getValue()*M_PER_S_TO_KM_PER_H;
00139 if(FeatType == FEAT_SPEEDLIMIT && speed_limit < SPEEDLIMIT_MIN)
00140 {
00141 strMessage.Format("Feature %d: Speed limit specified is smaller \nthan the minimum of %d km/h.", i+1, SPEEDLIMIT_MIN);
00142 nID = IDC_GRID;
00143 return;
00144 }
00145
00146 if(FeatType == FEAT_SPEEDLIMIT && speed_limit > SPEEDLIMIT_MAX)
00147 {
00148 strMessage.Format("Feature %d: Speed limit specified is greater \nthan the maximum of %d km/h.", i+1, SPEEDLIMIT_MAX);
00149 nID = IDC_GRID;
00150 return;
00151 }
00152
00153 bool FeatDirPos = pFeat->getDirPos();
00154
00155 for(int j = 0; j < nFeats; j++)
00156 {
00157 if( j != i)
00158 {
00159 CRoadFeature *pFeatJ = reinterpret_cast<CRoadFeature*>(m_vRoadFeatures.GetAt(j));
00160
00161
00162 if(FeatType == pFeatJ->getType() && FeatDirPos == pFeatJ->getDirPos())
00163 {
00164 int FeatJStart = pFeatJ->getStart();
00165 int FeatJEnd = pFeatJ->getEnd();
00166 if( (FeatStart > FeatJStart && FeatEnd < FeatJEnd) ||
00167 (FeatJStart > FeatStart && FeatJStart < FeatEnd) )
00168 {
00169 strMessage.Format("Feature %d overlaps with Feature %d \n- change start and end points.", i+1, j+1);
00170 nID = IDC_GRID;
00171 return;
00172 }
00173 }
00174 }
00175 }
00176 }
00177
00178 }
00179
00180 void CRoadFeaturesDlg::SetGridHeadings()
00181 {
00182 int row = 0;
00183 int col = 0;
00184
00185
00186 for (col = 1; col < m_nCols; col++)
00187 m_Grid.SetItemText(row,col,m_sColumnHeaders.GetAt(col-1));
00188
00189
00190 col = 0;
00191 for(row = m_nFixRows; row < m_nRows; row++)
00192 {
00193 CString str;
00194 str.Format("Feature %d", row);
00195 m_Grid.SetItemText(row,col,str);
00196 }
00197 }
00198
00199 void CRoadFeaturesDlg::SetCells(bool bAddDelete)
00200 {
00201
00202 if(bAddDelete)
00203 {
00204 m_NoFeatures = m_vRoadFeatures.GetSize();
00205 m_nRows = m_nFixRows + m_NoFeatures;
00206 m_Grid.SetRowCount(m_nRows);
00207
00208 for(int row = m_nFixRows; row < m_nRows; row++)
00209 {
00210 CString str;
00211 str.Format("Feature %d", row);
00212 m_Grid.SetItemText(row,0,str);
00213 }
00214 }
00215
00216 for (int row = m_nFixRows; row < m_nRows; row++)
00217 {
00218 int col = 1;
00219 m_Grid.SetCellType(row,col, RUNTIME_CLASS(CGridCellCombo));
00220 CGridCellCombo *pCell = (CGridCellCombo*) m_Grid.GetCell(row,col);
00221 pCell->SetOptions(m_sFeatureTypes);
00222 pCell->SetStyle(CBS_DROPDOWNLIST);
00223
00224 col = 2;
00225 m_Grid.SetCellType(row,col, RUNTIME_CLASS(CGridCellCombo));
00226 pCell = (CGridCellCombo*) m_Grid.GetCell(row,col);
00227 pCell->SetOptions(m_sDirections);
00228 pCell->SetStyle(CBS_DROPDOWNLIST);
00229 }
00230
00231 for (row = m_nFixRows; row < m_nRows; row++)
00232 {
00233 for (int col = m_nFixCols+2; col < m_nCols; col++)
00234 {
00235 m_Grid.SetCellType(row,col, RUNTIME_CLASS(CGridCellNumeric));
00236 m_Grid.GetCell(row,col)->SetFormat(DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS);
00237 CGridCellNumeric *pCell = (CGridCellNumeric*)m_Grid.GetCell(row,col);
00238 if(col == m_nCols - 1)
00239 pCell->SetFlags(CGridCellNumeric::Real | CGridCellNumeric::Negative);
00240 else
00241 pCell->SetFlags(CGridCellNumeric::Integer);
00242 }
00243 }
00244 }
00245
00246 void CRoadFeaturesDlg::LoadFeaturesIntoGrid()
00247 {
00248 for(int i = 0; i < m_NoFeatures; i++)
00249 {
00250 int col = m_nFixCols;
00251 int row = m_nFixRows + i;
00252 CRoadFeature* pFeat = reinterpret_cast<CRoadFeature*>(m_vRoadFeatures[i]);
00253
00254 CString txt = MapTypeToString( pFeat->getType() );
00255 m_Grid.SetItemText(row,col,txt);
00256
00257
00258 txt = pFeat->getDirPos() == true ? m_sDirections.GetAt(0) : m_sDirections.GetAt(1);
00259 m_Grid.SetItemText(row,col+1,txt);
00260
00261 CGridCellNumeric* pCell1 = (CGridCellNumeric *)(m_Grid.GetCell(row,col+2));
00262 CGridCellNumeric* pCell2 = (CGridCellNumeric *)(m_Grid.GetCell(row,col+3));
00263 CGridCellNumeric* pCell3 = (CGridCellNumeric *)(m_Grid.GetCell(row,col+4));
00264 pCell1->SetNumber( pFeat->getStart() );
00265 pCell2->SetNumber( pFeat->getEnd() );
00266
00267 double val = pFeat->getValue();
00268 if(pFeat->getType() == FEAT_SPEEDLIMIT)
00269 val = val * M_PER_S_TO_KM_PER_H;
00270
00271 pCell3->SetNumber( val );
00272 }
00273 m_Grid.AutoSizeRows();
00274 m_Grid.Invalidate();
00275 }
00276
00277 void CRoadFeaturesDlg::OnBtnAddfeat()
00278 {
00279
00280 m_NoFeatures++;
00281 CRoadFeature* pFeat = new CRoadFeature;
00282 m_vRoadFeatures.Add(pFeat);
00283
00284
00285 SetCells(true);
00286 LoadFeaturesIntoGrid();
00287 }
00288
00289 void CRoadFeaturesDlg::OnBtnDelfeat()
00290 {
00291 if(m_NoFeatures != 0)
00292 {
00293
00294 CRoadFeature* pFeat = reinterpret_cast<CRoadFeature*>(m_vRoadFeatures.GetAt(m_NoFeatures-1));
00295 m_vRoadFeatures.RemoveAt( m_NoFeatures-1 );
00296
00297 delete pFeat;
00298 m_NoFeatures--;
00299
00300
00301 SetCells(true);
00302 LoadFeaturesIntoGrid();
00303 }
00304 else
00305 MessageBox("No road feature to delete.", "EvolveTraffic", MB_OK|MB_ICONWARNING);
00306 }
00307
00308
00309 void CRoadFeaturesDlg::OnGridEndEdit(NMHDR *pNotifyStruct, LRESULT* pResult)
00310 {
00311
00312
00313
00314 NM_GRIDVIEW* pItem = (NM_GRIDVIEW*) pNotifyStruct;
00315
00316 int row = pItem->iRow; int col = pItem->iColumn;
00317
00318 if(col < 2 + m_nFixRows )
00319 {
00320 CString strCell = m_Grid.GetCell(row,col)->GetText();
00321 if(strCell != "")
00322 {
00323
00324 SetParamData(row,col,strCell);
00325 *pResult = 0;
00326 }
00327 else
00328 *pResult = -1;
00329 }
00330 else
00331 {
00332
00333
00334 double val = ((CGridCellNumeric *)(m_Grid.GetCell(row,col)))->GetNumber();
00335 SetParamData(row,col,val);
00336 *pResult = 0;
00337 }
00338
00339 }
00340
00341 void CRoadFeaturesDlg::SetParamData(int row, int col, CString str)
00342 {
00343
00344 CRoadFeature* pFeat = reinterpret_cast<CRoadFeature*>(m_vRoadFeatures[row-m_nFixRows]);
00345
00346 col = col - m_nFixCols;
00347
00348 if(col == 0)
00349 pFeat->setType( MapStringToType(str) );
00350
00351 else if(col == 1)
00352 {
00353 bool DirPos = str == m_sDirections.GetAt(0) ? true : false;
00354 pFeat->setDirPos(DirPos);
00355 }
00356 }
00357
00358 void CRoadFeaturesDlg::SetParamData(int row, int col, double val)
00359 {
00360 CRoadFeature* pFeat = reinterpret_cast<CRoadFeature*>(m_vRoadFeatures[row-m_nFixRows]);
00361
00362 switch(col)
00363 {
00364 case 3:
00365 pFeat->setStart( (int)val );
00366 break;
00367 case 4:
00368 pFeat->setEnd( (int)val );
00369 break;
00370 case 5:
00371 {
00372 if(pFeat->getType() == FEAT_SPEEDLIMIT)
00373 val = val * KM_PER_H_TO_M_PER_S;
00374 pFeat->setValue( val );
00375 break;
00376 }
00377 default:
00378 pFeat->setValue( val );
00379 }
00380 }
00381
00382 CString CRoadFeaturesDlg::MapTypeToString(WORD type)
00383 {
00384 switch(type)
00385 {
00386 case FEAT_SPEEDLIMIT: return m_sFeatureTypes.GetAt(0);
00387 case FEAT_GRADIENT: return m_sFeatureTypes.GetAt(1);
00388 default: return m_sFeatureTypes.GetAt(0);
00389 }
00390 }
00391
00392 WORD CRoadFeaturesDlg::MapStringToType(CString str)
00393 {
00394
00395
00396 int i = 0;
00397 while(str != m_sFeatureTypes.GetAt(i))
00398 i++;
00399
00400 switch(i)
00401 {
00402 case 0: return FEAT_SPEEDLIMIT;
00403 case 1: return FEAT_GRADIENT;
00404 default: return FEAT_SPEEDLIMIT;
00405 }
00406 }