SUMO - Simulation of Urban MObility

GUIEdge.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00010 // A road/street connecting two junctions (gui-version)
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <vector>
00035 #include <cmath>
00036 #include <string>
00037 #include <algorithm>
00038 #include <microsim/MSEdge.h>
00039 #include <microsim/MSJunction.h>
00040 #include <microsim/MSLaneChanger.h>
00041 #include <microsim/MSGlobals.h>
00042 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
00043 #include <utils/geom/GeomHelper.h>
00044 #include "GUIEdge.h"
00045 #include "GUINet.h"
00046 #include "GUILane.h"
00047 #include <utils/gui/div/GUIParameterTableWindow.h>
00048 #include <microsim/logging/CastingFunctionBinding.h>
00049 #include <microsim/logging/FunctionBinding.h>
00050 #include <utils/gui/div/GLHelper.h>
00051 #include <utils/gui/div/GUIGlobalSelection.h>
00052 #include <foreign/polyfonts/polyfonts.h>
00053 
00054 #ifdef HAVE_MESOSIM
00055 #include <mesosim/MESegment.h>
00056 #include <mesosim/MELoop.h>
00057 #include <microsim/MSGlobals.h>
00058 #endif
00059 
00060 #ifdef CHECK_MEMORY_LEAKS
00061 #include <foreign/nvwa/debug_new.h>
00062 #endif // CHECK_MEMORY_LEAKS
00063 
00064 
00065 // ===========================================================================
00066 // included modules
00067 // ===========================================================================
00068 GUIEdge::GUIEdge(const std::string& id, unsigned int numericalID, const std::string& streetName)
00069     : MSEdge(id, numericalID, streetName),
00070       GUIGlObject(GLO_EDGE, id) {}
00071 
00072 
00073 GUIEdge::~GUIEdge() {
00074     for (LaneWrapperVector::iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
00075         delete(*i);
00076     }
00077 }
00078 
00079 
00080 void
00081 GUIEdge::initGeometry() {
00082     // don't do this twice
00083     if (myLaneGeoms.size() > 0) {
00084         return;
00085     }
00086     // build the lane wrapper
00087     myLaneGeoms.reserve(myLanes->size());
00088     for (unsigned int i = 0; i < myLanes->size(); i++) {
00089         myLaneGeoms.push_back(myLanes->at(i)->buildLaneWrapper(i));
00090     }
00091 }
00092 
00093 
00094 MSLane&
00095 GUIEdge::getLane(size_t laneNo) {
00096     assert(laneNo < myLanes->size());
00097     return *((*myLanes)[laneNo]);
00098 }
00099 
00100 
00101 GUILaneWrapper&
00102 GUIEdge::getLaneGeometry(size_t laneNo) const {
00103     assert(laneNo < myLanes->size());
00104     return *(myLaneGeoms[laneNo]);
00105 }
00106 
00107 
00108 GUILaneWrapper&
00109 GUIEdge::getLaneGeometry(const MSLane* lane) const {
00110     LaneWrapperVector::const_iterator i =
00111         find_if(myLaneGeoms.begin(), myLaneGeoms.end(), lane_wrapper_finder(*lane));
00112     assert(i != myLaneGeoms.end());
00113     return *(*i);
00114 }
00115 
00116 
00117 std::vector<GUIGlID>
00118 GUIEdge::getIDs(bool includeInternal) {
00119     std::vector<GUIGlID> ret;
00120     ret.reserve(MSEdge::myDict.size());
00121     for (MSEdge::DictType::iterator i = MSEdge::myDict.begin(); i != MSEdge::myDict.end(); ++i) {
00122         GUIEdge* edge = dynamic_cast<GUIEdge*>(i->second);
00123         assert(edge);
00124         if (edge->getPurpose() != EDGEFUNCTION_INTERNAL || includeInternal) {
00125             ret.push_back(edge->getGlID());
00126         }
00127     }
00128     return ret;
00129 }
00130 
00131 
00132 Boundary
00133 GUIEdge::getBoundary() const {
00134     Boundary ret;
00135     for (LaneWrapperVector::const_iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
00136         const PositionVector& g = (*i)->getShape();
00137         for (unsigned int j = 0; j < g.size(); j++) {
00138             ret.add(g[j]);
00139         }
00140     }
00141     ret.grow(10);
00142     return ret;
00143 }
00144 
00145 
00146 void
00147 GUIEdge::fill(std::vector<GUIEdge*> &netsWrappers) {
00148     size_t size = MSEdge::dictSize();
00149     netsWrappers.reserve(size);
00150     for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
00151         if (i->second->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
00152             netsWrappers.push_back(static_cast<GUIEdge*>((*i).second));
00153         }
00154     }
00155 }
00156 
00157 
00158 
00159 GUIGLObjectPopupMenu*
00160 GUIEdge::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
00161     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
00162     buildPopupHeader(ret, app);
00163     buildCenterPopupEntry(ret);
00164     buildNameCopyPopupEntry(ret);
00165     buildSelectionPopupEntry(ret);
00166 #ifdef HAVE_MESOSIM
00167     if (MSGlobals::gUseMesoSim) {
00168         buildShowParamsPopupEntry(ret);
00169     }
00170 #endif
00171     buildPositionCopyEntry(ret, false);
00172     return ret;
00173 }
00174 
00175 
00176 GUIParameterTableWindow*
00177 GUIEdge::getParameterWindow(GUIMainWindow& app,
00178                             GUISUMOAbstractView&) {
00179     GUIParameterTableWindow* ret = 0;
00180 #ifdef HAVE_MESOSIM
00181     ret = new GUIParameterTableWindow(app, *this, 5);
00182     // add items
00183     ret->mkItem("length [m]", false, (*myLanes)[0]->getLength());
00184     ret->mkItem("allowed speed [m/s]", false, getAllowedSpeed());
00185     ret->mkItem("occupancy [%]", true,
00186                 new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getOccupancy));
00187     ret->mkItem("mean vehicle speed [m/s]", true,
00188                 new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getMeanSpeed));
00189     ret->mkItem("flow [veh/h/lane]", true,
00190                 new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getFlow));
00191     ret->mkItem("#vehicles", true,
00192                 new CastingFunctionBinding<GUIEdge, SUMOReal, unsigned int>(this, &GUIEdge::getVehicleNo));
00193     // close building
00194     ret->closeBuilding();
00195 #endif
00196     UNUSED_PARAMETER(&app);
00197     return ret;
00198 }
00199 
00200 
00201 Boundary
00202 GUIEdge::getCenteringBoundary() const {
00203     Boundary b = getBoundary();
00204     b.grow(20);
00205     return b;
00206 }
00207 
00208 
00209 void
00210 GUIEdge::drawGL(const GUIVisualizationSettings& s) const {
00211     if (s.hideConnectors && myFunction == MSEdge::EDGEFUNCTION_CONNECTOR) {
00212         return;
00213     }
00214     // draw the lanes
00215     for (LaneWrapperVector::const_iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
00216 #ifdef HAVE_MESOSIM
00217         if (MSGlobals::gUseMesoSim) {
00218             setColor(s);
00219         }
00220 #endif
00221         (*i)->drawGL(s);
00222     }
00223 #ifdef HAVE_MESOSIM
00224     if (MSGlobals::gUseMesoSim) {
00225         size_t idx = 0;
00226         for (LaneWrapperVector::const_iterator l = myLaneGeoms.begin(); l != myLaneGeoms.end(); ++l, ++idx) {
00227             const PositionVector& shape = (*l)->getShape();
00228             const DoubleVector& shapeRotations = (*l)->getShapeRotations();
00229             const DoubleVector& shapeLengths = (*l)->getShapeLengths();
00230             const Position& laneBeg = shape[0];
00231 
00232             glColor3d(1, 1, 0);
00233             glPushMatrix();
00234             glTranslated(laneBeg.x(), laneBeg.y(), 0);
00235             glRotated(shapeRotations[0], 0, 0, 1);
00236             // go through the vehicles
00237             int shapePos = 0;
00238             SUMOReal positionOffset = 0;
00239             SUMOReal position = 0;
00240             for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
00241                 const std::vector<size_t> numCars = segment->getQueSizes();
00242                 const SUMOReal length = segment->getLength();
00243                 if (idx < numCars.size()) {
00244                     const SUMOReal avgCarSize = segment->getOccupancy() / segment->getCarNumber();
00245                     for (size_t i = 0; i < numCars[idx]; i++) {
00246                         SUMOReal vehiclePosition = position + length - i * avgCarSize;
00247                         SUMOReal xOff = 0.f;
00248                         while (vehiclePosition < position) {
00249                             vehiclePosition += length;
00250                             xOff += 0.5f;
00251                         }
00252                         while (shapePos < (int)shapeRotations.size() - 1 && vehiclePosition > positionOffset + shapeLengths[shapePos]) {
00253                             glPopMatrix();
00254                             positionOffset += shapeLengths[shapePos];
00255                             shapePos++;
00256                             glPushMatrix();
00257                             glTranslated(shape[shapePos].x(), shape[shapePos].y(), 0);
00258                             glRotated(shapeRotations[shapePos], 0, 0, 1);
00259                         }
00260                         glPushMatrix();
00261                         glTranslated(xOff, -(vehiclePosition - positionOffset), 0);
00262                         glPushMatrix();
00263                         glScaled(1, avgCarSize, 1);
00264                         glBegin(GL_TRIANGLES);
00265                         glVertex2d(0, 0);
00266                         glVertex2d(0 - 1.25, 1);
00267                         glVertex2d(0 + 1.25, 1);
00268                         glEnd();
00269                         glPopMatrix();
00270                         glPopMatrix();
00271                     }
00272                 }
00273                 position += length;
00274             }
00275             glPopMatrix();
00276         }
00277     }
00278 #endif
00279     // (optionally) draw the name and/or the street name
00280     const bool drawEdgeName = s.edgeName.show && myFunction == EDGEFUNCTION_NORMAL;
00281     const bool drawInternalEdgeName = s.internalEdgeName.show && myFunction != EDGEFUNCTION_NORMAL;
00282     const bool drawStreetName = s.streetName.show && myStreetName != "";
00283     if (drawEdgeName || drawInternalEdgeName || drawStreetName) {
00284         GUILaneWrapper* lane1 = myLaneGeoms[0];
00285         GUILaneWrapper* lane2 = myLaneGeoms[myLaneGeoms.size() - 1];
00286         Position p = lane1->getShape().positionAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.);
00287         p.add(lane2->getShape().positionAtLengthPosition(lane2->getShape().length() / (SUMOReal) 2.));
00288         p.mul(.5);
00289         SUMOReal angle = lane1->getShape().rotationDegreeAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.);
00290         angle += 90;
00291         if (angle > 90 && angle < 270) {
00292             angle -= 180;
00293         }
00294         if (drawEdgeName) {
00295             drawName(p, s.scale, s.edgeName, angle);
00296         } else if (drawInternalEdgeName) {
00297             drawName(p, s.scale, s.internalEdgeName, angle);
00298         }
00299         if (drawStreetName) {
00300             GLHelper::drawText(getStreetName(), p, GLO_MAX,
00301                                s.streetName.size / s.scale, s.streetName.color, angle);
00302         }
00303     }
00304 }
00305 
00306 #ifdef HAVE_MESOSIM
00307 unsigned int
00308 GUIEdge::getVehicleNo() const {
00309     size_t vehNo = 0;
00310     for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
00311         vehNo += segment->getCarNumber();
00312     }
00313     return (unsigned int)vehNo;
00314 }
00315 
00316 
00317 SUMOReal
00318 GUIEdge::getFlow() const {
00319     SUMOReal flow = 0;
00320     for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
00321         flow += (SUMOReal) segment->getCarNumber() * segment->getMeanSpeed();
00322     }
00323     return flow * (SUMOReal) 1000. / (*myLanes)[0]->getLength() / (SUMOReal) 3.6;
00324 }
00325 
00326 
00327 SUMOReal
00328 GUIEdge::getOccupancy() const {
00329     SUMOReal occ = 0;
00330     for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
00331         occ += segment->getOccupancy();
00332     }
00333     return occ / (*myLanes)[0]->getLength() / (SUMOReal)(myLanes->size());
00334 }
00335 
00336 
00337 SUMOReal
00338 GUIEdge::getMeanSpeed() const {
00339     SUMOReal v = 0;
00340     SUMOReal no = 0;
00341     for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
00342         SUMOReal vehNo = (SUMOReal) segment->getCarNumber();
00343         v += vehNo * segment->getMeanSpeed();
00344         no += vehNo;
00345     }
00346     return v / no;
00347 }
00348 
00349 
00350 SUMOReal
00351 GUIEdge::getAllowedSpeed() const {
00352     return (*myLanes)[0]->getMaxSpeed();
00353 }
00354 
00355 
00356 void
00357 GUIEdge::setColor(const GUIVisualizationSettings& s) const {
00358     GLHelper::setColor(s.edgeColorer.getScheme().getColor(getColorValue(s.edgeColorer.getActive())));
00359 }
00360 
00361 
00362 SUMOReal
00363 GUIEdge::getColorValue(size_t activeScheme) const {
00364     switch (activeScheme) {
00365         case 1:
00366             return gSelected.isSelected(getType(), getGlID());
00367         case 2:
00368             return getPurpose();
00369         case 3:
00370             return getAllowedSpeed();
00371         case 4:
00372             return getOccupancy();
00373         case 5:
00374             return getMeanSpeed();
00375         case 6:
00376             return getFlow();
00377     }
00378     return 0;
00379 }
00380 
00381 #endif
00382 
00383 /****************************************************************************/
00384 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines