GUIEmitter.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A vehicle emitting device (gui version)
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 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/Position2DVector.h>
00037 #include <utils/geom/Line2D.h>
00038 #include <utils/geom/Boundary.h>
00039 #include <utils/gui/div/GLHelper.h>
00040 #include <utils/common/ToString.h>
00041 #include <microsim/MSNet.h>
00042 #include <microsim/MSLane.h>
00043 #include <microsim/MSEdge.h>
00044 #include <guisim/GUINet.h>
00045 #include <guisim/GUIEdge.h>
00046 #include "GUIEmitter.h"
00047 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
00048 #include <utils/gui/images/GUIIconSubSys.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 <utils/gui/globjects/GUIGlObjectStorage.h>
00057 #include <foreign/polyfonts/polyfonts.h>
00058 #include <utils/common/WrappingCommand.h>
00059 
00060 #ifdef CHECK_MEMORY_LEAKS
00061 #include <foreign/nvwa/debug_new.h>
00062 #endif // CHECK_MEMORY_LEAKS
00063 
00064 
00065 // ===========================================================================
00066 // FOX callback mapping
00067 // ===========================================================================
00068 /* -------------------------------------------------------------------------
00069  * GUIEmitter::GUIEmitterPopupMenu - mapping
00070  * ----------------------------------------------------------------------- */
00071 FXDEFMAP(GUIEmitter::GUIEmitterPopupMenu)
00072 GUIEmitterPopupMenuMap[]= {
00073     FXMAPFUNC(SEL_COMMAND,  MID_MANIP,         GUIEmitter::GUIEmitterPopupMenu::onCmdOpenManip),
00074     FXMAPFUNC(SEL_COMMAND,  MID_DRAWROUTE,     GUIEmitter::GUIEmitterPopupMenu::onCmdDrawRoute),
00075 
00076 };
00077 
00078 // Object implementation
00079 FXIMPLEMENT(GUIEmitter::GUIEmitterPopupMenu, GUIGLObjectPopupMenu, GUIEmitterPopupMenuMap, ARRAYNUMBER(GUIEmitterPopupMenuMap))
00080 
00081 
00082 /* -------------------------------------------------------------------------
00083  * GUIEmitter::GUIManip_TriggeredEmitter - mapping
00084  * ----------------------------------------------------------------------- */
00085 FXDEFMAP(GUIEmitter::GUIManip_TriggeredEmitter) GUIManip_TriggeredEmitterMap[]= {
00086     FXMAPFUNC(SEL_COMMAND,  GUIEmitter::GUIManip_TriggeredEmitter::MID_USER_DEF, GUIEmitter::GUIManip_TriggeredEmitter::onCmdUserDef),
00087     FXMAPFUNC(SEL_UPDATE,   GUIEmitter::GUIManip_TriggeredEmitter::MID_USER_DEF, GUIEmitter::GUIManip_TriggeredEmitter::onUpdUserDef),
00088     FXMAPFUNC(SEL_COMMAND,  GUIEmitter::GUIManip_TriggeredEmitter::MID_OPTION,   GUIEmitter::GUIManip_TriggeredEmitter::onCmdChangeOption),
00089     FXMAPFUNC(SEL_COMMAND,  GUIEmitter::GUIManip_TriggeredEmitter::MID_CLOSE,    GUIEmitter::GUIManip_TriggeredEmitter::onCmdClose),
00090 };
00091 
00092 FXIMPLEMENT(GUIEmitter::GUIManip_TriggeredEmitter, GUIManipulator, GUIManip_TriggeredEmitterMap, ARRAYNUMBER(GUIManip_TriggeredEmitterMap))
00093 
00094 
00095 
00096 // ===========================================================================
00097 // method definitions
00098 // ===========================================================================
00099 /* -------------------------------------------------------------------------
00100  * GUIEmitter::GUIManip_TriggeredEmitter - methods
00101  * ----------------------------------------------------------------------- */
00102 GUIEmitter::GUIEmitterChild_UserTriggeredChild::GUIEmitterChild_UserTriggeredChild(
00103     MSEmitter_FileTriggeredChild &s,
00104     MSEmitter &parent, MSVehicleControl &vc,
00105     SUMOReal flow) throw()
00106         : MSEmitter::MSEmitterChild(parent, vc), myUserFlow(flow),
00107         myVehicle(0), mySource(s) {
00108     if (myUserFlow>0) {
00109         Command* c = new WrappingCommand< GUIEmitterChild_UserTriggeredChild >(this, &GUIEmitterChild_UserTriggeredChild::wrappedExecute);
00110         MSNet::getInstance()->getEmissionEvents().addEvent(
00111             c, (SUMOTime)(1. / (flow / 3600.))+MSNet::getInstance()->getCurrentTimeStep(),
00112             MSEventControl::ADAPT_AFTER_EXECUTION);
00113     }
00114 }
00115 
00116 
00117 GUIEmitter::GUIEmitterChild_UserTriggeredChild::~GUIEmitterChild_UserTriggeredChild() throw() {
00118 }
00119 
00120 
00121 SUMOTime
00122 GUIEmitter::GUIEmitterChild_UserTriggeredChild::wrappedExecute(SUMOTime currentTime) throw(ProcessError) {
00123     if (myUserFlow<=0) {
00124         return 0;
00125     }
00126     if (!mySource.isInitialised()) {
00127         mySource.init();
00128     }
00129     if (myVehicle==0) {
00130         SUMOVehicleParameter* p = new SUMOVehicleParameter();
00131         p->id = myParent.getID() + "_user_" +  toString(currentTime);
00132         const MSRoute *aRoute = myRouteDist.getOverallProb()!=0
00133                                 ? myRouteDist.get()
00134                                 : mySource.hasRoutes()
00135                                 ? mySource.getRndRoute()
00136                                 : 0;
00137         if (aRoute==0) {
00138             MsgHandler::getErrorInstance()->inform("Emitter '" + myParent.getID() + "' has no valid route.");
00139             return 0;
00140         }
00141         MSVehicleType *aType = myVTypeDist.getOverallProb()!=0
00142                                ? myVTypeDist.get()
00143                                : mySource.hasVTypes()
00144                                ? mySource.getRndVType()
00145                                : MSNet::getInstance()->getVehicleControl().getVType();
00146         if (aType==0) {
00147             MsgHandler::getErrorInstance()->inform("Emitter '" + myParent.getID() + "' has no valid vehicle type.");
00148             return 0;
00149         }
00150         p->depart = currentTime;
00151         myVehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(p, aRoute, aType);
00152         myParent.schedule(this, myVehicle, -1);
00153     }
00154     if (myParent.childCheckEmit(this)) {
00155         myVehicle = 0;
00156         return (SUMOTime) computeOffset(myUserFlow);
00157     }
00158     return 1;
00159 }
00160 
00161 
00162 SUMOReal
00163 GUIEmitter::GUIEmitterChild_UserTriggeredChild::getUserFlow() const {
00164     return myUserFlow;
00165 }
00166 
00167 
00168 
00169 GUIEmitter::GUIManip_TriggeredEmitter::GUIManip_TriggeredEmitter(
00170     GUIMainWindow &app,
00171     const std::string &name, GUIEmitter &o,
00172     int /*xpos*/, int /*ypos*/)
00173         : GUIManipulator(app, name, 0, 0), myParent(&app),
00174         myChosenValue(0), myChosenTarget(myChosenValue, this, MID_OPTION),
00175         myFlowFactor(o.getUserFlow()), myFlowFactorTarget(myFlowFactor),
00176         myObject(&o) {
00177     FXVerticalFrame *f1 =
00178         new FXVerticalFrame(this, LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);
00179 
00180     myChosenValue = (FXint) o.getActiveChildIndex();
00181 
00182     FXGroupBox *gp = new FXGroupBox(f1, "Change Flow",
00183                                     GROUPBOX_TITLE_LEFT|FRAME_SUNKEN|FRAME_RIDGE,
00184                                     0, 0, 0, 0,  4, 4, 1, 1, 2, 0);
00185     {
00186         // default
00187         FXHorizontalFrame *gf1 =
00188             new FXHorizontalFrame(gp, LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0, 10,10,5,5);
00189         new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION+0,
00190                           ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP,
00191                           0, 0, 0, 0,   2, 2, 0, 0);
00192     }
00193     {
00194         // free
00195         FXHorizontalFrame *gf12 =
00196             new FXHorizontalFrame(gp, LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0, 10,10,5,5);
00197         new FXRadioButton(gf12, "User Defined Flow: ", &myChosenTarget, FXDataTarget::ID_OPTION+1,
00198                           ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_CENTER_Y,
00199                           0, 0, 0, 0,   2, 2, 0, 0);
00200         myFlowFactorDial =
00201             new FXRealSpinDial(gf12, 8, this, MID_USER_DEF,
00202                                LAYOUT_TOP|FRAME_SUNKEN|FRAME_THICK);
00203         myFlowFactorDial->setFormatString("%.0f");
00204         myFlowFactorDial->setIncrements(1,10,100);
00205         myFlowFactorDial->setRange(0,4000);
00206         myFlowFactorDial->setValue(myObject->getUserFlow());
00207     }
00208     new FXButton(f1,"Close",NULL,this,MID_CLOSE,
00209                  BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_CENTER_X,0,0,0,0, 30,30,4,4);
00210 }
00211 
00212 
00213 GUIEmitter::GUIManip_TriggeredEmitter::~GUIManip_TriggeredEmitter() {}
00214 
00215 
00216 long
00217 GUIEmitter::GUIManip_TriggeredEmitter::onCmdClose(FXObject*,FXSelector,void*) {
00218     destroy();
00219     return 1;
00220 }
00221 
00222 
00223 long
00224 GUIEmitter::GUIManip_TriggeredEmitter::onCmdUserDef(FXObject*,FXSelector,void*) {
00225     static_cast<GUIEmitter*>(myObject)->setUserFlow(
00226         (SUMOReal)(myFlowFactorDial->getValue()));
00227     static_cast<GUIEmitter*>(myObject)->setActiveChild(1);
00228     myParent->updateChildren();
00229     return 1;
00230 }
00231 
00232 
00233 long
00234 GUIEmitter::GUIManip_TriggeredEmitter::onUpdUserDef(FXObject *sender,FXSelector,void*ptr) {
00235     sender->handle(this,
00236                    myChosenValue!=1 ? FXSEL(SEL_COMMAND,ID_DISABLE):FXSEL(SEL_COMMAND,ID_ENABLE),
00237                    ptr);
00238     myParent->updateChildren();
00239     return 1;
00240 }
00241 
00242 
00243 long
00244 GUIEmitter::GUIManip_TriggeredEmitter::onCmdChangeOption(FXObject*,FXSelector,void*) {
00245     static_cast<GUIEmitter*>(myObject)->setUserFlow((SUMOReal) myFlowFactorDial->getValue());
00246     switch (myChosenValue) {
00247     case 0:
00248         static_cast<GUIEmitter*>(myObject)->setActiveChild(0);
00249         break;
00250     case 1:
00251         static_cast<GUIEmitter*>(myObject)->setActiveChild(1);
00252         break;
00253     default:
00254         // hmmm, should not happen
00255         break;
00256     }
00257     myParent->updateChildren();
00258     return 1;
00259 }
00260 
00261 
00262 /* -------------------------------------------------------------------------
00263  * GUIEmitter::GUIEmitterPopupMenu - methods
00264  * ----------------------------------------------------------------------- */
00265 GUIEmitter::GUIEmitterPopupMenu::GUIEmitterPopupMenu(
00266     GUIMainWindow &app, GUISUMOAbstractView &parent,
00267     GUIGlObject &o)
00268         : GUIGLObjectPopupMenu(app, parent, o) {}
00269 
00270 
00271 GUIEmitter::GUIEmitterPopupMenu::~GUIEmitterPopupMenu() throw() {}
00272 
00273 
00274 long
00275 GUIEmitter::GUIEmitterPopupMenu::onCmdOpenManip(FXObject*,
00276         FXSelector,
00277         void*) {
00278     static_cast<GUIEmitter*>(myObject)->openManipulator(
00279         *myApplication, *myParent);
00280     return 1;
00281 }
00282 
00283 
00284 long
00285 GUIEmitter::GUIEmitterPopupMenu::onCmdDrawRoute(FXObject*,
00286         FXSelector,
00287         void*) {
00288     static_cast<GUIEmitter*>(myObject)->toggleDrawRoutes();
00289     myParent->update();
00290     return 1;
00291 }
00292 
00293 
00294 /* -------------------------------------------------------------------------
00295  * GUIEmitter - methods
00296  * ----------------------------------------------------------------------- */
00297 GUIEmitter::GUIEmitter(const std::string &id,
00298                        MSNet &net, MSLane *destLanes, SUMOReal pos,
00299                        const std::string &file) throw()
00300         : MSEmitter(id, net, destLanes, pos, file),
00301         GUIGlObject_AbstractAdd(GUIGlObjectStorage::gIDStorage,
00302                                 "emitter:" + id, GLO_TRIGGER), myUserFlow(-1), myDrawRoutes(false) {
00303     const Position2DVector &v = destLanes->getShape();
00304     if (pos<0) {
00305         pos = destLanes->getLength()+ pos;
00306     }
00307     myFGPosition = v.positionAtLengthPosition(pos);
00308     Line2D l(v.getBegin(), v.getEnd());
00309     myFGRotation = -v.rotationDegreeAtLengthPosition(pos);
00310 
00311     myUserEmitChild =
00312         new GUIEmitterChild_UserTriggeredChild(
00313         static_cast<MSEmitter_FileTriggeredChild&>(*myFileBasedEmitter),
00314         *this, net.getVehicleControl(), 0);
00315 }
00316 
00317 
00318 GUIEmitter::~GUIEmitter() throw() {}
00319 
00320 
00321 void
00322 GUIEmitter::setUserFlow(SUMOReal factor) {
00323     // !!! the commands should be adapted to current flow imediatly
00324     myUserFlow = factor;
00325     if (myUserFlow>0) {
00326         delete myUserEmitChild;
00327         myUserEmitChild =
00328             new GUIEmitterChild_UserTriggeredChild(
00329             static_cast<MSEmitter_FileTriggeredChild&>(*myFileBasedEmitter),
00330             *this, myNet.getVehicleControl(), factor);
00331     }
00332 }
00333 
00334 
00335 SUMOReal
00336 GUIEmitter::getUserFlow() const {
00337     if (myUserFlow<0&&static_cast<MSEmitter_FileTriggeredChild*>(myFileBasedEmitter)->getLoadedFlow()>0) {
00338         myUserFlow = static_cast<MSEmitter_FileTriggeredChild*>(myFileBasedEmitter)->getLoadedFlow();
00339     }
00340     return myUserFlow;
00341 }
00342 
00343 
00344 GUIGLObjectPopupMenu *
00345 GUIEmitter::getPopUpMenu(GUIMainWindow &app,
00346                          GUISUMOAbstractView &parent) throw() {
00347     GUIGLObjectPopupMenu *ret = new GUIEmitterPopupMenu(app, parent, *this);
00348     buildPopupHeader(ret, app);
00349     buildCenterPopupEntry(ret);
00350     //
00351     buildShowManipulatorPopupEntry(ret, false);
00352     if (!myDrawRoutes) {
00353         new FXMenuCommand(ret, "Show Routes...", GUIIconSubSys::getIcon(ICON_MANIP), ret, MID_DRAWROUTE);
00354     } else {
00355         new FXMenuCommand(ret, "Hide Routes...", GUIIconSubSys::getIcon(ICON_MANIP), ret, MID_DRAWROUTE);
00356     }
00357     new FXMenuSeparator(ret);
00358     //
00359     buildNameCopyPopupEntry(ret);
00360     buildSelectionPopupEntry(ret);
00361     buildPositionCopyEntry(ret, false);
00362     return ret;
00363 }
00364 
00365 
00366 GUIParameterTableWindow *
00367 GUIEmitter::getParameterWindow(GUIMainWindow &,
00368                                GUISUMOAbstractView &) throw() {
00369     return 0;
00370 }
00371 
00372 
00373 const std::string &
00374 GUIEmitter::getMicrosimID() const throw() {
00375     return getID();
00376 }
00377 
00378 
00379 void
00380 GUIEmitter::toggleDrawRoutes() {
00381     myDrawRoutes = !myDrawRoutes;
00382 }
00383 
00384 
00385 std::map<const MSEdge*, SUMOReal>
00386 GUIEmitter::getEdgeProbs() const {
00387     std::map<const MSEdge*, SUMOReal> ret;
00388     const std::vector<const MSRoute*> &routes = myFileBasedEmitter->getRouteDist().getVals();
00389     const std::vector<SUMOReal> &probs = myFileBasedEmitter->getRouteDist().getProbs();
00390     size_t j;
00391 
00392     for (j=0; j<routes.size(); ++j) {
00393         SUMOReal prob = probs[j];
00394         const MSRoute *r = routes[j];
00395         MSRouteIterator i = r->begin();
00396         for (; i!=r->end(); ++i) {
00397             const MSEdge *e = *i;
00398             if (ret.find(e)==ret.end()) {
00399                 ret[e] = 0;
00400             }
00401             ret[e] = ret[e] + prob;
00402         }
00403     }
00404     return ret;
00405 }
00406 
00407 
00408 void
00409 GUIEmitter::drawGL(const GUIVisualizationSettings &s) const throw() {
00410     // (optional) set id
00411     if (s.needsGlID) {
00412         glPushName(getGlID());
00413     }
00414     glPushMatrix();
00415     glTranslated(myFGPosition.x(), myFGPosition.y(), 0);
00416     glScaled(s.addExaggeration, s.addExaggeration, 1);
00417     glRotated(myFGRotation, 0, 0, 1);
00418 
00419     glColor3d(1, 0, 0);
00420     // base
00421     glTranslated(0, 0, -.03);
00422     glBegin(GL_TRIANGLES);
00423     glVertex2d(0-1.5, 0);
00424     glVertex2d(0-1.5, 8);
00425     glVertex2d(0+1.5, 8);
00426     glVertex2d(0+1.5, 0);
00427     glVertex2d(0-1.5, 0);
00428     glVertex2d(0+1.5, 8);
00429     glEnd();
00430 
00431     // arrows
00432     glTranslated(0, 0, -.01);
00433     glBegin(GL_TRIANGLES);
00434     glColor3d(1, 1, 0);
00435     glVertex2d(0, 1-.5);
00436     glVertex2d(0-1.25, 1+2-.5);
00437     glVertex2d(0+1.25, 1+2-.5);
00438 
00439     glVertex2d(0, 3-.5);
00440     glVertex2d(0-1.25, 3+2-.5);
00441     glVertex2d(0+1.25, 3+2-.5);
00442 
00443     glVertex2d(0, 5-.5);
00444     glVertex2d(0-1.25, 5+2-.5);
00445     glVertex2d(0+1.25, 5+2-.5);
00446 
00447     glEnd();
00448     glTranslated(0, 0, .04);
00449     glPopMatrix();
00450 
00451     if (myDrawRoutes) {
00452         std::map<const MSEdge*, SUMOReal> e2prob = getEdgeProbs();
00453         for (std::map<const MSEdge*, SUMOReal>::iterator k=e2prob.begin(); k!=e2prob.end(); ++k) {
00454             double c = (*k).second;
00455             glColor3d(1.-c, 1.-c, 0);
00456             const MSEdge *e = (*k).first;
00457             const GUIEdge *ge = static_cast<const GUIEdge*>(e);
00458             const GUILaneWrapper &lane = ge->getLaneGeometry((size_t) 0);
00459             GLHelper::drawBoxLines(lane.getShape(), lane.getShapeRotations(), lane.getShapeLengths(), 0.5);
00460         }
00461     }
00462     // (optional) draw name
00463     if (s.drawAddName) {
00464         drawGLName(getCenteringBoundary().getCenter(), getMicrosimID(), s.addNameSize / s.scale);
00465     }
00466     // (optional) clear id
00467     if (s.needsGlID) {
00468         glPopName();
00469     }
00470 }
00471 
00472 
00473 Boundary
00474 GUIEmitter::getCenteringBoundary() const throw() {
00475     Boundary b(myFGPosition.x(), myFGPosition.y(), myFGPosition.x(), myFGPosition.y());
00476     b.grow(20);
00477     return b;
00478 }
00479 
00480 
00481 GUIManipulator *
00482 GUIEmitter::openManipulator(GUIMainWindow &app,
00483                             GUISUMOAbstractView &) {
00484     GUIManip_TriggeredEmitter *gui =
00485         new GUIManip_TriggeredEmitter(app, getFullName(), *this, 0, 0);
00486     gui->create();
00487     gui->show();
00488     return gui;
00489 }
00490 
00491 
00492 void
00493 GUIEmitter::setActiveChild(int index) {
00494     switch (index) {
00495     case 0:
00496         myActiveChild = myFileBasedEmitter;
00497         break;
00498     case 1:
00499         myActiveChild = myUserEmitChild;
00500         break;
00501     }
00502 }
00503 
00504 
00505 
00506 /****************************************************************************/
00507 

Generated on Wed May 5 00:06:29 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6