|
SUMO - Simulation of Urban MObility
|
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