SUMO - Simulation of Urban MObility

GUIEdge.cpp

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