Eclipse SUMO - Simulation of Urban MObility
GNEEdge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // A road/street connecting two junctions (netedit-version, adapted from GUIEdge)
16 // Basically a container for an NBEdge with drawing and editing capabilities
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <netedit/GNENet.h>
26 #include <netedit/GNEUndoList.h>
27 #include <netedit/GNEViewNet.h>
34 #include <utils/gui/div/GLHelper.h>
37 
38 #include "GNEConnection.h"
39 #include "GNECrossing.h"
40 #include "GNEJunction.h"
41 #include "GNELane.h"
42 #include "GNEEdge.h"
43 
44 //#define DEBUG_SMOOTH_GEOM
45 //#define DEBUGCOND(obj) (true)
46 
47 // ===========================================================================
48 // static
49 // ===========================================================================
51 
53  // @note: using local static idiom to avoid static initialization order problem
54  static GNEEdge* dummy = new GNEEdge(); // 'static local variable', this line is called only once
55  return *dummy; // this line gets called with the same 'dummy' every time the function is called
56 }
57 
58 // ===========================================================================
59 // members methods
60 // ===========================================================================
61 
62 GNEEdge::GNEEdge(NBEdge& nbe, GNENet* net, bool wasSplit, bool loaded):
64  myNBEdge(nbe),
65  myGNEJunctionSource(myNet->retrieveJunction(myNBEdge.getFromNode()->getID())),
66  myGNEJunctionDestiny(myNet->retrieveJunction(myNBEdge.getToNode()->getID())),
67  myLanes(0),
68  myAmResponsible(false),
69  myWasSplit(wasSplit),
71  // Create lanes
72  int numLanes = myNBEdge.getNumLanes();
73  myLanes.reserve(numLanes);
74  for (int i = 0; i < numLanes; i++) {
75  myLanes.push_back(new GNELane(*this, i));
76  myLanes.back()->incRef("GNEEdge::GNEEdge");
77  }
78  // update Lane geometries
79  for (auto i : myLanes) {
80  i->updateGeometry();
81  }
82 }
83 
85  GNENetElement(nullptr, "DUMMY", GLO_EDGE, SUMO_TAG_NOTHING),
86  myNBEdge(NBEdge::DummyEdge) {
87 }
88 
90  // Delete references to this eddge in lanes
91  for (auto i : myLanes) {
92  i->decRef("GNEEdge::~GNEEdge");
93  if (i->unreferenced()) {
94  // show extra information for tests
95  WRITE_DEBUG("Deleting unreferenced " + i->getTagStr() + " '" + i->getID() + "' in GNEEdge destructor");
96  delete i;
97  }
98  }
99  // delete references to this eddge in connections
100  for (auto i : myGNEConnections) {
101  i->decRef("GNEEdge::~GNEEdge");
102  if (i->unreferenced()) {
103  // show extra information for tests
104  WRITE_DEBUG("Deleting unreferenced " + i->getTagStr() + " '" + i->getID() + "' in GNEEdge destructor");
105  delete i;
106  }
107  }
108  if (myAmResponsible) {
109  delete &myNBEdge;
110  }
111 }
112 
113 
114 std::string
116  // currently unused
117  return "";
118 }
119 
120 
121 void
123  // Update geometry of lanes
124  for (auto i : myLanes) {
125  i->updateGeometry();
126  }
127  // Update geometry of connections (Only if updateGrid is enabled, because in move mode connections are hidden
128  // (note: only the previous marked as deprecated will be updated)
130  for (auto i : myGNEConnections) {
131  i->updateGeometry();
132  }
133  }
134  // Update geometry of additionals children vinculated to this edge
135  for (auto i : getAdditionalChildren()) {
136  i->updateGeometry();
137  }
138  // Update geometry of additional parents that have this edge as parent
139  for (auto i : getAdditionalParents()) {
140  i->updateGeometry();
141  }
142  // Mark geometry as deprecated for all demand elements vinculated with this edge
143  for (auto i : getDemandElementChildren()) {
144  // if child is a person plan, mark the person parent
145  if (i->getTagProperty().isPersonPlan()) {
146  i->getDemandElementParents().front()->markSegmentGeometryDeprecated();
147  } else {
148  i->markSegmentGeometryDeprecated();
149  }
150  }
151  // Update geometry of demand elements children vinculated to this edge
152  for (auto i : getDemandElementChildren()) {
153  i->updateGeometry();
154  }
155  // Update geometry of demand elements parents that have this edge as parent
156  for (auto i : getDemandElementParents()) {
157  i->updateGeometry();
158  }
159 }
160 
161 
162 Position
164  // currently unused
165  return Position(0, 0);
166 }
167 
168 
169 bool
172  return (myNBEdge.getGeometry().front().distanceTo2D(pos) < SNAP_RADIUS);
173  } else {
174  return false;
175  }
176 }
177 
178 
179 bool
182  return (myNBEdge.getGeometry().back().distanceTo2D(pos) < SNAP_RADIUS);
183  } else {
184  return false;
185  }
186 }
187 
188 
189 void
190 GNEEdge::moveShapeStart(const Position& oldPos, const Position& offset) {
191  // change shape startPosition using oldPosition and offset
192  Position shapeStartEdited = oldPos;
193  shapeStartEdited.add(offset);
194  // snap to active grid
195  shapeStartEdited = myNet->getViewNet()->snapToActiveGrid(shapeStartEdited, offset.z() == 0);
196  // make sure that start and end position are different
197  if (shapeStartEdited != myNBEdge.getGeometry().back()) {
198  // set shape start position without updating grid
199  setShapeStartPos(shapeStartEdited);
200  updateGeometry();
201  }
202 }
203 
204 
205 void
206 GNEEdge::moveShapeEnd(const Position& oldPos, const Position& offset) {
207  // change shape endPosition using oldPosition and offset
208  Position shapeEndEdited = oldPos;
209  shapeEndEdited.add(offset);
210  // snap to active grid
211  shapeEndEdited = myNet->getViewNet()->snapToActiveGrid(shapeEndEdited, offset.z() == 0);
212  // make sure that start and end position are different
213  if (shapeEndEdited != myNBEdge.getGeometry().front()) {
214  // set shape end position without updating grid
215  setShapeEndPos(shapeEndEdited);
216  updateGeometry();
217  }
218 }
219 
220 
221 void
223  // first save current shape start position
224  Position modifiedShapeStartPos = myNBEdge.getGeometry().front();
225  // restore old shape start position
226  setShapeStartPos(oldPos);
227  // end geometry moving
229  // set attribute using undolist
230  undoList->p_begin("shape start of " + getTagStr());
231  undoList->p_add(new GNEChange_Attribute(this, myNet, GNE_ATTR_SHAPE_START, toString(modifiedShapeStartPos), true, toString(oldPos)));
232  undoList->p_end();
233 }
234 
235 
236 void
238  // first save current shape end position
239  Position modifiedShapeEndPos = myNBEdge.getGeometry().back();
240  // restore old shape end position
241  setShapeEndPos(oldPos);
242  // end geometry moving
244  // set attribute using undolist
245  undoList->p_begin("shape end of " + getTagStr());
246  undoList->p_add(new GNEChange_Attribute(this, myNet, GNE_ATTR_SHAPE_END, toString(modifiedShapeEndPos), true, toString(oldPos)));
247  undoList->p_end();
248 }
249 
250 
251 void
253  // save current centering boundary
255  // Save current centering boundary of lanes (and their children)
256  for (auto i : myLanes) {
257  i->startGeometryMoving();
258  }
259  // Save current centering boundary of additionals children vinculated to this edge
260  for (auto i : getAdditionalChildren()) {
261  i->startGeometryMoving();
262  }
263  // Save current centering boundary of additional parents that have this edge as parent
264  for (auto i : getAdditionalParents()) {
265  i->startGeometryMoving();
266  }
267  // Save current centering boundary of demand elements children vinculated to this edge
268  for (auto i : getDemandElementChildren()) {
269  i->startGeometryMoving();
270  }
271  // Save current centering boundary of demand elements parents that have this edge as parent
272  for (auto i : getDemandElementParents()) {
273  i->startGeometryMoving();
274  }
275 }
276 
277 
278 void
280  // check that endGeometryMoving was called only once
282  // Remove object from net
284  // reset myMovingGeometryBoundary
286  // Restore centering boundary of lanes (and their children)
287  for (auto i : myLanes) {
288  i->endGeometryMoving();
289  }
290  // Restore centering boundary of additionals children vinculated to this edge
291  for (auto i : getAdditionalChildren()) {
292  i->endGeometryMoving();
293  }
294  // Restore centering boundary of additional parents that have this edge as parent
295  for (auto i : getAdditionalParents()) {
296  i->endGeometryMoving();
297  }
298  // Restore centering boundary of demand elements children vinculated to this edge
299  for (auto i : getDemandElementChildren()) {
300  i->endGeometryMoving();
301  }
302  // Restore centering boundary of demand elements parents that have this edge as parent
303  for (auto i : getDemandElementParents()) {
304  i->endGeometryMoving();
305  }
306  // add object into grid again (using the new centering boundary)
307  myNet->addGLObjectIntoGrid(this);
308  }
309 }
310 
311 
312 int
313 GNEEdge::getVertexIndex(Position pos, bool createIfNoExist, bool snapToGrid) {
314  PositionVector entireGeometry = myNBEdge.getGeometry();
315  // check if position has to be snapped to grid
316  if (snapToGrid) {
317  pos = myNet->getViewNet()->snapToActiveGrid(pos);
318  }
319  double offset = entireGeometry.nearest_offset_to_point2D(pos, true);
320  if (offset == GeomHelper::INVALID_OFFSET) {
321  return -1;
322  }
323  Position newPos = entireGeometry.positionAtOffset2D(offset);
324  // first check if vertex already exists in the inner geometry
325  for (int i = 0; i < (int)entireGeometry.size(); i++) {
326  if (entireGeometry[i].distanceTo2D(newPos) < SNAP_RADIUS) {
327  if (i == 0 || i == (int)(entireGeometry.size() - 1)) {
328  return -1;
329  }
330  // index refers to inner geometry
331  return i - 1;
332  }
333  }
334  // if vertex doesn't exist, insert it
335  if (createIfNoExist) {
336  // check if position has to be snapped to grid
337  if (snapToGrid) {
338  newPos = myNet->getViewNet()->snapToActiveGrid(newPos);
339  }
341  int index = entireGeometry.insertAtClosest(myNet->getViewNet()->snapToActiveGrid(newPos));
342  setGeometry(entireGeometry, false);
344  // index refers to inner geometry
345  return (index - 1);
346  } else {
347  return -1;
348  }
349 }
350 
351 
352 int
353 GNEEdge::getVertexIndex(const double offset, bool createIfNoExist, bool snapToGrid) {
354  return getVertexIndex(myNBEdge.getGeometry().positionAtOffset2D(offset), createIfNoExist, snapToGrid);
355 }
356 
357 
358 int
359 GNEEdge::moveVertexShape(const int index, const Position& oldPos, const Position& offset) {
360  // obtain inner geometry of edge
361  PositionVector edgeGeometry = myNBEdge.getInnerGeometry();
362  // Make sure that index is valid AND ins't the first and last index
363  if (index != -1) {
364  // check that index is correct before change position
365  if (index < (int)edgeGeometry.size()) {
366  // change position of vertex
367  edgeGeometry[index] = oldPos;
368  edgeGeometry[index].add(offset);
369  // filtern position using snap to active grid
370  edgeGeometry[index] = myNet->getViewNet()->snapToActiveGrid(edgeGeometry[index], offset.z() == 0);
371  // update edge's geometry without updating RTree (To avoid unnecesary changes in RTree)
372  setGeometry(edgeGeometry, true);
373  return index;
374  } else {
375  throw InvalidArgument("Index greater than shape size");
376  }
377  } else {
378  return index;
379  }
380 }
381 
382 
383 void
384 GNEEdge::moveEntireShape(const PositionVector& oldShape, const Position& offset) {
385  // make a copy of the old shape to change it
386  PositionVector modifiedShape = oldShape;
387  // change all points of the inner geometry using offset
388  for (auto& i : modifiedShape) {
389  i.add(offset);
390  }
391  // restore modified shape
392  setGeometry(modifiedShape, true);
393 }
394 
395 
396 void
398  // restore original shape into shapeToCommit
399  PositionVector innerShapeToCommit = myNBEdge.getInnerGeometry();
400  // first check if second and penultimate isn't in Junction's buubles
402  if (myNBEdge.getGeometry().size() > 2 && myNBEdge.getGeometry()[0].distanceTo(myNBEdge.getGeometry()[1]) < buubleRadius) {
403  innerShapeToCommit.removeClosest(innerShapeToCommit[0]);
404  }
405  if (myNBEdge.getGeometry().size() > 2 && myNBEdge.getGeometry()[(int)myNBEdge.getGeometry().size() - 2].distanceTo(myNBEdge.getGeometry()[(int)myNBEdge.getGeometry().size() - 1]) < buubleRadius) {
406  innerShapeToCommit.removeClosest(innerShapeToCommit[(int)innerShapeToCommit.size() - 1]);
407  }
408  // second check if double points has to be removed
409  innerShapeToCommit.removeDoublePoints(SNAP_RADIUS);
410  // show warning if some of edge's shape was merged
411  if (innerShapeToCommit.size() != myNBEdge.getInnerGeometry().size()) {
412  WRITE_WARNING("Merged shape's point")
413  }
414 
415  updateGeometry();
416  // restore old geometry to allow change attribute (And restore shape if during movement a new point was created
417  setGeometry(oldShape, true);
418  // finish geometry moving
420  // commit new shape
421  undoList->p_begin("moving " + toString(SUMO_ATTR_SHAPE) + " of " + getTagStr());
422  undoList->p_add(new GNEChange_Attribute(this, myNet, SUMO_ATTR_SHAPE, toString(innerShapeToCommit)));
423  undoList->p_end();
424 }
425 
426 
427 void
428 GNEEdge::deleteGeometryPoint(const Position& pos, bool allowUndo) {
429  // obtain index and remove point
430  PositionVector modifiedShape = myNBEdge.getInnerGeometry();
431  int index = modifiedShape.indexOfClosest(pos);
432  modifiedShape.erase(modifiedShape.begin() + index);
433  // set new shape depending of allowUndo
434  if (allowUndo) {
435  myNet->getViewNet()->getUndoList()->p_begin("delete geometry point");
438  } else {
439  // set new shape
440  setGeometry(modifiedShape, true);
441  }
442 }
443 
444 
445 void
447  Position delta = junction->getNBNode()->getPosition() - origPos;
449  // geometry endpoint need not equal junction position hence we modify it with delta
450  if (junction == myGNEJunctionSource) {
451  geom[0].add(delta);
452  } else {
453  geom[-1].add(delta);
454  }
455  setGeometry(geom, false);
456 }
457 
458 
459 Boundary
461  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
464  } else {
465  Boundary b;
466  for (const auto& i : myLanes) {
467  b.add(i->getCenteringBoundary());
468  }
469  // ensure that geometry points are selectable even if the lane geometry is strange
470  for (const Position& pos : myNBEdge.getGeometry()) {
471  b.add(pos);
472  }
473  b.grow(10);
474  return b;
475  }
476 }
477 
478 const std::string
480  return myNBEdge.getStreetName();
481 }
482 
485  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
486  buildPopupHeader(ret, app);
489  // build selection and show parameters menu
492  // build position copy entry
493  buildPositionCopyEntry(ret, false);
494  return ret;
495 }
496 
497 
500  return myGNEJunctionSource;
501 }
502 
503 
506  return myGNEJunctionDestiny;
507 }
508 
509 
510 GNEEdge*
513 }
514 
515 
516 void
518  // check if boundary has to be drawn
519  if (s.drawBoundaries) {
521  }
522  // draw lanes
523  for (auto i : myLanes) {
524  i->drawGL(s);
525  }
526  // draw additional parents
527  for (const auto& i : getAdditionalParents()) {
528  if (i->getTagProperty().getTag() == SUMO_TAG_REROUTER) {
529  // draw rerouter symbol
530  drawRerouterSymbol(s, i);
531  }
532  }
533  // draw additional children
534  for (const auto& i : getAdditionalChildren()) {
535  i->drawGL(s);
536  }
537  // draw edge child
539  // certain demand elements children can contain loops (for example, routes) and it causes overlapping problems. It's needed to filter it before drawing
541  // first check if route can be drawn
543  // draw partial route
544  drawPartialRoute(s, i, nullptr);
545  }
546  }
548  // first check if embedded route can be drawn
550  // draw partial route
551  drawPartialRoute(s, i, nullptr);
552  }
553  }
554  for (const auto& i : getSortedDemandElementChildrenByType(SUMO_TAG_TRIP)) {
555  // Start drawing adding an gl identificator
556  glPushName(i->getGlID());
557  // draw partial trip only if is being inspected or selected
558  if ((myNet->getViewNet()->getDottedAC() == i) || i->isAttributeCarrierSelected()) {
559  drawPartialTripFromTo(s, i, nullptr);
560  }
561  // only draw trip in the first edge
562  if (i->getAttribute(SUMO_ATTR_FROM) == getID()) {
563  i->drawGL(s);
564  }
565  // Pop name
566  glPopName();
567  }
568  for (const auto& i : getSortedDemandElementChildrenByType(SUMO_TAG_FLOW)) {
569  // Start drawing adding an gl identificator
570  glPushName(i->getGlID());
571  // draw partial trip only if is being inspected or selected
572  if ((myNet->getViewNet()->getDottedAC() == i) || i->isAttributeCarrierSelected()) {
573  drawPartialTripFromTo(s, i, nullptr);
574  }
575  // only draw flow in the first edge
576  if (i->getAttribute(SUMO_ATTR_FROM) == getID()) {
577  i->drawGL(s);
578  }
579  // Pop name
580  glPopName();
581  }
583  drawPartialPersonPlan(s, i, nullptr);
584  }
586  drawPartialPersonPlan(s, i, nullptr);
587  }
589  drawPartialPersonPlan(s, i, nullptr);
590  }
592  drawPartialPersonPlan(s, i, nullptr);
593  }
595  drawPartialPersonPlan(s, i, nullptr);
596  }
598  drawPartialPersonPlan(s, i, nullptr);
599  }
601  drawPartialPersonPlan(s, i, nullptr);
602  }
604  drawPartialPersonPlan(s, i, nullptr);
605  }
606  }
607  // draw geometry points if isnt's too small and
610  }
611  // draw name if isn't being drawn for selecting
612  if (!s.drawForSelecting) {
613  drawEdgeName(s);
614  }
615  // draw dotted contor around the first and last lane if isn't being drawn for selecting
616  if (myNet->getViewNet()->getDottedAC() == this) {
617  const double myHalfLaneWidthFront = myNBEdge.getLaneWidth(myLanes.front()->getIndex()) / 2;
618  const double myHalfLaneWidthBack = (s.spreadSuperposed && myLanes.back()->drawAsRailway(s) && myNBEdge.isBidiRail()) ? 0 : myNBEdge.getLaneWidth(myLanes.back()->getIndex()) / 2;
619  GLHelper::drawShapeDottedContourBetweenLanes(s, GLO_JUNCTION, myLanes.front()->getGeometry().shape, myHalfLaneWidthFront, myLanes.back()->getGeometry().shape, -1 * myHalfLaneWidthBack);
620  }
621 }
622 
623 
624 NBEdge*
626  return &myNBEdge;
627 }
628 
629 
630 Position
631 GNEEdge::getSplitPos(const Position& clickPos) {
632  const PositionVector& geom = myNBEdge.getGeometry();
633  int index = geom.indexOfClosest(clickPos);
634  if (geom[index].distanceTo(clickPos) < SNAP_RADIUS) {
635  // split at existing geometry point
636  return geom[index];
637  } else {
638  // split straight between the next two points
639  return geom.positionAtOffset(geom.nearest_offset_to_point2D(clickPos));
640  }
641 }
642 
643 
644 void
646  if ((myNBEdge.getGeometry().front() != myGNEJunctionSource->getPositionInView()) && (myNBEdge.getGeometry().front().distanceTo(pos) < SNAP_RADIUS)) {
647  undoList->p_begin("remove endpoint");
648  setAttribute(GNE_ATTR_SHAPE_START, "", undoList);
649  undoList->p_end();
650  } else if ((myNBEdge.getGeometry().back() != myGNEJunctionDestiny->getPositionInView()) && (myNBEdge.getGeometry().back().distanceTo(pos) < SNAP_RADIUS)) {
651  undoList->p_begin("remove endpoint");
652  setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
653  undoList->p_end();
654  } else {
655  // we need to create new Start/End position over Edge shape, not over clicked position
657  if (offset != GeomHelper::INVALID_OFFSET) {
659  // calculate position over edge shape relative to clicked positino
660  Position newPos = geom.positionAtOffset2D(offset);
661  // snap new position to grid
662  newPos = myNet->getViewNet()->snapToActiveGrid(newPos);
663  undoList->p_begin("set endpoint");
664  int index = geom.indexOfClosest(pos);
665  // check if snap to existing geometry
666  if (geom[index].distanceTo(pos) < SNAP_RADIUS) {
667  pos = geom[index];
668  }
671  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
672  setAttribute(GNE_ATTR_SHAPE_END, toString(newPos), undoList);
674  } else {
675  setAttribute(GNE_ATTR_SHAPE_START, toString(newPos), undoList);
677  }
678  // possibly existing inner point is no longer needed
679  if (myNBEdge.getInnerGeometry().size() > 0 && getVertexIndex(pos, false, false) != -1) {
680  deleteGeometryPoint(pos, false);
681  }
682  undoList->p_end();
683  }
684  }
685 }
686 
687 
688 void
692  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
693  setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
695  } else {
696  setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
698  }
699 }
700 
701 
702 void
704  // set new geometry
705  myNBEdge.setGeometry(geom, inner);
706  updateGeometry();
709 }
710 
711 
712 void
714  // create new and removed unused GNEConnectinos
715  const std::vector<NBEdge::Connection>& connections = myNBEdge.getConnections();
716  // create a vector to keep retrieved and created connections
717  std::vector<GNEConnection*> retrievedConnections;
718  // iterate over NBEdge::Connections of GNEEdge
719  for (auto it : connections) {
720  // retrieve existent GNEConnection, or create it
721  GNEConnection* retrievedGNEConnection = retrieveGNEConnection(it.fromLane, it.toEdge, it.toLane);
722  retrievedGNEConnection->updateLinkState();
723  retrievedConnections.push_back(retrievedGNEConnection);
724  // check if previously this GNEConnections exists, and if true, remove it from myGNEConnections
725  std::vector<GNEConnection*>::iterator retrievedExists = std::find(myGNEConnections.begin(), myGNEConnections.end(), retrievedGNEConnection);
726  if (retrievedExists != myGNEConnections.end()) {
727  myGNEConnections.erase(retrievedExists);
728  } else {
729  // include reference to created GNEConnection
730  retrievedGNEConnection->incRef("GNEEdge::remakeGNEConnections");
731  }
732  // mark it as deprecated
733  retrievedGNEConnection->markConnectionGeometryDeprecated();
734  }
735  // delete non retrieved GNEConnections
736  for (auto it : myGNEConnections) {
737  // decrease reference
738  it->decRef();
739  // delete GNEConnection if is unreferenced
740  if (it->unreferenced()) {
741  // show extra information for tests
742  WRITE_DEBUG("Deleting unreferenced " + it->getTagStr() + " '" + it->getID() + "' in rebuildGNEConnections()");
743  delete it;
744  }
745  }
746  // copy retrieved (existent and created) GNECrossigns to myGNEConnections
747  myGNEConnections = retrievedConnections;
748 }
749 
750 
751 void
753  // Drop all existents connections that aren't referenced anymore
754  for (auto i : myGNEConnections) {
755  // check if connection is selected
756  if (i->isAttributeCarrierSelected()) {
757  i->unselectAttributeCarrier();
758  }
759  // Dec reference of connection
760  i->decRef("GNEEdge::clearGNEConnections");
761  // Delete GNEConnectionToErase if is unreferenced
762  if (i->unreferenced()) {
763  // show extra information for tests
764  WRITE_DEBUG("Deleting unreferenced " + i->getTagStr() + " '" + i->getID() + "' in clearGNEConnections()");
765  delete i;
766  }
767  }
768  myGNEConnections.clear();
769 }
770 
771 
772 int
774  std::vector<GNEAdditional*> routeProbes;
775  for (auto i : getAdditionalChildren()) {
776  if (i->getTagProperty().getTag() == routeProbe->getTagProperty().getTag()) {
777  routeProbes.push_back(i);
778  }
779  }
780  // return index of routeProbe in routeProbes vector
781  auto it = std::find(routeProbes.begin(), routeProbes.end(), routeProbe);
782  if (it == routeProbes.end()) {
783  return -1;
784  } else {
785  return (int)(it - routeProbes.begin());
786  }
787 }
788 
789 
790 std::vector<GNECrossing*>
792  std::vector<GNECrossing*> crossings;
793  for (auto i : myGNEJunctionSource->getGNECrossings()) {
794  if (i->checkEdgeBelong(this)) {
795  crossings.push_back(i);
796  }
797  }
798  for (auto i : myGNEJunctionDestiny->getGNECrossings()) {
799  if (i->checkEdgeBelong(this)) {
800  crossings.push_back(i);
801  }
802  }
803  return crossings;
804 }
805 
806 
807 void
809  undoList->p_begin("copy template");
814  // copy raw values for lane-specific attributes
818  // copy lane attributes as well
819  for (int i = 0; i < (int)myLanes.size(); i++) {
820  myLanes[i]->setAttribute(SUMO_ATTR_ALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ALLOW), undoList);
821  myLanes[i]->setAttribute(SUMO_ATTR_SPEED, tpl->myLanes[i]->getAttribute(SUMO_ATTR_SPEED), undoList);
822  myLanes[i]->setAttribute(SUMO_ATTR_WIDTH, tpl->myLanes[i]->getAttribute(SUMO_ATTR_WIDTH), undoList);
823  myLanes[i]->setAttribute(SUMO_ATTR_ENDOFFSET, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
824  }
825  undoList->p_end();
826 }
827 
828 
829 std::set<GUIGlID>
831  std::set<GUIGlID> result;
832  for (auto i : myLanes) {
833  result.insert(i->getGlID());
834  }
835  return result;
836 }
837 
838 
839 const std::vector<GNELane*>&
841  return myLanes;
842 }
843 
844 
845 const std::vector<GNEConnection*>&
847  return myGNEConnections;
848 }
849 
850 
851 bool
853  return myWasSplit;
854 }
855 
856 
857 std::string
859  switch (key) {
860  case SUMO_ATTR_ID:
861  return getMicrosimID();
862  case SUMO_ATTR_FROM:
864  case SUMO_ATTR_TO:
866  case SUMO_ATTR_NUMLANES:
867  return toString(myNBEdge.getNumLanes());
868  case SUMO_ATTR_PRIORITY:
869  return toString(myNBEdge.getPriority());
870  case SUMO_ATTR_LENGTH:
871  return toString(myNBEdge.getFinalLength());
872  case SUMO_ATTR_TYPE:
873  return myNBEdge.getTypeID();
874  case SUMO_ATTR_SHAPE:
878  case SUMO_ATTR_NAME:
879  return myNBEdge.getStreetName();
880  case SUMO_ATTR_ALLOW:
881  return (getVehicleClassNames(myNBEdge.getPermissions()) + (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
882  case SUMO_ATTR_DISALLOW: {
884  }
885  case SUMO_ATTR_SPEED:
887  return "lane specific";
888  } else {
889  return toString(myNBEdge.getSpeed());
890  }
891  case SUMO_ATTR_WIDTH:
893  return "lane specific";
894  } else {
895  return toString(myNBEdge.getLaneWidth());
896  }
897  case SUMO_ATTR_ENDOFFSET:
899  return "lane specific";
900  } else {
901  return toString(myNBEdge.getEndOffset());
902  }
903  case SUMO_ATTR_DISTANCE:
904  return toString(myNBEdge.getDistance());
906  return myConnectionStatus;
909  return "";
910  } else {
911  return toString(myNBEdge.getGeometry().front());
912  }
913  case GNE_ATTR_SHAPE_END:
915  return "";
916  } else {
917  return toString(myNBEdge.getGeometry().back());
918  }
919  case GNE_ATTR_BIDIR:
920  return toString(myNBEdge.isBidiRail());
921  case GNE_ATTR_SELECTED:
923  case GNE_ATTR_GENERIC:
924  return getGenericParametersStr();
925  default:
926  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
927  }
928 }
929 
930 std::string
932  std::string result = getAttribute(key);
933  if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
934  result += " " + getVehicleClassNames(SVCAll, true);
935  }
936  return result;
937 }
938 
939 void
940 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
941  switch (key) {
942  case SUMO_ATTR_WIDTH:
943  case SUMO_ATTR_ENDOFFSET:
944  case SUMO_ATTR_SPEED:
945  case SUMO_ATTR_ALLOW:
946  case SUMO_ATTR_DISALLOW: {
947  undoList->p_begin("change " + getTagStr() + " attribute");
948  const std::string origValue = myLanes.at(0)->getAttribute(key); // will have intermediate value of "lane specific"
949  // lane specific attributes need to be changed via lanes to allow undo
950  for (auto it : myLanes) {
951  it->setAttribute(key, value, undoList);
952  }
953  // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
954  undoList->p_add(new GNEChange_Attribute(this, myNet, key, value, true, origValue));
955  undoList->p_end();
956  break;
957  }
958  case SUMO_ATTR_FROM: {
959  undoList->p_begin("change " + getTagStr() + " attribute");
960  // Remove edge from crossings of junction source
962  // continue changing from junction
963  GNEJunction* oldGNEJunctionSource = myGNEJunctionSource;
964  myGNEJunctionSource->setLogicValid(false, undoList);
965  undoList->p_add(new GNEChange_Attribute(this, myNet, key, value));
966  myGNEJunctionSource->setLogicValid(false, undoList);
967  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
970  undoList->p_end();
971  // update geometries of all implicated junctions
972  oldGNEJunctionSource->updateGeometry();
975  break;
976  }
977  case SUMO_ATTR_TO: {
978  undoList->p_begin("change " + getTagStr() + " attribute");
979  // Remove edge from crossings of junction destiny
981  // continue changing destiny junction
982  GNEJunction* oldGNEJunctionDestiny = myGNEJunctionDestiny;
983  myGNEJunctionDestiny->setLogicValid(false, undoList);
984  undoList->p_add(new GNEChange_Attribute(this, myNet, key, value));
985  myGNEJunctionDestiny->setLogicValid(false, undoList);
986  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
989  undoList->p_end();
990  // update geometries of all implicated junctions
991  oldGNEJunctionDestiny->updateGeometry();
994  break;
995  }
996  case SUMO_ATTR_ID:
997  case SUMO_ATTR_PRIORITY:
998  case SUMO_ATTR_LENGTH:
999  case SUMO_ATTR_TYPE:
1000  case SUMO_ATTR_SPREADTYPE:
1001  case SUMO_ATTR_DISTANCE:
1003  case GNE_ATTR_SHAPE_START:
1004  case GNE_ATTR_SHAPE_END:
1005  case GNE_ATTR_SELECTED:
1006  case GNE_ATTR_GENERIC:
1007  undoList->p_add(new GNEChange_Attribute(this, myNet, key, value));
1008  break;
1009  case SUMO_ATTR_NAME:
1010  // user cares about street names. Make sure they appear in the output
1012  OptionsCont::getOptions().set("output.street-names", "true");
1013  undoList->p_add(new GNEChange_Attribute(this, myNet, key, value));
1014  break;
1015  case SUMO_ATTR_NUMLANES:
1016  if (value != getAttribute(key)) {
1017  // Remove edge from crossings of junction source
1019  // Remove edge from crossings of junction destiny
1021  // set num lanes
1022  setNumLanes(parse<int>(value), undoList);
1023  }
1024  break;
1025  case SUMO_ATTR_SHAPE:
1026  // @note: assumes value of inner geometry!
1027  // actually the geometry is already updated (incrementally
1028  // during mouse movement). We set the restore point to the end
1029  // of the last change-set
1030  undoList->p_add(new GNEChange_Attribute(this, myNet, key, value));
1031  break;
1032  case GNE_ATTR_BIDIR:
1033  throw InvalidArgument("Attribute of '" + toString(key) + "' cannot be modified");
1034  default:
1035  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1036  }
1037 }
1038 
1039 
1040 bool
1041 GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
1042  switch (key) {
1043  case SUMO_ATTR_ID:
1044  return SUMOXMLDefinitions::isValidNetID(value) && (myNet->retrieveEdge(value, false) == nullptr);
1045  case SUMO_ATTR_FROM: {
1046  // check that is a valid ID and is different of ID of junction destiny
1048  GNEJunction* junctionFrom = myNet->retrieveJunction(value, false);
1049  // check that there isn't already another edge with the same From and To Edge
1050  if ((junctionFrom != nullptr) && (myNet->retrieveEdge(junctionFrom, myGNEJunctionDestiny, false) == nullptr)) {
1051  return true;
1052  } else {
1053  return false;
1054  }
1055  } else {
1056  return false;
1057  }
1058  }
1059  case SUMO_ATTR_TO: {
1060  // check that is a valid ID and is different of ID of junction Source
1062  GNEJunction* junctionTo = myNet->retrieveJunction(value, false);
1063  // check that there isn't already another edge with the same From and To Edge
1064  if ((junctionTo != nullptr) && (myNet->retrieveEdge(myGNEJunctionSource, junctionTo, false) == nullptr)) {
1065  return true;
1066  } else {
1067  return false;
1068  }
1069  } else {
1070  return false;
1071  }
1072  }
1073  case SUMO_ATTR_SPEED:
1074  return canParse<double>(value) && (parse<double>(value) > 0);
1075  case SUMO_ATTR_NUMLANES:
1076  return canParse<int>(value) && (parse<double>(value) > 0);
1077  case SUMO_ATTR_PRIORITY:
1078  return canParse<int>(value);
1079  case SUMO_ATTR_LENGTH:
1080  return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH));
1081  case SUMO_ATTR_ALLOW:
1082  case SUMO_ATTR_DISALLOW:
1083  return canParseVehicleClasses(value);
1084  case SUMO_ATTR_TYPE:
1085  return true;
1086  case SUMO_ATTR_SHAPE:
1087  // empty shapes are allowed
1088  return canParse<PositionVector>(value);
1089  case SUMO_ATTR_SPREADTYPE:
1091  case SUMO_ATTR_NAME:
1092  return true;
1093  case SUMO_ATTR_WIDTH:
1094  return canParse<double>(value) && ((parse<double>(value) >= -1) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
1095  case SUMO_ATTR_ENDOFFSET:
1096  return canParse<double>(value) && parse<double>(value) >= 0 && parse<double>(value) < myNBEdge.getLoadedLength();
1097  case SUMO_ATTR_DISTANCE:
1098  return canParse<double>(value);
1099  case GNE_ATTR_SHAPE_START: {
1100  if (value.empty()) {
1101  return true;
1102  } else if (canParse<Position>(value)) {
1103  Position shapeStart = parse<Position>(value);
1104  return (shapeStart != myNBEdge.getGeometry()[-1]);
1105  } else {
1106  return false;
1107  }
1108  }
1109  case GNE_ATTR_SHAPE_END: {
1110  if (value.empty()) {
1111  return true;
1112  } else if (canParse<Position>(value)) {
1113  Position shapeEnd = parse<Position>(value);
1114  return (shapeEnd != myNBEdge.getGeometry()[0]);
1115  } else {
1116  return false;
1117  }
1118  }
1119  case GNE_ATTR_BIDIR:
1120  return false;
1121  case GNE_ATTR_SELECTED:
1122  return canParse<bool>(value);
1123  case GNE_ATTR_GENERIC:
1124  return isGenericParametersValid(value);
1125  default:
1126  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1127  }
1128 }
1129 
1130 
1131 std::string
1133  std::string result;
1134  // Generate an string using the following structure: "key1=value1|key2=value2|...
1135  for (auto i : myNBEdge.getParametersMap()) {
1136  result += i.first + "=" + i.second + "|";
1137  }
1138  // remove the last "|"
1139  if (!result.empty()) {
1140  result.pop_back();
1141  }
1142  return result;
1143 }
1144 
1145 
1146 std::vector<std::pair<std::string, std::string> >
1148  std::vector<std::pair<std::string, std::string> > result;
1149  // iterate over parameters map and fill result
1150  for (auto i : myNBEdge.getParametersMap()) {
1151  result.push_back(std::make_pair(i.first, i.second));
1152  }
1153  return result;
1154 }
1155 
1156 
1157 void
1158 GNEEdge::setGenericParametersStr(const std::string& value) {
1159  // clear parameters
1161  // separate value in a vector of string using | as separator
1162  std::vector<std::string> parsedValues;
1163  StringTokenizer stValues(value, "|", true);
1164  while (stValues.hasNext()) {
1165  parsedValues.push_back(stValues.next());
1166  }
1167  // check that parsed values (A=B)can be parsed in generic parameters
1168  for (auto i : parsedValues) {
1169  std::vector<std::string> parsedParameters;
1170  StringTokenizer stParam(i, "=", true);
1171  while (stParam.hasNext()) {
1172  parsedParameters.push_back(stParam.next());
1173  }
1174  // Check that parsed parameters are exactly two and contains valid chracters
1175  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1176  myNBEdge.setParameter(parsedParameters.front(), parsedParameters.back());
1177  }
1178  }
1179 }
1180 
1181 
1182 void
1184  myAmResponsible = newVal;
1185 }
1186 
1187 
1188 GNELane*
1190  // iterate over all NBEdge lanes
1191  for (int i = 0; i < (int)myNBEdge.getLanes().size(); i++) {
1192  // if given VClass is in permissions, return lane
1193  if (myNBEdge.getLanes().at(i).permissions & vClass) {
1194  // return GNELane
1195  return myLanes.at(i);
1196  }
1197  }
1198  // return first lane
1199  return myLanes.front();
1200 }
1201 
1202 
1203 GNELane*
1204 GNEEdge::getLaneByVClass(const SUMOVehicleClass vClass, bool& found) const {
1205  // iterate over all NBEdge lanes
1206  for (int i = 0; i < (int)myNBEdge.getLanes().size(); i++) {
1207  // if given VClass is in permissions, return lane
1208  if (myNBEdge.getLanes().at(i).permissions & vClass) {
1209  // change found flag to true
1210  found = true;
1211  // return GNELane
1212  return myLanes.at(i);
1213  }
1214  }
1215  // change found flag to false
1216  found = false;
1217  // return first lane
1218  return myLanes.front();
1219 }
1220 
1221 
1222 void
1223 GNEEdge::drawPartialRoute(const GUIVisualizationSettings& s, const GNEDemandElement* route, const GNEJunction* junction) const {
1224  // calculate route width
1225  double routeWidth = s.addSize.getExaggeration(s, this) * s.widthSettings.route;
1226  // obtain color
1227  RGBColor routeColor;
1228  if (route->drawUsingSelectColor()) {
1229  routeColor = s.colorSettings.selectedRouteColor;
1230  } else {
1231  routeColor = route->getColor();
1232  }
1233  // Start drawing adding an gl identificator
1234  glPushName(route->getGlID());
1235  // Add a draw matrix
1236  glPushMatrix();
1237  // Start with the drawing of the area traslating matrix to origin
1238  glTranslated(0, 0, route->getType());
1239  // draw route
1240  if (junction) {
1241  // iterate over segments
1242  for (auto segment = route->getDemandElementSegmentGeometry().begin(); segment != route->getDemandElementSegmentGeometry().end(); segment++) {
1243  // draw partial segment
1244  if ((segment->junction == junction) && (segment->element == route) && segment->visible) {
1245  // Set route color (needed due drawShapeDottedContour)
1246  GLHelper::setColor(routeColor);
1247  // draw box line
1248  GLHelper::drawBoxLine(segment->pos, segment->rotation, segment->length, routeWidth, 0);
1249  // check if shape dotted contour has to be drawn
1250  if ((myNet->getViewNet()->getDottedAC() == route) && ((segment + 1) != route->getDemandElementSegmentGeometry().end())) {
1251  GLHelper::drawShapeDottedContourPartialShapes(s, getType(), segment->pos, (segment + 1)->pos, routeWidth);
1252  }
1253  }
1254  }
1255  } else {
1256  // iterate over segments
1257  for (auto segment = route->getDemandElementSegmentGeometry().begin(); segment != route->getDemandElementSegmentGeometry().end(); segment++) {
1258  // draw partial segment
1259  if ((segment->edge == this) && (segment->element == route) && segment->visible) {
1260  // Set route color (needed due drawShapeDottedContour)
1261  GLHelper::setColor(routeColor);
1262  // draw box line
1263  GLHelper::drawBoxLine(segment->pos, segment->rotation, segment->length, routeWidth, 0);
1264  // check if shape dotted contour has to be drawn
1265  if ((myNet->getViewNet()->getDottedAC() == route) && ((segment + 1) != route->getDemandElementSegmentGeometry().end())) {
1266  GLHelper::drawShapeDottedContourPartialShapes(s, getType(), segment->pos, (segment + 1)->pos, routeWidth);
1267  }
1268  }
1269  }
1270  }
1271  // Pop last matrix
1272  glPopMatrix();
1273  // Draw name if isn't being drawn for selecting
1274  if (!s.drawForSelecting) {
1275  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
1276  }
1277  // Pop name
1278  glPopName();
1279  // draw route children
1280  for (const auto& i : route->getDemandElementChildren()) {
1281  if (i->getTagProperty().getTag() == SUMO_TAG_WALK_ROUTE) {
1282  drawPartialPersonPlan(s, i, junction);
1283  } else {
1284  i->drawGL(s);
1285  }
1286  }
1287  // special case for embedded routes
1288  if ((route->getTagProperty().getTag() == SUMO_TAG_EMBEDDEDROUTE) && (route->getEdgeParents().front() == this)) {
1289  // draw vehicle parent
1290  route->getDemandElementParents().at(0)->drawGL(s);
1291  }
1292 }
1293 
1294 
1295 void
1296 GNEEdge::drawPartialTripFromTo(const GUIVisualizationSettings& s, const GNEDemandElement* tripOrFromTo, const GNEJunction* junction) const {
1297  // calculate tripOrFromTo width
1298  double tripOrFromToWidth = s.addSize.getExaggeration(s, this) * s.widthSettings.trip;
1299  // Add a draw matrix
1300  glPushMatrix();
1301  // Start with the drawing of the area traslating matrix to origin
1302  glTranslated(0, 0, tripOrFromTo->getType());
1303  // Set color of the base
1304  if (tripOrFromTo->drawUsingSelectColor()) {
1306  } else {
1308  }
1309  // draw trip from to
1310  if (junction) {
1311  // iterate over segments
1312  for (auto segment = tripOrFromTo->getDemandElementSegmentGeometry().begin(); segment != tripOrFromTo->getDemandElementSegmentGeometry().end(); segment++) {
1313  // draw partial segment
1314  if ((segment->junction == junction) && (segment->element == tripOrFromTo) && segment->visible) {
1315  GLHelper::drawBoxLine(segment->pos, segment->rotation, segment->length, tripOrFromToWidth, 0);
1316  }
1317  }
1318  } else {
1319  // iterate over segments
1320  for (auto segment = tripOrFromTo->getDemandElementSegmentGeometry().begin(); segment != tripOrFromTo->getDemandElementSegmentGeometry().end(); segment++) {
1321  // draw partial segment
1322  if ((segment->edge == this) && (segment->element == tripOrFromTo) && segment->visible) {
1323  GLHelper::drawBoxLine(segment->pos, segment->rotation, segment->length, tripOrFromToWidth, 0);
1324  }
1325  }
1326  }
1327  // Pop last matrix
1328  glPopMatrix();
1329  // Draw name if isn't being drawn for selecting
1330  if (!s.drawForSelecting) {
1331  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
1332  }
1333  // Pop name
1334  glPopName();
1335 }
1336 
1337 
1338 void
1339 GNEEdge::drawPartialPersonPlan(const GUIVisualizationSettings& s, const GNEDemandElement* personPlan, const GNEJunction* junction) const {
1340  // declare flag to enable or disable draw person plan
1341  bool drawPersonPlan = false;
1343  drawPersonPlan = true;
1344  } else if (myNet->getViewNet()->getDottedAC() == personPlan->getDemandElementParents().front()) {
1345  drawPersonPlan = true;
1346  } else if (myNet->getViewNet()->getDemandViewOptions().getLockedPerson() == personPlan->getDemandElementParents().front()) {
1347  drawPersonPlan = true;
1350  drawPersonPlan = true;
1351  }
1352  // check if draw person plan elements can be drawn
1353  if (drawPersonPlan) {
1354  // calculate personPlan width
1355  double personPlanWidth = 0;
1356  // flag to check if width must be duplicated
1357  bool duplicateWidth = (myNet->getViewNet()->getDottedAC() == personPlan) || (myNet->getViewNet()->getDottedAC() == personPlan->getDemandElementParents().front()) ? true : false;
1358  // Set width depending of person plan type
1359  if (personPlan->getTagProperty().isPersonTrip()) {
1360  personPlanWidth = s.addSize.getExaggeration(s, this) * s.widthSettings.personTrip;
1361  } else if (personPlan->getTagProperty().isWalk()) {
1362  personPlanWidth = s.addSize.getExaggeration(s, this) * s.widthSettings.walk;
1363  } else if (personPlan->getTagProperty().isRide()) {
1364  personPlanWidth = s.addSize.getExaggeration(s, this) * s.widthSettings.ride;
1365  }
1366  // check if width has to be duplicated
1367  if (duplicateWidth) {
1368  personPlanWidth *= 2;
1369  }
1370  // set personPlan color
1371  RGBColor personPlanColor;
1372  // Set color depending of person plan type
1373  if (personPlan->drawUsingSelectColor()) {
1374  personPlanColor = s.colorSettings.selectedPersonPlanColor;
1375  } else if (personPlan->getTagProperty().isPersonTrip()) {
1376  personPlanColor = s.colorSettings.personTrip;
1377  } else if (personPlan->getTagProperty().isWalk()) {
1378  personPlanColor = s.colorSettings.walk;
1379  } else if (personPlan->getTagProperty().isRide()) {
1380  personPlanColor = s.colorSettings.ride;
1381  }
1382  // Start drawing adding an gl identificator
1383  glPushName(personPlan->getGlID());
1384  // Add a draw matrix
1385  glPushMatrix();
1386  // Start with the drawing of the area traslating matrix to origin
1387  glTranslated(0, 0, personPlan->getType());
1388  // draw person plan
1389  if (junction) {
1390  // iterate over segments
1391  for (auto segment = personPlan->getDemandElementParents().front()->getDemandElementSegmentGeometry().begin();
1392  segment != personPlan->getDemandElementParents().front()->getDemandElementSegmentGeometry().end();
1393  segment++) {
1394  // draw partial segment
1395  if ((segment->junction == junction) && (segment->element == personPlan) && segment->visible) {
1396  // Set person plan color (needed due drawShapeDottedContour)
1397  GLHelper::setColor(personPlanColor);
1398  // draw box line
1399  GLHelper::drawBoxLine(segment->pos, segment->rotation, segment->length, personPlanWidth, 0);
1400  // check if shape dotted contour has to be drawn
1401  if ((myNet->getViewNet()->getDottedAC() == personPlan) && ((segment + 1) != personPlan->getDemandElementParents().front()->getDemandElementSegmentGeometry().end())) {
1402  GLHelper::drawShapeDottedContourPartialShapes(s, getType(), segment->pos, (segment + 1)->pos, personPlanWidth);
1403  }
1404  }
1405  }
1406  } else {
1407  // iterate over segments
1408  for (auto segment = personPlan->getDemandElementParents().front()->getDemandElementSegmentGeometry().begin();
1409  segment != personPlan->getDemandElementParents().front()->getDemandElementSegmentGeometry().end();
1410  segment++) {
1411  // draw partial segment
1412  if ((segment->edge == this) && (segment->element == personPlan) && segment->visible) {
1413  // Set person plan color (needed due drawShapeDottedContour)
1414  GLHelper::setColor(personPlanColor);
1415  // draw box line
1416  GLHelper::drawBoxLine(segment->pos, segment->rotation, segment->length, personPlanWidth, 0);
1417  // check if shape dotted contour has to be drawn
1418  if ((myNet->getViewNet()->getDottedAC() == personPlan) && ((segment + 1) != personPlan->getDemandElementParents().front()->getDemandElementSegmentGeometry().end())) {
1419  GLHelper::drawShapeDottedContourPartialShapes(s, getType(), segment->pos, (segment + 1)->pos, personPlanWidth);
1420  }
1421  }
1422  }
1423  }
1424  // Pop last matrix
1425  glPopMatrix();
1426  // Draw name if isn't being drawn for selecting
1427  if (!s.drawForSelecting) {
1428  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
1429  }
1430  // Pop name
1431  glPopName();
1432  // check if person plan ArrivalPos attribute
1433  if (personPlan->getTagProperty().hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1434  // obtain arrival position
1435  double arrivalPos = personPlan->getAttributeDouble(SUMO_ATTR_ARRIVALPOS);
1436  // only draw arrival position point if isn't -1
1437  if (arrivalPos != -1) {
1438  // get lane in which arrival position will be drawn
1439  SUMOVehicleClass vClassPersonPlan = personPlan->getTagProperty().isRide() ? SVC_PASSENGER : SVC_PEDESTRIAN;
1440  GNELane* arrivalPosLane = nullptr;
1441  // obtain arrivalPosLane depending if pesonPlan is a walk over a route
1442  if (personPlan->getTagProperty().getTag() == SUMO_TAG_WALK_ROUTE) {
1443  arrivalPosLane = personPlan->getDemandElementParents().at(1)->getEdgeParents().back()->getLaneByVClass(vClassPersonPlan);
1444  } else {
1445  arrivalPosLane = personPlan->getEdgeParents().back()->getLaneByVClass(vClassPersonPlan);
1446  }
1447  // obtain position or ArrivalPos
1448  Position pos = arrivalPosLane->getGeometry().shape.positionAtOffset2D(arrivalPos);
1449  // obtain circle width
1450  double circleWidth = (duplicateWidth ? SNAP_RADIUS : (SNAP_RADIUS / 2.0)) * MIN2((double)0.5, s.laneWidthExaggeration);
1451  double circleWidthSquared = circleWidth * circleWidth;
1452  if (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(pos) <= (circleWidthSquared + 2))) {
1453  glPushMatrix();
1454  // translate to pos and move to upper using GLO_PERSONTRIP (to avoid overlapping)
1455  glTranslated(pos.x(), pos.y(), GLO_PERSONTRIP + 0.01);
1456  // Set color depending of person plan type
1457  if (personPlan->drawUsingSelectColor()) {
1459  } else if (personPlan->getTagProperty().isPersonTrip()) {
1461  } else if (personPlan->getTagProperty().isWalk()) {
1463  } else if (personPlan->getTagProperty().isRide()) {
1465  }
1466  // resolution of drawn circle depending of the zoom (To improve smothness)
1468  glPopMatrix();
1469  }
1470  }
1471  }
1472  // draw personPlan children
1473  for (const auto& i : personPlan->getDemandElementChildren()) {
1474  i->drawGL(s);
1475  }
1476  }
1477  // draw person if this edge correspond to the first edge of first Person's person plan
1478  GNEEdge* firstEdge = nullptr;
1479  if (personPlan->getDemandElementParents().front()->getDemandElementChildren().front()->getTagProperty().isPersonStop()) {
1480  if (personPlan->getDemandElementParents().front()->getDemandElementChildren().front()->getTagProperty().getTag() == SUMO_TAG_PERSONSTOP_LANE) {
1481  // obtain edge of lane parent
1482  firstEdge = &personPlan->getDemandElementParents().front()->getDemandElementChildren().front()->getLaneParents().front()->getParentEdge();
1483  } else {
1484  // obtain edge of busstop's lane parent
1485  firstEdge = &personPlan->getDemandElementParents().front()->getDemandElementChildren().front()->getAdditionalParents().front()->getLaneParents().front()->getParentEdge();
1486  }
1487  } else if (personPlan->getDemandElementParents().front()->getDemandElementChildren().front()->getTagProperty().getTag() == SUMO_TAG_WALK_ROUTE) {
1488  // obtain first rute edge
1489  firstEdge = personPlan->getDemandElementParents().at(1)->getEdgeParents().front();
1490  } else {
1491  // obtain first edge parent
1492  firstEdge = personPlan->getDemandElementParents().front()->getDemandElementChildren().front()->getEdgeParents().front();
1493  }
1494  // draw person parent if this is the edge first edge and this is the first plan
1495  if ((firstEdge == this) && personPlan->getDemandElementParents().front()->getDemandElementChildren().front() == personPlan) {
1496  personPlan->getDemandElementParents().front()->drawGL(s);
1497  }
1498 }
1499 
1500 // ===========================================================================
1501 // private
1502 // ===========================================================================
1503 
1504 void
1505 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
1506  switch (key) {
1507  case SUMO_ATTR_ID:
1508  myNet->renameEdge(this, value);
1509  break;
1510  case SUMO_ATTR_FROM:
1512  // update this edge of list of outgoings edges of the old GNEJunctionSource
1514  // update GNEJunctionSource
1516  // update this edge of list of outgoings edges of the new GNEJunctionSource
1518  break;
1519  case SUMO_ATTR_TO:
1521  // update this edge of list of incomings edges of the old GNEJunctionDestiny
1523  // update GNEJunctionDestiny
1525  // update this edge of list of incomings edges of the new GNEJunctionDestiny
1527  break;
1528  case SUMO_ATTR_NUMLANES:
1529  throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
1530  break;
1531  case SUMO_ATTR_PRIORITY:
1532  myNBEdge.myPriority = parse<int>(value);
1533  break;
1534  case SUMO_ATTR_LENGTH:
1535  myNBEdge.setLoadedLength(parse<double>(value));
1536  break;
1537  case SUMO_ATTR_TYPE:
1538  myNBEdge.myType = value;
1539  break;
1540  case SUMO_ATTR_SHAPE:
1541  // start geometry moving (because a new shape affect all edge children)
1543  // set new geometry
1544  setGeometry(parse<PositionVector>(value), true);
1545  // start geometry moving (because a new shape affect all edge children)
1547  break;
1548  case SUMO_ATTR_SPREADTYPE:
1550  break;
1551  case SUMO_ATTR_NAME:
1552  myNBEdge.setStreetName(value);
1553  break;
1554  case SUMO_ATTR_SPEED:
1555  myNBEdge.setSpeed(-1, parse<double>(value));
1556  break;
1557  case SUMO_ATTR_WIDTH:
1558  myNBEdge.setLaneWidth(-1, parse<double>(value));
1559  break;
1560  case SUMO_ATTR_ENDOFFSET:
1561  myNBEdge.setEndOffset(-1, parse<double>(value));
1562  break;
1563  case SUMO_ATTR_ALLOW:
1564  break; // no edge value
1565  case SUMO_ATTR_DISALLOW:
1566  break; // no edge value
1567  case SUMO_ATTR_DISTANCE:
1568  myNBEdge.setDistance(parse<double>(value));
1569  break;
1571  myConnectionStatus = value;
1572  if (value == FEATURE_GUESSED) {
1573  WRITE_DEBUG("invalidating (removing) connections of edge '" + getID() + "' due it were guessed");
1576  } else if (value != FEATURE_GUESSED) {
1577  WRITE_DEBUG("declaring connections of edge '" + getID() + "' as loaded (It will not be removed)");
1579  }
1580  break;
1581  case GNE_ATTR_SHAPE_START: {
1582  // get geometry of NBEdge, remove FIRST element with the new value (or with the Junction Source position) and set it back to edge
1583  Position newShapeStart;
1584  if (value == "") {
1585  newShapeStart = myGNEJunctionSource->getPositionInView();
1586  } else {
1587  newShapeStart = parse<Position>(value);
1588  }
1589  // start geometry moving (because a new shape affect all edge children)
1591  // set shape start position
1592  setShapeStartPos(newShapeStart);
1593  // end geometry moving
1595  break;
1596  }
1597  case GNE_ATTR_SHAPE_END: {
1598  // get geometry of NBEdge, remove LAST element with the new value (or with the Junction Destiny position) and set it back to edge
1599  Position newShapeEnd;
1600  if (value == "") {
1601  newShapeEnd = myGNEJunctionDestiny->getPositionInView();
1602  } else {
1603  newShapeEnd = parse<Position>(value);
1604  }
1605  // start geometry moving (because a new shape affect all edge children)
1607  // set shape end position
1608  setShapeEndPos(newShapeEnd);
1609  // end geometry moving
1611  break;
1612  }
1613  case GNE_ATTR_BIDIR:
1614  throw InvalidArgument("Attribute of '" + toString(key) + "' cannot be modified");
1615  case GNE_ATTR_SELECTED:
1616  if (parse<bool>(value)) {
1618  } else {
1620  }
1621  break;
1622  case GNE_ATTR_GENERIC:
1623  setGenericParametersStr(value);
1624  break;
1625  default:
1626  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1627  }
1628 }
1629 
1630 
1631 void
1632 GNEEdge::setNumLanes(int numLanes, GNEUndoList* undoList) {
1633  undoList->p_begin("change number of " + toString(SUMO_TAG_LANE) + "s");
1634  myGNEJunctionSource->setLogicValid(false, undoList);
1635  myGNEJunctionDestiny->setLogicValid(false, undoList);
1636 
1637  const int oldNumLanes = (int)myLanes.size();
1638  for (int i = oldNumLanes; i < numLanes; i++) {
1639  // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
1640  undoList->add(new GNEChange_Lane(this, nullptr,
1641  myNBEdge.getLaneStruct(oldNumLanes - 1), true), true);
1642  }
1643  for (int i = oldNumLanes - 1; i > numLanes - 1; i--) {
1644  // delete leftmost lane
1645  undoList->add(new GNEChange_Lane(this, myLanes[i], myNBEdge.getLaneStruct(i), false), true);
1646  }
1647  undoList->p_end();
1648 }
1649 
1650 
1651 void
1652 GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs, bool recomputeConnections) {
1653  // boundary of edge depends of number of lanes. We need to extract if before add or remove lane
1655  const int index = lane ? lane->getIndex() : myNBEdge.getNumLanes();
1656  // the laneStruct must be created first to ensure we have some geometry
1657  // unless the connections are fully recomputed, existing indices must be shifted
1658  myNBEdge.addLane(index, true, recomputeConnections, !recomputeConnections);
1659  if (lane) {
1660  // restore a previously deleted lane
1661  myLanes.insert(myLanes.begin() + index, lane);
1662 
1663  } else {
1664  // create a new lane by copying leftmost lane
1665  lane = new GNELane(*this, index);
1666  myLanes.push_back(lane);
1667  }
1668  lane->incRef("GNEEdge::addLane");
1669  // check if lane is selected
1670  if (lane->isAttributeCarrierSelected()) {
1671  lane->selectAttributeCarrier();
1672  }
1673  // we copy all attributes except shape since this is recomputed from edge shape
1674  myNBEdge.setSpeed(lane->getIndex(), laneAttrs.speed);
1675  myNBEdge.setPermissions(laneAttrs.permissions, lane->getIndex());
1677  myNBEdge.setEndOffset(lane->getIndex(), laneAttrs.endOffset);
1678  myNBEdge.setLaneWidth(lane->getIndex(), laneAttrs.width);
1679  // udate indices
1680  for (int i = 0; i < (int)myLanes.size(); ++i) {
1681  myLanes[i]->setIndex(i);
1682  }
1683  /* while technically correct, this looks ugly
1684  myGNEJunctionSource->invalidateShape();
1685  myGNEJunctionDestiny->invalidateShape();
1686  */
1687  // Remake connections for this edge and all edges that target this lane
1689  // remake connections of all edges of junction source and destiny
1690  for (auto i : myGNEJunctionSource->getGNEEdges()) {
1691  i->remakeGNEConnections();
1692  }
1693  // remake connections of all edges of junction source and destiny
1694  for (auto i : myGNEJunctionDestiny->getGNEEdges()) {
1695  i->remakeGNEConnections();
1696  }
1697  // add object again
1698  myNet->addGLObjectIntoGrid(this);
1699  // Update geometry with the new lane
1700  updateGeometry();
1701 }
1702 
1703 
1704 void
1705 GNEEdge::removeLane(GNELane* lane, bool recomputeConnections) {
1706  // boundary of edge depends of number of lanes. We need to extract if before add or remove lane
1708  if (myLanes.size() == 0) {
1709  throw ProcessError("Should not remove the last " + toString(SUMO_TAG_LANE) + " from an " + getTagStr());
1710  }
1711  if (lane == nullptr) {
1712  lane = myLanes.back();
1713  }
1714  // check if lane is selected
1715  if (lane->isAttributeCarrierSelected()) {
1716  lane->unselectAttributeCarrier();
1717  }
1718  // Delete lane of edge's container
1719  // unless the connections are fully recomputed, existing indices must be shifted
1720  myNBEdge.deleteLane(lane->getIndex(), recomputeConnections, !recomputeConnections);
1721  lane->decRef("GNEEdge::removeLane");
1722  myLanes.erase(myLanes.begin() + lane->getIndex());
1723  // Delete lane if is unreferenced
1724  if (lane->unreferenced()) {
1725  // show extra information for tests
1726  WRITE_DEBUG("Deleting unreferenced " + lane->getTagStr() + " '" + lane->getID() + "' in removeLane()");
1727  delete lane;
1728  }
1729  // udate indices
1730  for (int i = 0; i < (int)myLanes.size(); ++i) {
1731  myLanes[i]->setIndex(i);
1732  }
1733  /* while technically correct, this looks ugly
1734  myGNEJunctionSource->invalidateShape();
1735  myGNEJunctionDestiny->invalidateShape();
1736  */
1737  // Remake connections of this edge
1739  // remake connections of all edges of junction source and destiny
1740  for (auto i : myGNEJunctionSource->getGNEEdges()) {
1741  i->remakeGNEConnections();
1742  }
1743  // remake connections of all edges of junction source and destiny
1744  for (auto i : myGNEJunctionDestiny->getGNEEdges()) {
1745  i->remakeGNEConnections();
1746  }
1747  // add object again
1748  myNet->addGLObjectIntoGrid(this);
1749  // Update element
1750  updateGeometry();
1751 }
1752 
1753 
1754 void
1755 GNEEdge::addConnection(NBEdge::Connection nbCon, bool selectAfterCreation) {
1756  // If a new connection was sucesfully created
1757  if (myNBEdge.setConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, NBEdge::L2L_USER, true, nbCon.mayDefinitelyPass,
1758  nbCon.keepClear, nbCon.contPos, nbCon.visibility,
1759  nbCon.speed, nbCon.customShape, nbCon.uncontrolled)) {
1760  // Create or retrieve existent GNEConection
1761  GNEConnection* con = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane);
1762  // add it to GNEConnection container
1763  myGNEConnections.push_back(con);
1764  // Add reference
1765  myGNEConnections.back()->incRef("GNEEdge::addConnection");
1766  // select GNEConnection if needed
1767  if (selectAfterCreation) {
1768  con->selectAttributeCarrier();
1769  }
1770  // update geometry
1771  con->updateGeometry();
1772  // iterate over all additionals from "from" lane and check E2 multilane integrity
1773  for (auto i : con->getLaneFrom()->getAdditionalChildren()) {
1774  if (i->getTagProperty().getTag() == SUMO_TAG_E2DETECTOR_MULTILANE) {
1775  dynamic_cast<GNEDetectorE2*>(i)->checkE2MultilaneIntegrity();
1776  }
1777  }
1778  // iterate over all additionals from "to" lane and check E2 multilane integrity
1779  for (auto i : con->getLaneTo()->getAdditionalChildren()) {
1780  if (i->getTagProperty().getTag() == SUMO_TAG_E2DETECTOR_MULTILANE) {
1781  dynamic_cast<GNEDetectorE2*>(i)->checkE2MultilaneIntegrity();
1782  }
1783  }
1784  }
1785  // actually we only do this to force a redraw
1786  updateGeometry();
1787 }
1788 
1789 
1790 void
1792  // check if is a explicit turnaround
1793  if (nbCon.toEdge == myNBEdge.getTurnDestination()) {
1795  }
1796  // remove NBEdge::connection from NBEdge
1798  // remove their associated GNEConnection
1799  GNEConnection* con = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, false);
1800  if (con != nullptr) {
1801  con->decRef("GNEEdge::removeConnection");
1802  myGNEConnections.erase(std::find(myGNEConnections.begin(), myGNEConnections.end(), con));
1803  // iterate over all additionals from "from" lane and check E2 multilane integrity
1804  for (auto i : con->getLaneFrom()->getAdditionalChildren()) {
1805  if (i->getTagProperty().getTag() == SUMO_TAG_E2DETECTOR_MULTILANE) {
1806  dynamic_cast<GNEDetectorE2*>(i)->checkE2MultilaneIntegrity();
1807  }
1808  }
1809  // iterate over all additionals from "to" lane and check E2 multilane integrity
1810  for (auto i : con->getLaneTo()->getAdditionalChildren()) {
1811  if (i->getTagProperty().getTag() == SUMO_TAG_E2DETECTOR_MULTILANE) {
1812  dynamic_cast<GNEDetectorE2*>(i)->checkE2MultilaneIntegrity();
1813  }
1814  }
1815  // check if connection is selected
1816  if (con->isAttributeCarrierSelected()) {
1817  con->unselectAttributeCarrier();
1818  }
1819  if (con->unreferenced()) {
1820  // show extra information for tests
1821  WRITE_DEBUG("Deleting unreferenced " + con->getTagStr() + " '" + con->getID() + "' in removeConnection()");
1822  delete con;
1823  // actually we only do this to force a redraw
1824  updateGeometry();
1825  }
1826  }
1827 }
1828 
1829 
1831 GNEEdge::retrieveGNEConnection(int fromLane, NBEdge* to, int toLane, bool createIfNoExist) {
1832  for (auto i : myGNEConnections) {
1833  if ((i->getFromLaneIndex() == fromLane) && (i->getEdgeTo()->getNBEdge() == to) && (i->getToLaneIndex() == toLane)) {
1834  return i;
1835  }
1836  }
1837  if (createIfNoExist) {
1838  // create new connection. Will be added to the rTree on first geometry computation
1839  GNEConnection* createdConnection = new GNEConnection(myLanes[fromLane], myNet->retrieveEdge(to->getID())->getLanes()[toLane]);
1840  // show extra information for tests
1841  WRITE_DEBUG("Created " + createdConnection->getTagStr() + " '" + createdConnection->getID() + "' in retrieveGNEConnection()");
1842  // iterate over all additionals from "from" lane and check E2 multilane integrity
1843  for (auto i : createdConnection->getLaneFrom()->getAdditionalChildren()) {
1844  if (i->getTagProperty().getTag() == SUMO_TAG_E2DETECTOR_MULTILANE) {
1845  dynamic_cast<GNEDetectorE2*>(i)->checkE2MultilaneIntegrity();
1846  }
1847  }
1848  // iterate over all additionals from "to" lane and check E2 multilane integrity
1849  for (auto i : createdConnection->getLaneTo()->getAdditionalChildren()) {
1850  if (i->getTagProperty().getTag() == SUMO_TAG_E2DETECTOR_MULTILANE) {
1851  dynamic_cast<GNEDetectorE2*>(i)->checkE2MultilaneIntegrity();
1852  }
1853  }
1854  return createdConnection;
1855  } else {
1856  return nullptr;
1857  }
1858 }
1859 
1860 
1861 
1862 void
1863 GNEEdge::setMicrosimID(const std::string& newID) {
1865  for (auto i : myLanes) {
1866  i->setMicrosimID(getNBEdge()->getLaneID(i->getIndex()));
1867  }
1868 }
1869 
1870 
1871 bool
1873  for (auto i : myLanes) {
1874  if (i->isRestricted(vclass)) {
1875  return true;
1876  }
1877  }
1878  return false;
1879 }
1880 
1881 
1882 void
1884  // Remove all crossings that contain this edge in parameter "edges"
1885  for (GNECrossing* const i : junction->getGNECrossings()) {
1886  if (i->checkEdgeBelong(this)) {
1887  myNet->deleteCrossing(i, undoList);
1888  }
1889  }
1890 }
1891 
1892 
1893 void
1895  PositionVector modifiedShape = myNBEdge.getGeometry().interpolateZ(
1897  myNBEdge.getToNode()->getPosition().z());
1898  PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
1899  setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
1900 }
1901 
1902 
1904 GNEEdge::smoothShape(const PositionVector& old, bool forElevation) {
1905  const OptionsCont& oc = OptionsCont::getOptions();
1906  // distinguish 3 cases:
1907  // a) if the edge has exactly 3 or 4 points, use these as control points
1908  // b) if the edge has more than 4 points, use the first 2 and the last 2 as control points
1909  // c) if the edge is straight and both nodes are geometry-like nodes, use geometry of the continuation edges as control points
1910  PositionVector init;
1911 #ifdef DEBUG_SMOOTH_GEOM
1912  if (DEBUGCOND(this)) std::cout << getID()
1913  << " forElevation=" << forElevation
1914  << " fromGeometryLike=" << myNBEdge.getFromNode()->geometryLike()
1915  << " toGeometryLike=" << myNBEdge.getToNode()->geometryLike()
1916  << " smoothShape old=" << old << "\n";
1917 #endif
1918  if (old.size() == 3 || old.size() == 4) {
1919  init = old;
1920  } else if (old.size() > 4 && !forElevation) {
1921  // for elevation, the initial segments are not useful
1922  init.push_back(old[0]);
1923  init.push_back(old[1]);
1924  init.push_back(old[-2]);
1925  init.push_back(old[-1]);
1926  } else if (myNBEdge.getFromNode()->geometryLike() && myNBEdge.getToNode()->geometryLike()) {
1927  PositionVector begShape;
1928  PositionVector endShape;
1929  const EdgeVector& incoming = myNBEdge.getFromNode()->getIncomingEdges();
1930  const EdgeVector& outgoing = myNBEdge.getToNode()->getOutgoingEdges();
1931  if (incoming.size() == 1) {
1932  begShape = incoming[0]->getGeometry();
1933  } else {
1934  assert(incoming.size() == 2);
1935  begShape = myNBEdge.isTurningDirectionAt(incoming[0]) ? incoming[1]->getGeometry() : incoming[0]->getGeometry();
1936  }
1937  if (outgoing.size() == 1) {
1938  endShape = outgoing[0]->getGeometry();
1939  } else {
1940  assert(outgoing.size() == 2);
1941  endShape = myNBEdge.isTurningDirectionAt(outgoing[0]) ? outgoing[1]->getGeometry() : outgoing[0]->getGeometry();
1942  }
1943  const double dist = MIN2(old.length2D(), MAX2(old.length2D() / 8, fabs(old[0].z() - old[-1].z()) * OptionsCont::getOptions().getFloat("geometry.max-grade") / 3));
1944  if (forElevation) {
1945  // initialize control point elevation for smooth continuation
1946  init.push_back(old[0]);
1947  init.push_back(old.positionAtOffset2D(dist));
1948  init.push_back(old.positionAtOffset2D(old.length2D() - dist));
1949  init.push_back(old[-1]);
1950  double begZ = begShape.positionAtOffset2D(MAX2(0.0, begShape.length2D() - dist)).z();
1951  double endZ = endShape.positionAtOffset2D(MIN2(begShape.length2D(), dist)).z();
1952  // continue incline
1953  init[1].setz(2 * init[0].z() - begZ);
1954  init[2].setz(2 * init[-1].z() - endZ);
1955  } else {
1956  bool ok = true;
1957  const double straightThresh = DEG2RAD(oc.getFloat("opendrive-output.straight-threshold"));
1958  init = NBNode::bezierControlPoints(begShape, endShape, false, dist, dist, ok, nullptr, straightThresh);
1959  }
1960 #ifdef DEBUG_SMOOTH_GEOM
1961  if (DEBUGCOND(this)) {
1962  std::cout << " begShape=" << begShape << " endShape=" << endShape << " forElevation=" << forElevation << " dist=" << dist << " ok=" << ok << " init=" << init << "\n";
1963  }
1964 #endif
1965  }
1966  if (init.size() == 0) {
1967  return PositionVector::EMPTY;
1968  } else {
1969  const int numPoints = MAX2(oc.getInt("junctions.internal-link-detail"),
1970  int(old.length2D() / oc.getFloat("opendrive.curve-resolution")));
1971  return init.bezier(numPoints);
1972  }
1973 }
1974 
1975 
1976 void
1978  PositionVector modifiedShape = smoothShape(myNBEdge.getGeometry(), false);
1979  if (modifiedShape.size() < 2) {
1980  WRITE_WARNING("Could not compute smooth shape for edge '" + getID() + "'");
1981  } else {
1982  PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
1983  setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
1984  }
1985 }
1986 
1987 
1988 void
1990  PositionVector elevationBase;
1991  for (const Position& pos : myNBEdge.getGeometry()) {
1992  if (elevationBase.size() == 0 || elevationBase[-1].z() != pos.z()) {
1993  elevationBase.push_back(pos);
1994  }
1995  }
1996  PositionVector elevation = smoothShape(elevationBase, true);
1997  if (elevation.size() <= 2) {
1998  WRITE_WARNING("Could not compute smooth elevation for edge '" + getID() + "'");
1999  } else {
2000  PositionVector modifiedShape = myNBEdge.getGeometry();
2001  if (modifiedShape.size() < 5) {
2002  modifiedShape = modifiedShape.resample(OptionsCont::getOptions().getFloat("opendrive.curve-resolution"));
2003  }
2004  const double scale = elevation.length2D() / modifiedShape.length2D();
2005  //std::cout << " elevation=" << elevation << "\n mod1=" << modifiedShape << " scale=" << scale << "\n";
2006  double seen = 0;
2007  for (int i = 1; i < (int)modifiedShape.size(); ++i) {
2008  seen += modifiedShape[i - 1].distanceTo2D(modifiedShape[i]);
2009  modifiedShape[i].setz(elevation.positionAtOffset2D(seen * scale).z());
2010  }
2011  //std::cout << " mod2=" << modifiedShape << "\n";
2012  PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2013  setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2014  }
2015 }
2016 
2017 
2018 void
2020  // remove start position and add it the new position
2022  geom.erase(geom.begin());
2023  geom.push_front_noDoublePos(pos);
2024  // restore modified shape
2025  setGeometry(geom, false);
2026 }
2027 
2028 
2029 void
2031  // remove end position and add it the new position
2033  geom.pop_back();
2034  geom.push_back_noDoublePos(pos);
2035  // restore modified shape
2036  setGeometry(geom, false);
2037 }
2038 
2039 
2040 void
2042  // Obtain exaggeration of the draw
2043  const double exaggeration = s.addSize.getExaggeration(s, this);
2044  // obtain circle width
2045  double circleWidth = SNAP_RADIUS * MIN2((double)1, s.laneWidthExaggeration);
2046  double circleWidthSquared = circleWidth * circleWidth;
2047  // obtain color
2048  RGBColor color = s.junctionColorer.getSchemes()[0].getColor(2);
2049  if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2050  // override with special colors (unless the color scheme is based on selection)
2052  }
2053  GLHelper::setColor(color);
2054  // recognize full transparency and simply don't draw
2055  if (color.alpha() > 0) {
2056  // push name
2057  glPushName(getGlID());
2058  // draw geometry points expect initial and final
2059  for (int i = 1; i < (int)myNBEdge.getGeometry().size() - 1; i++) {
2060  Position pos = myNBEdge.getGeometry()[i];
2061  if (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(pos) <= (circleWidthSquared + 2))) {
2062  glPushMatrix();
2063  glTranslated(pos.x(), pos.y(), GLO_JUNCTION - 0.01);
2064  // resolution of drawn circle depending of the zoom (To improve smothness)
2066  glPopMatrix();
2067  // draw elevation or special symbols (Start, End and Block)
2069  glPushMatrix();
2070  // Translate to geometry point
2071  glTranslated(pos.x(), pos.y(), GLO_JUNCTION);
2072  // draw Z value
2074  glPopMatrix();
2075  }
2076  }
2077  }
2078  // draw line geometry, start and end points if shapeStart or shape end is edited, and depending of drawForSelecting
2081  (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(myNBEdge.getGeometry().front()) <= (circleWidthSquared + 2)))) {
2082  glPushMatrix();
2083  glTranslated(myNBEdge.getGeometry().front().x(), myNBEdge.getGeometry().front().y(), GLO_JUNCTION + 0.01);
2084  // resolution of drawn circle depending of the zoom (To improve smothness)
2086  glPopMatrix();
2087  // draw a "s" over last point depending of drawForSelecting
2088  if (!s.drawForSelecting && s.drawDetail(s.detailSettings.geometryPointsText, exaggeration)) {
2089  glPushMatrix();
2090  glTranslated(myNBEdge.getGeometry().front().x(), myNBEdge.getGeometry().front().y(), GLO_JUNCTION + 0.02);
2091  GLHelper::drawText("S", Position(), 0, circleWidth, RGBColor::WHITE);
2092  glPopMatrix();
2093  // draw line between Junction and point
2094  glPushMatrix();
2095  glTranslated(0, 0, GLO_JUNCTION - 0.01);
2096  glLineWidth(4);
2098  // draw line between begin point of last lane shape and the first edge shape point
2099  GLHelper::drawLine(myNBEdge.getGeometry().front(), myNBEdge.getLanes().back().shape.front());
2100  glPopMatrix();
2101  }
2102  }
2104  (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(myNBEdge.getGeometry().back()) <= (circleWidthSquared + 2)))) {
2105  glPushMatrix();
2106  glTranslated(myNBEdge.getGeometry().back().x(), myNBEdge.getGeometry().back().y(), GLO_JUNCTION + 0.01);
2107  // resolution of drawn circle depending of the zoom (To improve smothness)
2109  glPopMatrix();
2110  // draw a "e" over last point depending of drawForSelecting
2111  if (!s.drawForSelecting && s.drawDetail(s.detailSettings.geometryPointsText, exaggeration)) {
2112  glPushMatrix();
2113  glTranslated(myNBEdge.getGeometry().back().x(), myNBEdge.getGeometry().back().y(), GLO_JUNCTION + 0.02);
2114  GLHelper::drawText("E", Position(), 0, circleWidth, RGBColor::WHITE);
2115  glPopMatrix();
2116  // draw line between Junction and point
2117  glPushMatrix();
2118  glTranslated(0, 0, GLO_JUNCTION - 0.01);
2119  glLineWidth(4);
2121  // draw line between last point of first lane shape and the last edge shape point
2122  GLHelper::drawLine(myNBEdge.getGeometry().back(), myNBEdge.getLanes().back().shape.back());
2123  glPopMatrix();
2124  }
2125  }
2126  }
2127  // pop name
2128  glPopName();
2129  }
2130 }
2131 
2132 
2133 void
2135  // draw the name and/or the street name
2136  const bool drawStreetName = s.streetName.show && (myNBEdge.getStreetName() != "");
2137  const bool spreadSuperposed = s.spreadSuperposed && myLanes.back()->drawAsRailway(s) && myNBEdge.isBidiRail();
2138  if (s.edgeName.show || drawStreetName || s.edgeValue.show) {
2139  glPushName(getGlID());
2140  GNELane* lane1 = myLanes[0];
2141  GNELane* lane2 = myLanes[myLanes.size() - 1];
2142  Position p = lane1->getGeometry().shape.positionAtOffset(lane1->getGeometry().shape.length() / (double) 2.);
2143  p.add(lane2->getGeometry().shape.positionAtOffset(lane2->getGeometry().shape.length() / (double) 2.));
2144  p.mul(.5);
2145  if (spreadSuperposed) {
2146  // move name to the right of the edge and towards its beginning
2147  const double dist = 0.6 * s.edgeName.scaledSize(s.scale);
2148  const double shiftA = lane1->getGeometry().shape.rotationAtOffset(lane1->getGeometry().shape.length() / (double) 2.) - DEG2RAD(135);
2149  Position shift(dist * cos(shiftA), dist * sin(shiftA));
2150  p.add(shift);
2151  }
2152  double angle = lane1->getGeometry().shape.rotationDegreeAtOffset(lane1->getGeometry().shape.length() / (double) 2.);
2153  angle += 90;
2154  if (angle > 90 && angle < 270) {
2155  angle -= 180;
2156  }
2157  if (s.edgeName.show) {
2158  drawName(p, s.scale, s.edgeName, angle);
2159  }
2160  if (drawStreetName) {
2162  }
2163  if (s.edgeValue.show) {
2164  double value = lane2->getColorValue(s, s.laneColorer.getActive());
2165  GLHelper::drawTextSettings(s.edgeValue, toString(value), p, s.scale, angle);
2166  }
2167  glPopName();
2168  }
2169 }
2170 
2171 
2172 void
2174  // Draw symbols in every lane
2175  const double exaggeration = s.addSize.getExaggeration(s, rerouter);
2176  if (s.scale * exaggeration >= 3) {
2177  // Start drawing adding an gl identificator
2178  glPushName(rerouter->getGlID());
2179  // draw rerouter symbol over all lanes
2180  for (const auto& j : myLanes) {
2181  const Position& lanePos = rerouter->getChildPosition(j);
2182  const double laneRot = rerouter->getChildRotation(j);
2183  // draw rerouter symbol
2184  glPushMatrix();
2185  glTranslated(lanePos.x(), lanePos.y(), rerouter->getType());
2186  glRotated(-1 * laneRot, 0, 0, 1);
2187  glScaled(exaggeration, exaggeration, 1);
2188  // mode
2189  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2190  glBegin(GL_TRIANGLES);
2191  glColor3d(1, .8f, 0);
2192  // base
2193  glVertex2d(0 - 1.4, 0);
2194  glVertex2d(0 - 1.4, 6);
2195  glVertex2d(0 + 1.4, 6);
2196  glVertex2d(0 + 1.4, 0);
2197  glVertex2d(0 - 1.4, 0);
2198  glVertex2d(0 + 1.4, 6);
2199  glEnd();
2200  // draw "U"
2201  if (!s.drawForSelecting) {
2202  GLHelper::drawText("U", Position(0, 2), .1, 3, RGBColor::BLACK, 180);
2203  double probability = parse<double>(rerouter->getAttribute(SUMO_ATTR_PROB)) * 100;
2204  // draw Probability
2205  GLHelper::drawText((toString(probability) + "%").c_str(), Position(0, 4), .1, 0.7, RGBColor::BLACK, 180);
2206  }
2207  // finish draw
2208  glPopMatrix();
2209  // draw contour if is selected
2210  if (myNet->getViewNet()->getDottedAC() == rerouter) {
2211  GLHelper::drawShapeDottedContourRectangle(s, getType(), lanePos, 2.8, 6, -1 * laneRot, 0, 3);
2212  }
2213  }
2214  }
2215  // Pop name
2216  glPopName();
2217  // Draw connections
2218  rerouter->drawChildConnections(s, getType());
2219 }
2220 
2221 /****************************************************************************/
GUIVisualizationSizeSettings junctionSize
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:762
static const PositionVector EMPTY
empty Vector
void copyTemplate(GNEEdge *tpl, GNEUndoList *undolist)
copy edge attributes from tpl
Definition: GNEEdge.cpp:808
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1363
GNEJunction * myGNEJunctionSource
pointer to GNEJunction source
Definition: GNEEdge.h:332
The information about how to spread the lanes from the given position.
static const RGBColor walk
color for walks
void updateGeometry()
update pre-computed geometry information
RGBColor selectedPersonPlanColor
person plan selection color (Rides, Walks, personStops...)
void remakeGNEConnections()
remake connections
Definition: GNEEdge.cpp:713
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
Position getPositionInView() const
Returns position of hierarchical element in view.
SumoXMLTag
Numbers representing SUMO-XML - element names.
double length2D() const
Returns the length.
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:184
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
void setNumLanes(int numLanes, GNEUndoList *undoList)
changes the number of lanes. When reducing the number of lanes, higher-numbered lanes are removed fir...
Definition: GNEEdge.cpp:1632
int toLane
The lane the connections yields in.
Definition: NBEdge.h:209
const std::vector< T > & getSchemes() const
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:1020
const Position & getChildPosition(const GNELane *lane)
get child position calculated in ChildConnections
double scale
information about a lane&#39;s width (temporary, used for a single view)
GUIVisualizationTextSettings streetName
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:154
PositionVector shape
The shape of the netElement element.
Definition: GNENetElement.h:57
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:318
void resetWritable()
Resets all options to be writeable.
GNENet * myNet
the net to inform about updates
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition: GNEEdge.h:344
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
void smoothElevation(GNEUndoList *undoList)
smooth elevation with regard to adjoining edges
Definition: GNEEdge.cpp:1989
void invalidateShape()
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEEdge.cpp:517
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
double z() const
Returns the z-position.
Definition: Position.h:67
void addLane(GNELane *lane, const NBEdge::Lane &laneAttrs, bool recomputeConnections)
increase number of lanes by one use the given attributes and restore the GNELane
Definition: GNEEdge.cpp:1652
GUIVisualizationTextSettings addName
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:206
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:460
begin/end of the description of a single lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
std::string myConnectionStatus
modification status of the connections
Definition: GNEEdge.h:350
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:127
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3332
GNEJunction * myGNEJunctionDestiny
pointer to GNEJunction destiny
Definition: GNEEdge.h:335
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED)
Adds a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:1058
a flow definitio nusing a from-to edges instead of a route (used by router)
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
int indexOfClosest(const Position &p) const
index of the closest position to p
RGBColor selectedVehicleColor
vehicle selection color
an e2 detector over multiple lanes (used by Netedit)
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:1863
static const RGBColor WHITE
Definition: RGBColor.h:197
void endGeometryMoving()
begin movement (used when user click over edge to start a movement, to avoid problems with problems w...
Definition: GNEEdge.cpp:279
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:244
GNEEdge()
constructor for dummy edge
Definition: GNEEdge.cpp:84
void straightenElevation(GNEUndoList *undoList)
interpolate z values linear between junctions
Definition: GNEEdge.cpp:1894
void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices)
add lane
Definition: NBEdge.cpp:3139
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3382
const GNEDemandElement * getLockedPerson() const
get locked person
double exaggeration
The size exaggeration (upscale)
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:83
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
GUIColorer laneColorer
The lane colorer.
bool isPersonPlan() const
return true if tag correspond to a person plan
Stores the information about how to visualize structures.
PositionVector resample(double maxLength) const
resample shape with the given number of points (equal spacing)
void drawEdgeName(const GUIVisualizationSettings &s) const
draw edge name
Definition: GNEEdge.cpp:2134
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:472
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1061
static const double SNAP_RADIUS
Definition: GNEEdge.h:281
double y() const
Returns the y-position.
Definition: Position.h:62
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
GUIVisualizationTextSettings edgeValue
The representation of a single edge during network building.
Definition: NBEdge.h:86
void drawPartialPersonPlan(const GUIVisualizationSettings &s, const GNEDemandElement *personPlan, const GNEJunction *junction) const
draw partial person plan
Definition: GNEEdge.cpp:1339
void moveShapeStart(const Position &oldPos, const Position &offset)
move position of shape start without commiting change
Definition: GNEEdge.cpp:190
static void drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048)
Definition: GLHelper.cpp:701
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
Definition: NBEdge.cpp:2054
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:846
bool hasRestrictedLane(SUMOVehicleClass vclass) const
check if edge has a restricted lane
Definition: GNEEdge.cpp:1872
double x() const
Returns the x-position.
Definition: Position.h:57
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
Definition: NBEdge.cpp:683
Representation of a RouteProbe in netedit.
Definition: GNERouteProbe.h:35
void setStreetName(const std::string &name)
sets the street name of this edge
Definition: NBEdge.h:593
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void smooth(GNEUndoList *undoList)
make geometry smooth
Definition: GNEEdge.cpp:1977
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, int align=0, double width=-1)
Definition: GLHelper.cpp:668
void drawPartialTripFromTo(const GUIVisualizationSettings &s, const GNEDemandElement *tripOrFromTo, const GNEJunction *junction) const
draw partial trip and Flow
Definition: GNEEdge.cpp:1296
bool drawDetail(const double detail, const double exaggeration) const
check if details can be drawn for the given GUIVisualizationDetailSettings and current scale and exxa...
T MAX2(T a, T b)
Definition: StdDefs.h:80
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:78
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:3116
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:3413
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
double getChildRotation(const GNELane *lane)
get child rotation calculated in ChildConnections
void setLoadedLength(double val)
set loaded lenght
Definition: NBEdge.cpp:3456
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:73
virtual double getAttributeDouble(SumoXMLAttr key) const =0
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:644
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:218
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
void setShapeEndPos(const Position &pos)
change Shape EndPos
Definition: GNEEdge.cpp:2030
double endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:154
void clearGNEConnections()
clear current connections
Definition: GNEEdge.cpp:752
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void moveShapeEnd(const Position &oldPos, const Position &offset)
move position of shape end without commiting change
Definition: GNEEdge.cpp:206
bool editingElevation() const
check if we&#39;re editing elevation
static const double ride
width for rides
PositionVector interpolateZ(double zStart, double zEnd) const
returned vector that varies z smoothly over its length
double visibility
custom foe visiblity for connection
Definition: NBEdge.h:227
void removeEdgeFromCrossings(GNEJunction *junction, GNEUndoList *undoList)
remove crossing of junction
Definition: GNEEdge.cpp:1883
int getVertexIndex(Position pos, bool createIfNoExist, bool snapToGrid)
return index of a vertex of shape, or of a new vertex if position is over an shape&#39;s edge ...
Definition: GNEEdge.cpp:313
static const RGBColor BLACK
Definition: RGBColor.h:198
const std::string & getID() const
Returns the id.
Definition: Named.h:77
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
bool hasNext()
returns the information whether further substrings exist
const SVCPermissions SVCAll
all VClasses are allowed
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1271
void commitShapeStartChange(const Position &oldPos, GNEUndoList *undoList)
commit position changing in shape start
Definition: GNEEdge.cpp:222
PositionVector smoothShape(const PositionVector &shape, bool forElevation)
return smoothed shape
Definition: GNEEdge.cpp:1904
void removeLane(GNELane *lane, bool recomputeConnections)
the number of lanes by one. argument is only used to increase robustness (assertions) ...
Definition: GNEEdge.cpp:1705
bool myWasSplit
whether this edge was created from a split
Definition: GNEEdge.h:347
~GNEEdge()
Destructor.
Definition: GNEEdge.cpp:89
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:348
const std::vector< GNEEdge * > & getGNEEdges() const
Returns all GNEEdges vinculated with this Junction.
virtual std::string getAttribute(SumoXMLAttr key) const =0
first coordinate of edge shape
void drawPartialRoute(const GUIVisualizationSettings &s, const GNEDemandElement *route, const GNEJunction *junction) const
draw partial route
Definition: GNEEdge.cpp:1223
static bool isValidGenericParameterKey(const std::string &value)
whether the given string is a valid key for a generic parameter
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.
bool isPersonTrip() const
return true if tag correspond to a person trip
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:574
const std::vector< GNEAdditional * > & getAdditionalChildren() const
return vector of additionals that have as Parent this edge (For example, Calibrators) ...
generic attribute
void editEndpoint(Position pos, GNEUndoList *undoList)
makes pos the new geometry endpoint at the appropriate end, or remove current existent endpoint ...
Definition: GNEEdge.cpp:645
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:303
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
virtual std::string getAttribute(SumoXMLAttr key) const =0
PositionVector customShape
custom shape for connection
Definition: NBEdge.h:233
begin/end of the description of a route
void deleteGeometryPoint(const Position &pos, bool allowUndo=true)
delete the geometry point closest to the given pos
Definition: GNEEdge.cpp:428
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
double getDistance() const
Definition: NBEdge.h:604
Boundary myMovingGeometryBoundary
boundary used during moving of elements
mode for moving network elements
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
const std::vector< GNEEdge * > & getEdgeParents() const
get edge parents
whether a feature has been loaded,guessed,modified or approved
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
bool isRide() const
return true if tag correspond to a ride element
GNELane * getLaneFrom() const
get lane of the incoming lane
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:264
const std::vector< GNEDemandElement * > & getDemandElementChildren() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
static void drawShapeDottedContourBetweenLanes(const GUIVisualizationSettings &s, const int type, const PositionVector &frontLaneShape, const double offsetFrontLaneShape, const PositionVector &backLaneShape, const double offsetBackLaneShape)
draw a dotted contour around the given lane shapes
Definition: GLHelper.cpp:523
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
PositionVector bezier(int numPoints)
return a bezier interpolation
bool keepClear
whether the junction must be kept clear when using this connection
Definition: NBEdge.h:221
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GUIVisualizationTextSettings edgeName
static void drawBoundary(const Boundary &b)
Draw a boundary (used for debugging)
Definition: GLHelper.cpp:812
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:625
int getCircleResolution() const
function to calculate circle resolution for all circles drawn in drawGL(...) functions ...
a person trip
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:137
static const double personTrip
width for person trips
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
Definition: NBEdge.h:148
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
GUIVisualizationSizeSettings addSize
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEEdge.cpp:858
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:933
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:733
void push_front_noDoublePos(const Position &p)
insert in front a non double position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false)
Removes positions if too near.
whether an edge is part of a bidirectional railway
GUIVisualizationWidthSettings widthSettings
width settings
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:2065
static bool isValidGenericParameterValue(const std::string &value)
whether the given string is a valid value for a generic parameter
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition: GNEEdge.cpp:163
double speed
custom speed for connection
Definition: NBEdge.h:230
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:2087
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
RGBColor selectedRouteColor
route selection color (used for routes and vehicle stops)
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:616
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:45
const double SUMO_const_halfLaneWidth
Definition: StdDefs.h:52
bool clickedOverShapeStart(const Position &pos)
Definition: GNEEdge.cpp:170
void commitShapeEndChange(const Position &oldPos, GNEUndoList *undoList)
commit position changing in shape end
Definition: GNEEdge.cpp:237
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition: NBEdge.h:151
std::string getGenericParametersStr() const
return generic parameters in string format
Definition: GNEEdge.cpp:1132
const std::set< GNEDemandElement * > & getSortedDemandElementChildrenByType(SumoXMLTag tag) const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:465
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:203
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:80
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:1001
GNELane * getLaneTo() const
get lane of the outgoing lane
A list of positions.
Supermode currentSupermode
the current supermode
double scaledSize(double scale, double constFactor=0.1) const
get scale size
static bool isGenericParametersValid(const std::string &value)
check if given string can be parsed to a map/list of generic parameters
void removeGLObjectFromGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1279
std::string generateChildID(SumoXMLTag childTag)
gererate a new ID for an element child
Definition: GNEEdge.cpp:115
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:544
static const double route
width for routes
friend class GNEChange_Attribute
declare friend class
GNEEdge * getOppositeEdge() const
get opposite edge
Definition: GNEEdge.cpp:511
std::vector< std::pair< std::string, std::string > > getGenericParameters() const
return generic parameters as vector of pairs format
Definition: GNEEdge.cpp:1147
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition: NBEdge.cpp:3193
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:505
virtual const RGBColor & getColor() const =0
get color
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
static GNEEdge & getDummyEdge()
Dummy edge to use when a reference must be supplied in the no-arguments constructor (FOX technicality...
Definition: GNEEdge.cpp:52
GNEConnection * retrieveGNEConnection(int fromLane, NBEdge *to, int toLane, bool createIfNoExist=true)
get GNEConnection if exist, and if not create it if create is enabled
Definition: GNEEdge.cpp:1831
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:840
const std::string & getID() const
Definition: NBEdge.h:1364
int myPriority
The priority of the edge.
Definition: NBEdge.h:1546
bool geometryLike() const
whether this is structurally similar to a geometry node
Definition: NBNode.cpp:3046
const std::vector< GNEAdditional * > & getAdditionalParents() const
return vector of additionals that have as Parent this edge (For example, Calibrators) ...
T MIN2(T a, T b)
Definition: StdDefs.h:74
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
void drawRerouterSymbol(const GUIVisualizationSettings &s, GNEAdditional *rerouter) const
draw Rerouter symbols
Definition: GNEEdge.cpp:2173
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:588
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
void startGeometryMoving()
Definition: GNEEdge.cpp:252
edge: the shape in xml-definition
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
GUIColorer junctionColorer
The junction colorer.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition: GNENet.cpp:599
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
const std::string getID() const
function to support debugging
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, bool &ok, NBNode *recordError=0, double straightThresh=DEG2RAD(5), int shapeFlag=0)
get bezier control points
Definition: NBNode.cpp:531
const NetElementGeometry & getGeometry() const
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:274
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:600
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:246
#define DEG2RAD(x)
Definition: GeomHelper.h:38
bool clickedOverShapeEnd(const Position &pos)
return true if user clicked over ShapeEnd
Definition: GNEEdge.cpp:180
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
Definition: GeomHelper.h:52
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:499
void incRef(const std::string &debugMsg="")
Increarse reference.
The connection was given by the user.
Definition: NBEdge.h:128
std::set< GUIGlID > getLaneGlIDs() const
returns GLIDs of all lanes
Definition: GNEEdge.cpp:830
double speed
The speed allowed on this lane.
Definition: NBEdge.h:145
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
double width
This lane&#39;s width.
Definition: NBEdge.h:161
static const RGBColor ride
color for rides
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:3441
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3704
vehicle is a passenger car (a "normal" car)
void selectAttributeCarrier(bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Definition: NBEdge.cpp:2040
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEEdge.cpp:484
void decRef(const std::string &debugMsg="")
Decrease reference.
std::vector< GNECrossing * > getGNECrossings()
get GNECrossings vinculated with this Edge
Definition: GNEEdge.cpp:791
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:411
begin/end of the description of an edge
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition: GNEEdge.cpp:703
void unselectAttributeCarrier(bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:559
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
static void drawShapeDottedContourRectangle(const GUIVisualizationSettings &s, const int type, const Position &center, const double width, const double height, const double rotation=0, const double offsetX=0, const double offsetY=0)
draw a dotted contour around the given Position with certain width and height
Definition: GLHelper.cpp:555
#define DEBUGCOND(PEDID)
const DemandElementSegmentGeometry & getDemandElementSegmentGeometry() const
get demand element segment geometry
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:680
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
int getRouteProbeRelativePosition(GNERouteProbe *routeProbe) const
obtain relative positions of RouteProbes
Definition: GNEEdge.cpp:773
GUIVisualizationDetailSettings detailSettings
detail settings
const std::vector< GNEDemandElement * > & getDemandElementParents() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
bool showNonInspectedDemandElements(const GNEDemandElement *demandElement) const
check if non inspected element has to be hidden
ConnectionVector myGNEConnections
vector with the connections of this edge
Definition: GNEEdge.h:341
static const double walk
width for walks
static const RGBColor vehicleTrips
color for vehicle trips
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:575
int moveVertexShape(const int index, const Position &oldPos, const Position &offset)
change position of a vertex of shape without commiting change
Definition: GNEEdge.cpp:359
static const double BUBBLE_RADIUS
constant values for drawing buubles
Definition: GNEJunction.h:56
void reset()
Resets the boundary.
Definition: Boundary.cpp:67
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
Definition: GNEEdge.cpp:1183
void addConnection(NBEdge::Connection nbCon, bool selectAfterCreation=false)
adds a connection
Definition: GNEEdge.cpp:1755
bool showDemandElements() const
check if show demand elements checkbox is enabled
void drawGeometryPoints(const GUIVisualizationSettings &s) const
draw geometry points
Definition: GNEEdge.cpp:2041
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
Definition: GNEViewNet.cpp:331
double length() const
Returns the length.
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
static const RGBColor personTrip
color for personStops
std::vector< Segment >::const_iterator end() const
end iterator
void updateGeometry()
update pre-computed geometry information
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:259
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:924
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a &#39; &#39;.
void setGenericParametersStr(const std::string &value)
set generic parameters in string format
Definition: GNEEdge.cpp:1158
void drawChildConnections(const GUIVisualizationSettings &s, const GUIGlObjectType GLTypeParent) const
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:417
const GNEAttributeCarrier * getDottedAC() const
get AttributeCarrier under cursor
Definition: GNEViewNet.cpp:939
void moveEntireShape(const PositionVector &oldShape, const Position &offset)
move entire shape without commiting change
Definition: GNEEdge.cpp:384
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
const std::string & getTagStr() const
get tag assigned to this object in string format
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:3427
Demanding mode (Routes, Vehicles etc..)
double contPos
custom position for internal junction on this connection
Definition: NBEdge.h:224
element is selected
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:217
A storage for options typed value containers)
Definition: OptionsCont.h:90
bool uncontrolled
check if Connection is uncontrolled
Definition: NBEdge.h:263
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition: GNEEdge.cpp:446
void markConnectionGeometryDeprecated()
check that connection&#39;s Geometry has to be updated
void updateGeometry()
update pre-computed geometry information
Definition: GNEEdge.cpp:122
The popup menu of a globject.
an edge
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions) ...
Definition: Position.h:249
std::string myType
The type of the edge.
Definition: NBEdge.h:1530
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:2044
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNEEdge.cpp:1041
static void drawShapeDottedContourPartialShapes(const GUIVisualizationSettings &s, const int type, const Position &begin, const Position &end, const double width)
draw a dotted contour in a partial shapes
Definition: GLHelper.cpp:588
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false, const bool keepPossibleTurns=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:1293
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:2783
void declareConnectionsAsLoaded(EdgeBuildingStep step=LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition: NBEdge.h:1285
const Position & getPosition() const
Definition: NBNode.h:251
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:2127
void commitShapeChange(const PositionVector &oldShape, GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of changeShapeGeometry(...)
Definition: GNEEdge.cpp:397
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
begin/end of the description of a embedded route (used in NETEDIT)
GUIGlID getGlID() const
Returns the numerical id of the object.
LaneVector myLanes
vectgor with the lanes of this edge
Definition: GNEEdge.h:338
static const std::string FEATURE_LOADED
void removeConnection(NBEdge::Connection nbCon)
removes a connection
Definition: GNEEdge.cpp:1791
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute attr
void updateLinkState()
recompute cached myLinkState
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
std::vector< Segment >::const_iterator begin() const
begin iterator
NetworkEditMode networkEditMode
the current Network edit mode
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
GUIVisualizationColorSettings colorSettings
color settings
last coordinate of edge shape
const std::string getOptionalName() const
Returns the street name.
Definition: GNEEdge.cpp:479
void push_back_noDoublePos(const Position &p)
insert in back a non double position
a single trip definition (used by router)
parent of an additional element
empty max
NBEdge & myNBEdge
the underlying NBEdge
Definition: GNEEdge.h:326
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:479
bool isWalk() const
return true if tag correspond to a walk element
bool showAllPersonPlans() const
check all person plans has to be show
RGBColor selectedEdgeColor
edge selection color
void setDistance(double distance)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.h:1263
void mul(double val)
Multiplies both positions with the given value.
Definition: Position.h:107
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:136
bool hasString(const std::string &str) const
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:542
void add(double xoff, double yoff, double zoff)
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition: NBEdge.cpp:877
bool drawForSelecting
whether drawing is performed for the purpose of selecting objects
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:399
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
static const double geometryPointsText
details for Geometry Points Texts
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const
return value for lane coloring according to the given scheme
Definition: GNELane.cpp:1065
bool spreadSuperposed
Whether to improve visualisation of superposed (rail) edges.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
void setShapeStartPos(const Position &pos)
change Shape StartPos
Definition: GNEEdge.cpp:2019
NBNode * getNBNode() const
Return net build node.
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:940
void addGLObjectIntoGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1273
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:689
GNELane * getLaneByVClass(const SUMOVehicleClass vClass) const
return the first lane that allow a vehicle of type vClass (or the first lane, if none was found) ...
Definition: GNEEdge.cpp:1189
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition: GNENet.cpp:2057
int removeClosest(const Position &p)
removes the point closest to p and return the removal index
std::string getAttributeForSelection(SumoXMLAttr key) const
method for getting the attribute in the context of object selection
Definition: GNEEdge.cpp:931
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:852
bool drawBoundaries
enable or disable draw boundaries
virtual std::string getAttribute(SumoXMLAttr key) const =0
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:486
Position getSplitPos(const Position &clickPos)
Definition: GNEEdge.cpp:631
bool unreferenced()
check if object ins&#39;t referenced
friend class GNEChange_Lane
Friend class.
Definition: GNEEdge.h:53
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
static const double trip
width for trips
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3271
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2067
void clearParameter()
Clears the parameter map.
a junction