|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Changes the speed allowed on a set of lanes (gui version) 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 // =========================================================================== 00020 // included modules 00021 // =========================================================================== 00022 #ifdef _MSC_VER 00023 #include <windows_config.h> 00024 #else 00025 #include <config.h> 00026 #endif 00027 00028 #ifdef _WIN32 00029 #include <windows.h> 00030 #endif 00031 00032 #include <GL/gl.h> 00033 00034 #include <string> 00035 #include <utils/common/MsgHandler.h> 00036 #include <utils/geom/PositionVector.h> 00037 #include <utils/geom/Line.h> 00038 #include <utils/geom/Boundary.h> 00039 #include <utils/gui/div/GLHelper.h> 00040 #include <utils/common/ToString.h> 00041 #include <utils/common/Command.h> 00042 #include <microsim/MSNet.h> 00043 #include <microsim/MSLane.h> 00044 #include <microsim/MSEdge.h> 00045 #include <guisim/GUINet.h> 00046 #include <guisim/GUIEdge.h> 00047 #include "GUILaneSpeedTrigger.h" 00048 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h> 00049 #include <utils/gui/windows/GUIAppEnum.h> 00050 #include <gui/GUIGlobals.h> 00051 #include <utils/gui/div/GUIParameterTableWindow.h> 00052 #include <gui/GUIApplicationWindow.h> 00053 #include <utils/gui/images/GUITexturesHelper.h> 00054 #include <microsim/logging/FunctionBinding.h> 00055 #include <utils/gui/div/GUIGlobalSelection.h> 00056 #include <foreign/polyfonts/polyfonts.h> 00057 #include <utils/gui/images/GUIIconSubSys.h> 00058 #include <gui/GUIApplicationWindow.h> 00059 #include <guisim/GUILaneSpeedTrigger.h> 00060 00061 #ifdef CHECK_MEMORY_LEAKS 00062 #include <foreign/nvwa/debug_new.h> 00063 #endif // CHECK_MEMORY_LEAKS 00064 00065 00066 // =========================================================================== 00067 // FOX callback mapping 00068 // =========================================================================== 00069 /* ------------------------------------------------------------------------- 00070 * GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu - mapping 00071 * ----------------------------------------------------------------------- */ 00072 FXDEFMAP(GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu) 00073 GUILaneSpeedTriggerPopupMenuMap[]= { 00074 FXMAPFUNC(SEL_COMMAND, MID_MANIP, GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::onCmdOpenManip), 00075 00076 }; 00077 00078 // Object implementation 00079 FXIMPLEMENT(GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu, GUIGLObjectPopupMenu, GUILaneSpeedTriggerPopupMenuMap, ARRAYNUMBER(GUILaneSpeedTriggerPopupMenuMap)) 00080 00081 00082 /* ------------------------------------------------------------------------- 00083 * GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger - mapping 00084 * ----------------------------------------------------------------------- */ 00085 FXDEFMAP(GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger) GUIManip_LaneSpeedTriggerMap[]= { 00086 FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_USER_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdUserDef), 00087 FXMAPFUNC(SEL_UPDATE, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_USER_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdUserDef), 00088 FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_PRE_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdPreDef), 00089 FXMAPFUNC(SEL_UPDATE, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_PRE_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdPreDef), 00090 FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_OPTION, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdChangeOption), 00091 FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_CLOSE, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdClose), 00092 }; 00093 00094 FXIMPLEMENT(GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger, GUIManipulator, GUIManip_LaneSpeedTriggerMap, ARRAYNUMBER(GUIManip_LaneSpeedTriggerMap)) 00095 00096 00097 // =========================================================================== 00098 // method definitions 00099 // =========================================================================== 00100 /* ------------------------------------------------------------------------- 00101 * GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger - methods 00102 * ----------------------------------------------------------------------- */ 00103 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::GUIManip_LaneSpeedTrigger( 00104 GUIMainWindow& app, 00105 const std::string& name, GUILaneSpeedTrigger& o, 00106 int /*xpos*/, int /*ypos*/) 00107 : GUIManipulator(app, name, 0, 0), 00108 myParent(&app), myChosenValue(0), myChosenTarget(myChosenValue, NULL, MID_OPTION), 00109 mySpeed(o.getDefaultSpeed()), mySpeedTarget(mySpeed), 00110 myObject(&o) { 00111 myChosenTarget.setTarget(this); 00112 FXVerticalFrame* f1 = 00113 new FXVerticalFrame(this, LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0); 00114 00115 FXGroupBox* gp = new FXGroupBox(f1, "Change Speed", 00116 GROUPBOX_TITLE_LEFT|FRAME_RIDGE, 00117 0, 0, 0, 0, 4, 4, 1, 1, 2, 0); 00118 { 00119 // default 00120 FXHorizontalFrame* gf1 = 00121 new FXHorizontalFrame(gp, LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0, 10,10,5,5); 00122 new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION+0, 00123 ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP, 00124 0, 0, 0, 0, 2, 2, 0, 0); 00125 } 00126 { 00127 // loaded 00128 FXHorizontalFrame* gf0 = 00129 new FXHorizontalFrame(gp, LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0, 10,10,5,5); 00130 new FXRadioButton(gf0, "Loaded", &myChosenTarget, FXDataTarget::ID_OPTION+1, 00131 ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP, 00132 0, 0, 0, 0, 2, 2, 0, 0); 00133 } 00134 { 00135 // predefined 00136 FXHorizontalFrame* gf2 = 00137 new FXHorizontalFrame(gp, LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0, 10,10,5,5); 00138 new FXRadioButton(gf2, "Predefined: ", &myChosenTarget, FXDataTarget::ID_OPTION+2, 00139 ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_CENTER_Y, 00140 0, 0, 0, 0, 2, 2, 0, 0); 00141 myPredefinedValues = 00142 new FXComboBox(gf2, 10, this, MID_PRE_DEF, 00143 ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_CENTER_Y|COMBOBOX_STATIC); 00144 myPredefinedValues->appendItem("20 km/h"); 00145 myPredefinedValues->appendItem("40 km/h"); 00146 myPredefinedValues->appendItem("60 km/h"); 00147 myPredefinedValues->appendItem("80 km/h"); 00148 myPredefinedValues->appendItem("100 km/h"); 00149 myPredefinedValues->appendItem("120 km/h"); 00150 myPredefinedValues->appendItem("140 km/h"); 00151 myPredefinedValues->appendItem("160 km/h"); 00152 myPredefinedValues->appendItem("180 km/h"); 00153 myPredefinedValues->appendItem("200 km/h"); 00154 myPredefinedValues->setNumVisible(5); 00155 } 00156 { 00157 // free 00158 FXHorizontalFrame* gf12 = 00159 new FXHorizontalFrame(gp, LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0, 10,10,5,5); 00160 new FXRadioButton(gf12, "Free Entry: ", &myChosenTarget, FXDataTarget::ID_OPTION+3, 00161 ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_CENTER_Y, 00162 0, 0, 0, 0, 2, 2, 0, 0); 00163 myUserDefinedSpeed = 00164 new FXRealSpinDial(gf12, 10, this, MID_USER_DEF, 00165 LAYOUT_TOP|FRAME_SUNKEN|FRAME_THICK); 00166 myUserDefinedSpeed->setFormatString("%.0f km/h"); 00167 myUserDefinedSpeed->setIncrements(1,10,10); 00168 myUserDefinedSpeed->setRange(0,300); 00169 myUserDefinedSpeed->setValue( 00170 static_cast<GUILaneSpeedTrigger*>(myObject)->getDefaultSpeed()*3.6); 00171 } 00172 new FXButton(f1,"Close",NULL,this,MID_CLOSE, 00173 BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_CENTER_X,0,0,0,0, 30,30,4,4); 00174 static_cast<GUILaneSpeedTrigger*>(myObject)->setOverriding(true); 00175 } 00176 00177 00178 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::~GUIManip_LaneSpeedTrigger() {} 00179 00180 00181 long 00182 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdClose(FXObject*,FXSelector,void*) { 00183 destroy(); 00184 return 1; 00185 } 00186 00187 00188 long 00189 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdUserDef(FXObject*,FXSelector,void*) { 00190 mySpeed = (SUMOReal)(myUserDefinedSpeed->getValue() / 3.6); 00191 static_cast<GUILaneSpeedTrigger*>(myObject)->setOverridingValue(mySpeed); 00192 myParent->updateChildren(); 00193 return 1; 00194 } 00195 00196 00197 long 00198 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdUserDef(FXObject* sender,FXSelector,void* ptr) { 00199 sender->handle(this, 00200 myChosenValue!=3 ? FXSEL(SEL_COMMAND,ID_DISABLE):FXSEL(SEL_COMMAND,ID_ENABLE), 00201 ptr); 00202 myParent->updateChildren(); 00203 return 1; 00204 } 00205 00206 00207 long 00208 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdPreDef(FXObject*,FXSelector,void*) { 00209 mySpeed = (SUMOReal)(SUMOReal)((myPredefinedValues->getCurrentItem() * 20 + 20)/3.6); 00210 static_cast<GUILaneSpeedTrigger*>(myObject)->setOverridingValue(mySpeed); 00211 myParent->updateChildren(); 00212 return 1; 00213 } 00214 00215 00216 long 00217 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdPreDef(FXObject* sender,FXSelector,void* ptr) { 00218 sender->handle(this, 00219 myChosenValue!=2 ? FXSEL(SEL_COMMAND,ID_DISABLE):FXSEL(SEL_COMMAND,ID_ENABLE), 00220 ptr); 00221 myParent->updateChildren(); 00222 return 1; 00223 } 00224 00225 00226 long 00227 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdChangeOption(FXObject*,FXSelector,void*) { 00228 static_cast<GUILaneSpeedTrigger*>(myObject)->setOverriding(true); 00229 switch (myChosenValue) { 00230 case 0: 00231 mySpeed = (SUMOReal) static_cast<GUILaneSpeedTrigger*>(myObject)->getDefaultSpeed(); 00232 break; 00233 case 1: 00234 mySpeed = (SUMOReal) static_cast<GUILaneSpeedTrigger*>(myObject)->getLoadedSpeed(); 00235 break; 00236 case 2: 00237 mySpeed = (SUMOReal)((myPredefinedValues->getCurrentItem() * 20 + 20)/3.6); 00238 break; 00239 case 3: 00240 mySpeed = (SUMOReal)(myUserDefinedSpeed->getValue() / 3.6); 00241 break; 00242 default: 00243 // hmmm, should not happen 00244 break; 00245 } 00246 static_cast<GUILaneSpeedTrigger*>(myObject)->setOverridingValue(mySpeed); 00247 myParent->updateChildren(); 00248 if (myChosenValue==1) { 00249 // !!! lock in between 00250 static_cast<GUILaneSpeedTrigger*>(myObject)->setOverriding(false); 00251 } 00252 return 1; 00253 } 00254 00255 00256 00257 /* ------------------------------------------------------------------------- 00258 * GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu - methods 00259 * ----------------------------------------------------------------------- */ 00260 GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::GUILaneSpeedTriggerPopupMenu( 00261 GUIMainWindow& app, GUISUMOAbstractView& parent, 00262 GUIGlObject& o) 00263 : GUIGLObjectPopupMenu(app, parent, o) {} 00264 00265 00266 GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::~GUILaneSpeedTriggerPopupMenu() throw() {} 00267 00268 00269 long 00270 GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::onCmdOpenManip(FXObject*, 00271 FXSelector, 00272 void*) { 00273 static_cast<GUILaneSpeedTrigger*>(myObject)->openManipulator( 00274 *myApplication, *myParent); 00275 return 1; 00276 } 00277 00278 00279 /* ------------------------------------------------------------------------- 00280 * GUILaneSpeedTrigger - methods 00281 * ----------------------------------------------------------------------- */ 00282 GUILaneSpeedTrigger::GUILaneSpeedTrigger( 00283 const std::string& id,const std::vector<MSLane*> &destLanes, 00284 const std::string& aXMLFilename) throw(ProcessError) 00285 : MSLaneSpeedTrigger(id, destLanes, aXMLFilename), 00286 GUIGlObject_AbstractAdd("speedtrigger", GLO_TRIGGER, id), 00287 myShowAsKMH(true), myLastValue(-1) { 00288 myFGPositions.reserve(destLanes.size()); 00289 myFGRotations.reserve(destLanes.size()); 00290 std::vector<MSLane*>::const_iterator i; 00291 for (i=destLanes.begin(); i!=destLanes.end(); ++i) { 00292 const PositionVector& v = (*i)->getShape(); 00293 myFGPositions.push_back(v.positionAtLengthPosition(0)); 00294 myBoundary.add(v.positionAtLengthPosition(0)); 00295 Line l(v.getBegin(), v.getEnd()); 00296 myFGRotations.push_back(-v.rotationDegreeAtLengthPosition(0)); 00297 myDefaultSpeed = (*i)->getMaxSpeed(); 00298 mySpeedOverrideValue = (*i)->getMaxSpeed(); 00299 } 00300 } 00301 00302 00303 GUILaneSpeedTrigger::~GUILaneSpeedTrigger() throw() {} 00304 00305 00306 GUIGLObjectPopupMenu* 00307 GUILaneSpeedTrigger::getPopUpMenu(GUIMainWindow& app, 00308 GUISUMOAbstractView& parent) throw() { 00309 GUIGLObjectPopupMenu* ret = new GUILaneSpeedTriggerPopupMenu(app, parent, *this); 00310 buildPopupHeader(ret, app); 00311 buildCenterPopupEntry(ret); 00312 buildShowManipulatorPopupEntry(ret); 00313 buildNameCopyPopupEntry(ret); 00314 buildSelectionPopupEntry(ret); 00315 buildShowParamsPopupEntry(ret); 00316 buildPositionCopyEntry(ret, false); 00317 return ret; 00318 } 00319 00320 00321 GUIParameterTableWindow* 00322 GUILaneSpeedTrigger::getParameterWindow(GUIMainWindow& app, 00323 GUISUMOAbstractView&) throw() { 00324 GUIParameterTableWindow* ret = 00325 new GUIParameterTableWindow(app, *this, 1); 00326 // add items 00327 ret->mkItem("speed [m/s]", true, 00328 new FunctionBinding<GUILaneSpeedTrigger, SUMOReal>(this, &GUILaneSpeedTrigger::getCurrentSpeed)); 00329 // close building 00330 ret->closeBuilding(); 00331 return ret; 00332 } 00333 00334 00335 void 00336 GUILaneSpeedTrigger::drawGL(const GUIVisualizationSettings& s) const throw() { 00337 glPushName(getGlID()); 00338 glPushMatrix(); 00339 glTranslated(0, 0, getType()); 00340 for (size_t i=0; i<myFGPositions.size(); ++i) { 00341 const Position& pos = myFGPositions[i]; 00342 SUMOReal rot = myFGRotations[i]; 00343 glPushMatrix(); 00344 glScaled(s.addExaggeration, s.addExaggeration, 1); 00345 glTranslated(pos.x(), pos.y(), 0); 00346 glRotated(rot, 0, 0, 1); 00347 glTranslated(0, -1.5, 0); 00348 00349 int noPoints = 9; 00350 if (s.scale>25) { 00351 noPoints = (int)(9.0 + s.scale / 10.0); 00352 if (noPoints>36) { 00353 noPoints = 36; 00354 } 00355 } 00356 glColor3d(1, 0, 0); 00357 GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints); 00358 if (s.scale>=5) { 00359 glTranslated(0, 0, .1); 00360 glColor3d(0, 0, 0); 00361 GLHelper::drawFilledCircle((SUMOReal) 1.1, noPoints); 00362 // draw the speed string 00363 // not if scale to low 00364 // compute 00365 SUMOReal value = (SUMOReal) getCurrentSpeed(); 00366 if (myShowAsKMH) { 00367 value *= 3.6f; 00368 if (((int) value+1)%10==0) { 00369 value = (SUMOReal)(((int) value+1) / 10 * 10); 00370 } 00371 } 00372 if (value!=myLastValue) { 00373 myLastValue = value; 00374 myLastValueString = toString<SUMOReal>(myLastValue); 00375 size_t idx = myLastValueString.find('.'); 00376 if (idx!=std::string::npos) { 00377 if (idx>myLastValueString.length()) { 00378 idx = myLastValueString.length(); 00379 } 00380 myLastValueString = myLastValueString.substr(0, idx); 00381 } 00382 } 00383 //draw 00384 glColor3d(1, 1, 0); 00385 glTranslated(0, 0, .1); 00386 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00387 pfSetPosition(0, 0); 00388 pfSetScale(1.2f); 00389 SUMOReal w = pfdkGetStringWidth(myLastValueString.c_str()); 00390 glRotated(180, 0, 1, 0); 00391 glTranslated(-w/2., 0.3, 0); 00392 pfDrawString(myLastValueString.c_str()); 00393 } 00394 glPopMatrix(); 00395 } 00396 glPopMatrix(); 00397 drawName(getCenteringBoundary().getCenter(), s.scale, s.addName); 00398 glPopName(); 00399 } 00400 00401 00402 Boundary 00403 GUILaneSpeedTrigger::getCenteringBoundary() const throw() { 00404 Boundary b(myBoundary); 00405 b.grow(20); 00406 return b; 00407 } 00408 00409 00410 GUIManipulator* 00411 GUILaneSpeedTrigger::openManipulator(GUIMainWindow& app, 00412 GUISUMOAbstractView&) { 00413 GUIManip_LaneSpeedTrigger* gui = 00414 new GUIManip_LaneSpeedTrigger(app, getFullName(), *this, 0, 0); 00415 gui->create(); 00416 gui->show(); 00417 return gui; 00418 } 00419 00420 00421 00422 /****************************************************************************/ 00423