SUMO - Simulation of Urban MObility
GNELane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A class for visualizing Lane geometry (adapted from GNELaneWrapper)
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <string>
32 #include <iostream>
33 #include <utility>
39 #include <utils/common/ToString.h>
40 #include <utils/geom/GeomHelper.h>
47 #include <utils/gui/div/GLHelper.h>
50 
51 #include "GNELane.h"
52 #include "GNEEdge.h"
53 #include "GNEJunction.h"
54 #include "GNETLSEditorFrame.h"
55 #include "GNEInternalLane.h"
56 #include "GNEUndoList.h"
57 #include "GNENet.h"
58 #include "GNEChange_Attribute.h"
59 #include "GNEViewNet.h"
60 #include "GNEViewParent.h"
61 
62 #ifdef CHECK_MEMORY_LEAKS
63 #include <foreign/nvwa/debug_new.h>
64 #endif // CHECK_MEMORY_LEAKS
65 
66 // ===========================================================================
67 // FOX callback mapping
68 // ===========================================================================
69 
70 // Object implementation
71 FXIMPLEMENT(GNELane, FXDelegator, 0, 0)
72 
73 // ===========================================================================
74 // method definitions
75 // ===========================================================================
76 
77 GNELane::GNELane(GNEEdge& edge, const int index) :
78  GNENetElement(edge.getNet(), edge.getNBEdge()->getLaneID(index), GLO_LANE, SUMO_TAG_LANE),
79  myParentEdge(edge),
80  myIndex(index),
81  mySpecialColor(0),
82  myTLSEditor(0) {
83  updateGeometry();
84 }
85 
87  GNENetElement(NULL, "dummyConstructorGNELane", GLO_LANE, SUMO_TAG_LANE),
88  myParentEdge(*static_cast<GNEEdge*>(0)),
89  myIndex(-1),
90  mySpecialColor(0),
91  myTLSEditor(0) {
92 }
93 
94 
96  // Remove all references to this lane in their additionals
97  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
98  (*i)->removeLaneReference();
99  }
100 }
101 
102 
103 void
105 }
106 
107 
108 void
110 }
111 
112 
113 void
115 }
116 
117 
118 void
120  const Position& end = getShape().back();
121  const Position& f = getShape()[-2];
122  SUMOReal rot = (SUMOReal) atan2((end.x() - f.x()), (f.y() - end.y())) * (SUMOReal) 180.0 / (SUMOReal) PI;
123  glPushMatrix();
124  glPushName(0);
125  glTranslated(0, 0, GLO_JUNCTION + .1); // must draw on top of junction shape
126  glColor3d(1, 1, 1);
127  glTranslated(end.x(), end.y(), 0);
128  glRotated(rot, 0, 0, 1);
129 
130  // draw all links
131  const std::vector<NBEdge::Connection>& edgeCons = myParentEdge.getNBEdge()->myConnections;
132  NBNode* dest = myParentEdge.getNBEdge()->myTo;
133  for (std::vector<NBEdge::Connection>::const_iterator i = edgeCons.begin(); i != edgeCons.end(); ++i) {
134  if ((*i).fromLane == myIndex) {
135  LinkDirection dir = dest->getDirection(myParentEdge.getNBEdge(), i->toEdge, OptionsCont::getOptions().getBool("lefthand"));
136  switch (dir) {
137  case LINKDIR_STRAIGHT:
138  GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
140  break;
141  case LINKDIR_LEFT:
142  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
143  GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
144  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (SUMOReal) 1, (SUMOReal) .25);
145  break;
146  case LINKDIR_RIGHT:
147  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
148  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
149  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (SUMOReal) 1, (SUMOReal) .25);
150  break;
151  case LINKDIR_TURN:
152  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
153  GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
154  GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
155  GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (SUMOReal) 1, (SUMOReal) .25);
156  break;
158  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
159  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
160  GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
161  GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (SUMOReal) 1, (SUMOReal) .25);
162  break;
163  case LINKDIR_PARTLEFT:
164  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
165  GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
166  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (SUMOReal) 1, (SUMOReal) .25);
167  break;
168  case LINKDIR_PARTRIGHT:
169  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
170  GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
171  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (SUMOReal) 1, (SUMOReal) .25);
172  break;
173  case LINKDIR_NODIR:
174  GLHelper::drawBoxLine(Position(1, 5.8), 245, 2, .05);
175  GLHelper::drawBoxLine(Position(-1, 5.8), 115, 2, .05);
176  glTranslated(0, 5, 0);
177  GLHelper::drawOutlineCircle(0.9, 0.8, 32);
178  glTranslated(0, -5, 0);
179  break;
180  }
181  }
182  }
183  glPopName();
184  glPopMatrix();
185 }
186 
187 
188 void
190  glPushMatrix();
191  glPushName(0);
192  glTranslated(0, 0, GLO_JUNCTION + .1); // must draw on top of junction shape
193  std::vector<NBEdge::Connection> connections = myParentEdge.getNBEdge()->getConnectionsFromLane(myIndex);
194  NBNode* node = myParentEdge.getNBEdge()->getToNode();
195  const Position& startPos = getShape()[-1];
196  for (std::vector<NBEdge::Connection>::iterator it = connections.begin(); it != connections.end(); it++) {
197  const LinkState state = node->getLinkState(
198  myParentEdge.getNBEdge(), it->toEdge, it->fromLane, it->toLane, it->mayDefinitelyPass, it->tlID);
199  switch (state) {
201  glColor3d(1, 1, 0);
202  break;
204  glColor3d(0, 1, 1);
205  break;
206  case LINKSTATE_MAJOR:
207  glColor3d(1, 1, 1);
208  break;
209  case LINKSTATE_MINOR:
210  glColor3d(.4, .4, .4);
211  break;
212  case LINKSTATE_STOP:
213  glColor3d(.7, .4, .4);
214  break;
215  case LINKSTATE_EQUAL:
216  glColor3d(.7, .7, .7);
217  break;
219  glColor3d(.7, .7, 1);
220  case LINKSTATE_ZIPPER:
221  glColor3d(.75, .5, 0.25);
222  break;
223  default:
224  throw ProcessError("Unexpected LinkState '" + toString(state) + "'");
225  }
226  const Position& endPos = it->toEdge->getLaneShape(it->toLane)[0];
227  glBegin(GL_LINES);
228  glVertex2f(startPos.x(), startPos.y());
229  glVertex2f(endPos.x(), endPos.y());
230  glEnd();
231  GLHelper::drawTriangleAtEnd(startPos, endPos, (SUMOReal) 1.5, (SUMOReal) .2);
232  }
233  glPopName();
234  glPopMatrix();
235 }
236 
237 
238 void
240  glPushMatrix();
241  glPushName(getGlID());
242  glTranslated(0, 0, getType());
243  const bool selectedEdge = gSelected.isSelected(myParentEdge.getType(), myParentEdge.getGlID());
244  const bool selected = gSelected.isSelected(getType(), getGlID());
245  if (mySpecialColor != 0) {
247  } else if (selected && s.laneColorer.getActive() != 1) {
248  // override with special colors (unless the color scheme is based on selection)
250  } else if (selectedEdge && s.laneColorer.getActive() != 1) {
251  // override with special colors (unless the color scheme is based on selection)
253  } else {
254  const GUIColorer& c = s.laneColorer;
255  if (!setFunctionalColor(c.getActive()) && !setMultiColor(c)) {
257  }
258  };
259 
260  // draw lane
261  // check whether it is not too small
262 
263 
264  const SUMOReal selectionScale = selected || selectedEdge ? s.selectionScale : 1;
265  SUMOReal exaggeration = selectionScale * s.laneWidthExaggeration; // * s.laneScaler.getScheme().getColor(getScaleValue(s.laneScaler.getActive()));
266  // XXX apply usefull scale values
267  //exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s.laneScaler.getActive()));
268 
269  // recognize full transparency and simply don't draw
270  GLfloat color[4];
271  glGetFloatv(GL_CURRENT_COLOR, color);
272  if (color[3] == 0 || s.scale * exaggeration < s.laneMinSize) {
273  glPopMatrix();
274  } else if (s.scale * exaggeration < 1.) {
275  // draw as lines
276  if (myShapeColors.size() > 0) {
278  } else {
280  }
281  glPopMatrix();
282  } else {
283  if (drawAsRailway(s)) {
284  // draw as railway
285  const SUMOReal halfRailWidth = 0.725 * exaggeration;
286  if (myShapeColors.size() > 0) {
288  } else {
290  }
291  RGBColor current = GLHelper::getColor();
292  glColor3d(1, 1, 1);
293  glTranslated(0, 0, .1);
295  GLHelper::setColor(current);
296  drawCrossties(0.3 * exaggeration, 1 * exaggeration, 1 * exaggeration);
297  } else {
298  // the actual lane
299  // reduce lane width to make sure that a selected edge can still be seen
300  const SUMOReal halfWidth = selectionScale * (myParentEdge.getNBEdge()->getLaneWidth(myIndex) / 2 - (selectedEdge ? .3 : 0));
301  if (myShapeColors.size() > 0) {
303  } else {
305  }
306  }
307  glPopMatrix();
308  if (exaggeration == 1) {
309  drawMarkings(selectedEdge, exaggeration);
310  }
311 
312  // draw ROWs only if target junction has a valid logic)
313  if (myParentEdge.getDest()->isLogicValid() && s.scale > 3) {
314  drawArrows();
315  }
316  if (s.showLaneDirection) {
318  }
319  }
320 
321  glPopName();
322 }
323 
324 
325 void
326 GNELane::drawMarkings(const bool& selectedEdge, SUMOReal scale) const {
327  glPushMatrix();
328  glTranslated(0, 0, GLO_EDGE);
329 
330  const SUMOReal halfWidth = myParentEdge.getNBEdge()->getLaneWidth(myIndex) * 0.5;
331  // optionally draw inverse markings
333  SUMOReal mw = (halfWidth + SUMO_const_laneOffset + .01) * scale;
334  int e = (int) getShape().size() - 1;
335  for (int i = 0; i < e; ++i) {
336  glPushMatrix();
337  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.1);
338  glRotated(myShapeRotations[i], 0, 0, 1);
339  for (SUMOReal t = 0; t < myShapeLengths[i]; t += 6) {
340  const SUMOReal length = MIN2((SUMOReal)3, myShapeLengths[i] - t);
341  glBegin(GL_QUADS);
342  glVertex2d(-mw, -t);
343  glVertex2d(-mw, -t - length);
344  glVertex2d(halfWidth * 0.5 * scale, -t - length);
345  glVertex2d(halfWidth * 0.5 * scale, -t);
346  glEnd();
347  }
348  glPopMatrix();
349  }
350  }
351 
352  // draw white boundings (and white markings) depending on selection
353  if (selectedEdge) {
354  glTranslated(0, 0, 0.2); // draw selection on top of regular markings
356  } else {
357  glColor3d(1, 1, 1);
358  }
359 
361  getShape(),
363  getShapeLengths(),
364  (halfWidth + SUMO_const_laneOffset) * scale);
365  glPopMatrix();
366 
367 }
368 
369 
372  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
373  buildPopupHeader(ret, app);
375  new FXMenuCommand(ret, "Copy edge name to clipboard", 0, ret, MID_COPY_EDGE_NAME);
378  buildPositionCopyEntry(ret, false);
379  const int editMode = parent.getVisualisationSettings()->editMode;
380  myTLSEditor = 0;
381  if (editMode != GNE_MODE_CONNECT && editMode != GNE_MODE_TLS && editMode != GNE_MODE_CREATE_EDGE) {
382  new FXMenuCommand(ret, "Split edge here", 0, &parent, MID_GNE_SPLIT_EDGE);
383  new FXMenuCommand(ret, "Split edges in both direction here", 0, &parent, MID_GNE_SPLIT_EDGE_BIDI);
384  new FXMenuCommand(ret, "Reverse edge", 0, &parent, MID_GNE_REVERSE_EDGE);
385  new FXMenuCommand(ret, "Add reverse direction", 0, &parent, MID_GNE_ADD_REVERSE_EDGE);
386  new FXMenuCommand(ret, "Set geometry endpoint here", 0, &parent, MID_GNE_SET_EDGE_ENDPOINT);
387  new FXMenuCommand(ret, "Restore geometry endpoint", 0, &parent, MID_GNE_RESET_EDGE_ENDPOINT);
389  new FXMenuCommand(ret, "Straighten selected Edges", 0, &parent, MID_GNE_STRAIGHTEN);
390  } else {
391  new FXMenuCommand(ret, "Straighten edge", 0, &parent, MID_GNE_STRAIGHTEN);
392  }
394  new FXMenuCommand(ret, "Duplicate selected lanes", 0, &parent, MID_GNE_DUPLICATE_LANE);
395  } else {
396  new FXMenuCommand(ret, "Duplicate lane", 0, &parent, MID_GNE_DUPLICATE_LANE);
397  }
398  } else if (editMode == GNE_MODE_TLS) {
399  myTLSEditor = static_cast<GNEViewNet&>(parent).getViewParent()->getTLSEditorFrame();
401  new FXMenuCommand(ret, "Select state for all links from this edge:", 0, 0, 0);
402  const std::vector<std::string> names = GNEInternalLane::LinkStateNames.getStrings();
403  for (std::vector<std::string>::const_iterator it = names.begin(); it != names.end(); it++) {
404  FXuint state = GNEInternalLane::LinkStateNames.get(*it);
405  FXMenuRadio* mc = new FXMenuRadio(ret, (*it).c_str(), this, FXDataTarget::ID_OPTION + state);
406  mc->setSelBackColor(MFXUtils::getFXColor(GNEInternalLane::colorForLinksState(state)));
408  }
409  }
410  } else {
411  FXMenuCommand* mc = new FXMenuCommand(ret, "Additional options available in 'Inspect Mode'", 0, 0, 0);
412  mc->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), 0);
413  }
414  // buildShowParamsPopupEntry(ret, false);
415  new FXMenuSeparator(ret);
417  const SUMOReal height = getShape().positionAtOffset2D(getShape().nearest_offset_to_point2D(parent.getPositionInformation())).z();
418  new FXMenuCommand(ret, ("Shape pos: " + toString(pos)).c_str(), 0, 0, 0);
419  new FXMenuCommand(ret, ("Length pos: " + toString(getPositionRelativeToShapeLenght(pos))).c_str(), 0, 0, 0);
420  new FXMenuCommand(ret, ("Height: " + toString(height)).c_str(), 0, 0, 0);
421  // new FXMenuSeparator(ret);
422  // buildPositionCopyEntry(ret, false);
423 
424  // let the GNEViewNet store the popup position
425  (dynamic_cast<GNEViewNet&>(parent)).markPopupPosition();
426  return ret;
427 }
428 
429 
433  new GUIParameterTableWindow(app, *this, 2);
434  // add items
435  ret->mkItem("length [m]", false, myParentEdge.getNBEdge()->getLength());
436  // close building
437  ret->closeBuilding();
438  return ret;
439 }
440 
441 Boundary
444 }
445 
446 
447 Boundary
450  b.grow(10);
451  return b;
452 }
453 
454 
455 const PositionVector&
458 }
459 
460 
461 const std::vector<SUMOReal>&
463  return myShapeRotations;
464 }
465 
466 
467 const std::vector<SUMOReal>&
469  return myShapeLengths;
470 }
471 
472 void
474  myShapeRotations.clear();
475  myShapeLengths.clear();
476  //SUMOReal length = myParentEdge.getLength(); // @todo see ticket #448
477  // may be different from length
478  int segments = (int) getShape().size() - 1;
479  if (segments >= 0) {
480  myShapeRotations.reserve(segments);
481  myShapeLengths.reserve(segments);
482  for (int i = 0; i < segments; ++i) {
483  const Position& f = getShape()[i];
484  const Position& s = getShape()[i + 1];
485  myShapeLengths.push_back(f.distanceTo2D(s));
486  myShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI);
487  }
488  }
489  // Update geometry of additionals vinculated with this lane
490  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
491  (*i)->updateGeometry();
492  }
493  // Update geometry of additionalSets vinculated to this lane
494  for (AdditionalSetVector::iterator i = myAdditionalSets.begin(); i != myAdditionalSets.end(); ++i) {
495  (*i)->updateGeometry();
496  }
497 }
498 
499 int
501  return myIndex;
502 }
503 
504 void
505 GNELane::setIndex(int index) {
506  myIndex = index;
508 }
509 
510 
511 SUMOReal
514 }
515 
516 
517 SUMOReal
520 }
521 
522 
523 SUMOReal
525  return getShape().length();
526 }
527 
528 
529 SUMOReal
531  return (position * getLaneShapeLenght()) / getLaneParametricLenght();
532 }
533 
534 
535 SUMOReal
537  return (position * getLaneParametricLenght()) / getLaneShapeLenght();
538 }
539 
540 
541 void
543  myAdditionals.push_back(additional);
544 }
545 
546 
547 bool
549  // Find and remove stoppingPlace
550  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
551  if (*i == additional) {
552  myAdditionals.erase(i);
553  return true;
554  }
555  }
556  return false;
557 }
558 
559 
560 const std::vector<GNEAdditional*>&
562  return myAdditionals;
563 }
564 
565 
566 bool
568  // Check if additionalSet already exists before insertion
569  for (AdditionalSetVector::iterator i = myAdditionalSets.begin(); i != myAdditionalSets.end(); i++) {
570  if ((*i) == additionalSet) {
571  return false;
572  }
573  }
574  // Insert it and retur true
575  myAdditionalSets.push_back(additionalSet);
576  return true;
577 }
578 
579 
580 bool
582  // search additionalSet and remove it
583  for (AdditionalSetVector::iterator i = myAdditionalSets.begin(); i != myAdditionalSets.end(); i++) {
584  if ((*i) == additionalSet) {
585  myAdditionalSets.erase(i);
586  return true;
587  }
588  }
589  // If additionalSet wasn't found, return false
590  return false;
591 }
592 
593 
594 const std::vector<GNEAdditionalSet*>&
596  return myAdditionalSets;
597 }
598 
599 
600 std::string
602  const NBEdge* edge = myParentEdge.getNBEdge();
603  switch (key) {
604  case SUMO_ATTR_ID:
605  return getMicrosimID();
606  case SUMO_ATTR_SPEED:
607  return toString(edge->getLaneSpeed(myIndex));
608  case SUMO_ATTR_ALLOW:
609  // return all allowed classes (may differ from the written attributes)
611  case SUMO_ATTR_DISALLOW:
612  // return all disallowed classes (may differ from the written attributes)
613  return getVehicleClassNames(~(edge->getPermissions(myIndex)));
614  case SUMO_ATTR_WIDTH:
615  return toString(edge->getLaneStruct(myIndex).width);
616  case SUMO_ATTR_ENDOFFSET:
617  return toString(edge->getLaneStruct(myIndex).endOffset);
618  case SUMO_ATTR_INDEX:
619  return toString(myIndex);
620  default:
621  throw InvalidArgument("lane attribute '" + toString(key) + "' not allowed");
622  }
623 }
624 
625 
626 void
627 GNELane::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
628  switch (key) {
629  case SUMO_ATTR_ID:
630  throw InvalidArgument("modifying lane attribute '" + toString(key) + "' not allowed");
631  case SUMO_ATTR_SPEED:
632  case SUMO_ATTR_ALLOW:
633  case SUMO_ATTR_DISALLOW:
634  case SUMO_ATTR_WIDTH:
635  case SUMO_ATTR_ENDOFFSET:
636  case SUMO_ATTR_INDEX:
637  // no special handling
638  undoList->p_add(new GNEChange_Attribute(this, key, value));
639  break;
640  default:
641  throw InvalidArgument("lane attribute '" + toString(key) + "' not allowed");
642  }
643 }
644 
645 
646 bool
647 GNELane::isValid(SumoXMLAttr key, const std::string& value) {
648  switch (key) {
649  case SUMO_ATTR_ID:
650  return false;
651  case SUMO_ATTR_SPEED:
652  return canParse<SUMOReal>(value);
653  case SUMO_ATTR_ALLOW:
654  case SUMO_ATTR_DISALLOW:
655  return canParseVehicleClasses(value);
656  case SUMO_ATTR_WIDTH:
657  return canParse<SUMOReal>(value) && (isPositive<SUMOReal>(value) || parse<SUMOReal>(value) == NBEdge::UNSPECIFIED_WIDTH);
658  case SUMO_ATTR_ENDOFFSET:
659  return canParse<SUMOReal>(value);
660  case SUMO_ATTR_INDEX:
661  return value == toString(myIndex);
662  default:
663  throw InvalidArgument("lane attribute '" + toString(key) + "' not allowed");
664  }
665 }
666 
667 
668 void
670  mySpecialColor = color;
671 }
672 
673 // ===========================================================================
674 // private
675 // ===========================================================================
676 
677 void
678 GNELane::setAttribute(SumoXMLAttr key, const std::string& value) {
679  NBEdge* edge = myParentEdge.getNBEdge();
680  switch (key) {
681  case SUMO_ATTR_ID:
682  throw InvalidArgument("modifying lane attribute '" + toString(key) + "' not allowed");
683  case SUMO_ATTR_SPEED:
684  edge->setSpeed(myIndex, parse<SUMOReal>(value));
685  break;
686  case SUMO_ATTR_ALLOW:
688  break;
689  case SUMO_ATTR_DISALLOW:
690  edge->setPermissions(~parseVehicleClasses(value), myIndex); // negation yields allowed
691  break;
692  case SUMO_ATTR_WIDTH:
693  edge->setLaneWidth(myIndex, parse<SUMOReal>(value));
694  break;
695  case SUMO_ATTR_ENDOFFSET:
696  edge->setEndOffset(myIndex, parse<SUMOReal>(value));
697  break;
698  default:
699  throw InvalidArgument("lane attribute '" + toString(key) + "' not allowed");
700  }
701 }
702 
703 
704 bool
705 GNELane::setFunctionalColor(int activeScheme) const {
706  switch (activeScheme) {
707  case 6: {
708  SUMOReal hue = GeomHelper::naviDegree(getShape().beginEndAngle()); // [0-360]
710  return true;
711  }
712  default:
713  return false;
714  }
715 }
716 
717 
718 bool
720  const int activeScheme = c.getActive();
721  myShapeColors.clear();
722  switch (activeScheme) {
723  case 9: // color by height at segment start
724  for (PositionVector::const_iterator ii = getShape().begin(); ii != getShape().end() - 1; ++ii) {
725  myShapeColors.push_back(c.getScheme().getColor(ii->z()));
726  }
727  return true;
728  case 11: // color by inclination at segment start
729  for (int ii = 1; ii < (int)getShape().size(); ++ii) {
730  const SUMOReal inc = (getShape()[ii].z() - getShape()[ii - 1].z()) / MAX2(POSITION_EPS, getShape()[ii].distanceTo2D(getShape()[ii - 1]));
731  myShapeColors.push_back(c.getScheme().getColor(inc));
732  }
733  return true;
734  default:
735  return false;
736  }
737 }
738 
739 
740 SUMOReal
741 GNELane::getColorValue(int activeScheme) const {
742  const SVCPermissions myPermissions = myParentEdge.getNBEdge()->getPermissions(myIndex);
743  switch (activeScheme) {
744  case 0:
745  switch (myPermissions) {
746  case SVC_PEDESTRIAN:
747  return 1;
748  case SVC_BICYCLE:
749  return 2;
750  case 0:
751  return 3;
752  case SVC_SHIP:
753  return 4;
754  default:
755  break;
756  }
757  if ((myPermissions & SVC_PASSENGER) != 0 || isRailway(myPermissions)) {
758  return 0;
759  } else {
760  return 5;
761  }
762  case 1:
763  return gSelected.isSelected(getType(), getGlID()) ||
764  gSelected.isSelected(GLO_EDGE, dynamic_cast<GNEEdge*>(&myParentEdge)->getGlID());
765  case 2:
766  return (SUMOReal)myPermissions;
767  case 3:
769  case 4:
770  return myParentEdge.getNBEdge()->getNumLanes();
771  case 5: {
773  }
774  // case 6: by angle (functional)
775  case 7: {
776  return myParentEdge.getNBEdge()->getPriority();
777  }
778  case 8: {
779  // color by z of first shape point
780  return getShape()[0].z();
781  }
782  // case 9: by segment height
783  case 10: {
784  // color by incline
785  return (getShape()[-1].z() - getShape()[0].z()) / myParentEdge.getNBEdge()->getLength();
786  }
787  }
788  return 0;
789 }
790 
791 
792 bool
795 }
796 
797 
798 bool
800  return isWaterway(myParentEdge.getNBEdge()->getPermissions(myIndex)) && s.showRails; // reusing the showRails setting
801 }
802 
803 
804 void
805 GNELane::drawCrossties(SUMOReal length, SUMOReal spacing, SUMOReal halfWidth) const {
806  glPushMatrix();
807  // draw on top of of the white area between the rails
808  glTranslated(0, 0, 0.1);
809  int e = (int) getShape().size() - 1;
810  for (int i = 0; i < e; ++i) {
811  glPushMatrix();
812  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.0);
813  glRotated(myShapeRotations[i], 0, 0, 1);
814  for (SUMOReal t = 0; t < myShapeLengths[i]; t += spacing) {
815  glBegin(GL_QUADS);
816  glVertex2d(-halfWidth, -t);
817  glVertex2d(-halfWidth, -t - length);
818  glVertex2d(halfWidth, -t - length);
819  glVertex2d(halfWidth, -t);
820  glEnd();
821  }
822  glPopMatrix();
823  }
824  glPopMatrix();
825 }
826 
827 
828 void
831  glColor3d(0.3, 0.3, 0.3);
832  glPushMatrix();
833  glTranslated(0, 0, GLO_JUNCTION + 0.1);
834  int e = (int) getShape().size() - 1;
835  for (int i = 0; i < e; ++i) {
836  glPushMatrix();
837  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.1);
838  glRotated(myShapeRotations[i], 0, 0, 1);
839  for (SUMOReal t = 0; t < myShapeLengths[i]; t += width) {
840  const SUMOReal length = MIN2(width * (SUMOReal)0.5, myShapeLengths[i] - t);
841  glBegin(GL_TRIANGLES);
842  glVertex2d(0, -t - length);
843  glVertex2d(-width * 0.25, -t);
844  glVertex2d(+width * 0.25, -t);
845  glEnd();
846  }
847  glPopMatrix();
848  }
849  glPopMatrix();
850 }
851 
852 
853 
854 const std::string&
856  return myParentEdge.getMicrosimID();
857 }
858 
859 
860 long
861 GNELane::onDefault(FXObject* obj, FXSelector sel, void* data) {
862  if (myTLSEditor != 0) {
863  myTLSEditor->handleMultiChange(this, obj, sel, data);
864  }
865  return 1;
866 }
867 
868 
869 GNEEdge&
871  return myParentEdge;
872 }
873 
874 
875 /****************************************************************************/
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterways
Definition: GNELane.cpp:799
The link is a partial left direction.
SUMOReal endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:136
bool controlsEdge(GNEEdge &edge) const
whether the given edge is controlled by the currently edited tlDef
const std::string & getParentName() const
Returns the name of the parent object (if any)
Definition: GNELane.cpp:855
const std::vector< SUMOReal > & getShapeRotations() const
returns the vector with the shape rotations
Definition: GNELane.cpp:462
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:203
float laneWidthExaggeration
The lane exaggeration (upscale thickness)
PositionVector shape
The lane&#39;s shape.
Definition: NBEdge.h:128
is a pedestrian
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
GNETLSEditorFrame * myTLSEditor
the tls-editor for setting multiple links in TLS-mode
Definition: GNELane.h:251
static RGBColor fromHSV(SUMOReal h, SUMOReal s, SUMOReal v)
Converts the given hsv-triplet to rgb.
Definition: RGBColor.cpp:294
AdditionalVector myAdditionals
list with the additonals vinculated with this lane
Definition: GNELane.h:239
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNELane.cpp:371
NBNode * myTo
Definition: NBEdge.h:1292
void drawMarkings(const bool &selectedEdge, SUMOReal scale) const
draw lane markings
Definition: GNELane.cpp:326
SUMOReal getSpeed() const
returns the current speed of lane
Definition: GNELane.cpp:512
const RGBColor * mySpecialColor
optional special color
Definition: GNELane.h:245
static const RGBColor selectedLaneColor
color of selected lane
Definition: GNENet.h:98
std::vector< Connection > getConnectionsFromLane(int lane) const
Returns connections from a given lane.
Definition: NBEdge.cpp:798
Copy edge name (for lanes only)
Definition: GUIAppEnum.h:235
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2476
SUMOReal getPositionRelativeToShapeLenght(SUMOReal position) const
Definition: GNELane.cpp:536
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2531
GUIColorer laneColorer
The lane colorer.
Stores the information about how to visualize structures.
This is an uncontrolled, minor link, has to stop.
vehicle is a bicycle
int SVCPermissions
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:70
static void drawOutlineCircle(SUMOReal width, SUMOReal iwidth, int steps=8)
Draws an unfilled circle around (0,0)
Definition: GLHelper.cpp:375
bool showRails
Information whether rails shall be drawn.
The link is a 180 degree turn.
static RGBColor colorForLinksState(FXuint state)
return the color for each linkstate
mode for editing tls
Definition: GNEViewNet.h:62
static void drawBoxLines(const PositionVector &geom, const std::vector< SUMOReal > &rots, const std::vector< SUMOReal > &lengths, SUMOReal width, int cornerDetail=0, SUMOReal offset=0)
Draws thick lines.
Definition: GLHelper.cpp:176
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
bool setFunctionalColor(int activeScheme) const
sets the color according to the current scheme index and some lane function
Definition: GNELane.cpp:705
SUMOReal getColorValue(int activeScheme) const
return value for lane coloring according to the given scheme
Definition: GNELane.cpp:741
T MAX2(T a, T b)
Definition: StdDefs.h:75
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:469
static void drawBoxLine(const Position &beg, SUMOReal rot, SUMOReal visLength, SUMOReal width, SUMOReal offset=0)
Draws a thick line.
Definition: GLHelper.cpp:130
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given ...
Definition: NBEdge.cpp:2547
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
int editMode
the current NETEDIT mode (temporary)
bool showLaneDirection
Whether to show direction indicators for lanes.
bool setMultiColor(const GUIColorer &c) const
sets multiple colors according to the current scheme index and some lane function ...
Definition: GNELane.cpp:719
GNELane()
FOX needs this.
Definition: GNELane.cpp:86
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
std::vector< RGBColor > myShapeColors
The color of the shape parts (cached)
Definition: GNELane.h:248
This is an uncontrolled, right-before-left link.
void drawTLSLinkNo() const
draw TLS Link Number
Definition: GNELane.cpp:109
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
const SUMOReal SUMO_const_laneOffset
Definition: StdDefs.h:52
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1090
An Element wich group additionalSet elements.
The link is controlled by a tls which is off, not blinking, may pass.
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
This is an uncontrolled, all-way stop link.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
Boundary getBoundary() const
returns the boundry (including lanes)
Definition: GNELane.cpp:442
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:500
GUIGlID getGlID() const
Returns the numerical id of the object.
static void drawTriangleAtEnd(const Position &p1, const Position &p2, SUMOReal tLength, SUMOReal tWidth)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:422
SUMOReal getLaneSpeed(int lane) const
Definition: NBEdge.cpp:1336
void setIndex(int index)
Definition: GNELane.cpp:505
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
int myIndex
The index of this lane.
Definition: GNELane.h:227
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
SUMOReal scale
information about a lane&#39;s width (temporary, used for a single view)
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
std::vector< std::string > getStrings() const
The link is a straight direction.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition: GNELane.cpp:793
SUMOReal getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:433
void drawDirectionIndicators() const
direction indicators for lanes
Definition: GNELane.cpp:829
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
#define PI
Definition: polyfonts.c:61
SUMOReal selectionScale
the current selection scaling in NETEDIT (temporary)
void drawLane2LaneConnections() const
draw lane to lane connections
Definition: GNELane.cpp:189
void drawArrows() const
draw arrows
Definition: GNELane.cpp:119
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:355
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:443
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:870
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNELane.cpp:627
float laneMinSize
The minimum visual lane width for drawing.
SUMOReal getLaneParametricLenght() const
returns the parameteric length of the lane
Definition: GNELane.cpp:518
SUMOReal getPositionRelativeToParametricLenght(SUMOReal position) const
Definition: GNELane.cpp:530
This is an uncontrolled, minor link, has to brake.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
bool isLogicValid()
whether this junction has a valid logic
std::vector< SUMOReal > myShapeRotations
Definition: GNELane.h:232
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
friend class GNEChange_Attribute
declare friend class
AdditionalSetVector myAdditionalSets
list with the additonalSets vinculated with this lane
Definition: GNELane.h:242
SUMOReal z() const
Returns the z-position.
Definition: Position.h:73
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:347
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
const T getColor(const SUMOReal value) const
T MIN2(T a, T b)
Definition: StdDefs.h:69
The link is a (hard) right direction.
#define POSITION_EPS
Definition: config.h:187
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
Definition: NBNode.cpp:1596
bool removeAdditionalSet(GNEAdditionalSet *additionalSet)
remove GNEAdditionalSet from this lane
Definition: GNELane.cpp:581
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
bool removeAdditional(GNEAdditional *additional)
Definition: GNELane.cpp:548
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream&#39;s direction.
Definition: NBNode.cpp:1532
std::vector< Connection > myConnections
List of connections to following edges.
Definition: NBEdge.h:1311
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
The link is a partial right direction.
std::string getVehicleClassNames(SVCPermissions permissions)
Returns the ids of the given classes, divided using a &#39; &#39;.
vehicle is a passenger car (a "normal" car)
void updateGeometry()
update pre-computed geometry information
Definition: GNELane.cpp:473
static SUMOReal naviDegree(const SUMOReal angle)
Definition: GeomHelper.cpp:191
is an arbitrary ship
void drawCrossties(SUMOReal length, SUMOReal spacing, SUMOReal halfWidth) const
draw crossties for railroads
Definition: GNELane.cpp:805
bool addAdditionalSet(GNEAdditionalSet *additionalSet)
add GNEAdditionalSet to this lane
Definition: GNELane.cpp:567
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
std::string getAttribute(SumoXMLAttr key) const
Definition: GNELane.cpp:601
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:54
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2575
void drawLinkRules() const
draw link rules
Definition: GNELane.cpp:114
GNEEdge & myParentEdge
The Edge that to which this lane belongs.
Definition: GNELane.h:224
SUMOReal length() const
Returns the length.
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:201
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:371
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:456
SUMOReal getLaneShapeLenght() const
returns the length of the lane&#39;s shape
Definition: GNELane.cpp:524
long onDefault(FXObject *, FXSelector, void *)
multiplexes message to two targets
Definition: GNELane.cpp:861
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:63
The link is controlled by a tls which is off and blinks, has to brake.
const std::vector< GNEAdditional * > & getAdditionals() const
method to obtain a list of additional elements associated to this lane
Definition: GNELane.cpp:561
std::vector< SUMOReal > myShapeLengths
The lengths of the shape parts.
Definition: GNELane.h:235
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
void setSpecialColor(const RGBColor *Color2)
Definition: GNELane.cpp:669
The popup menu of a globject.
an edge
const std::vector< SUMOReal > & getShapeLengths() const
returns the vector with the shape lengths
Definition: GNELane.cpp:468
This is an uncontrolled, major link, may pass.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNELane.cpp:448
GNEJunction * getDest() const
returns the destination-junction
Definition: GNEEdge.cpp:145
static const StringBijection< FXuint > LinkStateNames
long names for link states
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:125
Represents a single node (junction) during network building.
Definition: NBNode.h:74
T get(const std::string &str) const
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:232
The link is a 180 degree turn (left-hand network)
static void drawLine(const Position &beg, SUMOReal rot, SUMOReal visLength)
Draws a thin line.
Definition: GLHelper.cpp:269
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2515
#define SUMOReal
Definition: config.h:213
std::string getLaneID(int lane) const
Definition: NBEdge.cpp:2348
void addAdditional(GNEAdditional *additional)
Definition: GNELane.cpp:542
static const RGBColor selectionColor
color of selection
Definition: GNENet.h:95
mode for connecting lanes
Definition: GNEViewNet.h:60
const std::vector< GNEAdditionalSet * > & getAdditionalSets()
return list of additionalSets associated with this lane
Definition: GNELane.cpp:595
mode for creating new edges
Definition: GNEViewNet.h:50
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNELane.cpp:647
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:225
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
void drawLinkNo() const
draw link Number
Definition: GNELane.cpp:104
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void mkItem(const char *name, bool dynamic, ValueSource< unsigned > *src)
Adds a row which obtains its value from an unsigned-ValueSource.
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNELane.cpp:431
GUISelectedStorage gSelected
A global holder of selected objects.
void closeBuilding()
Closes the building of the table.
A window containing a gl-object&#39;s parameter.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:554
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNELane.cpp:239
~GNELane()
Destructor.
Definition: GNELane.cpp:95
SUMOReal width
This lane&#39;s width.
Definition: NBEdge.h:138
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
SUMOReal getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:424
The link has no direction (is a dead end link)
a junction
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:449