SUMO - Simulation of Urban MObility
GNETLSEditorFrame.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // The Widget for modifying traffic lights
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 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>
46 
47 #include "GNETLSEditorFrame.h"
48 #include "GNEViewNet.h"
49 #include "GNEViewParent.h"
50 #include "GNENet.h"
51 #include "GNEJunction.h"
52 #include "GNEEdge.h"
53 #include "GNELane.h"
54 #include "GNEUndoList.h"
55 #include "GNEInternalLane.h"
56 #include "GNEChange_TLS.h"
57 
58 #ifdef CHECK_MEMORY_LEAKS
59 #include <foreign/nvwa/debug_new.h>
60 #endif // CHECK_MEMORY_LEAKS
61 
62 // ===========================================================================
63 // FOX callback mapping
64 // ===========================================================================
65 FXDEFMAP(GNETLSEditorFrame) GNETLSEditorFrameMap[] = {
66  FXMAPFUNC(SEL_COMMAND, MID_CANCEL, GNETLSEditorFrame::onCmdCancel),
67  FXMAPFUNC(SEL_COMMAND, MID_OK, GNETLSEditorFrame::onCmdOK),
79  FXMAPFUNC(SEL_DESELECTED, MID_GNE_PHASE_TABLE, GNETLSEditorFrame::onCmdPhaseSwitch),
88  FXMAPFUNC(SEL_UPDATE, MID_CANCEL, GNETLSEditorFrame::onUpdModified),
89  FXMAPFUNC(SEL_UPDATE, MID_OK, GNETLSEditorFrame::onUpdModified),
90 };
91 
92 
93 // Object implementation
94 FXIMPLEMENT(GNETLSEditorFrame, FXVerticalFrame, GNETLSEditorFrameMap, ARRAYNUMBER(GNETLSEditorFrameMap))
95 
96 // ===========================================================================
97 // method definitions
98 // ===========================================================================
99 GNETLSEditorFrame::GNETLSEditorFrame(FXHorizontalFrame* horizontalFrameParent, GNEViewNet* viewNet):
100  GNEFrame(horizontalFrameParent, viewNet, "Edit Traffic Light"),
101  myTableFont(new FXFont(getApp(), "Courier New", 9)),
102  myCurrentJunction(0),
103  myHaveModifications(false),
104  myEditedDef(0) {
105  // create groupbox for description
106  myGroupBoxJunction = new FXGroupBox(myContentFrame, "Junction", GUIDesignGroupBoxFrame);
107 
108  // create description label
109  myDescription = new FXLabel(myGroupBoxJunction, "No Junction Selected\n", 0, GUIDesignLabelLeft);
110 
111  // create groupbox for tl df
112  myGroupBoxTLSDef = new FXGroupBox(myContentFrame, "Traffic lights definition", GUIDesignGroupBoxFrame);
113 
114  // create create tlDef button
115  myNewTLProgram = new FXButton(myGroupBoxTLSDef, "Create TLS\t\tCreate a new traffic light program", 0, this, MID_GNE_DEF_CREATE, GUIDesignButton);
116 
117  // create delete tlDef button
118  myDeleteTLProgram = new FXButton(myGroupBoxTLSDef, "Delete TLS\t\tDelete a traffic light program. If all programs are deleted the junction turns into a priority junction.", 0, this, MID_GNE_DEF_DELETE, GUIDesignButton);
119 
120  // create groupbox for phases
121  myGroupBoxAttributes = new FXGroupBox(myContentFrame, "Attributes", GUIDesignGroupBoxFrame);
122 
123  // Create matrix
124  myAttributeMatrix = new FXMatrix(myGroupBoxAttributes, 2, GUIDesignMatrixAttributes);
125 
126  // create label for name
127  myNameLabel = new FXLabel(myAttributeMatrix, "Name", 0, GUIDesignLabelAttribute);
128 
129  // create text field for name
130  myNameTextField = new FXTextField(myAttributeMatrix, GUIDesignTextFieldNCol, this, MID_GNE_DEF_SWITCH, GUIDesignTextFieldAttributeStr);
131 
132  // create label for program
133  myProgramLabel = new FXLabel(myAttributeMatrix, "Program", 0, GUIDesignLabelAttribute);
134 
135  // create combo box for program
136  myProgramComboBox = new FXComboBox(myAttributeMatrix, GUIDesignComboBoxNCol, this, MID_GNE_DEF_SWITCH, GUIDesignComboBoxAttribute);
137 
138  // create offset control
139  myOffsetLabel = new FXLabel(myAttributeMatrix, "Offset", 0, GUIDesignLabelAttribute);
140  myOffset = new FXTextField(myAttributeMatrix, GUIDesignTextFieldNCol, this, MID_GNE_DEF_OFFSET, GUIDesignTextFieldAttributeReal);
141 
142  // create groupbox for phases
143  myGroupBoxPhases = new FXGroupBox(myContentFrame, "Phases", GUIDesignGroupBoxFrame);
144 
145  // create and configure phase table
146  myPhaseTable = new FXTable(myGroupBoxPhases, this, MID_GNE_PHASE_TABLE, GUIDesignTableLimitedHeight);
147  myPhaseTable->setColumnHeaderMode(LAYOUT_FIX_HEIGHT);
148  myPhaseTable->setColumnHeaderHeight(0);
149  myPhaseTable->setRowHeaderMode(LAYOUT_FIX_WIDTH);
150  myPhaseTable->setRowHeaderWidth(0);
151  myPhaseTable->hide();
152  myPhaseTable->setFont(myTableFont);
153  myPhaseTable->setHelpText("phase duration in seconds | phase state");
154 
155  // create total duration info label
156  myCycleDuration = new FXLabel(myGroupBoxPhases, "", 0, GUIDesignLabelLeft);
157 
158  // create new phase button
159  myInsertDuplicateButton = new FXButton(myGroupBoxPhases, "Copy Phase\t\tInsert duplicate phase after selected phase", 0, this, MID_GNE_PHASE_CREATE, GUIDesignButton);
160 
161  // create delete phase button
162  myDeleteSelectedPhaseButton = new FXButton(myGroupBoxPhases, "Delete Phase\t\tDelete selected phase", 0, this, MID_GNE_PHASE_DELETE, GUIDesignButton);
163 
164  // create groupbox for modifications
165  myGroupBoxModifications = new FXGroupBox(myContentFrame, "Modifications", GUIDesignGroupBoxFrame);
166 
167  // create discard modifications buttons
168  myDiscardModificationsButtons = new FXButton(myGroupBoxModifications, "Cancel\t\tDiscard program modifications (Esc)", 0, this, MID_CANCEL, GUIDesignButton);
169 
170  // create save modifications button
171  mySaveModificationsButtons = new FXButton(myGroupBoxModifications, "Save\t\tSave program modifications (Enter)", 0, this, MID_OK, GUIDesignButton);
172 
173 
174  // "Add 'off' program"
175  /*
176  new FXButton(myContentFrame, "Add \"Off\"-Program\t\tAdds a program for switching off this traffic light",
177  0, this, MID_GNE_DEF_ADDOFF, GUIDesignButton);
178  */
179 }
180 
181 
183  delete myTableFont;
184  cleanup();
185 }
186 
187 
188 void
190  if (myCurrentJunction == 0 || (!myHaveModifications && (junction != myCurrentJunction))) {
191  onCmdCancel(0, 0, 0);
192  myViewNet->getUndoList()->p_begin("modifying traffic light definition");
193  myCurrentJunction = junction;
195  initDefinitions();
196  } else {
197  myViewNet->setStatusBarText("Unsaved modifications. Abort or Save");
198  }
199 }
200 
201 
202 long
203 GNETLSEditorFrame::onCmdCancel(FXObject*, FXSelector, void*) {
204  if (myCurrentJunction != 0) {
206  cleanup();
207  myViewNet->update();
208  }
209  return 1;
210 }
211 
212 
213 long
214 GNETLSEditorFrame::onCmdOK(FXObject*, FXSelector, void*) {
215  if (myCurrentJunction != 0) {
216  if (myHaveModifications) {
217  NBTrafficLightDefinition* old = myDefinitions[myProgramComboBox->getCurrentItem()];
218  std::vector<NBNode*> nodes = old->getNodes();
219  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
220  GNEJunction* junction = myViewNet->getNet()->retrieveJunction((*it)->getID());
221  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, old, false), true);
222  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, myEditedDef, true), true);
223  }
224  myEditedDef = 0;
226  cleanup();
227  myViewNet->update();
228  } else {
229  onCmdCancel(0, 0, 0);
230  }
231  }
232  return 1;
233 }
234 
235 
236 long
237 GNETLSEditorFrame::onCmdDefCreate(FXObject*, FXSelector, void*) {
238  GNEJunction* junction = myCurrentJunction;
239  onCmdCancel(0, 0, 0); // abort because we onCmdOk assumes we wish to save an edited definition
242  } else {
243  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, 0, true, true), true);
244  }
245  editJunction(junction);
246  return 1;
247 }
248 
249 
250 long
251 GNETLSEditorFrame::onCmdDefDelete(FXObject*, FXSelector, void*) {
252  GNEJunction* junction = myCurrentJunction;
253  const bool changeType = myDefinitions.size() == 1;
254  onCmdCancel(0, 0, 0); // abort because onCmdOk assumes we wish to save an edited definition
255  if (changeType) {
257  } else {
258  NBTrafficLightDefinition* tlDef = myDefinitions[myProgramComboBox->getCurrentItem()];
259  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, tlDef, false), true);
260  }
261  return 1;
262 }
263 
264 
265 long
266 GNETLSEditorFrame::onCmdDefSwitch(FXObject*, FXSelector, void*) {
267  assert(myCurrentJunction != 0);
268  assert((int)myDefinitions.size() == myProgramComboBox->getNumItems());
269  NBTrafficLightDefinition* tlDef = myDefinitions[myProgramComboBox->getCurrentItem()];
270  // logic may not have been recomputed yet. recompute to be sure
273  NBTrafficLightLogic* tllogic = tllCont.getLogic(tlDef->getID(), tlDef->getProgramID());
274  if (tllogic != 0) {
275  // now we can be sure that the tlDef is up to date (i.e. re-guessed)
276  buildIinternalLanes(tlDef);
277  // create working copy from original def
278  delete myEditedDef;
279  myEditedDef = new NBLoadedSUMOTLDef(tlDef, tllogic);
280  myOffset->setText(toString(STEPS2TIME(myEditedDef->getLogic()->getOffset())).c_str());
281  initPhaseTable();
283  } else {
284  // tlDef has no valid logic (probably because id does not control any links
285  onCmdCancel(0, 0, 0);
286  myViewNet->setStatusBarText("Traffic light does not control any links");
287  }
288  return 1;
289 }
290 
291 
292 long
293 GNETLSEditorFrame::onUpdDefSwitch(FXObject* o, FXSelector, void*) {
294  const bool enable = myDefinitions.size() > 0 && !myHaveModifications;
295  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
296  return 1;
297 }
298 
299 
300 long
301 GNETLSEditorFrame::onUpdNeedsDef(FXObject* o, FXSelector, void*) {
302  const bool enable = myDefinitions.size() > 0;
303  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
304  return 1;
305 }
306 
307 
308 long
309 GNETLSEditorFrame::onUpdNeedsDefAndPhase(FXObject* o, FXSelector, void*) {
310  // do not delete the last phase
311  const bool enable = myDefinitions.size() > 0 && myPhaseTable->getNumRows() > 1;
312  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
313  return 1;
314 }
315 
316 
317 long
318 GNETLSEditorFrame::onUpdDefCreate(FXObject* o, FXSelector, void*) {
319  const bool enable = myCurrentJunction != 0 && !myHaveModifications;
320  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
321  return 1;
322 }
323 
324 
325 long
326 GNETLSEditorFrame::onUpdModified(FXObject* o, FXSelector, void*) {
327  bool enable = myHaveModifications;
328  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
329  return 1;
330 }
331 
332 
333 
334 long
335 GNETLSEditorFrame::onCmdDefOffset(FXObject*, FXSelector, void*) {
336  myHaveModifications = true;
338  return 1;
339 }
340 
341 
342 long
343 GNETLSEditorFrame::onCmdDefRename(FXObject*, FXSelector, void*) {
344  return 1;
345 }
346 
347 
348 long
349 GNETLSEditorFrame::onCmdDefSubRename(FXObject*, FXSelector, void*) {
350  return 1;
351 }
352 
353 
354 long
355 GNETLSEditorFrame::onCmdDefAddOff(FXObject*, FXSelector, void*) {
356  return 1;
357 }
358 
359 
360 long
361 GNETLSEditorFrame::onCmdGuess(FXObject*, FXSelector, void*) {
362  return 1;
363 }
364 
365 
366 long
367 GNETLSEditorFrame::onCmdPhaseSwitch(FXObject*, FXSelector, void*) {
368  const int index = myPhaseTable->getCurrentRow();
369  const NBTrafficLightLogic::PhaseDefinition& phase = getPhases()[index];
370  myPhaseTable->selectRow(index);
371  // need not hold since links could have been deleted somewhere else and indices may be reused
372  // assert(phase.state.size() == myInternalLanes.size());
373  for (TLIndexMap::iterator it = myInternalLanes.begin(); it != myInternalLanes.end(); it++) {
374  int tlIndex = it->first;
375  std::vector<GNEInternalLane*> lanes = it->second;
376  assert(tlIndex >= 0);
377  assert(tlIndex < (int)phase.state.size());
378  for (std::vector<GNEInternalLane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
379  (*it_lane)->setLinkState((LinkState)phase.state[tlIndex]);
380  }
381  }
382  myViewNet->update();
383  return 1;
384 }
385 
386 
387 long
388 GNETLSEditorFrame::onCmdPhaseCreate(FXObject*, FXSelector, void*) {
389  myHaveModifications = true;
390  // allows insertion at first position by deselecting via arrow keys
391  int newIndex = myPhaseTable->getSelStartRow() + 1;
392  int oldIndex = MAX2(0, myPhaseTable->getSelStartRow());
393  // copy current row
394  const SUMOTime duration = getSUMOTime(myPhaseTable->getItemText(oldIndex, 0));
395  const std::string state = myPhaseTable->getItemText(oldIndex, 1).text();
396  myEditedDef->getLogic()->addStep(duration, state, newIndex);
397  myPhaseTable->setCurrentItem(newIndex, 0);
398  initPhaseTable(newIndex);
399  myPhaseTable->setFocus();
400  return 1;
401 }
402 
403 
404 long
405 GNETLSEditorFrame::onCmdPhaseDelete(FXObject*, FXSelector, void*) {
406  myHaveModifications = true;
407  const int newRow = MAX2((int)0, (int)myPhaseTable->getCurrentRow() - 1);
408  myEditedDef->getLogic()->deletePhase(myPhaseTable->getCurrentRow());
409  initPhaseTable(newRow);
410  myPhaseTable->setFocus();
411  return 1;
412 }
413 
414 
415 long
416 GNETLSEditorFrame::onCmdPhaseEdit(FXObject*, FXSelector, void* ptr) {
417  /* @note: there is a bug when copying/pasting rows: when this handler is
418  * called the value of the cell is not yet updated. This means you have to
419  * click inside the cell and hit enter to actually update the value */
420  FXTablePos* tp = (FXTablePos*)ptr;
421  FXString value = myPhaseTable->getItemText(tp->row, tp->col);
422  if (tp->col == 0) {
423  // duration edited
424  if (GNEAttributeCarrier::canParse<SUMOReal>(value.text())) {
425  SUMOTime duration = getSUMOTime(value);
426  if (duration > 0) {
427  myEditedDef->getLogic()->setPhaseDuration(tp->row, duration);
428  myHaveModifications = true;
430  return 1;
431  }
432  }
433  // input error, reset value
434  myPhaseTable->setItemText(tp->row, 0, toString(STEPS2TIME(getPhases()[tp->row].duration)).c_str());
435  } else {
436  // state edited
437  try {
438  // insert phase with new step and delete the old phase
439  myEditedDef->getLogic()->addStep(getPhases()[tp->row].duration, value.text(), tp->row);
440  myEditedDef->getLogic()->deletePhase(tp->row + 1);
441  myHaveModifications = true;
442  onCmdPhaseSwitch(0, 0, 0);
443  } catch (ProcessError) {
444  // input error, reset value
445  myPhaseTable->setItemText(tp->row, 1, getPhases()[tp->row].state.c_str());
446  }
447  }
448  return 1;
449 }
450 
451 
452 void
454  std::string description;
455  if (myCurrentJunction == 0) {
456  description = "No Junction Selected\n";
457  } else {
459  description = "Current junction: " + nbn->getID() + "\n(";
460  if (!nbn->isTLControlled()) {
461  description += "uncontrolled, ";
462  }
463  description += (myHaveModifications ? "modified)" : "unmodified)");
464  }
465  myDescription->setText(description.c_str());
466 }
467 
468 
469 void
471  if (myCurrentJunction) {
473  }
474  // clean data structures
475  myCurrentJunction = 0;
476  myHaveModifications = false;
477  delete myEditedDef;
478  myEditedDef = 0;
479  buildIinternalLanes(0); // only clears
480  // clean up controls
481  myNameTextField->setText("");
482  myOffset->setText("");
483  myDefinitions.clear();
484  myProgramComboBox->hide();
485  initPhaseTable(); // only clears when there are no definitions
486  myCycleDuration->hide();
488 }
489 
490 
491 void
493  // clean up previous objects
495  for (TLIndexMap::iterator it = myInternalLanes.begin(); it != myInternalLanes.end(); it++) {
496  std::vector<GNEInternalLane*> lanes = it->second;
497  for (std::vector<GNEInternalLane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
498  rtree.removeAdditionalGLObject(*it_lane);
499  delete *it_lane;
500  }
501  }
502  myInternalLanes.clear();
503  if (tlDef != 0) {
504  const int NUM_POINTS = 10;
505  assert(myCurrentJunction);
508  std::string innerID = ":" + nbn->getID(); // see NWWriter_SUMO::writeInternalEdges
509  const NBConnectionVector& links = tlDef->getControlledLinks();
510  for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
511  int tlIndex = it->getTLIndex();
512  PositionVector shape = nbn->computeInternalLaneShape(it->getFrom(), NBEdge::Connection(it->getFromLane(),
513  it->getTo(), it->getToLane()), NUM_POINTS);
514  GNEInternalLane* ilane = new GNEInternalLane(this, innerID + '_' + toString(tlIndex), shape, tlIndex);
515  rtree.addAdditionalGLObject(ilane);
516  myInternalLanes[tlIndex].push_back(ilane);
517  }
518  const std::vector<NBNode::Crossing>& crossings = nbn->getCrossings();
519  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
520  const NBNode::Crossing& c = *it;
521  GNEInternalLane* ilane = new GNEInternalLane(this, c.id, c.shape, c.tlLinkNo);
522  rtree.addAdditionalGLObject(ilane);
523  myInternalLanes[c.tlLinkNo].push_back(ilane);
524  }
525  }
526 }
527 
528 
529 void
531  myDefinitions.clear();
532  myNameTextField->setText("");
533  myProgramComboBox->clearItems();
534  assert(myCurrentJunction);
536  std::set<NBTrafficLightDefinition*> tldefs = nbn->getControllingTLS();
537  for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) {
538  myDefinitions.push_back(*it);
539  myNameTextField->setText((*it)->getID().c_str());
540  myProgramComboBox->appendItem((*it)->getProgramID().c_str());
541  }
542  if (myDefinitions.size() > 0) {
543  myProgramComboBox->setCurrentItem(0);
544  myProgramComboBox->setNumVisible(myProgramComboBox->getNumItems());
545  myProgramComboBox->show();
546  onCmdDefSwitch(0, 0, 0);
547  }
549 }
550 
551 
552 void
554  myPhaseTable->setVisibleRows(1);
555  myPhaseTable->setVisibleColumns(2);
556  myPhaseTable->hide();
557  if (myDefinitions.size() > 0) {
558  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = getPhases();
559  myPhaseTable->setTableSize((int)phases.size(), 2);
560  myPhaseTable->setVisibleRows((int)phases.size());
561  myPhaseTable->setVisibleColumns(2);
562  for (int row = 0; row < (int)phases.size(); row++) {
563  myPhaseTable->setItemText(row, 0, toString(STEPS2TIME(phases[row].duration)).c_str());
564  myPhaseTable->setItemText(row, 1, phases[row].state.c_str());
565  myPhaseTable->getItem(row, 1)->setJustify(FXTableItem::LEFT);
566  }
567  myPhaseTable->fitColumnsToContents(0, 2);
568  myPhaseTable->setHeight((int)phases.size() * 21); // experimental
569  myPhaseTable->setCurrentItem(index, 0);
570  myPhaseTable->selectRow(index, true);
571  myPhaseTable->show();
572  myPhaseTable->setFocus();
573  }
574  update();
575 }
576 
577 
578 const std::vector<NBTrafficLightLogic::PhaseDefinition>&
580  return myEditedDef->getLogic()->getPhases();
581 }
582 
583 
584 void
586  myHaveModifications = true;
587  if (myViewNet->changeAllPhases()) {
588  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = getPhases();
589  for (int row = 0; row < (int)phases.size(); row++) {
590  myEditedDef->getLogic()->setPhaseState(row, lane->getTLIndex(), lane->getLinkState());
591  }
592  } else {
593  myEditedDef->getLogic()->setPhaseState(myPhaseTable->getCurrentRow(), lane->getTLIndex(), lane->getLinkState());
594  }
595  initPhaseTable(myPhaseTable->getCurrentRow());
596  myPhaseTable->setFocus();
597 }
598 
599 
600 void
601 GNETLSEditorFrame::handleMultiChange(GNELane* lane, FXObject* obj, FXSelector sel, void* data) {
602  if (myEditedDef != 0) {
603  myHaveModifications = true;
605  std::set<std::string> fromIDs;
606  fromIDs.insert(lane->getMicrosimID());
607  GNEEdge& edge = lane->getParentEdge();
608  // if neither the lane nor its edge are selected, apply changes to the whole edge
610  for (GNEEdge::LaneVector::const_iterator it_lane = edge.getLanes().begin(); it_lane != edge.getLanes().end(); it_lane++) {
611  fromIDs.insert((*it_lane)->getMicrosimID());
612  }
613  } else {
614  // if the edge is selected, apply changes to all lanes of all selected edges
615  if (gSelected.isSelected(GLO_EDGE, edge.getGlID())) {
616  std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges(true);
617  for (std::vector<GNEEdge*>::iterator it = edges.begin(); it != edges.end(); it++) {
618  for (GNEEdge::LaneVector::const_iterator it_lane = (*it)->getLanes().begin(); it_lane != (*it)->getLanes().end(); it_lane++) {
619  fromIDs.insert((*it_lane)->getMicrosimID());
620  }
621  }
622  }
623  // if the lane is selected, apply changes to all selected lanes
624  if (gSelected.isSelected(GLO_LANE, lane->getGlID())) {
625  std::vector<GNELane*> lanes = myViewNet->getNet()->retrieveLanes(true);
626  for (std::vector<GNELane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
627  fromIDs.insert((*it_lane)->getMicrosimID());
628  }
629  }
630 
631  }
632  // set new state for all connections from the chosen lane IDs
633  for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
634  const NBConnection& c = *it;
635  if (fromIDs.count(c.getFrom()->getLaneID(c.getFromLane())) > 0) {
636  std::vector<GNEInternalLane*> lanes = myInternalLanes[c.getTLIndex()];
637  for (std::vector<GNEInternalLane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
638  (*it_lane)->onDefault(obj, sel, data);
639  }
640  }
641  }
642  }
643 }
644 
645 
646 bool
648  if (myEditedDef != 0) {
650  for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
651  if ((*it).getFrom()->getID() == edge.getMicrosimID()) {
652  return true;
653  }
654  }
655  }
656  return false;
657 }
658 
659 
660 SUMOTime
661 GNETLSEditorFrame::getSUMOTime(const FXString& string) {
662  assert(GNEAttributeCarrier::canParse<SUMOReal>(string.text()));
663  return TIME2STEPS(GNEAttributeCarrier::parse<SUMOReal>(string.text()));
664 }
665 
666 
667 void
669  SUMOTime cycleDuration = 0;
670  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = getPhases().begin(); it != getPhases().end(); it++) {
671  cycleDuration += it->duration;
672  }
673  std::string text = "Cycle time: " + toString(STEPS2TIME(cycleDuration));
674  myCycleDuration->setText(text.c_str());
675 }
676 
677 
678 /****************************************************************************/
int NUM_POINTS
TLIndexMap myInternalLanes
long onCmdGuess(FXObject *, FXSelector, void *)
Called when the user presses the button Guess.
std::vector< NBTrafficLightDefinition * > myDefinitions
the list of Definitions for the current junction
std::vector< GNELane * > retrieveLanes(bool onlySelected=false)
return all lanes
Definition: GNENet.cpp:759
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
bool controlsEdge(GNEEdge &edge) const
whether the given edge is controlled by the currently edited tlDef
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:157
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:179
FXLabel * myDescription
the label that shows the current editing state
long long int SUMOTime
Definition: SUMOTime.h:43
FXTable * myPhaseTable
table for selecting and rearranging phases and for changing duration
long onUpdNeedsDefAndPhase(FXObject *, FXSelector, void *)
Called when occurs an update of needs definition an dphase.
long onCmdPhaseDelete(FXObject *, FXSelector, void *)
Called when the user deletes a Phase.
long onCmdDefCreate(FXObject *, FXSelector, void *)
Called when the user creates a TLS.
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled ...
Definition: NBConnection.h:100
bool changeAllPhases() const
change all phases
Definition: GNEViewNet.cpp:381
std::string id
the (edge)-id of this crossing
Definition: NBNode.h:153
void setOffset(SUMOTime offset)
Sets the offset of this tls.
#define GUIDesignTextFieldAttributeStr
text field extended over the matrix column with thick frame
Definition: GUIDesigns.h:56
A loaded (complete) traffic light logic.
void setPhaseState(int phaseIndex, int tlIndex, LinkState linkState)
Modifies the state for an existing phase (used by NETEDIT)
A container for traffic light definitions and built programs.
A SUMO-compliant built logic for a traffic light.
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:288
#define GUIDesignTableLimitedHeight
design for table extended over frame but with limited Height
Definition: GUIDesigns.h:420
#define GUIDesignTextFieldAttributeReal
text field extended over the matrix column with thick frame and limited to real
Definition: GUIDesigns.h:53
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition: GUIDesigns.h:176
long onCmdPhaseSwitch(FXObject *, FXSelector, void *)
Called when the user switchs a Phase.
int getFromLane() const
returns the from-lane
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
definition related controls
Definition: GUIAppEnum.h:512
NBNode * getNBNode() const
Return net build node.
const std::vector< Crossing > & getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.h:620
The base class for traffic light logic definitions.
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
Definition: NBNode.cpp:631
T MAX2(T a, T b)
Definition: StdDefs.h:70
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
PositionVector shape
The lane&#39;s shape.
Definition: NBNode.h:149
void editJunction(GNEJunction *junction)
edits the traffic light for the given junction
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:86
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
The definition of a single phase of the logic.
long onUpdNeedsDef(FXObject *, FXSelector, void *)
Called when occurs an update of needs definition.
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:74
FXFont * myTableFont
font for the phase table
NBEdge * getFrom() const
returns the from-edge (start of the connection)
GUIGlID getGlID() const
Returns the numerical id of the object.
#define GUIDesignMatrixAttributes
Matrix design extended over Frame and used for represent attributes and their values.
Definition: GUIDesigns.h:201
long onCmdDefDelete(FXObject *, FXSelector, void *)
Called when the user deletes a TLS.
long onCmdDefOffset(FXObject *, FXSelector, void *)
Called when the user changes the offset of a TLS.
long onCmdDefSwitch(FXObject *, FXSelector, void *)
Called when the user switchs a TLS.
long onCmdDefAddOff(FXObject *, FXSelector, void *)
Called when the user adds a OFF.
replace program with a newly guessed program
Definition: GUIAppEnum.h:510
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:995
GNEViewNet * myViewNet
the window to inform when the tls is modfied
Definition: GNEFrame.h:92
void updateDescription() const
update descrition
FXTextField * myNameTextField
name text field
create phase thable
Definition: GUIAppEnum.h:526
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
#define new
Definition: debug_new.h:121
const std::string & getID() const
Returns the id.
Definition: Named.h:66
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:298
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
long onCmdCancel(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button.
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1027
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
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:93
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:719
A list of positions.
const NBConnectionVector & getControlledLinks() const
returns the controlled links (depends on previous call to collectLinks)
long onUpdDefCreate(FXObject *, FXSelector, void *)
Called when occurs an update of create definition.
void buildIinternalLanes(NBTrafficLightDefinition *tlDef)
builds internal lanes for the given tlDef
bool myHaveModifications
whether the current tls was modified
long onCmdPhaseEdit(FXObject *, FXSelector, void *)
Called when the user edits a Phase.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
std::string state
The state definition.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
void computeJunction(GNEJunction *junction)
Definition: GNENet.cpp:959
~GNETLSEditorFrame()
Destructor.
void handleChange(GNEInternalLane *lane)
update phase definition for the current traffic light and phase
delete phase thable
Definition: GUIAppEnum.h:528
NBTrafficLightLogic * getLogic()
Returns the internal logic.
FXDEFMAP(GNETLSEditorFrame) GNETLSEditorFrameMap[]
Ok-button pressed.
Definition: GUIAppEnum.h:63
int getTLIndex() const
get Traffic Light index
void p_abort()
reverts and discards ALL active command groups
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
SUMORTree & getVisualisationSpeedUp()
Returns the RTree used for visualisation speed-up.
Definition: GNENet.cpp:229
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
Cancel-button pressed.
Definition: GUIAppEnum.h:65
FXTextField * myOffset
the control for modifying offset
static SUMOTime getSUMOTime(const FXString &string)
converts to SUMOTime
SUMOTime getOffset() const
Returns the offset of first switch.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:54
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:59
NBTrafficLightLogic * getLogic(const std::string &id, const std::string &programID) const
Returns the computed logic for the given name.
long onUpdDefSwitch(FXObject *, FXSelector, void *)
Called when occurs an update of switch definition.
#define GUIDesignButton
Definition: GUIDesigns.h:66
void updateCycleDuration()
recomputes cycle duration and updates label
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:479
void initDefinitions()
initializes the definitions and corresponding listbox
std::vector< GNEEdge * > retrieveEdges(bool onlySelected=false)
return all edges
Definition: GNENet.cpp:747
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:129
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:204
int tlLinkNo
the traffic light index of this crossing (if controlled)
Definition: NBNode.h:161
long onCmdOK(FXObject *, FXSelector, void *)
long onCmdDefSubRename(FXObject *, FXSelector, void *)
Called when the user sub-renames a TLS.
an edge
FXComboBox * myProgramComboBox
the comboBox for selecting the tl-definition to edit
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:989
GNEJunction * myCurrentJunction
the junction of the tls is being modified
void text()
Definition: gl2psTest.c:260
const std::vector< NBTrafficLightLogic::PhaseDefinition > & getPhases()
the phase of the current traffic light
void setPhaseDuration(int phaseIndex, SUMOTime duration)
Modifies the duration for an existing phase (used by NETEDIT)
long onCmdPhaseCreate(FXObject *, FXSelector, void *)
Called when the user creates a Phase.
Represents a single node (junction) during network building.
Definition: NBNode.h:75
A definition of a pedestrian crossing.
Definition: NBNode.h:135
void setStatusBarText(const std::string &text)
set staturBar text
Definition: GNEViewNet.cpp:345
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2536
std::string getAttribute(SumoXMLAttr key) const
#define GUIDesignLabelLeft
Definition: GUIDesigns.h:139
void addStep(SUMOTime duration, const std::string &state, int index=-1)
Adds a phase to the logic.
long onCmdDefRename(FXObject *, FXSelector, void *)
Called when the user renames a TLS.
long onUpdModified(FXObject *, FXSelector, void *)
Called when occurs an update of modified.
#define GUIDesignLabelAttribute
label extended over the matrix column with thick frame
Definition: GUIDesigns.h:160
GUISelectedStorage gSelected
A global holder of selected objects.
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1120
NBLoadedSUMOTLDef * myEditedDef
the traffic light definition being edited
void cleanup()
cleans up previous lanes
FXLabel * myCycleDuration
label with the cycle duration
LinkState getLinkState() const
whether link state has been modfied
void initPhaseTable(int index=0)
initialies the phase table