SUMO - Simulation of Urban MObility
GNEConnector.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // The Widget for modifying lane-to-lane connections
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #ifdef HAVE_VERSION_H
32 #include <version.h>
33 #endif
34 
35 #include <iostream>
42 #include "GNEConnector.h"
43 #include "GNESelector.h"
44 #include "GNEViewNet.h"
45 #include "GNEChange_Connection.h"
46 #include "GNEUndoList.h"
47 #include "GNENet.h"
48 #include "GNELane.h"
49 #include "GNEInternalLane.h"
50 #include "GNEEdge.h"
51 #include "GNEJunction.h"
52 
53 #ifdef CHECK_MEMORY_LEAKS
54 #include <foreign/nvwa/debug_new.h>
55 #endif // CHECK_MEMORY_LEAKS
56 
57 
58 // ===========================================================================
59 // FOX callback mapping
60 // ===========================================================================
61 FXDEFMAP(GNEConnector) GNEConnectorMap[] = {
62  FXMAPFUNC(SEL_COMMAND, MID_CANCEL, GNEConnector::onCmdCancel),
63  FXMAPFUNC(SEL_COMMAND, MID_OK, GNEConnector::onCmdOK),
67  FXMAPFUNC(SEL_COMMAND, MID_GNE_SELECT_PASS, GNEConnector::onCmdSelectPass),
70 };
71 
72 // Object implementation
73 FXIMPLEMENT(GNEConnector, FXScrollWindow, GNEConnectorMap, ARRAYNUMBER(GNEConnectorMap))
74 
75 // ===========================================================================
76 // static members
77 // ===========================================================================
78 const int GNEConnector::WIDTH = 140;
79 RGBColor GNEConnector::sourceColor;
80 RGBColor GNEConnector::potentialTargetColor;
81 RGBColor GNEConnector::targetColor;
82 RGBColor GNEConnector::targetPassColor;
83 RGBColor GNEConnector::conflictColor;
84 
85 // ===========================================================================
86 // method definitions
87 // ===========================================================================
88 GNEConnector::GNEConnector(FXComposite* parent, GNEViewNet* updateTarget, GNEUndoList* undoList):
89  FXScrollWindow(parent, LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, WIDTH, 0),
90  myHeaderFont(new FXFont(getApp(), "Arial", 11, FXFont::Bold)),
91  myCurrentLane(0),
92  myUndoList(undoList),
93  myUpdateTarget(updateTarget) {
94  // heading
95  myContentFrame = new FXVerticalFrame(this, LAYOUT_FILL_Y | LAYOUT_FIX_WIDTH, 0, 0, WIDTH, 0);
96  FXLabel* heading = new FXLabel(myContentFrame, "Edit Connections", 0, JUSTIFY_LEFT);
97  heading->setFont(myHeaderFont);
98  myDescription = new FXLabel(myContentFrame, "", 0, JUSTIFY_LEFT);
99  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
100  updateDescription();
101 
102  // buttons
103  // "Cancel"
104  new FXButton(myContentFrame, "Cancel\t\tDiscard connection modifications (Esc)", 0, this, MID_CANCEL,
105  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
106  0, 0, 0, 0, 4, 4, 3, 3);
107  // "OK"
108  new FXButton(myContentFrame, "OK\t\tSave connection modifications (Enter)", 0, this, MID_OK,
109  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
110  0, 0, 0, 0, 4, 4, 3, 3);
111  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
112  // "Select Dead Ends"
113  new FXButton(myContentFrame,
114  "Select Dead Ends\t\tSelects all lanes that have no outgoing connection (clears previous selection)",
115  0, this, MID_GNE_SELECT_DEAD_ENDS,
116  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
117  0, 0, 0, 0, 4, 4, 3, 3);
118  // "Select Dead Starts"
119  new FXButton(myContentFrame,
120  "Select Dead Starts\t\tSelects all lanes that have no incoming connection (clears previous selection)",
122  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
123  0, 0, 0, 0, 4, 4, 3, 3);
124  // "Select Conflicts"
125  new FXButton(myContentFrame,
126  "Select Conflicts\t\tSelects all lanes with more than one incoming connection from the same edge (clears previous selection)",
127  0, this, MID_GNE_SELECT_CONFLICTS,
128  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
129  0, 0, 0, 0, 4, 4, 3, 3);
130  // "Select Edges which may always pass"
131  new FXButton(myContentFrame,
132  "Select Passing\t\tSelects all lanes with a connection that has has the 'pass' attribute set",
133  0, this, MID_GNE_SELECT_PASS,
134  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
135  0, 0, 0, 0, 4, 4, 3, 3);
136  // "Clear Selected"
137  new FXButton(myContentFrame,
138  "Clear Selected\t\tClears all connections of all selected objects",
139  0, this, MID_CHOOSEN_CLEAR,
140  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
141  0, 0, 0, 0, 4, 4, 3, 3);
142  // "Reset Selected"
143  new FXButton(myContentFrame,
144  "Reset Selected\nJunctions\t\tRecomputes connections at all selected junctions",
145  0, this, MID_CHOOSEN_RESET,
146  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
147  0, 0, 0, 0, 4, 4, 3, 3);
148 
149  new FXHorizontalSeparator(this, SEPARATOR_GROOVE | LAYOUT_FILL_X);
150  // Selection Hint
151  new FXLabel(myContentFrame, "Hold <SHIFT> while\nclicking to create\nunyielding conn's.\n", 0, JUSTIFY_LEFT);
152  new FXLabel(myContentFrame, "Hold <CTRL> while\nclicking to create\nconflicting conn's.\n", 0, JUSTIFY_LEFT);
153  // Legend
154  // init colors here to avoid static order fiasco (https://isocpp.org/wiki/faq/ctors#static-init-order)
155  sourceColor = RGBColor::CYAN;
156  potentialTargetColor = RGBColor(0, 64, 0, 255);
157  targetColor = RGBColor::GREEN;
158  targetPassColor = RGBColor::MAGENTA;
159  conflictColor = RGBColor::YELLOW;
160 
161  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
162  FXLabel* l;
163  new FXLabel(myContentFrame, "Color Legend:", 0, JUSTIFY_LEFT);
164  l = new FXLabel(myContentFrame, "Source", 0, JUSTIFY_LEFT);
165  l->setBackColor(MFXUtils::getFXColor(sourceColor));
166  l = new FXLabel(myContentFrame, "Target", 0, JUSTIFY_LEFT);
167  l->setBackColor(MFXUtils::getFXColor(targetColor));
168  l = new FXLabel(myContentFrame, "Possible Target", 0, JUSTIFY_LEFT);
169  l->setBackColor(MFXUtils::getFXColor(potentialTargetColor));
170  l = new FXLabel(myContentFrame, "Target (pass)", 0, JUSTIFY_LEFT);
171  l->setBackColor(MFXUtils::getFXColor(targetPassColor));
172  l = new FXLabel(myContentFrame, "Conflict", 0, JUSTIFY_LEFT);
173  l->setBackColor(MFXUtils::getFXColor(conflictColor));
174 }
175 
176 
178  delete myHeaderFont;
179 }
180 
181 
182 void
183 GNEConnector::handleLaneClick(GNELane* lane, bool mayDefinitelyPass, bool allowConflict, bool toggle) {
184  if (myCurrentLane == 0) {
185  myCurrentLane = lane;
187  initTargets();
189  myNumChanges = 0;
190  myUndoList->p_begin("modify connections");
191  } else if (myPotentialTargets.count(lane) || allowConflict) {
192  const unsigned int fromIndex = myCurrentLane->getIndex();
193  GNEEdge& srcEdge = myCurrentLane->getParentEdge();
194  GNEEdge& destEdge = lane->getParentEdge();
195  const std::string& destEdgeID = destEdge.getMicrosimID();
196  std::vector<NBEdge::Connection> connections = srcEdge.getNBEdge()->getConnectionsFromLane(fromIndex);
197  bool changed = false;
198  NBConnection deletedConnection = NBConnection::InvalidConnection;
199  LaneStatus status = getLaneStatus(connections, lane);
200  if (status == CONFLICTED && allowConflict) {
201  status = UNCONNECTED;
202  }
203  switch (status) {
204  case UNCONNECTED:
205  if (toggle) {
206  myUndoList->add(new GNEChange_Connection(&srcEdge, fromIndex,
207  destEdgeID, lane->getIndex(), mayDefinitelyPass, true), true);
208  lane->setSpecialColor(mayDefinitelyPass ? &targetPassColor : &targetColor);
209  changed = true;
210  }
211  break;
212  case CONNECTED:
213  case CONNECTED_PASS:
214  myUndoList->add(new GNEChange_Connection(&srcEdge, fromIndex, destEdgeID, lane->getIndex(),
215  status == CONNECTED_PASS, false), true);
217  changed = true;
218  deletedConnection = NBConnection(srcEdge.getNBEdge(), fromIndex,
219  destEdge.getNBEdge(), lane->getIndex(),
220  (int)getTLLLinkNumber(connections, lane));
221  break;
222  case CONFLICTED:
223  myUpdateTarget->setStatusBarText("Another lane from the same edge already connects to that lane");
224  break;
225  }
226  if (changed) {
227  myNumChanges += 1;
229  affected->invalidateTLS(myUndoList, deletedConnection);
231  }
232  } else {
233  myUpdateTarget->setStatusBarText("Invalid target for connection");
234  }
236 }
237 
238 
239 
240 long
241 GNEConnector::onCmdCancel(FXObject*, FXSelector, void*) {
242  if (myCurrentLane != 0) {
243  myUndoList->p_abort();
244  if (myNumChanges) {
245  myUpdateTarget->setStatusBarText("Changes reverted");
246  }
247  cleanup();
248  myUpdateTarget->update();
249  }
250  return 1;
251 }
252 
253 
254 long
255 GNEConnector::onCmdOK(FXObject*, FXSelector, void*) {
256  if (myCurrentLane != 0) {
257  myUndoList->p_end();
258  if (myNumChanges) {
259  myUpdateTarget->setStatusBarText("Changes accepted");
260  }
261  cleanup();
262  myUpdateTarget->update();
263  }
264  return 1;
265 }
266 
267 
268 long
269 GNEConnector::onCmdSelectDeadEnds(FXObject*, FXSelector, void*) {
270  std::vector<GUIGlID> selectIDs;
271  // every edge knows its outgoing connections so we can look at each edge in isolation
272  const std::vector<GNEEdge*> edges = myUpdateTarget->getNet()->retrieveEdges();
273  for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) {
274  const GNEEdge::LaneVector& lanes = (*edge_it)->getLanes();
275  for (GNEEdge::LaneVector::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
276  if ((*edge_it)->getNBEdge()->getConnectionsFromLane((*it_lane)->getIndex()).size() == 0) {
277  selectIDs.push_back((*it_lane)->getGlID());
278  }
279  }
280  }
282  return 1;
283 }
284 
285 
286 long
287 GNEConnector::onCmdSelectDeadStarts(FXObject*, FXSelector, void*) {
288  GNENet* net = myUpdateTarget->getNet();
289  std::set<GUIGlID> selectIDs;
290  // every edge knows only its outgoing connections so we look at whole junctions
291  const std::vector<GNEJunction*> junctions = net->retrieveJunctions();
292  for (std::vector<GNEJunction*>::const_iterator junction_it = junctions.begin(); junction_it != junctions.end(); junction_it++) {
293  // first collect all outgoing lanes
294  const EdgeVector& outgoing = (*junction_it)->getNBNode()->getOutgoingEdges();
295  for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
296  GNEEdge* edge = net->retrieveEdge((*it)->getID());
297  const std::set<GUIGlID> laneIDs = edge->getLaneGlIDs();
298  for (std::set<GUIGlID>::const_iterator lid_it = laneIDs.begin(); lid_it != laneIDs.end(); lid_it++) {
299  selectIDs.insert(*lid_it);
300  }
301  }
302  // then remove all approached lanes
303  const EdgeVector& incoming = (*junction_it)->getNBNode()->getIncomingEdges();
304  for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); it++) {
305  GNEEdge* edge = net->retrieveEdge((*it)->getID());
306  NBEdge* nbe = edge->getNBEdge();
307  const std::vector<NBEdge::Connection>& connections = nbe->getConnections();
308  for (std::vector<NBEdge::Connection>::const_iterator con_it = connections.begin(); con_it != connections.end(); con_it++) {
309  GNEEdge* approachedEdge = net->retrieveEdge(con_it->toEdge->getID());
310  GNELane* approachedLane = approachedEdge->getLanes()[con_it->toLane];
311  selectIDs.erase(approachedLane->getGlID());
312  }
313  }
314  }
316  std::vector<GUIGlID>(selectIDs.begin(), selectIDs.end()),
317  false, GNESelector::SET_REPLACE);
318  return 1;
319 }
320 
321 
322 long
323 GNEConnector::onCmdSelectConflicts(FXObject*, FXSelector, void*) {
324  std::vector<GUIGlID> selectIDs;
325  // conflicts happen per edge so we can look at each edge in isolation
326  const std::vector<GNEEdge*> edges = myUpdateTarget->getNet()->retrieveEdges();
327  for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) {
328  NBEdge* nbe = (*edge_it)->getNBEdge();
329  const EdgeVector destinations = nbe->getConnectedEdges();
330  const std::vector<NBEdge::Connection>& connections = nbe->getConnections();
331  for (EdgeVector::const_iterator dest_it = destinations.begin(); dest_it != destinations.end(); dest_it++) {
332  GNEEdge* dest = myUpdateTarget->getNet()->retrieveEdge((*dest_it)->getID());
333  const GNEEdge::LaneVector& destLanes = dest->getLanes();
334  for (GNEEdge::LaneVector::const_iterator it_lane = destLanes.begin(); it_lane != destLanes.end(); it_lane++) {
335  const bool isConflicted = count_if(
336  connections.begin(), connections.end(),
337  NBEdge::connections_toedgelane_finder(*dest_it, (int)(*it_lane)->getIndex(), -1)) > 1;
338  if (isConflicted) {
339  selectIDs.push_back((*it_lane)->getGlID());
340  }
341  }
342  }
343 
344  }
346  return 1;
347 }
348 
349 
350 long
351 GNEConnector::onCmdSelectPass(FXObject*, FXSelector, void*) {
352  std::vector<GUIGlID> selectIDs;
353  const std::vector<GNEEdge*> edges = myUpdateTarget->getNet()->retrieveEdges();
354  for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) {
355  GNEEdge* edge = *edge_it;
356  NBEdge* nbe = edge->getNBEdge();
357  const std::vector<NBEdge::Connection>& connections = nbe->getConnections();
358  for (std::vector<NBEdge::Connection>::const_iterator it = connections.begin(); it != connections.end(); ++it) {
359  if (it->mayDefinitelyPass) {
360  GNELane* lane = edge->getLanes()[it->fromLane];
361  selectIDs.push_back(lane->getGlID());
362  }
363  }
364  }
366  return 1;
367 }
368 
369 
370 long
371 GNEConnector::onCmdClearSelectedConnections(FXObject*, FXSelector, void*) {
372  onCmdCancel(0, 0, 0);
373  myUndoList->p_begin("clear connections from selected lanes, edges and junctions");
374  const std::set<GUIGlID> ids = gSelected.getSelected();
375  for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
376  GUIGlID id = *it;
378  if (object) {
379  switch (object->getType()) {
380  case GLO_JUNCTION: {
381  GNEJunction* junction = dynamic_cast<GNEJunction*>(object);
382  junction->setLogicValid(false, myUndoList); // clear connections
383  junction->setLogicValid(false, myUndoList, GNEAttributeCarrier::MODIFIED); // prevent re-guessing
384  break;
385  }
386  case GLO_EDGE: {
387  const GNEEdge::LaneVector& lanes = dynamic_cast<GNEEdge*>(object)->getLanes();
388  for (GNEEdge::LaneVector::const_iterator l_it = lanes.begin(); l_it != lanes.end(); ++l_it) {
389  removeConnections(*l_it);
390  }
391  break;
392  }
393  case GLO_LANE:
394  removeConnections(dynamic_cast<GNELane*>(object));
395  break;
396  default:
397  break;
398  }
399  }
400  }
401  myUndoList->p_end();
402  return 1;
403 }
404 
405 
406 void
408  handleLaneClick(lane, false, false, true); // select as current lane
409  for (std::set<GNELane*>::iterator it = myPotentialTargets.begin(); it != myPotentialTargets.end(); it++) {
410  handleLaneClick(*it, false, false, false); // deselect
411  }
412  onCmdOK(0, 0, 0); // save
413 }
414 
415 
416 long
417 GNEConnector::onCmdResetSelectedConnections(FXObject*, FXSelector, void*) {
418  onCmdCancel(0, 0, 0);
419  myUndoList->p_begin("reset connections from selected lanes");
420  const std::set<GUIGlID> nodeIDs = gSelected.getSelected(GLO_JUNCTION);
421  for (std::set<GUIGlID>::const_iterator nid_it = nodeIDs.begin(); nid_it != nodeIDs.end(); nid_it++) {
423  if (object) {
424  GNEJunction* junction = dynamic_cast<GNEJunction*>(object);
425  if (junction) {
426  junction->setLogicValid(false, myUndoList);
427  } else {
428  throw ProcessError("Wrong object type returned from gIDStorage");
429  }
430  }
431  }
432  myUndoList->p_end();
433  return 1;
434 }
435 
436 
437 void
439  if (myCurrentLane == 0) {
440  myDescription->setText("No Lane Selected\n");
441  } else {
442  myDescription->setText((
443  myCurrentLane->getMicrosimID() + "\n(" +
444  toString(myNumChanges) + " changes)").c_str());
445  }
446 }
447 
448 
449 void
451  // gather potential targets
453 
454  const EdgeVector& outgoing = nbn->getOutgoingEdges();
455  for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
456  GNEEdge* edge = myUpdateTarget->getNet()->retrieveEdge((*it)->getID());
457  const GNEEdge::LaneVector& lanes = edge->getLanes();
458  for (GNEEdge::LaneVector::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
459  myPotentialTargets.insert(*it_lane);
460  }
461  }
462  // set color for existing connections
463  const unsigned int fromIndex = myCurrentLane->getIndex();
465  std::vector<NBEdge::Connection> connections = srcEdge->getConnectionsFromLane(fromIndex);
466  for (std::set<GNELane*>::iterator it = myPotentialTargets.begin(); it != myPotentialTargets.end(); it++) {
467  switch (getLaneStatus(connections, *it)) {
468  case CONNECTED:
469  (*it)->setSpecialColor(&targetColor);
470  break;
471  case CONNECTED_PASS:
472  (*it)->setSpecialColor(&targetPassColor);
473  break;
474  case CONFLICTED:
475  (*it)->setSpecialColor(&conflictColor);
476  break;
477  case UNCONNECTED:
478  (*it)->setSpecialColor(&potentialTargetColor);
479  break;
480  }
481  }
482 }
483 
484 
485 void
487  // clean up
488  for (std::set<GNELane*>::iterator it = myPotentialTargets.begin(); it != myPotentialTargets.end(); it++) {
489  (*it)->setSpecialColor(0);
490  }
491  myPotentialTargets.clear();
492  myNumChanges = 0;
494  myCurrentLane = 0;
495  buildIinternalLanes(0); // only clears
497 }
498 
499 
501 GNEConnector::getLaneStatus(const std::vector<NBEdge::Connection>& connections, GNELane* targetLane) {
503  const unsigned int fromIndex = myCurrentLane->getIndex();
504  NBEdge* destEdge = targetLane->getParentEdge().getNBEdge();
505  const unsigned int toIndex = targetLane->getIndex();
506  std::vector<NBEdge::Connection>::const_iterator con_it = find_if(
507  connections.begin(), connections.end(),
508  NBEdge::connections_finder(fromIndex, destEdge, toIndex));
509  const bool isConnected = con_it != connections.end();
510  if (isConnected) {
511  if (con_it->mayDefinitelyPass) {
512  return CONNECTED_PASS;
513  } else {
514  return CONNECTED;
515  }
516  } else if (srcEdge->hasConnectionTo(destEdge, toIndex)) {
517  return CONFLICTED;
518  } else {
519  return UNCONNECTED;
520  }
521 }
522 
523 
524 unsigned int
525 GNEConnector::getTLLLinkNumber(const std::vector<NBEdge::Connection>& connections, GNELane* targetLane) {
526  const unsigned int fromIndex = myCurrentLane->getIndex();
527  NBEdge* destEdge = targetLane->getParentEdge().getNBEdge();
528  const unsigned int toIndex = targetLane->getIndex();
529  std::vector<NBEdge::Connection>::const_iterator it = find_if(
530  connections.begin(), connections.end(),
531  NBEdge::connections_finder(fromIndex, destEdge, toIndex));
532  assert(it != connections.end());
533  return it->tlLinkNo;
534 }
535 
536 
537 void
539  // clean up previous objects
541  for (std::map<int, GNEInternalLane*>::iterator it = myInternalLanes.begin(); it != myInternalLanes.end(); it++) {
542  rtree.removeAdditionalGLObject(it->second);
543  delete it->second;
544  }
545  myInternalLanes.clear();
546  if (node != 0) {
547  const int NUM_POINTS = 5;
549  std::string innerID = ":" + node->getID(); // see NWWriter_SUMO::writeInternalEdges
550 
551  int index = 0;
552  const EdgeVector& incoming = node->getIncomingEdges();
553  for (EdgeVector::const_iterator it_edg = incoming.begin(); it_edg != incoming.end(); it_edg++) {
554  const std::vector<NBEdge::Connection>& conns = (*it_edg)->getConnections();
555  for (std::vector<NBEdge::Connection>::const_iterator it_con = conns.begin(); it_con != conns.end(); ++it_con) {
556  const PositionVector shape = node->computeInternalLaneShape(*it_edg, *it_con, NUM_POINTS);
557  LinkState state = node->getLinkState(*it_edg, it_con->toEdge, it_con->fromLane, it_con->toLane, it_con->mayDefinitelyPass, it_con->tlID);
558  GNEInternalLane* ilane = new GNEInternalLane(0, innerID + '_' + toString(index) , shape, -1, state);
559  rtree.addAdditionalGLObject(ilane);
560  myInternalLanes[index] = ilane;
561  index++;
562  }
563  }
564  }
565 }
566 
567 
568 /****************************************************************************/
unsigned int getTLLLinkNumber(const std::vector< NBEdge::Connection > &connections, GNELane *targetLane)
std::vector< GNEJunction * > retrieveJunctions(bool onlySelected=false)
return all junctions
Definition: GNENet.cpp:580
bool hasConnectionTo(NBEdge *destEdge, unsigned int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:812
void initTargets()
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges.
Definition: NBNode.h:240
std::map< int, GNEInternalLane * > myInternalLanes
the internal lanes belonging the the current junction indexed by their tl-index
Definition: GNEConnector.h:138
FXDEFMAP(GNEConnector) GNEConnectorMap[]
long onCmdSelectDeadEnds(FXObject *, FXSelector, void *)
Called when the user presses the Corresponding-button.
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:541
static RGBColor targetPassColor
color for the to-lane of a connection with pass attribute
Definition: GNEConnector.h:149
LaneStatus getLaneStatus(const std::vector< NBEdge::Connection > &connections, GNELane *targetLane)
long onCmdSelectDeadStarts(FXObject *, FXSelector, void *)
FXLabel * myDescription
the label that shows the current editing state
Definition: GNEConnector.h:122
GNELane * myCurrentLane
the lane of which connections are to be modified
Definition: GNEConnector.h:125
void handleLaneClick(GNELane *lane, bool mayDefinitelyPass, bool allowConflict, bool toggle)
either sets the current lane or toggles the connection of the current lane to this lane (if they shar...
static const NBConnection InvalidConnection
Definition: NBConnection.h:128
std::set< GUIGlID > getLaneGlIDs()
Definition: GNEEdge.cpp:391
void setLogicValid(bool valid, GNEUndoList *undoList=0, const std::string &status=GUESSED)
long onCmdOK(FXObject *, FXSelector, void *)
Called when the user presses the OK-Button saves any connection modifications.
The representation of a single edge during network building.
Definition: NBEdge.h:70
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.h:108
std::vector< GNELane * > LaneVector
Definition of the lane&#39;s positions vector.
Definition: GNEEdge.h:68
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
void removeAdditionalGLObject(GUIGlObject *o)
Removes an additional object (detector/shape/trigger) from being visualised.
Definition: SUMORTree.h:141
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
Definition: GUIGlObject.h:167
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:77
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:56
void p_begin(const std::string &description)
Definition: GNEUndoList.cpp:75
GNENet * getNet()
Definition: GNEViewNet.h:173
~GNEConnector()
Destructor.
unsigned int getIndex() const
Definition: GNELane.h:139
std::vector< Connection > getConnectionsFromLane(unsigned int lane) const
Returns connections from a given lane.
Definition: NBEdge.cpp:785
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:74
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:123
static RGBColor conflictColor
color for a to-lane that cannot be used because another connection conflicts
Definition: GNEConnector.h:147
void removeConnections(GNELane *lane)
static RGBColor sourceColor
color for the from-lane of a connection
Definition: GNEConnector.h:143
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
Definition: NBEdge.cpp:868
long onCmdClearSelectedConnections(FXObject *, FXSelector, void *)
#define new
Definition: debug_new.h:121
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges.
Definition: NBNode.h:248
long onCmdCancel(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button discards any connection modifications.
const std::string & getID() const
Returns the id.
Definition: Named.h:65
static const std::string MODIFIED
feature has been manually modified (implies approval)
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:180
GNESelector * getSelector()
Definition: GNEViewNet.h:191
static const RGBColor GREEN
Definition: RGBColor.h:190
LaneStatus
the status of a target lane
Definition: GNEConnector.h:108
GNEViewNet * myUpdateTarget
Definition: GNEConnector.h:135
const std::set< GUIGlID > & getSelected() const
Returns the list of ids of all selected objects.
GNEUndoList * myUndoList
Definition: GNEConnector.h:130
long onCmdSelectPass(FXObject *, FXSelector, void *)
void p_end()
Definition: GNEUndoList.cpp:82
void setSpecialColor(const RGBColor *color)
Definition: GNELane.h:159
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:529
A list of positions.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
void updateDescription() const
Cancel-button pressed.
Definition: GUIAppEnum.h:65
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
static const RGBColor MAGENTA
Definition: RGBColor.h:194
NBNode * getNBNode()
returns the internal NBNode
Definition: GNEJunction.h:153
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
Definition: NBNode.cpp:1535
long onCmdResetSelectedConnections(FXObject *, FXSelector, void *)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:54
Clear set.
Definition: GUIAppEnum.h:329
void p_abort()
reverts and discards ALL active command groups
Definition: GNEUndoList.cpp:96
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection)
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.h:132
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:61
unsigned int GUIGlID
Definition: GUIGlObject.h:49
SUMORTree & getVisualisationSpeedUp()
Returns the RTree used for visualisation speed-up.
Definition: GNENet.h:154
Reset set.
Definition: GUIAppEnum.h:331
static const RGBColor YELLOW
Definition: RGBColor.h:192
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints) const
Compute the shape for an internal lane.
Definition: NBNode.cpp:559
static const RGBColor CYAN
Definition: RGBColor.h:193
std::set< GNELane * > myPotentialTargets
the set of lanes to which the current lane may be connected
Definition: GNEConnector.h:128
std::vector< GNEEdge * > retrieveEdges(bool onlySelected=false)
return all edges
Definition: GNENet.cpp:553
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:129
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:41
Ok-button pressed.
Definition: GUIAppEnum.h:63
unsigned int myNumChanges
Definition: GNEConnector.h:132
an edge
GNEJunction * getDest() const
returns the destination-junction
Definition: GNEEdge.cpp:135
long onCmdSelectConflicts(FXObject *, FXSelector, void *)
FXFont * myHeaderFont
Font for the widget.
Definition: GNEConnector.h:119
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:125
Represents a single node (junction) during network building.
Definition: NBNode.h:74
void setStatusBarText(const std::string &text)
Definition: GNEViewNet.cpp:310
void handleIDs(std::vector< GUIGlID > ids, bool selectEdges, SetOperation setop=SET_DEFAULT)
void buildIinternalLanes(NBNode *node)
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
static RGBColor targetColor
color for the to-lane of a connection
Definition: GNEConnector.h:145
GUISelectedStorage gSelected
A global holder of selected objects.
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:763
static RGBColor potentialTargetColor
color for potential to-lane targets (currently unconnected)
Definition: GNEConnector.h:151
const LaneVector & getLanes()
Definition: GNEEdge.h:219
a junction