SUMO - Simulation of Urban MObility
GNEJunction.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-2018 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 class for visualizing and editing junctions in netedit (adapted from
16 // GUIJunctionWrapper)
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <string>
26 #include <utility>
29 #include <utils/geom/Position.h>
34 #include <utils/gui/div/GLHelper.h>
39 #include <netbuild/NBOwnTLDef.h>
41 #include <netbuild/NBAlgorithms.h>
46 #include <netedit/GNEViewParent.h>
47 #include <netedit/GNENet.h>
48 #include <netedit/GNEUndoList.h>
49 #include <netedit/GNEViewNet.h>
50 
51 #include "GNEEdge.h"
52 #include "GNEConnection.h"
53 #include "GNEJunction.h"
54 #include "GNECrossing.h"
55 
56 
57 // ===========================================================================
58 // static members
59 // ===========================================================================
60 
61 const double GNEJunction::BUBBLE_RADIUS(4);
62 
63 // ===========================================================================
64 // method definitions
65 // ===========================================================================
66 
67 GNEJunction::GNEJunction(NBNode& nbn, GNENet* net, bool loaded) :
68  GNENetElement(net, nbn.getID(), GLO_JUNCTION, SUMO_TAG_JUNCTION),
69  myNBNode(nbn),
70  myAmCreateEdgeSource(false),
71  myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
72  myAmResponsible(false),
73  myHasValidLogic(loaded),
74  myAmTLSSelected(false) {
75  // give a temporal value for boundary
77 }
78 
79 
81  // delete all GNECrossing
82  for (auto it : myGNECrossings) {
83  it->decRef();
84  if (it->unreferenced()) {
85  // show extra information for tests
86  WRITE_DEBUG("Deleting unreferenced " + toString(it->getTag()) + " '" + it->getID() + "' in GNEJunction destructor");
87  delete it;
88  }
89  }
90 
91  if (myAmResponsible) {
92  // show extra information for tests
93  WRITE_DEBUG("Deleting NBNode of '" + getID() + "' in GNEJunction destructor");
94  delete &myNBNode;
95  }
96 }
97 
98 
99 void
100 GNEJunction::updateGeometry(bool updateGrid) {
101  // first check if object has to be removed from grid (SUMOTree)
102  if (updateGrid) {
104  }
105  // calculate boundary using EXTENT as size
106  const double EXTENT = 2;
107  myJunctionBoundary = Boundary(myNBNode.getPosition().x() - EXTENT, myNBNode.getPosition().y() - EXTENT,
108  myNBNode.getPosition().x() + EXTENT, myNBNode.getPosition().y() + EXTENT);
109  // if junctio own a extra shape, add it to boundary
110  if (myNBNode.getShape().size() > 0) {
112  }
114  // last step is to check if object has to be added into grid (SUMOTree) again
115  if (updateGrid) {
116  myNet->addGLObjectIntoGrid(this);
117  }
118  // rebuild GNECrossings
119  rebuildGNECrossings(true);
120 }
121 
122 
123 void
124 GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
125  // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
127  if (rebuildNBNodeCrossings) {
128  // build new NBNode::Crossings and walking areas
130  }
131  // extract ALL crossing of Tree (Due after rebuild some IDs can referenciate another GNECrossing)
132  for (auto i : myGNECrossings) {
134  }
135 
136  // create a vector to keep retrieved and created crossings
137  std::vector<GNECrossing*> retrievedCrossings;
138  // iterate over NBNode::Crossings of GNEJunction
139  for (auto NBc : myNBNode.getCrossingsIncludingInvalid()) {
140  // retrieve existent GNECrossing, or create it
141  GNECrossing* retrievedGNECrossing = retrieveGNECrossing(NBc);
142  retrievedCrossings.push_back(retrievedGNECrossing);
143  // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
144  std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
145  if (retrievedExists != myGNECrossings.end()) {
146  myGNECrossings.erase(retrievedExists);
147  // insert retrieved crossing in tree again
148  myNet->addGLObjectIntoGrid(retrievedGNECrossing);
149  // update geometry of retrieved crossing
150  retrievedGNECrossing->updateGeometry(true);
151  } else {
152  // include reference to created GNECrossing
153  retrievedGNECrossing->incRef();
154  }
155  // check if crossing is selected
156  if (retrievedGNECrossing->isAttributeCarrierSelected()) {
157  retrievedGNECrossing->selectAttributeCarrier();
158  }
159  }
160  // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
161  for (auto it : myGNECrossings) {
162  it->decRef();
163  // check if crossing is selected
164  if (it->isAttributeCarrierSelected()) {
165  it->unselectAttributeCarrier();
166  }
167  if (it->unreferenced()) {
168  // show extra information for tests
169  WRITE_DEBUG("Deleting unreferenced " + toString(it->getTag()) + " in rebuildGNECrossings()");
170  delete it;
171  }
172  }
173  // copy retrieved (existent and created) GNECrossigns to myGNECrossings
174  myGNECrossings = retrievedCrossings;
175  }
176 }
177 
178 
181  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
182  buildPopupHeader(ret, app);
185  // build selection and show parameters menu
188  buildPositionCopyEntry(ret, false);
189  //if (parent.getVisualisationSettings()->editMode != GNE_MODE_CONNECT) {
190  // // XXX if joinable
191  // new FXMenuCommand(ret, "Join adjacent edges", 0, &parent, MID_GNE_JOIN_EDGES);
192  //}
193  const int numEndpoints = (int)myNBNode.getEndPoints().size();
194  // create menu commands
195  FXMenuCommand* mcCustomShape = new FXMenuCommand(ret, "Set custom junction shape", 0, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
196  FXMenuCommand* mcResetCustomShape = new FXMenuCommand(ret, "Reset junction shape", 0, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
197  FXMenuCommand* mcReplace = new FXMenuCommand(ret, "Replace junction by geometry point", 0, &parent, MID_GNE_JUNCTION_REPLACE);
198  FXMenuCommand* mcSplit = new FXMenuCommand(ret, ("Split junction (" + toString(numEndpoints) + " end points)").c_str(), 0, &parent, MID_GNE_JUNCTION_SPLIT);
199  FXMenuCommand* mcClearConnections = new FXMenuCommand(ret, "Clear connections", 0, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
200  FXMenuCommand* mcResetConnections = new FXMenuCommand(ret, "Reset connections", 0, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
201  // check if menu commands has to be disabled
202  EditMode editMode = myNet->getViewNet()->getCurrentEditMode();
203  const bool wrongMode = (editMode == GNE_MODE_CONNECT || editMode == GNE_MODE_TLS || editMode == GNE_MODE_CREATE_EDGE);
204  if (wrongMode) {
205  mcCustomShape->disable();
206  mcClearConnections->disable();
207  mcResetConnections->disable();
208  }
209  // disable mcClearConnections if juction hasn't connections
210  if (getGNEConnections().empty()) {
211  mcClearConnections->disable();
212  }
213  // disable mcResetCustomShape if junction doesn't have a custom shape
214  if (!myNBNode.hasCustomShape()) {
215  mcResetCustomShape->disable();
216  }
217  // checkIsRemovable requiers turnarounds to be computed. This is ugly
218  if (myNBNode.getIncomingEdges().size() == 2 && myNBNode.getOutgoingEdges().size() == 2) {
220  }
221  std::string reason = "wrong edit mode";
222  if (wrongMode || !myNBNode.checkIsRemovableReporting(reason)) {
223  mcReplace->setText(mcReplace->getText() + " (" + reason.c_str() + ")");
224  mcReplace->disable();
225  }
226  if (numEndpoints == 1) {
227  mcSplit->disable();
228  }
229  return ret;
230 }
231 
232 
233 Boundary
235  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
238  } else {
240  b.grow(20);
241  return b;
242  }
243 }
244 
245 
246 void
248  /*
249  // first call function mouseOverObject (to check if this object is under cursor)
250  // @note currently disabled. It will be implemented in an different ticket of #2905
251  mouseOverObject(s);
252  */
253  // declare variables
254  GLfloat color[4];
255  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
256  exaggeration *= s.junctionSize.getExaggeration(s);
257  // declare values for circles
258  double circleWidth = BUBBLE_RADIUS * exaggeration;
259  double circleWidthSquared = circleWidth * circleWidth;
260  int circleResolution = GNEAttributeCarrier::getCircleResolution(s);
261  // push name
262  glPushName(getGlID());
263  if (s.scale * exaggeration * myMaxSize < 1.) {
264  // draw something simple so that selection still works
266  } else {
267  // node shape has been computed and is valid for drawing
268  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
269  const bool drawBubble = (((!drawShape || myNBNode.getShape().area() < 4)
270  && s.drawJunctionShape)
272 
273  if (drawShape) {
274  setColor(s, false);
275  // recognize full transparency and simply don't draw
276  glGetFloatv(GL_CURRENT_COLOR, color);
277  if (color[3] != 0) {
278  glPushMatrix();
279  glTranslated(0, 0, getType());
280  PositionVector shape = myNBNode.getShape();
281  shape.closePolygon();
282  if (exaggeration > 1) {
283  shape.scaleRelative(exaggeration);
284  }
285  if ((s.drawForSelecting) || (s.scale * exaggeration * myMaxSize < 40.)) {
286  GLHelper::drawFilledPoly(shape, true);
287  } else {
289  }
290  // check if dotted contour has to be drawn
291  if (!s.drawForSelecting && (myNet->getViewNet()->getACUnderCursor() == this) && !drawBubble) {
293  }
294  glPopMatrix();
295  }
296  }
297  if (drawBubble) {
298  setColor(s, true);
299  // recognize full transparency and simply don't draw
300  glGetFloatv(GL_CURRENT_COLOR, color);
301  if (color[3] != 0) {
302  glPushMatrix();
303  glTranslated(myNBNode.getPosition().x(), myNBNode.getPosition().y(), getType() + 0.05);
304  if (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo(myNBNode.getPosition()) <= (circleWidthSquared + 2))) {
305  std::vector<Position> vertices = GLHelper::drawFilledCircleReturnVertices(circleWidth, circleResolution);
306  // check if dotted contour has to be drawn
307  if (!s.drawForSelecting && myNet->getViewNet()->getACUnderCursor() == this) {
309  }
310  } else {
311  GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);
312  }
313  glPopMatrix();
314  }
315  }
316  // draw TLS icon if isn't being drawn for selecting
318  glPushMatrix();
319  Position pos = myNBNode.getPosition();
320  glTranslated(pos.x(), pos.y(), getType() + 0.1);
321  glColor3d(1, 1, 1);
322  const double halfWidth = 32 / s.scale;
323  const double halfHeight = 64 / s.scale;
324  GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GNETEXTURE_TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
325  glPopMatrix();
326  }
327  // draw crossings
328  for (auto it : myGNECrossings) {
329  it->drawGL(s);
330  }
331  // (optional) draw name @todo expose this setting if isn't drawed if isn't being drawn for selecting
332  if (!s.drawForSelecting) {
334  }
335  }
336  glPopName();
337 }
338 
339 Boundary
341  return myJunctionBoundary;
342 }
343 
344 
345 NBNode*
347  return &myNBNode;
348 }
349 
350 
351 Position
353  return myNBNode.getPosition();
354 }
355 
356 
357 std::vector<GNEJunction*>
359  // use set to avoid duplicates junctions
360  std::set<GNEJunction*> junctions;
361  for (auto i : myGNEIncomingEdges) {
362  junctions.insert(i->getGNEJunctionSource());
363  }
364  for (auto i : myGNEOutgoingEdges) {
365  junctions.insert(i->getGNEJunctionDestiny());
366  }
367  return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
368 }
369 
370 
371 void
373  // Check if incoming edge was already inserted
374  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
375  if (i != myGNEIncomingEdges.end()) {
376  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + toString(getTag()) + " with ID " + getID() + "'");
377  } else {
378  // Add edge into containers
379  myGNEIncomingEdges.push_back(edge);
380  myGNEEdges.push_back(edge);
381  }
382 }
383 
384 
385 
386 void
388  // Check if outgoing edge was already inserted
389  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
390  if (i != myGNEOutgoingEdges.end()) {
391  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + toString(getTag()) + " with ID " + getID() + "'");
392  } else {
393  // Add edge into containers
394  myGNEOutgoingEdges.push_back(edge);
395  myGNEEdges.push_back(edge);
396  }
397 }
398 
399 
400 void
402  // Check if incoming edge was already inserted
403  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
404  if (i == myGNEIncomingEdges.end()) {
405  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + toString(getTag()) + " with ID " + getID() + "'");
406  } else {
407  // remove edge from containers
408  myGNEIncomingEdges.erase(i);
409  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
410  }
411 }
412 
413 
414 void
416  // Check if outgoing edge was already inserted
417  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
418  if (i == myGNEOutgoingEdges.end()) {
419  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + toString(getTag()) + " with ID " + getID() + "'");
420  } else {
421  // remove edge from containers
422  myGNEOutgoingEdges.erase(i);
423  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
424  }
425 }
426 
427 
428 const std::vector<GNEEdge*>&
430  return myGNEEdges;
431 }
432 
433 
434 const std::vector<GNEEdge*>&
436  return myGNEIncomingEdges;
437 }
438 
439 
440 const std::vector<GNEEdge*>&
442  return myGNEOutgoingEdges;
443 }
444 
445 
446 const std::vector<GNECrossing*>&
448  return myGNECrossings;
449 }
450 
451 
452 std::vector<GNEConnection*>
454  std::vector<GNEConnection*> connections;
455  for (auto i : myGNEIncomingEdges) {
456  for (auto j : i->getGNEConnections()) {
457  connections.push_back(j);
458  }
459  }
460  return connections;
461 }
462 
463 
464 void
466  myAmCreateEdgeSource = true;
467 }
468 
469 
470 void
472  myAmCreateEdgeSource = false;
473 }
474 
475 
476 void
477 GNEJunction::selectTLS(bool selected) {
478  myAmTLSSelected = selected;
479 }
480 
481 
482 void
483 GNEJunction::startGeometryMoving(bool extendToNeighbors) {
484  // save current centering boundary
486  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
487  std::set<GNEJunction*> affectedJunctions;
488  std::set<GNEEdge*> affectedEdges;
489  // Iterate over GNEEdges
490  for (auto i : myGNEEdges) {
491  // Add source and destiny junctions
492  affectedJunctions.insert(i->getGNEJunctionSource());
493  affectedJunctions.insert(i->getGNEJunctionDestiny());
494  // Obtain neighbors of Junction source
495  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
496  affectedEdges.insert(j);
497  }
498  // Obtain neighbors of Junction destiny
499  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
500  affectedEdges.insert(j);
501  }
502  }
503  // Iterate over affected Junctions only if extendToNeighbors is enabled
504  if (extendToNeighbors) {
505  for (auto i : affectedJunctions) {
506  // don't include this junction (to avoid start more than one times)
507  if (i != this) {
508  // start geometry moving in edges
509  i->startGeometryMoving(false);
510  }
511  }
512  }
513  // Iterate over affected Edges
514  for (auto i : affectedEdges) {
515  // start geometry moving in edges
516  i->startGeometryMoving();
517  }
518 }
519 
520 
521 void
522 GNEJunction::endGeometryMoving(bool extendToNeighbors) {
523  // Remove object from net
525  // reset myMovingGeometryBoundary
527  // update geometry without updating grid
528  updateGeometry(false);
529  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
530  std::set<GNEJunction*> affectedJunctions;
531  std::set<GNEEdge*> affectedEdges;
532  // Iterate over GNEEdges
533  for (auto i : myGNEEdges) {
534  // Add source and destiny junctions
535  affectedJunctions.insert(i->getGNEJunctionSource());
536  affectedJunctions.insert(i->getGNEJunctionDestiny());
537  // Obtain neighbors of Junction source
538  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
539  affectedEdges.insert(j);
540  }
541  // Obtain neighbors of Junction destiny
542  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
543  affectedEdges.insert(j);
544  }
545  }
546  // Iterate over affected Junctions
547  if (extendToNeighbors) {
548  for (auto i : affectedJunctions) {
549  // don't include this junction (to avoid end it more than one times)
550  if (i != this) {
551  // end geometry moving in edges
552  i->endGeometryMoving(false);
553  }
554  }
555  }
556  // Iterate over affected Edges
557  for (auto i : affectedEdges) {
558  // end geometry moving in edges
559  i->endGeometryMoving();
560  }
561  // add object into grid again (using the new centering boundary)
562  myNet->addGLObjectIntoGrid(this);
563 }
564 
565 
566 void
567 GNEJunction::moveGeometry(const Position& oldPos, const Position& offset) {
568  // Abort moving if there is another junction in the exactly target position
569  bool abort = false;
570  std::vector<GNEJunction*> junctionNeighbours = getJunctionNeighbours();
571  for (auto i : junctionNeighbours) {
572  if (i->getPositionInView() == myNBNode.getPosition()) {
573  abort = true;
574  }
575  }
576  if (!abort) {
577  Position newPosition = oldPos;
578  newPosition.add(offset);
579  moveJunctionGeometry(newPosition, false);
580  }
581 }
582 
583 
584 void
587  undoList->p_begin("position of " + toString(getTag()));
588  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_POSITION, toString(myNBNode.getPosition()), true, toString(oldPos)));
589  undoList->p_end();
590  } else {
591  // tried to set an invalid position, revert back to the previous one
592  moveJunctionGeometry(oldPos, true);
593  }
594 }
595 
596 
597 void
599  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
600  std::set<GNEJunction*> affectedJunctions;
601  std::set<GNEEdge*> affectedEdges;
602  // Iterate over GNEEdges
603  for (auto i : myGNEEdges) {
604  // Add source and destiny junctions
605  affectedJunctions.insert(i->getGNEJunctionSource());
606  affectedJunctions.insert(i->getGNEJunctionDestiny());
607  // Obtain neighbors of Junction source
608  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
609  affectedEdges.insert(j);
610  }
611  // Obtain neighbors of Junction destiny
612  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
613  affectedEdges.insert(j);
614  }
615  }
616  // Iterate over affected Junctions only if updateGrid is enabled
617  if (updateGrid) {
618  for (auto i : affectedJunctions) {
619  // Update geometry of Junction
620  i->updateGeometry(updateGrid);
621  }
622  }
623  // Iterate over affected Edges
624  for (auto i : affectedEdges) {
625  // Update edge geometry
626  i->updateGeometry(updateGrid);
627  }
628  // Finally update geometry of this junction
629  updateGeometry(updateGrid);
630  // Update view to show the new shapes
631  if (myNet->getViewNet()) {
632  myNet->getViewNet()->update();
633  }
634 }
635 
636 
637 void
639  if (!myNBNode.hasCustomShape()) {
640  myNBNode.myPoly.clear();
642  }
643 }
644 
645 
646 void
647 GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
648  myHasValidLogic = valid;
649  if (!valid) {
650  assert(undoList != 0);
651  assert(undoList->hasCommandGroup());
653  EdgeVector incoming = myNBNode.getIncomingEdges();
654  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
655  GNEEdge* srcEdge = myNet->retrieveEdge((*it)->getID());
656  removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
657  undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, status), true);
658  }
659  undoList->add(new GNEChange_Attribute(this, GNE_ATTR_MODIFICATION_STATUS, status), true);
660  invalidateTLS(undoList);
661  } else {
662  // logic valed, then rebuild GNECrossings to adapt it to the new logic
663  // (but don't rebuild the crossings in NBNode because they are already finished)
664  rebuildGNECrossings(false);
665  }
666 }
667 
668 
669 void
670 GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
671  NBEdge* srcNBE = edge->getNBEdge();
672  NBEdge* turnEdge = srcNBE->getTurnDestination();
673  // Make a copy of connections
674  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
675  // delete in reverse so that undoing will add connections in the original order
676  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
677  if (lane >= 0 && (*con_it).fromLane != lane) {
678  continue;
679  }
680  bool hasTurn = con_it->toEdge == turnEdge;
681  undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
682  // needs to come after GNEChange_Connection
683  // XXX bug: this code path will not be used on a redo!
684  if (hasTurn) {
685  myNet->addExplicitTurnaround(srcNBE->getID());
686  }
687  }
688  if (updateTLS) {
689  std::vector<NBConnection> removeConnections;
690  for (NBEdge::Connection con : connections) {
691  removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
692  }
693  removeTLSConnections(removeConnections, undoList);
694  }
695 }
696 
697 
698 void
699 GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
700  NBEdge* destNBE = edge->getNBEdge();
701  std::vector<NBConnection> removeConnections;
702  for (NBEdge* srcNBE : myNBNode.getIncomingEdges()) {
703  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
704  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
705  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
706  if ((*con_it).toEdge == destNBE) {
707  if (lane >= 0 && (*con_it).toLane != lane) {
708  continue;
709  }
710  bool hasTurn = srcNBE->getTurnDestination() == destNBE;
711  undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
712  // needs to come after GNEChange_Connection
713  // XXX bug: this code path will not be used on a redo!
714  if (hasTurn) {
715  myNet->addExplicitTurnaround(srcNBE->getID());
716  }
717  removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
718  }
719  }
720  }
721  if (updateTLS) {
722  removeTLSConnections(removeConnections, undoList);
723  }
724 }
725 
726 
727 void
728 GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
729  if (connections.size() == 0) {
730  return;
731  }
732  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
733  for (auto it : coypOfTls) {
734  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
735  // guessed TLS (NBOwnTLDef) do not need to be updated
736  if (tlDef != 0) {
737  std::string newID = tlDef->getID();
738  // create replacement before deleting the original because deletion will mess up saving original nodes
739  NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
740  for (NBConnection& con : connections) {
741  replacementDef->removeConnection(con);
742  }
743  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
744  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
745  // the removed traffic light may have controlled more than one junction. These too have become invalid now
746  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
747  for (auto it_node : copyOfNodes) {
748  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
749  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
750  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
751  }
752  }
753  }
754 }
755 
756 
757 void
759  // remap connections of the edge
760  assert(which->getLanes().size() == by->getLanes().size());
761  std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
762  for (NBEdge::Connection& c : connections) {
763  undoList->add(new GNEChange_Connection(which, c, false, false), true);
764  undoList->add(new GNEChange_Connection(by, c, false, true), true);
765  }
766  // also remap tls connections
767  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
768  for (auto it : coypOfTls) {
769  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
770  // guessed TLS (NBOwnTLDef) do not need to be updated
771  if (tlDef != 0) {
772  std::string newID = tlDef->getID();
773  // create replacement before deleting the original because deletion will mess up saving original nodes
774  NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
775  for (int i = 0; i < (int)which->getLanes().size(); ++i) {
776  replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i);
777  }
778  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
779  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
780  // the removed traffic light may have controlled more than one junction. These too have become invalid now
781  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
782  for (auto it_node : copyOfNodes) {
783  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
784  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
785  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
786  }
787  }
788  }
789 }
790 
791 
792 void
794  EdgeVector incoming = myNBNode.getIncomingEdges();
795  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
796  NBEdge* srcNBE = *it;
797  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
798  undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, FEATURE_MODIFIED), true);
799  }
800 }
801 
802 
803 void
804 GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
805  assert(undoList->hasCommandGroup());
806  // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
807  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
808  for (auto it : coypOfTls) {
809  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
810  if (tlDef != 0) {
811  NBTrafficLightDefinition* replacementDef = 0;
812  std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
813  if (deletedConnection != NBConnection::InvalidConnection) {
814  // create replacement before deleting the original because deletion will mess up saving original nodes
815  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
816  repl->removeConnection(deletedConnection);
817  replacementDef = repl;
818  } else if (addedConnection != NBConnection::InvalidConnection) {
819  if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
820  // custom tl indices of crossings might become invalid upon recomputation so we must save them
821  // however, the could remain valud so we register a change but keep them at their old value
822  for (GNECrossing* c : myGNECrossings) {
823  const std::string oldValue = c->getAttribute(SUMO_ATTR_TLLINKINDEX);
825  undoList->add(new GNEChange_Attribute(c, SUMO_ATTR_TLLINKINDEX, oldValue), true);
826  const std::string oldValue2 = c->getAttribute(SUMO_ATTR_TLLINKINDEX);
828  undoList->add(new GNEChange_Attribute(c, SUMO_ATTR_TLLINKINDEX2, oldValue2), true);
829  }
830  }
831  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
832  repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
833  addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex());
834  replacementDef = repl;
835  } else {
836  replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
837  replacementDef->setProgramID(tlDef->getProgramID());
838  }
839  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
840  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
841  // the removed traffic light may have controlled more than one junction. These too have become invalid now
842  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
843  for (auto it_node : copyOfNodes) {
844  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
845  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
846  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
847  }
848  }
849  }
850 }
851 
852 void
854  // obtain a copy of GNECrossing of junctions
855  auto copyOfGNECrossings = myGNECrossings;
856  // iterate over copy of GNECrossings
857  for (int i = 0; i < (int)myGNECrossings.size(); i++) {
858  auto c = myGNECrossings.at(i);
859  // obtain the set of edges vinculated with the crossing (due it works as ID)
860  EdgeSet edgeSet(c->getCrossingEdges().begin(), c->getCrossingEdges().end());
861  // If this edge is part of the set of edges of crossing
862  if (edgeSet.count(edge->getNBEdge()) == 1) {
863  // delete crossing if this is their last edge
864  if ((c->getCrossingEdges().size() == 1) && (c->getCrossingEdges().front() == edge->getNBEdge())) {
865  myNet->deleteCrossing(c, undoList);
866  i = 0;
867  } else {
868  // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
869  std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(c->getAttribute(SUMO_ATTR_EDGES));
870  edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
871  c->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
872  }
873  }
874  }
875 }
876 
877 
878 bool
880  return myHasValidLogic;
881 }
882 
883 
885 GNEJunction::retrieveGNECrossing(NBNode::Crossing* crossing, bool createIfNoExist) {
886  // iterate over all crossing
887  for (auto i : myGNECrossings) {
888  // if found, return it
889  if (i->getCrossingEdges() == crossing->edges) {
890  return i;
891  }
892  }
893  if (createIfNoExist) {
894  // create new GNECrossing
895  GNECrossing* createdGNECrossing = new GNECrossing(this, crossing->edges);
896  // show extra information for tests
897  WRITE_DEBUG("Created " + toString(createdGNECrossing->getTag()) + " '" + createdGNECrossing->getID() + "' in retrieveGNECrossing()");
898  // insert it in Tree
899  myNet->addGLObjectIntoGrid(createdGNECrossing);
900  // update geometry after creating
901  createdGNECrossing->updateGeometry(true);
902  return createdGNECrossing;
903  } else {
904  return nullptr;
905  }
906 }
907 
908 
909 void
910 GNEJunction::markConnectionsDeprecated(bool includingNeighbours) {
911  // only it's needed to mark the connections of incoming edges
912  for (auto i : myGNEIncomingEdges) {
913  for (auto j : i->getGNEConnections()) {
914  j->markConnectionGeometryDeprecated();
915  }
916  if (includingNeighbours) {
917  i->getGNEJunctionSource()->markConnectionsDeprecated(false);
918  }
919  }
920 }
921 
922 
923 std::string
925  switch (key) {
926  case SUMO_ATTR_ID:
927  return getMicrosimID();
928  case SUMO_ATTR_POSITION:
929  return toString(myNBNode.getPosition());
930  case SUMO_ATTR_TYPE:
931  return toString(myNBNode.getType());
933  return myLogicStatus;
934  case SUMO_ATTR_SHAPE:
935  return toString(myNBNode.getShape());
936  case SUMO_ATTR_RADIUS:
937  return toString(myNBNode.getRadius());
938  case SUMO_ATTR_TLTYPE:
939  // @todo this causes problems if the node were to have multiple programs of different type (plausible)
940  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getType()) : "";
941  case SUMO_ATTR_TLID:
942  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getID()) : "";
944  // keep clear is only used as a convenience feature in plain xml
945  // input. When saving to .net.xml the status is saved only for the connections
946  // to show the correct state we must check all connections
947  if (!myNBNode.getKeepClear()) {
948  return toString(false);
949  } else {
950  for (auto i : myGNEIncomingEdges) {
951  for (auto j : i->getGNEConnections()) {
952  if (j->getNBEdgeConnection().keepClear) {
953  return toString(true);
954  }
955  }
956  }
957  return toString(false);
958  }
959  case GNE_ATTR_SELECTED:
961  case GNE_ATTR_GENERIC:
962  return getGenericParametersStr();
963  default:
964  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
965  }
966 }
967 
968 
969 void
970 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
971  if (value == getAttribute(key)) {
972  return; //avoid needless changes, later logic relies on the fact that attributes have changed
973  }
974  switch (key) {
975  case SUMO_ATTR_ID:
976  case SUMO_ATTR_POSITION:
978  case SUMO_ATTR_SHAPE:
979  case SUMO_ATTR_RADIUS:
980  case SUMO_ATTR_TLTYPE:
981  case GNE_ATTR_SELECTED:
982  case GNE_ATTR_GENERIC:
983  undoList->add(new GNEChange_Attribute(this, key, value), true);
984  break;
986  // change Keep Clear attribute in all connections
987  undoList->p_begin("change keepClear for whole junction");
988  for (auto i : myGNEIncomingEdges) {
989  for (auto j : i->getGNEConnections()) {
990  undoList->add(new GNEChange_Attribute(j, key, value), true);
991  }
992  }
993  undoList->add(new GNEChange_Attribute(this, key, value), true);
994  undoList->p_end();
995  break;
996  case SUMO_ATTR_TYPE: {
997  undoList->p_begin("change " + toString(getTag()) + " type");
999  if (getNBNode()->isTLControlled() &&
1000  // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
1003  ) {
1004  // make a copy because we will modify the original
1005  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1006  for (auto it : copyOfTls) {
1007  undoList->add(new GNEChange_TLS(this, it, false), true);
1008  }
1009  }
1010  if (!getNBNode()->isTLControlled()) {
1011  // create new traffic light
1012  undoList->add(new GNEChange_TLS(this, 0, true), true);
1013  }
1014  } else if (getNBNode()->isTLControlled()) {
1015  // delete old traffic light
1016  // make a copy because we will modify the original
1017  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1018  for (auto it : copyOfTls) {
1019  undoList->add(new GNEChange_TLS(this, it, false, false), true);
1020  }
1021  }
1022  // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1023  undoList->add(new GNEChange_Attribute(this, key, value), true);
1024  undoList->p_end();
1025  break;
1026  }
1027  case SUMO_ATTR_TLID: {
1028  undoList->p_begin("change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1029  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1030  assert(copyOfTls.size() > 0);
1031  NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1032  NBTrafficLightDefinition* currentTLSCopy = 0;
1033  const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1034  const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != 0;
1035  if (currentIsLoaded) {
1036  currentTLSCopy = new NBLoadedSUMOTLDef(currentTLS,
1037  dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1038  }
1039  // remove from previous tls
1040  for (auto it : copyOfTls) {
1041  undoList->add(new GNEChange_TLS(this, it, false), true);
1042  }
1044  // programs to which the current node shall be added
1045  const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1046  if (programs.size() > 0) {
1047  for (auto it : programs) {
1048  NBTrafficLightDefinition* oldTLS = it.second;
1049  if (dynamic_cast<NBOwnTLDef*>(oldTLS) != 0) {
1050  undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1051  } else {
1052  // delete and re-create the definition because the loaded phases are now invalid
1053  if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != 0 &&
1054  dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1055  // keep the old program and add all-red state for the added links
1056  NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(oldTLS, dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1057  newTLSJoined->joinLogic(currentTLSCopy);
1058  undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1059  } else {
1060  undoList->add(new GNEChange_TLS(this, 0, true, false, value), true);
1061  }
1063  // switch from old to new definition
1064  const std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1065  for (auto it_node : copyOfNodes) {
1066  GNEJunction* oldJunction = myNet->retrieveJunction(it_node->getID());
1067  undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1068  undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1069  }
1070  }
1071  }
1072  } else {
1073  if (currentIsSingle && currentIsLoaded) {
1074  // rename the traffic light but keep everything else
1075  NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1076  renamedLogic->setID(value);
1077  NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(currentTLSCopy, renamedLogic);
1078  renamedTLS->setID(value);
1079  undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1080  } else {
1081  // create new traffic light
1082  undoList->add(new GNEChange_TLS(this, 0, true, false, value), true);
1083  }
1084  }
1085  delete currentTLSCopy;
1086  undoList->p_end();
1087  break;
1088  }
1089  default:
1090  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
1091  }
1092 }
1093 
1094 
1095 bool
1096 GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1097  switch (key) {
1098  case SUMO_ATTR_ID:
1099  return SUMOXMLDefinitions::isValidNetID(value) && (myNet->retrieveJunction(value, false) == 0);
1100  case SUMO_ATTR_TYPE:
1102  case SUMO_ATTR_POSITION: {
1103  bool ok;
1104  return GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false).size() == 1;
1105  }
1106  case SUMO_ATTR_SHAPE: {
1107  bool ok = true;
1108  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true);
1109  return ok;
1110  }
1111  case SUMO_ATTR_RADIUS:
1112  return canParse<double>(value);
1113  case SUMO_ATTR_TLTYPE:
1115  case SUMO_ATTR_TLID:
1116  return myNBNode.isTLControlled() && (value != "");
1117  case SUMO_ATTR_KEEP_CLEAR:
1118  return canParse<bool>(value);
1119  case GNE_ATTR_SELECTED:
1120  return canParse<bool>(value);
1121  case GNE_ATTR_GENERIC:
1122  return isGenericParametersValid(value);
1123  default:
1124  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
1125  }
1126 }
1127 
1128 
1129 bool
1130 GNEJunction::addGenericParameter(const std::string& key, const std::string& value) {
1131  if (!myNBNode.knowsParameter(key)) {
1132  myNBNode.setParameter(key, value);
1133  return true;
1134  } else {
1135  return false;
1136  }
1137 }
1138 
1139 
1140 bool
1141 GNEJunction::removeGenericParameter(const std::string& key) {
1142  if (myNBNode.knowsParameter(key)) {
1143  myNBNode.unsetParameter(key);
1144  return true;
1145  } else {
1146  return false;
1147  }
1148 }
1149 
1150 
1151 bool
1152 GNEJunction::updateGenericParameter(const std::string& oldKey, const std::string& newKey) {
1153  if (myNBNode.knowsParameter(oldKey) && !myNBNode.knowsParameter(newKey)) {
1154  std::string value = myNBNode.getParameter(oldKey);
1155  myNBNode.unsetParameter(oldKey);
1156  myNBNode.setParameter(newKey, value);
1157  return true;
1158  } else {
1159  return false;
1160  }
1161 }
1162 
1163 
1164 bool
1165 GNEJunction::updateGenericParameterValue(const std::string& key, const std::string& newValue) {
1166  if (myNBNode.knowsParameter(key)) {
1167  myNBNode.setParameter(key, newValue);
1168  return true;
1169  } else {
1170  return false;
1171  }
1172 }
1173 
1174 
1175 std::string
1177  std::string result;
1178  // Generate an string using the following structure: "key1=value1|key2=value2|...
1179  for (auto i : myNBNode.getParametersMap()) {
1180  result += i.first + "=" + i.second + "|";
1181  }
1182  // remove the last "|"
1183  if (!result.empty()) {
1184  result.pop_back();
1185  }
1186  return result;
1187 }
1188 
1189 
1190 std::vector<std::pair<std::string, std::string> >
1192  std::vector<std::pair<std::string, std::string> > result;
1193  // iterate over parameters map and fill result
1194  for (auto i : myNBNode.getParametersMap()) {
1195  result.push_back(std::make_pair(i.first, i.second));
1196  }
1197  return result;
1198 }
1199 
1200 
1201 void
1202 GNEJunction::setGenericParametersStr(const std::string& value) {
1203  // clear parameters
1205  // separate value in a vector of string using | as separator
1206  std::vector<std::string> parsedValues;
1207  StringTokenizer stValues(value, "|", true);
1208  while (stValues.hasNext()) {
1209  parsedValues.push_back(stValues.next());
1210  }
1211  // check that parsed values (A=B)can be parsed in generic parameters
1212  for (auto i : parsedValues) {
1213  std::vector<std::string> parsedParameters;
1214  StringTokenizer stParam(i, "=", true);
1215  while (stParam.hasNext()) {
1216  parsedParameters.push_back(stParam.next());
1217  }
1218  // Check that parsed parameters are exactly two and contains valid chracters
1219  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1220  myNBNode.setParameter(parsedParameters.front(), parsedParameters.back());
1221  }
1222  }
1223 }
1224 
1225 
1226 void
1228  myAmResponsible = newVal;
1229 }
1230 
1231 // ===========================================================================
1232 // private
1233 // ===========================================================================
1234 
1235 void
1236 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1237  switch (key) {
1238  case SUMO_ATTR_ID: {
1239  myNet->renameJunction(this, value);
1240  break;
1241  }
1242  case SUMO_ATTR_TYPE: {
1244  break;
1245  }
1246  case SUMO_ATTR_POSITION: {
1247  // set new position in NBNode (note: Junctions don't need to refresh it in the RTREE due the variable myJunctionBoundary
1248  bool ok;
1249  moveJunctionGeometry(GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0], true);
1250  // mark this connections and all of the junction's Neighbours as deprecated
1252  break;
1253  }
1255  if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1256  // clear guessed connections. previous connections will be restored
1258  // Clear GNEConnections of incoming edges
1259  for (auto i : myGNEIncomingEdges) {
1260  i->clearGNEConnections();
1261  }
1262  }
1263  myLogicStatus = value;
1264  break;
1265  case SUMO_ATTR_SHAPE: {
1266  bool ok;
1267  const PositionVector shape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
1268  myNBNode.setCustomShape(shape);
1269  // mark this connections and all of the junction's Neighbours as deprecated
1271  break;
1272  }
1273  case SUMO_ATTR_RADIUS: {
1274  myNBNode.setRadius(parse<double>(value));
1275  break;
1276  }
1277  case SUMO_ATTR_TLTYPE: {
1278  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1279  for (auto it : copyOfTls) {
1280  it->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
1281  }
1282  break;
1283  }
1284  case SUMO_ATTR_KEEP_CLEAR: {
1285  myNBNode.setKeepClear(parse<bool>(value));
1286  break;
1287  }
1288  case GNE_ATTR_SELECTED:
1289  if (parse<bool>(value)) {
1291  } else {
1293  }
1294  break;
1295  case GNE_ATTR_GENERIC:
1296  setGenericParametersStr(value);
1297  break;
1298  default:
1299  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
1300  }
1301  // After setting attribute always update Geometry
1302  updateGeometry(true);
1303 }
1304 
1305 
1306 void
1308  // only continue if there isn't already a AC under cursor
1309  if (myNet->getViewNet()->getACUnderCursor() == nullptr) {
1310  // obtain current x-y coordinates
1312  // check if junction are drawn as buuble or as polygon
1313  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
1314  const bool drawBubble = (((!drawShape || myNBNode.getShape().area() < 4) && s.drawJunctionShape) || myNet->getViewNet()->showJunctionAsBubbles());
1315  // declare values for circles
1316  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
1317  exaggeration *= s.junctionSize.getExaggeration(s);
1318  double circleWidth = BUBBLE_RADIUS * exaggeration;
1319  double circleWidthSquared = circleWidth * circleWidth;
1320  if (drawBubble) {
1321  // check if cursor is whithin the circle
1322  if (myNet->getViewNet()->getPositionInformation().distanceSquaredTo(myNBNode.getPosition()) <= circleWidthSquared) {
1323  myNet->getViewNet()->setACUnderCursor(this);
1324  }
1325  } else if (drawShape) {
1326  // check if cursor is within the shape
1327  if (myNBNode.getShape().around(mousePos)) {
1328  myNet->getViewNet()->setACUnderCursor(this);
1329  }
1330  }
1331  }
1332 }
1333 
1334 
1335 double
1337  switch (s.junctionColorer.getActive()) {
1338  case 0:
1339  if (bubble) {
1340  return 1;
1341  } else {
1342  return 0;
1343  }
1344  case 1:
1345  return isAttributeCarrierSelected();
1346  case 2:
1347  switch (myNBNode.getType()) {
1349  return 0;
1351  return 1;
1352  case NODETYPE_PRIORITY:
1353  return 2;
1355  return 3;
1357  return 4;
1358  case NODETYPE_ALLWAY_STOP:
1359  return 5;
1360  case NODETYPE_DISTRICT:
1361  return 6;
1362  case NODETYPE_NOJUNCTION:
1363  return 7;
1364  case NODETYPE_DEAD_END:
1366  return 8;
1367  case NODETYPE_UNKNOWN:
1368  case NODETYPE_INTERNAL:
1369  assert(false);
1370  return 8;
1371  case NODETYPE_RAIL_SIGNAL:
1372  return 9;
1373  case NODETYPE_ZIPPER:
1374  return 10;
1376  return 11;
1378  return 12;
1379  }
1380  case 3:
1381  return myNBNode.getPosition().z();
1382  default:
1383  assert(false);
1384  return 0;
1385  }
1386 }
1387 
1388 
1389 void
1390 GNEJunction::moveJunctionGeometry(const Position& pos, bool updateGrid) {
1391  const Position orig = myNBNode.getPosition();
1392  myNBNode.reinit(pos, myNBNode.getType());
1393  // set new position of adjacent edges
1394  for (auto i : getNBNode()->getEdges()) {
1395  myNet->retrieveEdge(i->getID())->updateJunctionPosition(this, orig, updateGrid);
1396  }
1397  // Update shapes without include connections, because the aren't showed in Move mode
1398  updateShapesAndGeometries(updateGrid);
1399 }
1400 
1401 
1402 void
1403 GNEJunction::setColor(const GUIVisualizationSettings& s, bool bubble) const {
1405  // override with special colors (unless the color scheme is based on selection)
1408  }
1409  if (myAmCreateEdgeSource) {
1410  glColor3d(0, 1, 0);
1411  }
1412 }
1413 
1414 void
1417  tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
1418  tlDef->addNode(&myNBNode);
1419 }
1420 
1421 
1422 void
1425  if (tlDef->getNodes().size() == 1) {
1426  tlCont.extract(tlDef);
1427  }
1429 }
1430 
1431 /****************************************************************************/
GUIVisualizationSizeSettings junctionSize
bool getKeepClear() const
Returns the keepClear flag.
Definition: NBNode.h:276
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition: GNEJunction.h:293
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
GUIVisualizationTextSettings junctionName
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
void removeConnection(const NBConnection &conn, bool reconstruct=true)
removes the given connection from the traffic light if recontruct=true, reconstructs the logic and in...
bool myHasValidLogic
whether this junctions logic is valid
Definition: GNEJunction.h:296
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
static const std::string FEATURE_MODIFIED
feature has been manually modified (implies approval)
double myMaxSize
The maximum size (in either x-, or y-dimension) for determining whether to draw or not...
Definition: GNEJunction.h:283
const GNEAttributeCarrier * getACUnderCursor() const
get AttributeCarrier under cursor
Position getPositionInView() const
Return current position.
std::string myLogicStatus
modification status of the junction logic (all connections across this junction)
Definition: GNEJunction.h:290
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:160
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
static StringBijection< SumoXMLNodeType > NodeTypes
node types
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:915
double scale
information about a lane&#39;s width (temporary, used for a single view)
Whether vehicles must keep the junction clear.
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
GNENet * myNet
the net to inform about updates
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
std::string next()
void invalidateShape()
void moveJunctionGeometry(const Position &pos, bool updateGrid)
reposition the node at pos and informs the edges
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
double z() const
Returns the z-position.
Definition: Position.h:66
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
begin/end of the description of a junction
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:126
PositionVector myPoly
the (outer) shape of the junction
Definition: NBNode.h:796
void markAsCreateEdgeSource()
marks as first junction in createEdge-mode
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1407
A loaded (complete) traffic light logic.
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
Definition: GNEJunction.h:287
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static const NBConnection InvalidConnection
Definition: NBConnection.h:121
A container for traffic light definitions and built programs.
A SUMO-compliant built logic for a traffic light.
std::vector< GNEEdge * > myGNEIncomingEdges
vector with the incomings GNEEdges vinculated with this junction
Definition: GNEJunction.h:277
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:284
bool isValid(SumoXMLAttr key, const std::string &value)
friend class GNEChange_TLS
Declare friend class.
Definition: GNEJunction.h:51
Stores the information about how to visualize structures.
edit junction shape
Definition: GUIAppEnum.h:724
double y() const
Returns the y-position.
Definition: Position.h:61
bool hasCustomShape() const
return whether the shape was set by the user
Definition: NBNode.h:494
The representation of a single edge during network building.
Definition: NBEdge.h:65
TrafficLightType getType() const
get the algorithm type (static etc..)
void unsetParameter(const std::string &key)
Removes a parameter.
double x() const
Returns the x-position.
Definition: Position.h:56
mode for editing tls
Definition: GNEViewNet.h:58
The base class for traffic light logic definitions.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void removeTLSConnections(std::vector< NBConnection > &connections, GNEUndoList *undoList)
remove the given connections from all traffic light definitions of this junction
link,node: the traffic light id responsible for this link
T MAX2(T a, T b)
Definition: StdDefs.h:76
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:155
std::string getGenericParametersStr() const
return generic parameters in string format
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:80
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2981
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:78
int editMode
the current NETEDIT mode (temporary)
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:78
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition: GNENet.cpp:1783
NBEdge * getFrom() const
returns the from-edge (start of the connection)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
const std::string & getID() const
Returns the id.
Definition: Named.h:69
bool myAmTLSSelected
whether this junction is selected in tls-mode
Definition: GNEJunction.h:299
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition: NBNode.cpp:345
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1917
void startGeometryMoving(bool extendToNeighbors=true)
begin movement (used when user click over edge to start a movement, to avoid problems with problems w...
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
const std::vector< GNEEdge * > & getGNEEdges() const
Returns all GNEEdges vinculated with this Junction.
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
removes a traffic light
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.
Boundary getBoundary() const
Returns the boundary of the junction.
turn junction into geometry node
Definition: GUIAppEnum.h:720
generic attribute
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
void markConnectionsDeprecated(bool includingNeighbours)
mark connections as deprecated
Boundary myMovingGeometryBoundary
boundary used during moving of elements
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces a removed edge/lane.
link: the index of the opposite direction link of a pedestrian crossing
whether a feature has been loaded,guessed,modified or approved
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:254
double area() const
Returns the area (0 for non-closed)
SUMOTime getOffset()
Returns the offset.
void renameJunction(GNEJunction *junction, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1771
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:97
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
void updateGeometry(bool updateGrid)
update pre-computed geometry information
Definition: GNECrossing.cpp:64
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:484
std::string getAttribute(SumoXMLAttr key) const
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:297
void invalidateIncomingConnections()
invalidate incoming connections
Definition: NBNode.cpp:1450
void mouseOverObject(const GUIVisualizationSettings &s) const
method for check if mouse is over objects
static const int InvalidTlIndex
Definition: NBConnection.h:120
The turning radius at an intersection in m.
static bool isValidGenericParameterValue(const std::string &value)
whether the given string is a valid value for a generic parameter
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:46
void removeConnectionsFrom(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections from the given edge
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
bool hasCommandGroup() const
Check if undoList has command group.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:573
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:45
std::vector< std::pair< std::string, std::string > > getGenericParameters() const
return generic parameters as vector of pairs format
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
bool updateGenericParameter(const std::string &oldKey, const std::string &newKey)
update generic parameter
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
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:85
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:902
A list of positions.
static bool isGenericParametersValid(const std::string &value)
check if given string can be parsed to a map/list of generic parameters
bool isLogicValid()
whether this junction has a valid logic
void removeGLObjectFromGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1175
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
Definition: NBNode.cpp:2200
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, bool reconstruct=true)
Adds a connection and immediately informs the edges.
double distanceSquaredTo(const Position &p2) const
returns the square of the distance to another position
Definition: Position.h:238
friend class GNEChange_Attribute
declare friend class
T get(const std::string &str) const
reset junction shape
Definition: GUIAppEnum.h:726
void updateGeometry(bool updateGrid)
Update the boundary of the junction.
Boundary myJunctionBoundary
junction boundary
Definition: GNEJunction.h:271
static std::vector< Position > drawFilledCircleReturnVertices(double width, int steps=8)
Draws a filled circle around (0,0) returning circle vertex.
Definition: GLHelper.cpp:350
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
registers completed movement with the undoList
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
Definition: NBNode.h:259
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
Definition: GNEViewNet.cpp:375
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
turn junction into multiple junctions
Definition: GUIAppEnum.h:722
NBTrafficLightLogic * getLogic()
Returns the internal logic.
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
node: the type of traffic light
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.
void removeConnectionsTo(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections to the given edge
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:579
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
std::vector< GNEEdge * > myGNEEdges
vector with the GNEEdges vinculated with this junction
Definition: GNEJunction.h:274
const std::string getID() const
function to support debugging
void unMarkAsCreateEdgeSource()
removes mark as first junction in createEdge-mode
void setProgramID(const std::string &programID)
Sets the programID.
const T getColor(const double value) const
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:249
const std::string & getProgramID() const
Returns the ProgramID.
void incRef(const std::string &debugMsg="")
Increarse reference.
double getColorValue(const GUIVisualizationSettings &s, bool bubble) const
determines color value
void setGenericParametersStr(const std::string &value)
set generic parameters in string format
NBNode & myNBNode
A reference to the represented junction.
Definition: GNEJunction.h:268
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
EditMode
Definition: GNEViewNet.h:42
void selectAttributeCarrier(bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
void setKeepClear(bool keepClear)
set the keepClear flag
Definition: NBNode.h:489
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition: NBNode.cpp:1821
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any) ...
begin/end of the description of an edge
void joinLogic(NBTrafficLightDefinition *def)
join nodes and states from the given logic (append red state)
void unselectAttributeCarrier(bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
EditMode getCurrentEditMode() const
get the current edit mode
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1911
int getToLane() const
returns the to-lane
NBEdge * getTo() const
returns the to-edge (end of the connection)
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
static const double BUBBLE_RADIUS
constant values for drawing buubles
Definition: GNEJunction.h:56
void reset()
Resets the boundary.
Definition: Boundary.cpp:67
bool removeGenericParameter(const std::string &key)
remove generic parameter
void setID(const std::string &newID)
resets the id
Definition: Named.h:77
reset junction&#39;s connections
Definition: GUIAppEnum.h:718
bool updateGenericParameterValue(const std::string &key, const std::string &newValue)
update value generic parameter
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:832
double selectionScale
the current selection scaling in NETEDIT (temporary)
void setACUnderCursor(const GNEAttributeCarrier *AC)
set attributeCarrier under cursor
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
Definition: GNEViewNet.cpp:263
~GNEJunction()
Destructor.
Definition: GNEJunction.cpp:80
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:271
bool haveNetworkCrossings()
notify about style of loaded network (Without Crossings)
Definition: NBNetBuilder.h:191
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:249
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:865
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:161
static void drawShapeDottedContour(const int type, const PositionVector &shape, const double width)
draw a dotted contour around the given Non closed shape with certain width
Definition: GLHelper.cpp:471
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node) ...
Definition: NBNode.h:302
void setColor(const GUIVisualizationSettings &s, bool bubble) const
sets junction color depending on circumstances
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
Definition: GNEJunction.h:302
std::vector< Position > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition: NBNode.cpp:3122
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
void updateShapesAndGeometries(bool updateGrid)
update shapes of all elements associated to the junction
void moveGeometry(const Position &oldPos, const Position &offset)
change the position of the element geometry without saving in undoList
element is selected
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:217
The popup menu of a globject.
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:266
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
static int getCircleResolution(const GUIVisualizationSettings &settings)
function to calculate circle resolution for all circles drawn in drawGL(...) functions ...
std::vector< GNEEdge * > myGNEOutgoingEdges
vector with the outgoings GNEEdges vinculated with this junction
Definition: GNEJunction.h:280
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
bool addGenericParameter(const std::string &key, const std::string &value)
add generic parameter
const Position & getPosition() const
Definition: NBNode.h:241
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:131
int getFromLane() const
returns the from-lane
Represents a single node (junction) during network building.
Definition: NBNode.h:68
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
GUIGlID getGlID() const
Returns the numerical id of the object.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
A definition of a pedestrian crossing.
Definition: NBNode.h:125
GNEJunction(NBNode &nbn, GNENet *net, bool loaded=false)
Constructor.
Definition: GNEJunction.cpp:67
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void rebuildGNECrossings(bool rebuildNBNodeCrossings=true)
rebuilds crossing objects for this junction
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
link: the index of the link within the traffic light
const std::vector< Crossing * > & getCrossingsIncludingInvalid() const
Definition: NBNode.h:636
bool drawJunctionShape
whether the shape of the junction should be drawn
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
static const RGBColor selectionColor
Definition: GNENet.h:96
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled ...
Definition: NBConnection.h:94
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
mode for connecting lanes
Definition: GNEViewNet.h:56
mode for creating new edges
Definition: GNEViewNet.h:46
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:132
bool hasString(const std::string &str) const
GNECrossing * retrieveGNECrossing(NBNode::Crossing *crossing, bool createIfNoExist=true)
get GNECrossing if exist, and if not create it if create is enabled
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:586
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:47
bool drawForSelecting
whether drawing is performed for the purpose of selecting objects
void closePolygon()
ensures that the last position equals the first
NBNode * getNBNode() const
Return net build node.
void addGLObjectIntoGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1168
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1765
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3017
static PositionVector parseShapeReporting(const std::string &shpdef, const std::string &objecttype, const char *objectid, bool &ok, bool allowEmpty, bool report=true)
Builds a PositionVector from a string representation, reporting occurred errors.
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:230
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1384
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection, const NBConnection &addedConnection=NBConnection::InvalidConnection)
void addTrafficLight(NBTrafficLightDefinition *tlDef, bool forceInsert)
adds a traffic light
clear junction&#39;s connections
Definition: GUIAppEnum.h:716
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1745
void endGeometryMoving(bool extendToNeighbors=true)
begin movement (used when user click over edge to start a movement, to avoid problems with problems w...
void clearParameter()
Clears the parameter map.
a junction
SumoXMLTag getTag() const
get XML Tag assigned to this object