SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUIEdge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A road/street connecting two junctions (gui-version)
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
13 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <vector>
35 #include <cmath>
36 #include <string>
37 #include <algorithm>
39 #include <utils/geom/GeomHelper.h>
40 #include "GUIEdge.h"
41 #include "GUINet.h"
42 #include "GUILane.h"
44 #include <microsim/MSEdge.h>
45 #include <microsim/MSJunction.h>
46 #include <microsim/MSLaneChanger.h>
47 #include <microsim/MSGlobals.h>
50 #include <utils/gui/div/GLHelper.h>
53 
54 #ifdef HAVE_MESOSIM
55 #include <mesosim/MESegment.h>
56 #include <mesosim/MELoop.h>
57 #include <mesosim/MEVehicle.h>
58 #include <microsim/MSGlobals.h>
59 #endif
60 
61 #ifdef CHECK_MEMORY_LEAKS
62 #include <foreign/nvwa/debug_new.h>
63 #endif // CHECK_MEMORY_LEAKS
64 
65 
66 // ===========================================================================
67 // included modules
68 // ===========================================================================
69 GUIEdge::GUIEdge(const std::string& id, unsigned int numericalID, const std::string& streetName)
70  : MSEdge(id, numericalID, streetName),
71  GUIGlObject(GLO_EDGE, id) {}
72 
73 
75  for (LaneWrapperVector::iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
76  delete(*i);
77  }
78 }
79 
80 
81 void
83  // don't do this twice
84  if (myLaneGeoms.size() > 0) {
85  return;
86  }
87  // build the lane wrapper
88  myLaneGeoms.reserve(myLanes->size());
89  for (unsigned int i = 0; i < myLanes->size(); i++) {
90  myLaneGeoms.push_back(myLanes->at(i)->buildLaneWrapper(i));
91  }
92 }
93 
94 
95 MSLane&
96 GUIEdge::getLane(size_t laneNo) {
97  assert(laneNo < myLanes->size());
98  return *((*myLanes)[laneNo]);
99 }
100 
101 
103 GUIEdge::getLaneGeometry(size_t laneNo) const {
104  assert(laneNo < myLanes->size());
105  return *(myLaneGeoms[laneNo]);
106 }
107 
108 
110 GUIEdge::getLaneGeometry(const MSLane* lane) const {
111  LaneWrapperVector::const_iterator i =
112  find_if(myLaneGeoms.begin(), myLaneGeoms.end(), lane_wrapper_finder(*lane));
113  assert(i != myLaneGeoms.end());
114  return *(*i);
115 }
116 
117 
118 std::vector<GUIGlID>
119 GUIEdge::getIDs(bool includeInternal) {
120  std::vector<GUIGlID> ret;
121  ret.reserve(MSEdge::myDict.size());
122  for (MSEdge::DictType::iterator i = MSEdge::myDict.begin(); i != MSEdge::myDict.end(); ++i) {
123  GUIEdge* edge = dynamic_cast<GUIEdge*>(i->second);
124  assert(edge);
125  if (edge->getPurpose() != EDGEFUNCTION_INTERNAL || includeInternal) {
126  ret.push_back(edge->getGlID());
127  }
128  }
129  return ret;
130 }
131 
132 
133 Boundary
135  Boundary ret;
136  for (LaneWrapperVector::const_iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
137  const PositionVector& g = (*i)->getShape();
138  for (unsigned int j = 0; j < g.size(); j++) {
139  ret.add(g[j]);
140  }
141  }
142  ret.grow(10);
143  return ret;
144 }
145 
146 
147 void
148 GUIEdge::fill(std::vector<GUIEdge*> &netsWrappers) {
149  size_t size = MSEdge::dictSize();
150  netsWrappers.reserve(size);
151  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
152  if (i->second->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
153  netsWrappers.push_back(static_cast<GUIEdge*>((*i).second));
154  }
155  }
156 }
157 
158 
159 
162  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
163  buildPopupHeader(ret, app);
169  }
170  buildPositionCopyEntry(ret, false);
171  return ret;
172 }
173 
174 
178  GUIParameterTableWindow* ret = 0;
179 #ifdef HAVE_MESOSIM
180  ret = new GUIParameterTableWindow(app, *this, 7);
181  // add items
182  ret->mkItem("length [m]", false, (*myLanes)[0]->getLength());
183  ret->mkItem("allowed speed [m/s]", false, getAllowedSpeed());
184  ret->mkItem("occupancy [%]", true,
185  new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getOccupancy));
186  ret->mkItem("mean vehicle speed [m/s]", true,
187  new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getMeanSpeed));
188  ret->mkItem("flow [veh/h/lane]", true,
189  new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getFlow));
190  ret->mkItem("#vehicles", true,
191  new CastingFunctionBinding<GUIEdge, SUMOReal, unsigned int>(this, &GUIEdge::getVehicleNo));
192  ret->mkItem("vehicle ids", false, getVehicleIDs());
193  // close building
194  ret->closeBuilding();
195 #endif
196  UNUSED_PARAMETER(&app);
197  return ret;
198 }
199 
200 
201 Boundary
203  Boundary b = getBoundary();
204  b.grow(20);
205  return b;
206 }
207 
208 
209 void
212  return;
213  }
215  glPushName(getGlID());
216  }
217  // draw the lanes
218  for (LaneWrapperVector::const_iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
219 #ifdef HAVE_MESOSIM
221  setColor(s);
222  }
223 #endif
224  (*i)->drawGL(s);
225  }
226 #ifdef HAVE_MESOSIM
228  size_t idx = 0;
229  for (LaneWrapperVector::const_iterator l = myLaneGeoms.begin(); l != myLaneGeoms.end(); ++l, ++idx) {
230  const PositionVector& shape = (*l)->getShape();
231  const std::vector<SUMOReal>& shapeRotations = (*l)->getShapeRotations();
232  const std::vector<SUMOReal>& shapeLengths = (*l)->getShapeLengths();
233  const Position& laneBeg = shape[0];
234 
235  glColor3d(1, 1, 0);
236  glPushMatrix();
237  glTranslated(laneBeg.x(), laneBeg.y(), 0);
238  glRotated(shapeRotations[0], 0, 0, 1);
239  // go through the vehicles
240  int shapePos = 0;
241  SUMOReal positionOffset = 0;
242  SUMOReal position = 0;
243  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
244  const std::vector<size_t> numCars = segment->getQueSizes();
245  const SUMOReal length = segment->getLength();
246  if (idx < numCars.size()) {
247  const SUMOReal avgCarSize = segment->getOccupancy() / segment->getCarNumber();
248  for (size_t i = 0; i < numCars[idx]; i++) {
249  SUMOReal vehiclePosition = position + length - i * avgCarSize;
250  SUMOReal xOff = 0.f;
251  while (vehiclePosition < position) {
252  vehiclePosition += length;
253  xOff += 0.5f;
254  }
255  while (shapePos < (int)shapeRotations.size() - 1 && vehiclePosition > positionOffset + shapeLengths[shapePos]) {
256  glPopMatrix();
257  positionOffset += shapeLengths[shapePos];
258  shapePos++;
259  glPushMatrix();
260  glTranslated(shape[shapePos].x(), shape[shapePos].y(), 0);
261  glRotated(shapeRotations[shapePos], 0, 0, 1);
262  }
263  glPushMatrix();
264  glTranslated(xOff, -(vehiclePosition - positionOffset), GLO_VEHICLE);
265  glPushMatrix();
266  glScaled(1, avgCarSize, 1);
267  glBegin(GL_TRIANGLES);
268  glVertex2d(0, 0);
269  glVertex2d(0 - 1.25, 1);
270  glVertex2d(0 + 1.25, 1);
271  glEnd();
272  glPopMatrix();
273  glPopMatrix();
274  }
275  }
276  position += length;
277  }
278  glPopMatrix();
279  }
280  glPopName();
281  }
282 #endif
283  // (optionally) draw the name and/or the street name
284  const bool drawEdgeName = s.edgeName.show && myFunction == EDGEFUNCTION_NORMAL;
285  const bool drawInternalEdgeName = s.internalEdgeName.show && myFunction != EDGEFUNCTION_NORMAL;
286  const bool drawStreetName = s.streetName.show && myStreetName != "";
287  if (drawEdgeName || drawInternalEdgeName || drawStreetName) {
288  GUILaneWrapper* lane1 = myLaneGeoms[0];
289  GUILaneWrapper* lane2 = myLaneGeoms[myLaneGeoms.size() - 1];
290  Position p = lane1->getShape().positionAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.);
291  p.add(lane2->getShape().positionAtLengthPosition(lane2->getShape().length() / (SUMOReal) 2.));
292  p.mul(.5);
293  SUMOReal angle = lane1->getShape().rotationDegreeAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.);
294  angle += 90;
295  if (angle > 90 && angle < 270) {
296  angle -= 180;
297  }
298  if (drawEdgeName) {
299  drawName(p, s.scale, s.edgeName, angle);
300  } else if (drawInternalEdgeName) {
301  drawName(p, s.scale, s.internalEdgeName, angle);
302  }
303  if (drawStreetName) {
305  s.streetName.size / s.scale, s.streetName.color, angle);
306  }
307  }
308 }
309 
310 #ifdef HAVE_MESOSIM
311 unsigned int
312 GUIEdge::getVehicleNo() const {
313  size_t vehNo = 0;
314  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
315  vehNo += segment->getCarNumber();
316  }
317  return (unsigned int)vehNo;
318 }
319 
320 
321 std::string
322 GUIEdge::getVehicleIDs() const {
323  std::string result = " ";
324  std::vector<const MEVehicle*> vehs;
325  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
326  std::vector<const MEVehicle*> segmentVehs = segment->getVehicles();
327  vehs.insert(vehs.end(), segmentVehs.begin(), segmentVehs.end());
328  }
329  for (std::vector<const MEVehicle*>::const_iterator it = vehs.begin(); it != vehs.end(); it++) {
330  result += (*it)->getID() + " ";
331  }
332  return result;
333 }
334 
335 
336 SUMOReal
337 GUIEdge::getFlow() const {
338  SUMOReal flow = 0;
339  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
340  flow += (SUMOReal) segment->getCarNumber() * segment->getMeanSpeed();
341  }
342  return flow * (SUMOReal) 1000. / (*myLanes)[0]->getLength() / (SUMOReal) 3.6;
343 }
344 
345 
346 SUMOReal
347 GUIEdge::getFlowAlternative() const {
348  // @note: only the first segment is considered because that is sufficient in equilibrium
349  return MSGlobals::gMesoNet->getSegmentForEdge(*this)->getFlow() / myLanes->size();
350 }
351 
352 
353 SUMOReal
354 GUIEdge::getOccupancy() const {
355  SUMOReal occ = 0;
356  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
357  occ += segment->getOccupancy();
358  }
359  return occ / (*myLanes)[0]->getLength() / (SUMOReal)(myLanes->size());
360 }
361 
362 
363 SUMOReal
364 GUIEdge::getMeanSpeed() const {
365  SUMOReal v = 0;
366  SUMOReal no = 0;
367  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
368  SUMOReal vehNo = (SUMOReal) segment->getCarNumber();
369  v += vehNo * segment->getMeanSpeed();
370  no += vehNo;
371  }
372  if (no == 0) {
373  return getMaxSpeed();
374  }
375  return v / no;
376 }
377 
378 
379 SUMOReal
380 GUIEdge::getAllowedSpeed() const {
381  return (*myLanes)[0]->getMaxSpeed();
382 }
383 
384 
385 SUMOReal
386 GUIEdge::getRelativeSpeed() const {
387  return getMeanSpeed() / getAllowedSpeed();
388 }
389 
390 
391 void
392 GUIEdge::setColor(const GUIVisualizationSettings& s) const {
393  GLHelper::setColor(s.edgeColorer.getScheme().getColor(getColorValue(s.edgeColorer.getActive())));
394 }
395 
396 
397 SUMOReal
398 GUIEdge::getColorValue(size_t activeScheme) const {
399  switch (activeScheme) {
400  case 1:
401  return gSelected.isSelected(getType(), getGlID());
402  case 2:
403  return getPurpose();
404  case 3:
405  return getAllowedSpeed();
406  case 4:
407  return getOccupancy();
408  case 5:
409  return getMeanSpeed();
410  case 6:
411  return getFlow();
412  case 7:
413  return getRelativeSpeed();
414  }
415  return 0;
416 }
417 
418 #endif
419 
420 /****************************************************************************/
421