Eclipse SUMO - Simulation of Urban MObility
GNETLSEditorFrame.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-2022 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// The Widget for modifying traffic lights
19/****************************************************************************/
20#include <config.h>
21
23#include <netbuild/NBOwnTLDef.h>
24#include <netedit/GNENet.h>
25#include <netedit/GNEUndoList.h>
26#include <netedit/GNEViewNet.h>
40#include <utils/xml/XMLSubSys.h>
41
42#include "GNETLSEditorFrame.h"
43
44
45// ===========================================================================
46// FOX callback mapping
47// ===========================================================================
48
58};
59
75};
76
85};
86
96};
97
103};
104
105// Object implementation
106FXIMPLEMENT(GNETLSEditorFrame::TLSJunction, MFXGroupBoxModule, TLSJunctionMap, ARRAYNUMBER(TLSJunctionMap))
107FXIMPLEMENT(GNETLSEditorFrame::TLSDefinition, MFXGroupBoxModule, TLSDefinitionMap, ARRAYNUMBER(TLSDefinitionMap))
108FXIMPLEMENT(GNETLSEditorFrame::TLSAttributes, MFXGroupBoxModule, TLSAttributesMap, ARRAYNUMBER(TLSAttributesMap))
109FXIMPLEMENT(GNETLSEditorFrame::TLSPhases, MFXGroupBoxModule, TLSPhasesMap, ARRAYNUMBER(TLSPhasesMap))
110FXIMPLEMENT(GNETLSEditorFrame::TLSFile, MFXGroupBoxModule, TLSFileMap, ARRAYNUMBER(TLSFileMap))
111
112
113// ===========================================================================
114// method definitions
115// ===========================================================================
116
118 GNEFrame(viewParent, viewNet, "Edit Traffic Light"),
119 myEditedDef(nullptr) {
120
121 // Create Overlapped Inspection module
122 myOverlappedInspection = new GNEOverlappedInspection(this, SUMO_TAG_JUNCTION);
123
124 // create TLSJunction module
125 myTLSJunction = new GNETLSEditorFrame::TLSJunction(this);
126
127 // create TLSDefinition module
128 myTLSDefinition = new GNETLSEditorFrame::TLSDefinition(this);
129
130 // create TLSAttributes module
131 myTLSAttributes = new GNETLSEditorFrame::TLSAttributes(this);
132
133 // create TLSPhases module
134 myTLSPhases = new GNETLSEditorFrame::TLSPhases(this);
135
136 // create TLSFile module
137 myTLSFile = new GNETLSEditorFrame::TLSFile(this);
138}
139
140
142 cleanup();
143}
144
145
146void
148 // hide myOverlappedInspection
150 // show
152}
153
154
155void
157 // recalc table width
159}
160
161
162void
163GNETLSEditorFrame::editTLS(const Position& clickedPosition, const GNEViewNetHelper::ObjectsUnderCursor& objectsUnderCursor) {
164 // first check if in objectsUnderCursor there is a junction
165 if (objectsUnderCursor.getJunctionFront()) {
166 // show objects under cursor
167 myOverlappedInspection->showOverlappedInspection(objectsUnderCursor, clickedPosition);
168 // hide if we inspect only one junction
171 }
172 // check if we're adding or removing joined TLSs
175 } else {
176 editJunction(objectsUnderCursor.getJunctionFront());
177 }
178 } else if (objectsUnderCursor.getAdditionalFront() && myTLSAttributes->isSetDetectorsToggleButtonEnabled() &&
179 (objectsUnderCursor.getAdditionalFront()->getTagProperty().getTag() == SUMO_TAG_INDUCTION_LOOP)) {
181 } else {
182 myViewNet->setStatusBarText("Click over a junction to edit a TLS");
183 }
184}
185
186
187bool
190 // write warning if netedit is running in testing mode
191 WRITE_DEBUG("Opening question FXMessageBox 'save TLS'");
192 // open question box
193 FXuint answer = FXMessageBox::question(this, MBOX_YES_NO_CANCEL,
194 "Save TLS Changes", "%s",
195 "There is unsaved changes in current edited traffic light.\nDo you want to save it before changing mode?");
196 if (answer == MBOX_CLICKED_YES) { //1:yes, 2:no, 4:esc/cancel
197 // write warning if netedit is running in testing mode
198 WRITE_DEBUG("Closed FXMessageBox 'save TLS' with 'YES'");
199 // save modifications
200 myTLSDefinition->onCmdSaveChanges(nullptr, 0, nullptr);
201 return true;
202 } else if (answer == MBOX_CLICKED_NO) {
203 // write warning if netedit is running in testing mode
204 WRITE_DEBUG("Closed FXMessageBox 'save TLS' with 'No'");
205 // cancel modifications
206 myTLSDefinition->onCmdSaveChanges(nullptr, 0, nullptr);
207 return true;
208 } else {
209 // write warning if netedit is running in testing mode
210 WRITE_DEBUG("Closed FXMessageBox 'save TLS' with 'Cancel'");
211 // abort changing mode
212 return false;
213 }
214 } else {
215 return true;
216 }
217}
218
219
220bool
221GNETLSEditorFrame::parseTLSPrograms(const std::string& file) {
223 NBTrafficLightLogicCont tmpTLLCont;
224 NIXMLTrafficLightsHandler tllHandler(tmpTLLCont, myViewNet->getNet()->getEdgeCont());
225 // existing definitions must be available to update their programs
226 std::set<NBTrafficLightDefinition*> origDefs;
227 for (NBTrafficLightDefinition* def : tllCont.getDefinitions()) {
228 // make a duplicate of every program
229 NBTrafficLightLogic* logic = tllCont.getLogic(def->getID(), def->getProgramID());
230 if (logic != nullptr) {
231 NBTrafficLightDefinition* duplicate = new NBLoadedSUMOTLDef(*def, *logic);
232 std::vector<NBNode*> nodes = def->getNodes();
233 for (auto it_node : nodes) {
234 GNEJunction* junction = myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
235 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, def, false, false), true);
236 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, duplicate, true), true);
237 }
238 tmpTLLCont.insert(duplicate);
239 origDefs.insert(duplicate);
240 } else {
241 WRITE_WARNING("tlLogic '" + def->getID() + "', program '" + def->getProgramID() + "' could not be built");
242 }
243 }
244 //std::cout << " initialized tmpCont with " << origDefs.size() << " defs\n";
245 XMLSubSys::runParser(tllHandler, file);
246
247 std::vector<NBLoadedSUMOTLDef*> loadedTLS;
248 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
249 NBLoadedSUMOTLDef* sdef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
250 if (sdef != nullptr) {
251 loadedTLS.push_back(sdef);
252 }
253 }
254 myViewNet->setStatusBarText("Loaded " + toString(loadedTLS.size()) + " programs");
255 for (auto def : loadedTLS) {
256 if (origDefs.count(def) != 0) {
257 // already add to undolist before
258 //std::cout << " skip " << def->getDescription() << "\n";
259 continue;
260 }
261 std::vector<NBNode*> nodes = def->getNodes();
262 //std::cout << " add " << def->getDescription() << " for nodes=" << toString(nodes) << "\n";
263 for (auto it_node : nodes) {
264 GNEJunction* junction = myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
265 //myViewNet->getUndoList()->add(new GNEChange_TLS(junction, myTLSEditorParent->myEditedDef, false), true);
266 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, def, true), true);
267 }
268 }
269 // clean up temporary container to avoid deletion of defs when it's destruct is called
270 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
271 tmpTLLCont.removeProgram(def->getID(), def->getProgramID(), false);
272 }
273 return true;
274}
275
276
277void
279 editJunction(dynamic_cast<GNEJunction*>(AC));
280}
281
282
283void
288 for (const auto& node : myTLSDefinition->getCurrentTLSDefinition()->getNodes()) {
289 myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(node->getID())->selectTLS(false);
290 }
291 }
292 }
293 // clean data structures
295 // check if delete myEditedDef
296 if (myEditedDef) {
297 delete myEditedDef;
298 myEditedDef = nullptr;
299 }
300 // clear internal lanes
301 buildInternalLanes(nullptr);
302 // clean up attributes
304 // clean up attributes
306 // only clears when there are no definitions
308}
309
310
313 return myTLSJunction;
314}
315
316
319 return myTLSDefinition;
320}
321
322
325 return myTLSAttributes;
326}
327
328
329void
331 // clean up previous internal lanes
332 for (const auto& internalLanes : myInternalLanes) {
333 for (const auto& internalLane : internalLanes.second) {
334 // remove internal lane from grid
336 // delete internal lane
337 delete internalLane;
338 }
339 }
340 // clear container
341 myInternalLanes.clear();
342 // create new internal lanes
343 if (tlDef != nullptr) {
344 const int NUM_POINTS = 10;
345 const NBNode* nbnCurrentJunction = myTLSJunction->getCurrentJunction()->getNBNode();
346 // get innerID NWWriter_SUMO::writeInternalEdges
347 const std::string innerID = ":" + nbnCurrentJunction->getID();
348 const NBConnectionVector& links = tlDef->getControlledLinks();
349 // iterate over links
350 for (const auto& link : links) {
351 int tlIndex = link.getTLIndex();
352 PositionVector shape;
353 try {
354 const NBEdge::Connection& con = link.getFrom()->getConnection(link.getFromLane(), link.getTo(), link.getToLane());
355 shape = con.shape;
356 shape.append(con.viaShape);
357 } catch (ProcessError&) {
358 shape = link.getFrom()->getToNode()->computeInternalLaneShape(link.getFrom(), NBEdge::Connection(link.getFromLane(),
359 link.getTo(), link.getToLane()), NUM_POINTS);
360 }
361 if (shape.length() < 2) {
362 // enlarge shape to ensure visibility
363 shape.clear();
364 const PositionVector laneShapeFrom = link.getFrom()->getLaneShape(link.getFromLane());
365 const PositionVector laneShapeTo = link.getTo()->getLaneShape(link.getToLane());
366 shape.push_back(laneShapeFrom.positionAtOffset(MAX2(0.0, laneShapeFrom.length() - 1)));
367 shape.push_back(laneShapeTo.positionAtOffset(MIN2(1.0, laneShapeFrom.length())));
368 }
369 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), innerID + '_' + toString(tlIndex), shape, tlIndex);
370 // due GNEInternalLane aren't attribute carriers, we need to use the net grid
371 myViewNet->getNet()->getGrid().addAdditionalGLObject(internalLane);
372 myInternalLanes[tlIndex].push_back(internalLane);
373 }
374 // iterate over crossings
375 for (const auto& nbn : tlDef->getNodes()) {
376 for (const auto& crossing : nbn->getCrossings()) {
377 if (crossing->tlLinkIndex2 > 0 && crossing->tlLinkIndex2 != crossing->tlLinkIndex) {
378 // draw both directions
379 PositionVector forward = crossing->shape;
380 forward.move2side(crossing->width / 4);
381 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id, forward, crossing->tlLinkIndex);
382 // due GNEInternalLane aren't attribute carriers, we need to use the net grid
383 myViewNet->getNet()->getGrid().addAdditionalGLObject(internalLane);
384 myInternalLanes[crossing->tlLinkIndex].push_back(internalLane);
385 PositionVector backward = crossing->shape.reverse();
386 backward.move2side(crossing->width / 4);
387 GNEInternalLane* internalLaneReverse = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id + "_r", backward, crossing->tlLinkIndex2);
388 // due GNEInternalLane aren't attribute carriers, we need to use the net grid
389 myViewNet->getNet()->getGrid().addAdditionalGLObject(internalLaneReverse);
390 myInternalLanes[crossing->tlLinkIndex2].push_back(internalLaneReverse);
391 } else {
392 // draw only one lane for both directions
393 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id, crossing->shape, crossing->tlLinkIndex);
394 // due GNEInternalLane aren't attribute carriers, we need to use the net grid
395 myViewNet->getNet()->getGrid().addAdditionalGLObject(internalLane);
396 myInternalLanes[crossing->tlLinkIndex].push_back(internalLane);
397 }
398 }
399 }
400 }
401}
402
403
404std::string
407}
408
409
412 if ((index >= 0) || (index < (int)myEditedDef->getLogic()->getPhases().size())) {
413 return myEditedDef->getLogic()->getPhases().at(index);
414 } else {
415 throw ProcessError("Invalid phase index");
416 }
417}
418
419
420void
423 // get current selected row
424 const auto selectedRow = myTLSPhases->getPhaseTable()->getCurrentSelectedRow();
425 if (myViewNet->changeAllPhases()) {
426 for (int row = 0; row < (int)myEditedDef->getLogic()->getPhases().size(); row++) {
427 myEditedDef->getLogic()->setPhaseState(row, lane->getTLIndex(), lane->getLinkState());
428 }
429 } else {
431 }
432 // init phaseTable
434 // select row
435 myTLSPhases->getPhaseTable()->selectRow(selectedRow);
436 // focus table
437 myTLSPhases->getPhaseTable()->setFocus();
438}
439
440
441void
442GNETLSEditorFrame::handleMultiChange(GNELane* lane, FXObject* obj, FXSelector sel, void* eventData) {
443 if (myEditedDef != nullptr) {
446 std::set<std::string> fromIDs;
447 fromIDs.insert(lane->getMicrosimID());
448 // if neither the lane nor its edge are selected, apply changes to the whole edge
450 for (auto it_lane : lane->getParentEdge()->getLanes()) {
451 fromIDs.insert(it_lane->getMicrosimID());
452 }
453 } else {
454 // if the edge is selected, apply changes to all lanes of all selected edges
456 const auto selectedEdge = myViewNet->getNet()->getAttributeCarriers()->getSelectedEdges();
457 for (const auto& edge : selectedEdge) {
458 for (auto it_lane : edge->getLanes()) {
459 fromIDs.insert(it_lane->getMicrosimID());
460 }
461 }
462 }
463 // if the lane is selected, apply changes to all selected lanes
464 if (lane->isAttributeCarrierSelected()) {
465 const auto selectedLanes = myViewNet->getNet()->getAttributeCarriers()->getSelectedLanes();
466 for (auto it_lane : selectedLanes) {
467 fromIDs.insert(it_lane->getMicrosimID());
468 }
469 }
470
471 }
472 // set new state for all connections from the chosen lane IDs
473 for (auto it : links) {
474 if (fromIDs.count(it.getFrom()->getLaneID(it.getFromLane())) > 0) {
475 std::vector<GNEInternalLane*> lanes = myInternalLanes[it.getTLIndex()];
476 for (auto it_lane : lanes) {
477 it_lane->onDefault(obj, sel, eventData);
478 }
479 }
480 }
481 }
482}
483
484
485bool
487 if (myEditedDef != nullptr) {
489 for (auto it : links) {
490 if (it.getFrom()->getID() == edge->getMicrosimID()) {
491 return true;
492 }
493 }
494 }
495 return false;
496}
497
498
499void
502 // discard previous changes
504 // set junction
506 // init TLS definitions
508 // init TLSAttributes
510 // begin undo-list
511 myViewNet->getUndoList()->begin(GUIIcon::MODETLS, "modifying TLS definition");
512 // only select TLS if getCurrentJunction exist
515 }
519 }
520 // update color
522 }
523 }
524 } else {
525 myViewNet->setStatusBarText("Unsaved modifications. Abort or Save");
526 }
527}
528
529
531GNETLSEditorFrame::getSUMOTime(const std::string& string) {
532 return TIME2STEPS(GNEAttributeCarrier::parse<double>(string));
533}
534
535const std::string
537 return toString(STEPS2TIME(value));
538}
539
540// ---------------------------------------------------------------------------
541// GNETLSEditorFrame::TLSAttributes - methods
542// ---------------------------------------------------------------------------
543
545 MFXGroupBoxModule(TLSEditorParent, TL("Traffic light Attributes")),
546 myTLSEditorParent(TLSEditorParent) {
547 // create frame, label and TextField for Offset (By default disabled)
548 FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
549 new FXLabel(horizontalFrame, toString(SUMO_ATTR_OFFSET).c_str(), nullptr, GUIDesignLabelAttribute);
551 myOffsetTextField->disable();
552 // create frame, label and TextField for parameters (By default disabled)
553 horizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
554 myButtonEditParameters = new FXButton(horizontalFrame, TL("parameters"), nullptr, this, MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERSDIALOG, GUIDesignButtonAttribute);
556 myButtonEditParameters->disable();
557 myParametersTextField->disable();
558 // create Checkable button
561 "Assign E1 detectors\tEnable assign E1 mode\tAssign E1 detectors to the current TLS",
562 "Assign E1 detectors\tDisable assign E1 mode\tAssign E1 detectors to the current TLS",
565}
566
567
569
570
571void
573 show();
574}
575
576
577void
579 hide();
580}
581
582
583void
585 // get current edited junction
586 const auto junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
587 if (junction == nullptr) {
588 throw ProcessError("Junction cannot be NULL");
589 } else {
590 // enable Offset
591 myOffsetTextField->enable();
592 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
593 // enable parameters
594 myButtonEditParameters->enable();
595 myParametersTextField->enable();
596 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
597 // reset mySetDetectorsToggleButton
598 disableE1DetectorMode();
599 }
600}
601
602
603void
605 // clear and disable Offset TextField
606 myOffsetTextField->setText("");
607 myOffsetTextField->disable();
608 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
609 // clear and disable parameters TextField
610 myButtonEditParameters->disable();
611 myParametersTextField->setText("");
612 myParametersTextField->disable();
613 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
614}
615
616
619 return getSUMOTime(myOffsetTextField->getText().text());
620}
621
622
623void
625 myOffsetTextField->setText(getSteps2Time(offset).c_str());
626 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
627}
628
629
630bool
632 if (GNEAttributeCarrier::canParse<SUMOTime>(myOffsetTextField->getText().text())) {
633 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
634 return true;
635 } else {
636 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::RED));
637 return false;
638 }
639}
640
641
642std::string
644 return myParametersTextField->getText().text();
645}
646
647
648void
650 myParametersTextField->setText(parameters.c_str());
651 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
652 // update E1 detectors
653 if (myTLSEditorParent->myEditedDef->getType() != TrafficLightType::STATIC) {
654 updateE1Detectors();
655 }
656}
657
658
659bool
661 if (Parameterised::areParametersValid(myParametersTextField->getText().text())) {
662 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
663 return true;
664 } else {
665 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::RED));
666 return false;
667 }
668}
669
670
671bool
673 return (mySetDetectorsToggleButton->getState() == TRUE);
674}
675
676
677bool
679 // get E1 lane ID
680 const auto laneID = E1->getParentLanes().front()->getID();
681 // iterate over all E1 detectors
682 for (auto it = myE1Detectors.begin(); it != myE1Detectors.end(); it++) {
683 if (E1->getID() == it->second) {
684 // already selected, then remove it from detectors
685 myE1Detectors.erase(it);
686 // and remove it from parameters
687 myTLSEditorParent->myEditedDef->unsetParameter(laneID);
688 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
689 // mark TL as modified
690 myTLSEditorParent->myTLSDefinition->markAsModified();
691 return true;
692 } else if (laneID == it->first) {
693 // there is another E1 in the same lane, then swap
694 myE1Detectors.erase(it);
695 myE1Detectors[laneID] = E1->getID();
696 // also in parameters
697 myTLSEditorParent->myEditedDef->setParameter(laneID, E1->getID());
698 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
699 // mark TL as modified
700 myTLSEditorParent->myTLSDefinition->markAsModified();
701 return true;
702 }
703 }
704 // add it in parameters
705 myE1Detectors[laneID] = E1->getID();
706 myTLSEditorParent->myEditedDef->setParameter(laneID, E1->getID());
707 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
708 // mark TL as modified
709 myTLSEditorParent->myTLSDefinition->markAsModified();
710 return true;
711}
712
713
714const std::map<std::string, std::string>&
716 return myE1Detectors;
717}
718
719
720void
722 mySetDetectorsToggleButton->setState(FALSE, TRUE);
723}
724
725
726long
728 if (isValidOffset()) {
729 myTLSEditorParent->myTLSDefinition->markAsModified();
730 myTLSEditorParent->myEditedDef->setOffset(getOffset());
731 myOffsetTextField->killFocus();
732 myTLSEditorParent->update();
733 }
734 return 1;
735}
736
737
738long
740 if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 0) {
741 myOffsetTextField->disable();
742 // clear E1 detectors
743 if (myE1Detectors.size() > 0) {
744 myE1Detectors.clear();
745 myTLSEditorParent->getViewNet()->update();
746 }
747 } else if (isSetDetectorsToggleButtonEnabled()) {
748 myOffsetTextField->disable();
749 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
750 // joining TLSs, disable button
751 myOffsetTextField->disable();
752 } else {
753 myOffsetTextField->enable();
754 }
755 return 1;
756}
757
758
759long
761 if (isValidParameters()) {
762 myTLSEditorParent->myTLSDefinition->markAsModified();
763 myTLSEditorParent->myEditedDef->setParametersStr(getParameters());
764 myParametersTextField->killFocus();
765 myTLSEditorParent->update();
766 }
767 return 1;
768}
769
770
771long
773 // continue depending of myEditedDef
774 if (myTLSEditorParent->myEditedDef) {
775 // get previous parameters
776 const auto previousParameters = getParameters();
777 // write debug information
778 WRITE_DEBUG("Open single parameters dialog");
779 if (GNESingleParametersDialog(myTLSEditorParent->getViewNet()->getApp(), myTLSEditorParent->myEditedDef).execute()) {
780 // write debug information
781 WRITE_DEBUG("Close single parameters dialog");
782 // set parameters in textfield
783 setParameters(myTLSEditorParent->myEditedDef->getParametersStr());
784 // only mark as modified if parameters are different
785 if (getParameters() != previousParameters) {
786 myTLSEditorParent->myTLSDefinition->markAsModified();
787 }
788 } else {
789 // write debug information
790 WRITE_DEBUG("Cancel single parameters dialog");
791 }
792 }
793 return 1;
794}
795
796
797long
799 if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 0) {
800 myButtonEditParameters->disable();
801 myParametersTextField->disable();
802 // clear E1 detectors
803 if (myE1Detectors.size() > 0) {
804 myE1Detectors.clear();
805 myTLSEditorParent->getViewNet()->update();
806 }
807 } else if (isSetDetectorsToggleButtonEnabled()) {
808 myButtonEditParameters->disable();
809 myParametersTextField->disable();
810 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
811 // joining TLSs, disable button
812 myButtonEditParameters->disable();
813 myParametersTextField->disable();
814 } else {
815 myButtonEditParameters->enable();
816 myParametersTextField->enable();
817 }
818 return 1;
819}
820
821
822long
824 if (mySetDetectorsToggleButton->getState()) {
825 // set special color
826 mySetDetectorsToggleButton->setBackColor(FXRGBA(253, 255, 206, 255));
827 } else {
828 // restore default color
829 mySetDetectorsToggleButton->setBackColor(4293980400);
830 }
831 // update view
832 myTLSEditorParent->getViewNet()->update();
833 return 1;
834}
835
836
837long
839 if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 0) {
840 disableE1DetectorMode();
841 mySetDetectorsToggleButton->disable();
842 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
843 // joining TLSs, disable button
844 disableE1DetectorMode();
845 mySetDetectorsToggleButton->disable();
846 } else if (myTLSEditorParent->myTLSDefinition->getCurrentTLSDefinition()->getType() == TrafficLightType::STATIC) {
847 disableE1DetectorMode();
848 mySetDetectorsToggleButton->disable();
849 } else {
850 mySetDetectorsToggleButton->enable();
851 }
852 return 1;
853}
854
855
856void
858 // first clear E1 detectors
859 myE1Detectors.clear();
860 // iterate over parameters
861 for (const auto& parameter : myTLSEditorParent->myEditedDef->getParametersMap()) {
862 // check if both lane and E1 exists
863 if (myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveLane(parameter.first, false) &&
864 myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_INDUCTION_LOOP, parameter.second, false)) {
865 // add it into list
866 myE1Detectors[parameter.first] = parameter.second;
867 }
868 }
869 // update view net
870 myTLSEditorParent->getViewNet()->update();
871}
872
873// ---------------------------------------------------------------------------
874// GNETLSEditorFrame::TLSJunction - methods
875// ---------------------------------------------------------------------------
876
878 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light")),
879 myTLSEditorParent(TLSEditorParent),
880 myCurrentJunction(nullptr) {
881 // Create frame for junction IDs
882 FXHorizontalFrame* junctionIDFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
883 myJunctionIDLabel = new FXLabel(junctionIDFrame, "Junction ID", nullptr, GUIDesignLabelAttribute);
884 myJunctionIDTextField = new MFXTextFieldTooltip(junctionIDFrame,
887 myJunctionIDTextField->disable();
888 // Create frame for TLS Program ID
889 FXHorizontalFrame* TLSIDFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
890 new FXLabel(TLSIDFrame, "TLS ID", nullptr, GUIDesignLabelAttribute);
891 myTLSIDTextField = new MFXTextFieldTooltip(TLSIDFrame,
894 // create frame, label and textfield for type
895 FXHorizontalFrame* typeFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
896 new FXLabel(typeFrame, toString(SUMO_ATTR_TYPE).c_str(), nullptr, GUIDesignLabelAttribute);
898 // fill comboBox (only certain TL types)
904 // create frame for join buttons
905 FXHorizontalFrame* joinButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
906 // create join states button
909 "Join\tEnable join mode\tJoin TLS and junctions in the current junction.",
910 "Join\tDisable join mode\tJoin TLS and junctions in the current junction.",
913 myDisjoinTLSButton = new MFXButtonTooltip(joinButtons,
915 "Disjoin\tDisjoin current TLS\tDisjoin current TLS.",
917 // update junction description after creation
919 // show TLS Junction
920 show();
921}
922
923
925
926
929 return myCurrentJunction;
930}
931
932
933void
935 myCurrentJunction = junction;
936 // update junction description
937 updateJunctionDescription();
938}
939
940
941void
943 // first reset junction label
944 myJunctionIDLabel->setText(TL("Junction ID"));
945 // clear selected junctions
946 mySelectedJunctionIDs.clear();
947 // disable joining junction mode
948 disableJoiningJunctionMode();
949 // continue depending of current junction
950 if (myCurrentJunction == nullptr) {
951 myJunctionIDTextField->setText(TL("no junction selected"));
952 } else {
953 const auto nbn = myCurrentJunction->getNBNode();
954 // update junction ID text field
955 myJunctionIDTextField->setText(nbn->getID().c_str());
956 // check if junction is controlled
957 if (nbn->getControllingTLS().size() > 0) {
958 // get all nodes controlled by this TLS
959 const auto NBNodes = (*nbn->getControllingTLS().begin())->getNodes();
960 // declare string
961 std::string nodesStr;
962 for (auto it = NBNodes.begin(); it != NBNodes.end(); it++) {
963 if (it == (NBNodes.end() - 1)) {
964 nodesStr += (*it)->getID();
965 } else {
966 nodesStr += (*it)->getID() + ", ";
967 }
968 }
969 // updated junction fields
970 myJunctionIDTextField->setText(nodesStr.c_str());
971 // update junction label
972 if (NBNodes.size() > 1) {
973 myJunctionIDLabel->setText(TL("Junction IDs"));
974 }
975 // update TLS ID text field
976 myTLSIDTextField->setText((*nbn->getControllingTLS().begin())->getID().c_str());
977 // set TLS type
978 myTLSTypeComboBox->setText(myCurrentJunction->getAttribute(SUMO_ATTR_TLTYPE).c_str());
979 }
980 }
981}
982
983
984void
986 myJoinTLSToggleButton->setState(FALSE, TRUE);
987}
988
989
990bool
992 return (myJoinTLSToggleButton->getState() == TRUE);
993}
994
995
996bool
998 return (std::find(mySelectedJunctionIDs.begin(), mySelectedJunctionIDs.end(), junction->getID()) != mySelectedJunctionIDs.end());
999}
1000
1001
1002void
1004 // avoid current junction
1005 if (junction != myCurrentJunction) {
1006 // find ID in selected junctions
1007 auto it = std::find(mySelectedJunctionIDs.begin(), mySelectedJunctionIDs.end(), junction->getID());
1008 // check if add or remove
1009 if (it == mySelectedJunctionIDs.end()) {
1010 mySelectedJunctionIDs.push_back(junction->getID());
1011 } else {
1012 mySelectedJunctionIDs.erase(it);
1013 }
1014 }
1015}
1016
1017
1018const std::vector<std::string>&
1020 return mySelectedJunctionIDs;
1021}
1022
1023
1024long
1026 // get IDs
1027 const std::string currentTLID = (*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getID();
1028 const std::string newTLID = myTLSIDTextField->getText().text();
1029 // check if ID is valid
1030 if (newTLID.empty() || (newTLID == currentTLID)) {
1031 // same ID or empty
1032 myTLSIDTextField->setTextColor(FXRGB(0, 0, 0));
1033 myTLSIDTextField->setText(currentTLID.c_str());
1034 myTLSIDTextField->killFocus();
1035 myTLSEditorParent->update();
1036 // show all moduls
1037 myTLSEditorParent->myTLSDefinition->showTLSDefinition();
1038 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1039 myTLSEditorParent->myTLSPhases->showTLSPhases();
1040 myTLSEditorParent->myTLSFile->showTLSFile();
1041 } else if (!SUMOXMLDefinitions::isValidNetID(newTLID) || myCurrentJunction->getNet()->getTLLogicCont().exist(newTLID)) {
1042 // set invalid color
1043 myTLSIDTextField->setTextColor(FXRGB(255, 0, 0));
1044 // hide moduls
1045 myTLSEditorParent->myTLSDefinition->hideTLSDefinition();
1046 myTLSEditorParent->myTLSAttributes->hideTLSAttributes();
1047 myTLSEditorParent->myTLSPhases->hideTLSPhases();
1048 myTLSEditorParent->myTLSFile->hideTLSFile();
1049 } else {
1050 // make a copy of myCurrentJunction and current tlDef (because will be reset after calling discardChanges)
1051 auto junction = myCurrentJunction;
1052 const auto tlDef = myTLSEditorParent->myTLSDefinition->getCurrentTLSDefinition();
1053 // restore color
1054 myTLSIDTextField->setTextColor(FXRGB(0, 0, 0));
1055 myTLSIDTextField->killFocus();
1056 myTLSEditorParent->update();
1057 // discard previous changes
1058 myTLSEditorParent->myTLSDefinition->discardChanges(false);
1059 // change name using undo-List
1060 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, "rename TLS");
1061 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, tlDef, newTLID), true);
1062 myTLSEditorParent->getViewNet()->getUndoList()->end();
1063 // show all moduls
1064 myTLSEditorParent->myTLSDefinition->showTLSDefinition();
1065 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1066 myTLSEditorParent->myTLSPhases->showTLSPhases();
1067 myTLSEditorParent->myTLSFile->showTLSFile();
1068 // edit junction again
1069 myTLSEditorParent->editJunction(junction);
1070 }
1071 return 1;
1072}
1073
1074
1075long
1076GNETLSEditorFrame::TLSJunction::onUpdTLSID(FXObject*, FXSelector, void*) {
1077 if (myCurrentJunction == nullptr) {
1078 // no junction, disable and clear
1079 myTLSIDTextField->setText("");
1080 myTLSIDTextField->disable();
1081 } else if (myCurrentJunction->getNBNode()->getControllingTLS().size() == 0) {
1082 // no TLSs in Junctions, disable
1083 myTLSIDTextField->disable();
1084 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1085 // selecting E1, disable button
1086 myTLSIDTextField->disable();
1087 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1088 // joining TLSs, disable button
1089 myTLSIDTextField->disable();
1090 } else if (myTLSEditorParent->myTLSDefinition->checkHaveModifications()) {
1091 // current TLS modified, disable
1092 myTLSIDTextField->disable();
1093 } else if (isJoiningJunctions()) {
1094 // joining TLSs, disable button
1095 myTLSIDTextField->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1096 } else {
1097 // enable
1098 myTLSIDTextField->enable();
1099 }
1100 return 1;
1101}
1102
1103
1104long
1106 // get IDs
1107 const std::string currentTLType = toString((*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getType());
1108 const std::string newTLType = myTLSTypeComboBox->getText().text();
1109 // check if ID is valid
1110 if (newTLType.empty() || (newTLType == currentTLType)) {
1111 // same ID or empty, don't change
1112 myTLSTypeComboBox->setTextColor(FXRGB(0, 0, 0));
1113 myTLSTypeComboBox->setText(currentTLType.c_str());
1114 myTLSTypeComboBox->killFocus();
1115 myTLSEditorParent->update();
1116 // show all moduls
1117 myTLSEditorParent->myTLSDefinition->showTLSDefinition();
1118 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1119 myTLSEditorParent->myTLSPhases->showTLSPhases();
1120 myTLSEditorParent->myTLSFile->showTLSFile();
1121 } else if (!SUMOXMLDefinitions::TrafficLightTypes.hasString(newTLType)) {
1122 // set invalid color
1123 myTLSTypeComboBox->setTextColor(FXRGB(255, 0, 0));
1124 // hide moduls
1125 myTLSEditorParent->myTLSDefinition->hideTLSDefinition();
1126 myTLSEditorParent->myTLSAttributes->hideTLSAttributes();
1127 myTLSEditorParent->myTLSPhases->hideTLSPhases();
1128 myTLSEditorParent->myTLSFile->hideTLSFile();
1129 } else {
1130 // reset color
1131 myTLSTypeComboBox->setTextColor(FXRGB(0, 0, 0));
1132 myTLSTypeComboBox->killFocus();
1133 myTLSEditorParent->update();
1134 // make a copy of myCurrentJunction (because will be reset after calling discardChanges)
1135 auto junction = myCurrentJunction;
1136 // discard previous changes
1137 myTLSEditorParent->myTLSDefinition->discardChanges(false);
1138 // change name using undo-List
1139 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, "change TLS type");
1140 junction->setAttribute(SUMO_ATTR_TLTYPE, newTLType, myTLSEditorParent->getViewNet()->getUndoList());
1141 myTLSEditorParent->getViewNet()->getUndoList()->end();
1142 // show all moduls
1143 myTLSEditorParent->myTLSDefinition->showTLSDefinition();
1144 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1145 myTLSEditorParent->myTLSPhases->showTLSPhases();
1146 myTLSEditorParent->myTLSFile->showTLSFile();
1147 // edit junction again
1148 myTLSEditorParent->editJunction(junction);
1149 }
1150 return 1;
1151
1152}
1153
1154
1155long
1157 if (myCurrentJunction == nullptr) {
1158 // no junction, disable and clear
1159 myTLSTypeComboBox->setText("");
1160 myTLSTypeComboBox->disable();
1161 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1162 // selecting E1, disable button
1163 myTLSTypeComboBox->disable();
1164 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1165 // joining TLSs, disable button
1166 myTLSTypeComboBox->disable();
1167 } else if (myCurrentJunction->getNBNode()->getControllingTLS().size() == 0) {
1168 // no TLSs in Junctions, disable
1169 myTLSTypeComboBox->disable();
1170 } else if (myTLSEditorParent->myTLSDefinition->checkHaveModifications()) {
1171 // current TLS modified, disable
1172 myTLSTypeComboBox->disable();
1173 } else {
1174 // enable
1175 myTLSTypeComboBox->enable();
1176 }
1177 return 1;
1178}
1179
1180
1181long
1183 if (myJoinTLSToggleButton->getState()) {
1184 // set special color
1185 myJoinTLSToggleButton->setBackColor(FXRGBA(253, 255, 206, 255));
1186 // clear and fill mySelectedJunctionIDs
1187 mySelectedJunctionIDs.clear();
1188 // get all nodes controlled by this TLS
1189 const auto TLNodes = (*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getNodes();
1190 // fill mySelectedJunctionIDs with TLNodes
1191 mySelectedJunctionIDs.clear();
1192 for (const auto& TLNode : TLNodes) {
1193 mySelectedJunctionIDs.push_back(TLNode->getID());
1194 }
1195 } else {
1196 // make a copy of current junction
1197 const auto currentJunction = myCurrentJunction;
1198 // declare vectors for junctions
1199 std::vector<GNEJunction*> selectedJunctions, resetTLJunctions;
1200 // get selected junctions (all except current
1201 for (const auto& selectedJunctionID : mySelectedJunctionIDs) {
1202 if (selectedJunctionID != currentJunction->getID()) {
1203 selectedJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(selectedJunctionID));
1204 }
1205 }
1206 // get junctions to reset TL (all TL nodes except current)
1207 for (const auto& TLNBNode : (*currentJunction->getNBNode()->getControllingTLS().begin())->getNodes()) {
1208 if (TLNBNode != currentJunction->getNBNode()) {
1209 resetTLJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLNBNode->getID()));
1210 }
1211 }
1212 // discard changes
1213 myTLSEditorParent->myTLSDefinition->discardChanges(false);
1214 // begin undo list
1215 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, "join TLS");
1216 // remove tl from TLNBNode
1217 for (const auto& resetTLJunction : resetTLJunctions) {
1218 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, "priority", myTLSEditorParent->getViewNet()->getUndoList());
1219 }
1220 // now update it in all joined junctions
1221 for (const auto& selectedJunction : selectedJunctions) {
1222 selectedJunction->setAttribute(SUMO_ATTR_TYPE, currentJunction->getAttribute(SUMO_ATTR_TYPE), myTLSEditorParent->getViewNet()->getUndoList());
1223 selectedJunction->setAttribute(SUMO_ATTR_TLID, currentJunction->getAttribute(SUMO_ATTR_TLID), myTLSEditorParent->getViewNet()->getUndoList());
1224 }
1225 // end undo list
1226 myTLSEditorParent->getViewNet()->getUndoList()->end();
1227 // restore default color
1228 myJoinTLSToggleButton->setBackColor(4293980400);
1229 // clear selected junction IDs
1230 mySelectedJunctionIDs.clear();
1231 // edit junction again
1232 myTLSEditorParent->editJunction(currentJunction);
1233 }
1234 // update view
1235 myTLSEditorParent->getViewNet()->update();
1236 return 1;
1237}
1238
1239
1240long
1241GNETLSEditorFrame::TLSJunction::onUpdJoinTLS(FXObject* sender, FXSelector, void*) {
1242 if (myCurrentJunction == nullptr) {
1243 // no junction, disable
1244 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1245 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1246 // selecting E1, disable
1247 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1248 } else if (myTLSEditorParent->myTLSDefinition->checkHaveModifications()) {
1249 // current TLS modified, disable
1250 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1251 } else if (myCurrentJunction->getNBNode()->getControllingTLS().size() == 0) {
1252 // no TLSs in Junctions, disable
1253 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1254 } else {
1255 // enable
1256 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
1257 }
1258}
1259
1260
1261long
1263 // make a copy of current junction
1264 const auto currentJunction = myCurrentJunction;
1265 // declare vectors for junctions
1266 std::vector<GNEJunction*> resetTLJunctions;
1267 // get junctions to reset TL
1268 for (const auto& TLNBNode : (*currentJunction->getNBNode()->getControllingTLS().begin())->getNodes()) {
1269 resetTLJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLNBNode->getID()));
1270 }
1271 // save TL types
1272 const auto type = resetTLJunctions.front()->getAttribute(SUMO_ATTR_TYPE);
1273 const auto tlType = resetTLJunctions.front()->getAttribute(SUMO_ATTR_TLTYPE);
1274 // discard changes
1275 myTLSEditorParent->myTLSDefinition->discardChanges(false);
1276 // begin undo list
1277 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, "disjoin TLS");
1278 // remove tl from TLNBNode
1279 for (const auto& resetTLJunction : resetTLJunctions) {
1280 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, "priority", myTLSEditorParent->getViewNet()->getUndoList());
1281 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, type, myTLSEditorParent->getViewNet()->getUndoList());
1282 resetTLJunction->setAttribute(SUMO_ATTR_TLTYPE, tlType, myTLSEditorParent->getViewNet()->getUndoList());
1283 }
1284 // end undo list
1285 myTLSEditorParent->getViewNet()->getUndoList()->end();
1286 // restore default color
1287 myJoinTLSToggleButton->setBackColor(4293980400);
1288 // clear selected junction IDs
1289 mySelectedJunctionIDs.clear();
1290 // edit junction again
1291 myTLSEditorParent->editJunction(currentJunction);
1292 return 1;
1293}
1294
1295
1296long
1297GNETLSEditorFrame::TLSJunction::onUpdDisjoinTLS(FXObject* sender, FXSelector, void*) {
1298 if (myCurrentJunction == nullptr) {
1299 // no junction, disable
1300 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1301 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1302 // selecting E1, disable
1303 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1304 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1305 // joining TLSs, disable button
1306 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1307 } else if (myTLSEditorParent->myTLSDefinition->checkHaveModifications()) {
1308 // current TLS modified, disable
1309 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1310 } else if (myCurrentJunction->getNBNode()->getControllingTLS().size() == 0) {
1311 // no TLSs in Junctions, disable
1312 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1313 } else if ((*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getNodes().size() == 1) {
1314 // TLS only control one junction, disable
1315 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1316 } else {
1317 // enable
1318 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
1319 }
1320}
1321
1322// ---------------------------------------------------------------------------
1323// GNETLSEditorFrame::TLSDefinition - methods
1324// ---------------------------------------------------------------------------
1325
1327 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light Programs")),
1328 myTLSEditorParent(TLSEditorParent) {
1329 // create frame, label and comboBox for programID
1330 FXHorizontalFrame* programFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1331 new FXLabel(programFrame, toString(SUMO_ATTR_PROGRAMID).c_str(), nullptr, GUIDesignLabelAttribute);
1333 myProgramComboBox->setEditable(false);
1334 myProgramComboBox->disable();
1335 // create auxiliar frames
1336 FXHorizontalFrame* horizontalFrameAux = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
1337 FXVerticalFrame* verticalFrameAuxA = new FXVerticalFrame(horizontalFrameAux, GUIDesignAuxiliarHorizontalFrame);
1338 FXVerticalFrame* verticalFrameAuxB = new FXVerticalFrame(horizontalFrameAux, GUIDesignAuxiliarHorizontalFrame);
1339 // create create tlDef button
1340 myCreateButton = new FXButton(verticalFrameAuxA, TL("Create TLS\t\tCreate a new traffic light program."),
1342 // create delete tlDef button
1343 new FXButton(verticalFrameAuxA, TL("Delete\t\tDelete a traffic light program. If all programs are deleted the junction turns into a priority junction."),
1345 // create reset current tlDef button
1346 new FXButton(verticalFrameAuxB, TL("Reset single\t\\Reset current TLS program."),
1348 // create reset all tlDefs button
1349 new FXButton(verticalFrameAuxB, TL("Reset all\t\tReset all TLS programs."),
1351 // create save modifications button
1352 new FXButton(verticalFrameAuxA, TL("Save\t\tSave program modifications. (Enter)"),
1354 // create discard modifications buttons
1355 new FXButton(verticalFrameAuxB, TL("Cancel\t\tDiscard program modifications. (Esc)"),
1357 // show GroupBox
1358 show();
1359}
1360
1361
1363
1364
1365void
1367 show();
1368}
1369
1370
1371void
1373 hide();
1374}
1375
1376
1377bool
1379 // get current edited junction
1380 const auto junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1381 if (junction == nullptr) {
1382 throw ProcessError("Junction cannot be NULL");
1383 } else {
1384 // clear definitions
1385 myTLSDefinitions.clear();
1386 // obtain TLSs sorted by ID
1387 std::set<std::string> programIDs;
1388 for (const auto& TLS : junction->getNBNode()->getControllingTLS()) {
1389 myTLSDefinitions.push_back(TLS);
1390 programIDs.insert(TLS->getProgramID());
1391 }
1392 for (const auto& programID : programIDs) {
1393 myProgramComboBox->appendItem(programID.c_str());
1394 }
1395 // check if enable TLS definitions
1396 if (myTLSDefinitions.size() > 0) {
1397 myProgramComboBox->enable();
1398 myProgramComboBox->setCurrentItem(0);
1399 myProgramComboBox->setNumVisible(myProgramComboBox->getNumItems());
1400 // switch TLS Program
1401 return switchProgram();
1402 }
1403 return false;
1404 }
1405}
1406
1407
1408void
1410 // clear definitions
1411 myTLSDefinitions.clear();
1412 // clear and disable myProgramComboBox
1413 myProgramComboBox->clearItems();
1414 myProgramComboBox->disable();
1415}
1416
1417
1418int
1420 return myProgramComboBox->getNumItems();
1421}
1422
1423
1424int
1426 return (int)myTLSDefinitions.size();
1427}
1428
1429
1430bool
1432 return myHaveModifications;
1433}
1434
1435
1436void
1438 myHaveModifications = true;
1439}
1440
1441
1444 // find TLS definition
1445 for (const auto& TLSDefinition : myTLSDefinitions) {
1446 if (TLSDefinition->getProgramID() == myProgramComboBox->getText().text()) {
1447 return TLSDefinition;
1448 }
1449 }
1450 throw ProcessError("TLSDefinition cannot be found");
1451}
1452
1453
1454const std::string
1456 if (myProgramComboBox->getNumItems() == 0) {
1457 return "";
1458 } else {
1459 return myProgramComboBox->getText().text();
1460 }
1461}
1462
1463
1464void
1466 // get junction copy
1467 auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1468 if (currentJunction != nullptr) {
1469 myTLSEditorParent->getViewNet()->getUndoList()->abortAllChangeGroups();
1470 myTLSEditorParent->cleanup();
1471 myTLSEditorParent->getViewNet()->updateViewNet();
1472 // edit junction again
1473 if (editJunctionAgain) {
1474 myTLSEditorParent->editJunction(currentJunction);
1475 }
1476 }
1477}
1478
1479
1480long
1482 // get current edited junction (needed because onCmdDiscardChanges clear junction)
1483 GNEJunction* currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1484 // abort because we onCmdOk assumes we wish to save an edited definition
1485 discardChanges(false);
1486 // check that current junction has two or more edges
1487 if ((currentJunction->getGNEIncomingEdges().size() > 0) && (currentJunction->getGNEOutgoingEdges().size() > 0)) {
1488 // create TLS in junction
1489 createTLS(currentJunction);
1490 // edit junction
1491 myTLSEditorParent->editJunction(currentJunction);
1492 // switch to the last program
1493 myProgramComboBox->setCurrentItem(myProgramComboBox->getNumItems() - 1, TRUE);
1494 } else {
1495 // write warning if netedit is running in testing mode
1496 WRITE_DEBUG("Opening warning FXMessageBox 'invalid TLS'");
1497 // open question box
1498 FXMessageBox::warning(this, MBOX_OK,
1499 "TLS cannot be created", "%s",
1500 "Traffic Light cannot be created because junction must have\n at least one incoming edge and one outgoing edge.");
1501 // write warning if netedit is running in testing mode
1502 WRITE_DEBUG("Closed FXMessageBox 'invalid TLS'");
1503 }
1504 return 1;
1505}
1506
1507
1508long
1509GNETLSEditorFrame::TLSDefinition::onUpdCreate(FXObject* sender, FXSelector, void*) {
1510 // get current junction
1511 const auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1512 // check conditions
1513 if (currentJunction == nullptr) {
1514 // no junction, disable button
1515 sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1516 } else if (myHaveModifications) {
1517 // wait for modifications, disable button
1518 sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1519 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1520 // selecting E1, disable button
1521 sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1522 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1523 // joining TLSs, disable button
1524 sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1525 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1526 // joining TLSs, disable button
1527 sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1528 } else {
1529 // enable button
1530 sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
1531 }
1532 // update button text
1533 if (currentJunction == nullptr) {
1534 myCreateButton->setText(TL("Create"));
1535 } else if (currentJunction->getNBNode()->isTLControlled()) {
1536 myCreateButton->setText(TL("Duplicate"));
1537 } else {
1538 myCreateButton->setText(TL("Create"));
1539 }
1540 return 1;
1541}
1542
1543
1544long
1546 // get current junction
1547 GNEJunction* currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1548 // get current edited tlDef
1549 NBTrafficLightDefinition* tlDef = myTLSEditorParent->myTLSDefinition->getCurrentTLSDefinition();
1550 // check if remove entire TLS or only one program
1551 const bool changeJunctionType = (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 1);
1552 // abort because onCmdOk assumes we wish to save an edited definition
1553 discardChanges(false);
1554 // check if change junction type
1555 if (changeJunctionType) {
1556 currentJunction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::PRIORITY), myTLSEditorParent->getViewNet()->getUndoList());
1557 } else {
1558 // just remove TLDef
1559 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(currentJunction, tlDef, false), true);
1560 // edit junction again
1561 myTLSEditorParent->editJunction(currentJunction);
1562 }
1563 return 1;
1564}
1565
1566
1567long
1569 // obtain junction and old definitions
1570 GNEJunction* junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1571 NBTrafficLightDefinition* oldDef = myTLSEditorParent->myTLSDefinition->getCurrentTLSDefinition();
1572 const std::string programID = oldDef->getProgramID();
1573 // discard changes
1574 discardChanges(false);
1575 // begin undo
1576 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, "reset current program");
1577 // remove old definition
1578 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, oldDef, false), true);
1579 // create new definition, and add it
1580 NBOwnTLDef* newDef = new NBOwnTLDef(oldDef->getID(), oldDef->getNodes(), oldDef->getOffset(), oldDef->getType());
1581 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, newDef, true, true), true);
1582 // set old index
1583 newDef->setProgramID(programID);
1584 // end undo
1585 myTLSEditorParent->getViewNet()->getUndoList()->end();
1586 // inspect junction again
1587 myTLSEditorParent->editJunction(junction);
1588 // switch to programID
1589 int index = -1;
1590 for (int i = 0; i < myProgramComboBox->getNumItems(); i++) {
1591 if (myProgramComboBox->getItem(i).text() == programID) {
1592 index = i;
1593 }
1594 }
1595 if (index != -1) {
1596 myProgramComboBox->setCurrentItem(index, TRUE);
1597 }
1598 return 1;
1599}
1600
1601
1602long
1604 // obtain junction and old definitions
1605 GNEJunction* junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1606 NBTrafficLightDefinition* oldDef = myTLSEditorParent->myTLSDefinition->getCurrentTLSDefinition();
1607 // get a list of all affected nodes
1608 std::vector<GNEJunction*> TLSJunctions;
1609 for (const auto& TLSNode : oldDef->getNodes()) {
1610 TLSJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLSNode->getID()));
1611 }
1612 // discard all previous changes
1613 discardChanges(false);
1614 // begin undo
1615 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, "reset TLS");
1616 // set junction as priority (this will also remove all program, see GNEJunction::setJunctionType)
1617 for (const auto& TLSJunction : TLSJunctions) {
1618 TLSJunction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::PRIORITY), myTLSEditorParent->getViewNet()->getUndoList());
1619 }
1620 // create TLS in junction
1621 createTLS(junction);
1622 // set TLS in all other junctions
1623 for (const auto& TLSJunction : TLSJunctions) {
1624 if (TLSJunction != junction) {
1625 TLSJunction->setAttribute(SUMO_ATTR_TYPE, TLSJunction->getAttribute(SUMO_ATTR_TYPE), myTLSEditorParent->getViewNet()->getUndoList());
1626 TLSJunction->setAttribute(SUMO_ATTR_TLID, TLSJunction->getAttribute(SUMO_ATTR_TLID), myTLSEditorParent->getViewNet()->getUndoList());
1627 }
1628 }
1629 // end undo
1630 myTLSEditorParent->getViewNet()->getUndoList()->end();
1631 // edit junction
1632 myTLSEditorParent->editJunction(junction);
1633 return 1;
1634}
1635
1636
1637long
1639 // just switch program
1640 switchProgram();
1641 return 1;
1642}
1643
1644
1645long
1647 if (getNumberOfTLSDefinitions() == 0) {
1648 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1649 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1650 // selecting E1, disable button
1651 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1652 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1653 // joining TLSs, disable button
1654 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1655 } else if (myHaveModifications) {
1656 // modifications, enable button
1657 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
1658 } else {
1659 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1660 }
1661}
1662
1663
1664long
1666 if (getNumberOfTLSDefinitions() == 0) {
1667 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1668 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1669 // selecting E1, disable button
1670 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1671 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1672 // joining TLSs, disable button
1673 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1674 } else if (myHaveModifications) {
1675 // modifications, disable button
1676 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1677 } else {
1678 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
1679 }
1680}
1681
1682
1683long
1685 if (getNumberOfTLSDefinitions() <= 1) {
1686 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1687 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1688 // selecting E1, disable button
1689 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1690 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1691 // joining TLSs, disable button
1692 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1693 } else if (myHaveModifications) {
1694 // modifications, disable button
1695 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
1696 } else {
1697 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
1698 }
1699}
1700
1701
1702long
1704 // get junction copy
1705 const auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1706 // get current program
1707 const auto currentProgram = myProgramComboBox->getCurrentItem();
1708 // check that junction is valid
1709 if (currentJunction != nullptr) {
1710 const auto oldDefinition = getCurrentTLSDefinition();
1711 std::vector<NBNode*> nodes = oldDefinition->getNodes();
1712 for (const auto& node : nodes) {
1713 GNEJunction* junction = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(node->getID());
1714 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, oldDefinition, false), true);
1715 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, myTLSEditorParent->myEditedDef, true), true);
1716 }
1717 // end change
1718 myTLSEditorParent->getViewNet()->getUndoList()->end();
1719 // mark as saved
1720 myHaveModifications = false;
1721 // reset myEditedDef (because is already in eine undo-list)
1722 myTLSEditorParent->myEditedDef = nullptr;
1723 myTLSEditorParent->cleanup();
1724 myTLSEditorParent->getViewNet()->updateViewNet();
1725 // edit junction again
1726 myTLSEditorParent->editJunction(currentJunction);
1727 // change program
1728 myProgramComboBox->setCurrentItem(currentProgram, TRUE);
1729 } else {
1730 // discard changes inspecting junction again
1731 discardChanges(true);
1732 }
1733 return 1;
1734}
1735
1736
1737long
1739 // discard changes inspecting junction again
1740 discardChanges(true);
1741 return 1;
1742}
1743
1744
1745void
1747 // get current TLS program id
1748 const auto currentTLS = getCurrentTLSProgramID();
1749 // check conditions
1750 if (junction == nullptr) {
1751 throw ProcessError("junction cannot be null");
1753 // set junction as TLS
1754 junction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::TRAFFIC_LIGHT), myTLSEditorParent->getViewNet()->getUndoList());
1755 } else if (junction->getNBNode()->isTLControlled()) {
1756 // use existing traffic light as template for type, signal groups, controlled nodes etc
1757 NBTrafficLightDefinition* tpl = nullptr;
1758 for (const auto& TLS : junction->getNBNode()->getControllingTLS()) {
1759 if (TLS->getProgramID() == currentTLS) {
1760 tpl = TLS;
1761 }
1762 }
1763 // if template is empty, use first TLS
1764 if (tpl == nullptr) {
1765 tpl = *junction->getNBNode()->getControllingTLS().begin();
1766 }
1767 // create new logic
1769 // create new TLDef
1770 NBLoadedSUMOTLDef* newDef = new NBLoadedSUMOTLDef(*tpl, *newLogic);
1771 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1772 newDef->setProgramID(tllCont.getNextProgramID(newDef->getID()));
1773 // remove new logic
1774 delete newLogic;
1775 // add it using GNEChange_TLS
1776 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TLF("duplicate program '%' of traffic light '%'", tpl->getProgramID(), tpl->getID()));
1777 for (NBNode* node : newDef->getNodes()) {
1778 GNEJunction* j = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(node->getID());
1779 // not forcing insertion because we already ensured a new id and multiple junctions will attempt insertion
1780 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(j, newDef, true, false), true);
1781 }
1782 myTLSEditorParent->getViewNet()->getUndoList()->end();
1783 } else {
1784 // for some reason the traffic light was not built, try again
1785 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, nullptr, true, true), true);
1786 }
1787}
1788
1789
1790bool
1792 if (myTLSEditorParent->myTLSJunction->getCurrentJunction() == nullptr) {
1793 throw ProcessError("Junction cannot be NULL");
1794 } else if (getNumberOfTLSDefinitions() != getNumberOfPrograms()) {
1795 throw ProcessError("myProgramComboBox must have the same number of TLSDefinitions");
1796 } else {
1797 // reset save flag
1798 myHaveModifications = false;
1799 // get current definition
1800 NBTrafficLightDefinition* tlDef = getCurrentTLSDefinition();
1801 // logic may not have been recomputed yet. recompute to be sure
1802 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1803 // compute junction
1804 myTLSEditorParent->getViewNet()->getNet()->computeJunction(myTLSEditorParent->myTLSJunction->getCurrentJunction());
1805 // obtain TrafficLight logic vinculated with tlDef
1806 NBTrafficLightLogic* tllogic = tllCont.getLogic(tlDef->getID(), tlDef->getProgramID());
1807 // check that tllLogic exist
1808 if (tllogic != nullptr) {
1809 // now we can be sure that the tlDef is up to date (i.e. re-guessed)
1810 myTLSEditorParent->buildInternalLanes(tlDef);
1811 // create working duplicate from original def
1812 delete myTLSEditorParent->myEditedDef;
1813 myTLSEditorParent->myEditedDef = new NBLoadedSUMOTLDef(*tlDef, *tllogic);
1814 // set values
1815 myTLSEditorParent->myTLSAttributes->setOffset(myTLSEditorParent->myEditedDef->getLogic()->getOffset());
1816 myTLSEditorParent->myTLSAttributes->setParameters(myTLSEditorParent->myEditedDef->getLogic()->getParametersStr());
1817 // init phaseTable with the new TLS
1818 myTLSEditorParent->myTLSPhases->initPhaseTable();
1819 } else {
1820 // tlDef has no valid logic (probably because id does not control any links
1821 discardChanges(false);
1822 myTLSEditorParent->getViewNet()->setStatusBarText("Traffic light does not control any links");
1823 return false;
1824 }
1825 }
1826 return true;
1827}
1828
1829// ---------------------------------------------------------------------------
1830// GNETLSEditorFrame::TLSPhases - methods
1831// ---------------------------------------------------------------------------
1832
1834 MFXGroupBoxModule(TLSEditorParent, TL("Phases"), MFXGroupBoxModule::Options::COLLAPSIBLE | MFXGroupBoxModule::Options::EXTENSIBLE),
1835 myTLSEditorParent(TLSEditorParent) {
1836 // create GNETLSTable
1837 myPhaseTable = new GNETLSTable(this);
1838 // hide phase table
1839 myPhaseTable->hide();
1840 FXHorizontalFrame* phaseButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
1841 FXVerticalFrame* col1 = new FXVerticalFrame(phaseButtons, GUIDesignAuxiliarHorizontalFrame); // left button columm
1842 FXVerticalFrame* col2 = new FXVerticalFrame(phaseButtons, GUIDesignAuxiliarHorizontalFrame); // right button column
1843 // create cleanup states button
1845 "Clean States\tClean unused states from all phase\tClean unused states from all phase. (Not allowed for multiple programs)",
1847 // add unused states button
1849 "Add States\tExtend the state vector for all phases by one entry\tExtend the state vector for all phases by one entry. (Unused until a connection or crossing is assigned to the new index)",
1851 // group states button
1853 "Group Sig.\tShorten state definition by letting connections with the same signal states use the same index\tShorten state definition by letting connections with the same signal states use the same index. (Not allowed for multiple programs)",
1855 // ungroup states button
1857 "Ungroup Sig.\tLet every connection use a distinct index (reverse state grouping)\tLet every connection use a distinct index (reverse state grouping). (Not allowed for multiple programs)",
1859 // show TLSFile
1860 show();
1861}
1862
1863
1865}
1866
1867
1868void
1870 show();
1871}
1872
1873
1874void
1876 hide();
1877}
1878
1879
1882 return myTLSEditorParent;
1883}
1884
1885
1888 return myPhaseTable;
1889}
1890
1891
1892void
1894 // first clear table
1895 myPhaseTable->clearTable();
1896 if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() > 0) {
1897 if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC) {
1898 initStaticPhaseTable();
1899 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::ACTUATED) {
1900 initActuatedPhaseTable();
1901 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::DELAYBASED) {
1902 initDelayBasePhaseTable();
1903 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA) {
1904 initNEMAPhaseTable();
1905 }
1906 // select first element (by default)
1907 myPhaseTable->selectRow(0);
1908 // recalc width and show
1909 myPhaseTable->recalcTableWidth();
1910 myPhaseTable->show();
1911 } else {
1912 myPhaseTable->hide();
1913 }
1914 update();
1915}
1916
1917
1918bool
1919GNETLSEditorFrame::TLSPhases::changePhaseValue(const int col, const int row, const std::string& value) {
1920 // Declare columns
1921 int colDuration = 1;
1922 int colState = -1;
1923 int colNext = -1;
1924 int colName = -1;
1925 int colMinDur = -1;
1926 int colMaxDur = -1;
1927 int colEarliestEnd = -1;
1928 int colLatestEnd = -1;
1929 int colVehExt = -1;
1930 int colYellow = -1;
1931 int colRed = -1;
1932 // set columns depending of traffic light type
1933 if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC) {
1934 colState = 2;
1935 colNext = 3;
1936 colName = 4;
1937 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::ACTUATED) {
1938 colMinDur = 2;
1939 colMaxDur = 3;
1940 colState = 4;
1941 colEarliestEnd = 5;
1942 colLatestEnd = 6;
1943 colNext = 7;
1944 colName = 8;
1945 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::DELAYBASED) {
1946 colMinDur = 2;
1947 colMaxDur = 3;
1948 colState = 4;
1949 colNext = 5;
1950 colName = 6;
1951 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA) {
1952 colMinDur = 2;
1953 colMaxDur = 3;
1954 colState = 4;
1955 colVehExt = 5;
1956 colYellow = 6;
1957 colRed = 7;
1958 colNext = 8;
1959 colName = 9;
1960 }
1961 // check column
1962 if (col == colDuration) {
1963 return setDuration(col, row, value);
1964 } else if (col == colState) {
1965 return setState(col, row, value);
1966 } else if (col == colNext) {
1967 return setNext(col, row, value);
1968 } else if (col == colName) {
1969 return setName(row, value);
1970 } else if (col == colMinDur) {
1971 return setMinDur(row, value);
1972 } else if (col == colMaxDur) {
1973 return setMaxDur(row, value);
1974 } else if (col == colEarliestEnd) {
1975 return setEarliestEnd(row, value);
1976 } else if (col == colLatestEnd) {
1977 return setLatestEnd(row, value);
1978 } else if (col == colVehExt) {
1979 return setVehExt(row, value);
1980 } else if (col == colYellow) {
1981 return setYellow(row, value);
1982 } else if (col == colRed) {
1983 return setRed(row, value);
1984 } else {
1985 throw ProcessError("invalid column");
1986 }
1987}
1988
1989
1990void
1991GNETLSEditorFrame::TLSPhases::addPhase(const int row, const char c) {
1992 // mark TLS as modified
1993 myTLSEditorParent->myTLSDefinition->markAsModified();
1994 // build default phase
1995 const int newIndex = buildDefaultPhase(row);
1996 // check if override state
1997 switch (c) {
1998 case 'r':
1999 case 'y':
2000 case 'g':
2001 case 'G':
2002 myTLSEditorParent->myEditedDef->getLogic()->overrideState(newIndex, c);
2003 break;
2004 default:
2005 break;
2006 }
2007 // Write debug
2008 if (c == ' ') {
2009 WRITE_DEBUG("Add default phase in row " + toString(row));
2010 } else {
2011 WRITE_DEBUG("Add new phase in row " + toString(row) + " of type: " + c);
2012 }
2013 // int phase table again
2014 initPhaseTable();
2015 // mark new row as selected
2016 myPhaseTable->selectRow(newIndex);
2017 // set focus in table
2018 getPhaseTable()->setFocus();
2019}
2020
2021
2022void
2024 // mark TLS as modified
2025 myTLSEditorParent->myTLSDefinition->markAsModified();
2026 // build default phase
2027 const int newIndex = buildDefaultPhase(row);
2028 // coply old phase in the new phase
2029 myTLSEditorParent->myEditedDef->getLogic()->copyPhase(row, row + 1);
2030 // Write debug
2031 WRITE_DEBUG("Duplicated phase " + toString(row));
2032 // int phase table again
2033 initPhaseTable();
2034 // mark new row as selected
2035 myPhaseTable->selectRow(newIndex);
2036 // set focus in table
2037 getPhaseTable()->setFocus();
2038}
2039
2040
2041void
2043 // mark TLS ad modified
2044 myTLSEditorParent->myTLSDefinition->markAsModified();
2045 // calculate new row
2046 const auto newRow = MAX2(0, (row - 1));
2047 // delete selected row
2048 myTLSEditorParent->myEditedDef->getLogic()->deletePhase(row);
2049 // Write debug
2050 WRITE_DEBUG("removed phase " + toString(row));
2051 // int phase table again
2052 initPhaseTable();
2053 // mark new row as selected
2054 myPhaseTable->selectRow(newRow);
2055 // set focus in table
2056 getPhaseTable()->setFocus();
2057}
2058
2059
2060void
2062 // mark TLS ad modified
2063 myTLSEditorParent->myTLSDefinition->markAsModified();
2064 // Write debug
2065 WRITE_DEBUG("Move up phase " + toString(row));
2066 // delete selected row
2067 if (row == 0) {
2068 myTLSEditorParent->myEditedDef->getLogic()->swapfirstPhase();
2069 } else {
2070 myTLSEditorParent->myEditedDef->getLogic()->swapPhase(row, row - 1);
2071 }
2072 // int phase table again
2073 initPhaseTable();
2074 // mark new row as selected
2075 if (row == 0) {
2076 myPhaseTable->selectRow((int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1);
2077 } else {
2078 myPhaseTable->selectRow(row - 1);
2079 }
2080 // set focus in table
2081 getPhaseTable()->setFocus();
2082}
2083
2084
2085void
2087 // mark TLS ad modified
2088 myTLSEditorParent->myTLSDefinition->markAsModified();
2089 // Write debug
2090 WRITE_DEBUG("Move down phase " + toString(row));
2091 // delete selected row
2092 if (row == (int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1) {
2093 myTLSEditorParent->myEditedDef->getLogic()->swaplastPhase();
2094 } else {
2095 myTLSEditorParent->myEditedDef->getLogic()->swapPhase(row, row + 1);
2096 }
2097 // int phase table again
2098 initPhaseTable();
2099 // mark new row as selected
2100 if (row == (int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1) {
2101 myPhaseTable->selectRow(0);
2102 } else {
2103 myPhaseTable->selectRow(row + 1);
2104 }
2105 // set focus in table
2106 getPhaseTable()->setFocus();
2107}
2108
2109
2110void
2112 // get phase
2113 const auto& phase = myTLSEditorParent->getPhase(myPhaseTable->getCurrentSelectedRow());
2114 // need not hold since links could have been deleted somewhere else and indices may be reused
2115 for (const auto& internalLane : myTLSEditorParent->myInternalLanes) {
2116 int tlIndex = internalLane.first;
2117 std::vector<GNEInternalLane*> lanes = internalLane.second;
2119 if (tlIndex >= 0 && tlIndex < (int)phase.state.size()) {
2120 state = (LinkState)phase.state[tlIndex];
2121 }
2122 for (const auto& lane : lanes) {
2123 lane->setLinkState(state);
2124 }
2125 }
2126 // update view net (for coloring)
2127 myTLSEditorParent->getViewNet()->updateViewNet();
2128}
2129
2130
2131long
2132GNETLSEditorFrame::TLSPhases::onUpdNeedsDef(FXObject* sender, FXSelector, void*) {
2133 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2134 // selecting E1, disable buttons
2135 sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2136 // also disable table
2137 myPhaseTable->disable();
2138 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2139 // joining TLSs, disable button
2140 sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2141 // also disable table
2142 myPhaseTable->disable();
2143 } else if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() > 0) {
2144 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
2145 // also enable table
2146 myPhaseTable->enable();
2147 } else {
2148 sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2149 // also disable table
2150 myPhaseTable->disable();
2151 }
2152 return 1;
2153}
2154
2155
2156long
2157GNETLSEditorFrame::TLSPhases::onUpdNeedsDefAndPhase(FXObject* sender, FXSelector, void*) {
2158 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2159 // selecting E1, disable buttons
2160 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2161 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2162 // joining TLSs, disable button
2163 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2164 } else if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 0) {
2165 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2166 } else if (myPhaseTable->getNumRows() <= 1) {
2167 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2168 } else {
2169 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
2170 }
2171}
2172
2173
2174long
2176 if (myTLSEditorParent->myEditedDef->cleanupStates()) {
2177 myTLSEditorParent->myTLSDefinition->markAsModified();
2178 }
2179 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2180 initPhaseTable();
2181 myPhaseTable->setFocus();
2182 myTLSEditorParent->myTLSDefinition->markAsModified();
2183 WRITE_DEBUG("Clean states");
2184 return 1;
2185}
2186
2187
2188long
2190 myTLSEditorParent->myEditedDef->getLogic()->setStateLength(myTLSEditorParent->myEditedDef->getLogic()->getNumLinks() + 1);
2191 myTLSEditorParent->myTLSDefinition->markAsModified();
2192 initPhaseTable();
2193 myPhaseTable->setFocus();
2194 WRITE_DEBUG("Add unused states");
2195 return 1;
2196}
2197
2198
2199long
2201 myTLSEditorParent->myEditedDef->groupSignals();
2202 myTLSEditorParent->myTLSDefinition->markAsModified();
2203 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2204 initPhaseTable();
2205 myPhaseTable->setFocus();
2206 WRITE_DEBUG("Group states");
2207 return 1;
2208}
2209
2210
2211long
2213 myTLSEditorParent->myEditedDef->setParticipantsInformation();
2214 myTLSEditorParent->myEditedDef->ungroupSignals();
2215 myTLSEditorParent->myTLSDefinition->markAsModified();
2216 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2217 initPhaseTable();
2218 myPhaseTable->setFocus();
2219 WRITE_DEBUG("Ungroup states");
2220 return 1;
2221}
2222
2223
2224long
2225GNETLSEditorFrame::TLSPhases::onUpdNeedsSingleDef(FXObject* sender, FXSelector, void*) {
2226 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2227 // selecting E1, disable buttons
2228 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2229 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2230 // joining TLSs, disable button
2231 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2232 } else if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 1) {
2233 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
2234 } else {
2235 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2236 }
2237}
2238
2239
2240long
2241GNETLSEditorFrame::TLSPhases::onUpdUngroupStates(FXObject* sender, FXSelector, void*) {
2242 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2243 // selecting E1, disable buttons
2244 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2245 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2246 // joining TLSs, disable button
2247 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2248 } else if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() != 1) {
2249 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2250 } else if (myTLSEditorParent->myEditedDef == nullptr) {
2251 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2252 } else if (myTLSEditorParent->myEditedDef->usingSignalGroups()) {
2253 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2254 } else {
2255 return sender->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
2256 }
2257}
2258
2259
2260void
2262 // declare constants for columns
2263 const int colDuration = 1;
2264 const int colState = 2;
2265 const int colNext = 3;
2266 const int colName = 4;
2267 // get phases
2268 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2269 // adjust table
2270 myPhaseTable->setTableSize("sup-midtb", (int)phases.size());
2271 // fill rows
2272 for (int row = 0; row < (int)phases.size(); row++) {
2273 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2274 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2275 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2276 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2277 }
2278 // set columns
2279 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2280 myPhaseTable->setColumnLabelTop(colState, "state");
2281 myPhaseTable->setColumnLabelTop(colNext, "next");
2282 myPhaseTable->setColumnLabelTop(colName, "name");
2283 // set bot labels
2284 updateCycleDuration(colDuration);
2285 updateStateSize(colState);
2286 // set focus
2287 myPhaseTable->setFocus();
2288}
2289
2290
2291void
2293 // declare constants for columns
2294 const int colDuration = 1;
2295 const int colMinDur = 2;
2296 const int colMaxDur = 3;
2297 const int colState = 4;
2298 const int colEarliestEnd = 5;
2299 const int colLatestEnd = 6;
2300 const int colNext = 7;
2301 const int colName = 8;
2302 // get phases
2303 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2304 // adjust table
2305 myPhaseTable->setTableSize("suffpff-midtb", (int)phases.size());
2306 // fill rows
2307 for (int row = 0; row < (int)phases.size(); row++) {
2308 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2309 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2310 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2311 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2312 myPhaseTable->setItemText(row, colEarliestEnd, varDurString(phases.at(row).earliestEnd).c_str());
2313 myPhaseTable->setItemText(row, colLatestEnd, varDurString(phases.at(row).latestEnd).c_str());
2314 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2315 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2316 }
2317 // set columns
2318 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2319 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2320 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2321 myPhaseTable->setColumnLabelTop(colEarliestEnd, "ear.end", "earlyEnd");
2322 myPhaseTable->setColumnLabelTop(colLatestEnd, "lat.end", "latestEnd");
2323 myPhaseTable->setColumnLabelTop(colState, "state");
2324 myPhaseTable->setColumnLabelTop(colNext, "next");
2325 myPhaseTable->setColumnLabelTop(colName, "name");
2326 // set bot labels
2327 updateCycleDuration(colDuration);
2328 updateStateSize(colState);
2329 // set focus
2330 myPhaseTable->setFocus();
2331}
2332
2333
2334void
2336 // declare constants for columns
2337 const int colDuration = 1;
2338 const int colMinDur = 2;
2339 const int colMaxDur = 3;
2340 const int colState = 4;
2341 const int colNext = 5;
2342 const int colName = 6;
2343 // get phases
2344 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2345 // adjust table
2346 myPhaseTable->setTableSize("suffp-midtb", (int)phases.size());
2347 // fill rows
2348 for (int row = 0; row < (int)phases.size(); row++) {
2349 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2350 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2351 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2352 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2353 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2354 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2355 }
2356 // set columns
2357 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2358 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2359 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2360 myPhaseTable->setColumnLabelTop(colState, "state");
2361 myPhaseTable->setColumnLabelTop(colNext, "next");
2362 myPhaseTable->setColumnLabelTop(colName, "name");
2363 // set bot labels
2364 updateCycleDuration(colDuration);
2365 updateStateSize(colState);
2366 // set focus
2367 myPhaseTable->setFocus();
2368}
2369
2370
2371void
2373 // declare constants for columns
2374 const int colDuration = 1;
2375 const int colMinDur = 2;
2376 const int colMaxDur = 3;
2377 const int colState = 4;
2378 const int colVehExt = 5;
2379 const int colYellow = 6;
2380 const int colRed = 7;
2381 const int colNext = 8;
2382 const int colName = 9;
2383 // get phases
2384 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2385 // adjust table
2386 myPhaseTable->setTableSize("suffpfff-midtb", (int)phases.size());
2387 // fill rows
2388 for (int row = 0; row < (int)phases.size(); row++) {
2389 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2390 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2391 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2392 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2393 myPhaseTable->setItemText(row, colVehExt, varDurString(phases.at(row).vehExt).c_str());
2394 myPhaseTable->setItemText(row, colYellow, varDurString(phases.at(row).yellow).c_str());
2395 myPhaseTable->setItemText(row, colRed, varDurString(phases.at(row).red).c_str());
2396 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2397 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2398 }
2399 // set columns
2400 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2401 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2402 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2403 myPhaseTable->setColumnLabelTop(colState, "state");
2404 myPhaseTable->setColumnLabelTop(colVehExt, "vehExt", "vehicle extension");
2405 myPhaseTable->setColumnLabelTop(colYellow, "yellow");
2406 myPhaseTable->setColumnLabelTop(colRed, "red");
2407 myPhaseTable->setColumnLabelTop(colNext, "next");
2408 myPhaseTable->setColumnLabelTop(colName, "name");
2409 // set bot labels
2410 updateCycleDuration(colDuration);
2411 updateStateSize(colState);
2412 // set focus
2413 myPhaseTable->setFocus();
2414}
2415
2416
2417int
2419 // get option container
2421 // check if TLS is static
2422 const bool TLSStatic = (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC);
2423 const bool NEMA = (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA);
2424 // calculate new index
2425 const int newIndex = row + 1;
2426 // duplicate current row
2427 auto duration = getSUMOTime(myPhaseTable->getItemText(row, 1));
2428 const auto oldState = myPhaseTable->getItemText(row, TLSStatic ? 2 : 4);
2429 auto state = oldState;
2430 // update crossingINdices
2431 std::set<int> crossingIndices;
2432 for (const auto& node : myTLSEditorParent->myEditedDef->getNodes()) {
2433 for (const auto& crossing : node->getCrossings()) {
2434 crossingIndices.insert(crossing->tlLinkIndex);
2435 crossingIndices.insert(crossing->tlLinkIndex2);
2436 }
2437 }
2438 // smart adapations for new state
2439 bool haveGreen = false;
2440 bool haveYellow = false;
2441 for (const auto& linkStateChar : state) {
2442 if ((linkStateChar == LINKSTATE_TL_GREEN_MAJOR) || (linkStateChar == LINKSTATE_TL_GREEN_MINOR)) {
2443 haveGreen = true;
2444 } else if ((linkStateChar == LINKSTATE_TL_YELLOW_MAJOR) || (linkStateChar == LINKSTATE_TL_YELLOW_MINOR)) {
2445 haveYellow = true;
2446 }
2447 }
2448 if (haveGreen && haveYellow) {
2449 // guess left-mover state
2450 duration = TIME2STEPS(oc.getInt("tls.left-green.time"));
2451 for (int i = 0; i < (int)state.size(); i++) {
2452 if ((state[i] == LINKSTATE_TL_YELLOW_MAJOR) || (state[i] == LINKSTATE_TL_YELLOW_MINOR)) {
2453 state[i] = LINKSTATE_TL_RED;
2454 } else if (state[i] == LINKSTATE_TL_GREEN_MINOR) {
2455 state[i] = LINKSTATE_TL_GREEN_MAJOR;
2456 }
2457 }
2458 } else if (haveGreen) {
2459 // guess yellow state
2460 myTLSEditorParent->myEditedDef->setParticipantsInformation();
2461 duration = TIME2STEPS(myTLSEditorParent->myEditedDef->computeBrakingTime(oc.getFloat("tls.yellow.min-decel")));
2462 for (int i = 0; i < (int)state.size(); i++) {
2463 if ((state[i] == LINKSTATE_TL_GREEN_MAJOR) || (state[i] == LINKSTATE_TL_GREEN_MINOR)) {
2464 if (crossingIndices.count(i) == 0) {
2465 state[i] = LINKSTATE_TL_YELLOW_MINOR;
2466 } else {
2467 state[i] = LINKSTATE_TL_RED;
2468 }
2469 }
2470 }
2471 } else if (haveYellow) {
2472 duration = TIME2STEPS(oc.isDefault("tls.allred.time") ? 2 : oc.getInt("tls.allred.time"));
2473 // guess all-red state
2474 for (int i = 0; i < (int)state.size(); i++) {
2475 if ((state[i] == LINKSTATE_TL_YELLOW_MAJOR) || (state[i] == LINKSTATE_TL_YELLOW_MINOR)) {
2476 state[i] = LINKSTATE_TL_RED;
2477 }
2478 }
2479 }
2480 // fix continuous green states
2481 const int nextIndex = (myPhaseTable->getNumRows() > newIndex) ? newIndex : 0;
2482 const std::string state2 = myPhaseTable->getItemText(nextIndex, (TLSStatic ? 2 : 4));
2483 for (int i = 0; i < (int)state.size(); i++) {
2484 if (((oldState[i] == LINKSTATE_TL_GREEN_MAJOR) || (oldState[i] == LINKSTATE_TL_GREEN_MINOR)) &&
2485 ((state2[i] == LINKSTATE_TL_GREEN_MAJOR) || (state2[i] == LINKSTATE_TL_GREEN_MINOR))) {
2486 state[i] = oldState[i];
2487 }
2488 }
2489 // add new step
2490 if (NEMA) {
2491 myTLSEditorParent->myEditedDef->getLogic()->addStep(string2time("90"), state, string2time("5"), string2time("50"),
2493 string2time("2"), string2time("3"), string2time("2"), "1", std::vector<int>(), newIndex);
2494 } else {
2495 myTLSEditorParent->myEditedDef->getLogic()->addStep(duration, state, std::vector<int>(), "", newIndex);
2496 }
2497 // return new index
2498 return newIndex;
2499}
2500
2501
2502bool
2503GNETLSEditorFrame::TLSPhases::setDuration(const int col, const int row, const std::string& value) {
2504 // check value
2505 if (value.empty()) {
2506 // input empty, reset
2507 getPhaseTable()->setItemText(row, col, getSteps2Time(myTLSEditorParent->getPhase(row).duration).c_str());
2508 return true;
2509 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2510 const auto duration = getSUMOTime(value);
2511 // check that duration > 0
2512 if (duration > 0) {
2513 myTLSEditorParent->myEditedDef->getLogic()->setPhaseDuration(row, duration);
2514 myTLSEditorParent->myTLSDefinition->markAsModified();
2515 // update Cycle duration
2516 updateCycleDuration(col);
2517 return true;
2518 } else {
2519 return false;
2520 }
2521 } else {
2522 return false;
2523 }
2524}
2525
2526
2527bool
2528GNETLSEditorFrame::TLSPhases::setState(const int col, const int row, const std::string& value) {
2529 // get state
2530 const auto& phase = myTLSEditorParent->getPhase(row);
2531 // declare new state. If value is empty, use previous value (reset)
2532 const auto newState = value.empty() ? phase.state : value;
2533 // insert phase
2534 try {
2535 myTLSEditorParent->myEditedDef->getLogic()->addStep(phase.duration, newState, phase.next, phase.name, row);
2536 } catch (ProcessError&) {
2537 // invalid character in newState
2538 return false;
2539 }
2540 // delete next phase
2541 try {
2542 myTLSEditorParent->myEditedDef->getLogic()->deletePhase(row + 1);
2543 } catch (InvalidArgument&) {
2544 WRITE_ERROR("Error deleting phase '" + toString(row + 1) + "'");
2545 return false;
2546 }
2547 // mark TLS as modified depending of value
2548 if (value.size() > 0) {
2549 myTLSEditorParent->myTLSDefinition->markAsModified();
2550 // select row
2551 myPhaseTable->selectRow(row);
2552 } else {
2553 // input empty, reset
2554 getPhaseTable()->setItemText(row, col, newState);
2555 }
2556 // update state size
2557 updateStateSize(col);
2558 return true;
2559}
2560
2561
2562bool
2563GNETLSEditorFrame::TLSPhases::setNext(const int col, const int row, const std::string& value) {
2564 // check value
2565 if (value.empty()) {
2566 // input empty, reset value
2567 myPhaseTable->setItemText(row, col, toString(myTLSEditorParent->getPhase(row).next));
2568 return true;
2569 } else {
2570 // check next
2571 if (GNEAttributeCarrier::canParse<std::vector<int> >(value)) {
2572 const auto nextEdited = GNEAttributeCarrier::parse<std::vector<int> >(value);
2573 for (const auto nextPhase : nextEdited) {
2574 if ((nextPhase < 0) || (nextPhase >= myPhaseTable->getNumRows())) {
2575 return false;
2576 }
2577 }
2578 // set new next
2579 myTLSEditorParent->myEditedDef->getLogic()->setPhaseNext(row, nextEdited);
2580 myTLSEditorParent->myTLSDefinition->markAsModified();
2581 return true;
2582 } else {
2583 return false;
2584 }
2585 }
2586}
2587
2588
2589bool
2590GNETLSEditorFrame::TLSPhases::setName(const int row, const std::string& value) {
2591 // update name (currently no check needed)
2592 myTLSEditorParent->myEditedDef->getLogic()->setPhaseName(row, value);
2593 myTLSEditorParent->myTLSDefinition->markAsModified();
2594 return true;
2595}
2596
2597
2598bool
2599GNETLSEditorFrame::TLSPhases::setMinDur(const int row, const std::string& value) {
2600 // check value
2601 if (value.empty()) {
2602 // set empty value
2603 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2604 myTLSEditorParent->myTLSDefinition->markAsModified();
2605 return true;
2606 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2607 const auto minDur = getSUMOTime(value);
2608 // check that minDur > 0
2609 if (minDur > 0) {
2610 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, minDur);
2611 myTLSEditorParent->myTLSDefinition->markAsModified();
2612 return true;
2613 } else {
2614 return false;
2615 }
2616 } else if (StringUtils::prune(value).empty()) {
2617 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2618 myTLSEditorParent->myTLSDefinition->markAsModified();
2619 return true;
2620 } else {
2621 return false;
2622 }
2623}
2624
2625
2626bool
2627GNETLSEditorFrame::TLSPhases::setMaxDur(const int row, const std::string& value) {
2628 // check value
2629 if (value.empty()) {
2630 // set empty value
2631 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2632 myTLSEditorParent->myTLSDefinition->markAsModified();
2633 return true;
2634 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2635 const auto maxDur = getSUMOTime(value);
2636 // check that minDur > 0
2637 if (maxDur > 0) {
2638 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, maxDur);
2639 myTLSEditorParent->myTLSDefinition->markAsModified();
2640 return true;
2641 } else {
2642 return false;
2643 }
2644 } else if (StringUtils::prune(value).empty()) {
2645 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2646 myTLSEditorParent->myTLSDefinition->markAsModified();
2647 return true;
2648 } else {
2649 return false;
2650 }
2651}
2652
2653
2654bool
2655GNETLSEditorFrame::TLSPhases::setEarliestEnd(const int row, const std::string& value) {
2656 // check value
2657 if (value.empty()) {
2658 // set empty value
2659 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2660 myTLSEditorParent->myTLSDefinition->markAsModified();
2661 return true;
2662 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2663 const auto earliestEnd = getSUMOTime(value);
2664 // check that earliestEnd > 0
2665 if (earliestEnd > 0) {
2666 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, earliestEnd);
2667 myTLSEditorParent->myTLSDefinition->markAsModified();
2668 return true;
2669 } else {
2670 return false;
2671 }
2672 } else if (StringUtils::prune(value).empty()) {
2673 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2674 myTLSEditorParent->myTLSDefinition->markAsModified();
2675 return true;
2676 } else {
2677 return false;
2678 }
2679}
2680
2681
2682bool
2683GNETLSEditorFrame::TLSPhases::setLatestEnd(const int row, const std::string& value) {
2684 // check value
2685 if (value.empty()) {
2686 // set empty value
2687 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2688 myTLSEditorParent->myTLSDefinition->markAsModified();
2689 return true;
2690 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2691 const auto latestEnd = getSUMOTime(value);
2692 // check that latestEnd > 0
2693 if (latestEnd > 0) {
2694 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, latestEnd);
2695 myTLSEditorParent->myTLSDefinition->markAsModified();
2696 return true;
2697 } else {
2698 return false;
2699 }
2700 } else if (StringUtils::prune(value).empty()) {
2701 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2702 myTLSEditorParent->myTLSDefinition->markAsModified();
2703 return true;
2704 } else {
2705 return false;
2706 }
2707}
2708
2709
2710bool
2711GNETLSEditorFrame::TLSPhases::setVehExt(const int row, const std::string& value) {
2712 // check value
2713 if (value.empty()) {
2714 // set empty value
2715 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2716 myTLSEditorParent->myTLSDefinition->markAsModified();
2717 return true;
2718 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2719 const auto vehExt = getSUMOTime(value);
2720 // check that vehExt > 0
2721 if (vehExt > 0) {
2722 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, vehExt);
2723 myTLSEditorParent->myTLSDefinition->markAsModified();
2724 return true;
2725 } else {
2726 return false;
2727 }
2728 } else if (StringUtils::prune(value).empty()) {
2729 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2730 myTLSEditorParent->myTLSDefinition->markAsModified();
2731 return true;
2732 } else {
2733 return false;
2734 }
2735}
2736
2737
2738bool
2739GNETLSEditorFrame::TLSPhases::setYellow(const int row, const std::string& value) {
2740 // check value
2741 if (value.empty()) {
2742 // set empty value
2743 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2744 myTLSEditorParent->myTLSDefinition->markAsModified();
2745 return true;
2746 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2747 const auto yellow = getSUMOTime(value);
2748 // check that yellow > 0
2749 if (yellow > 0) {
2750 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, yellow);
2751 myTLSEditorParent->myTLSDefinition->markAsModified();
2752 return true;
2753 } else {
2754 return false;
2755 }
2756 } else if (StringUtils::prune(value).empty()) {
2757 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2758 myTLSEditorParent->myTLSDefinition->markAsModified();
2759 return true;
2760 } else {
2761 return false;
2762 }
2763}
2764
2765
2766bool
2767GNETLSEditorFrame::TLSPhases::setRed(const int row, const std::string& value) {
2768 // check value
2769 if (value.empty()) {
2770 // set empty value
2771 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2772 myTLSEditorParent->myTLSDefinition->markAsModified();
2773 return true;
2774 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2775 const auto red = getSUMOTime(value);
2776 // check that red > 0
2777 if (red > 0) {
2778 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, red);
2779 myTLSEditorParent->myTLSDefinition->markAsModified();
2780 return true;
2781 } else {
2782 return false;
2783 }
2784 } else if (StringUtils::prune(value).empty()) {
2785 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2786 myTLSEditorParent->myTLSDefinition->markAsModified();
2787 return true;
2788 } else {
2789 return false;
2790 }
2791}
2792
2793
2794void
2796 SUMOTime cycleDuration = 0;
2797 for (const auto& phase : myTLSEditorParent->myEditedDef->getLogic()->getPhases()) {
2798 cycleDuration += phase.duration;
2799 }
2800 // update bot label with cycle duration
2801 myPhaseTable->setColumnLabelBot(col, getSteps2Time(cycleDuration));
2802}
2803
2804
2805void
2807 // update bot label with number of links
2808 myPhaseTable->setColumnLabelBot(col, "Links: " + toString(myTLSEditorParent->myEditedDef->getLogic()->getNumLinks()));
2809}
2810
2811// ---------------------------------------------------------------------------
2812// GNETLSEditorFrame::TLSFile - methods
2813// ---------------------------------------------------------------------------
2814
2816 MFXGroupBoxModule(TLSEditorParent, TL("TLS Program File")),
2817 myTLSEditorParent(TLSEditorParent) {
2818 FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
2819 // create create tlDef button
2820 new FXButton(buttonsFrame, TL("Load\t\tLoad TLS program from additional file"), GUIIconSubSys::getIcon(GUIIcon::OPEN_CONFIG), this, MID_GNE_TLSFRAME_FILE_LOADPROGRAM, GUIDesignButton);
2821 // create create tlDef button
2822 new FXButton(buttonsFrame, TL("Save\t\tSave TLS program to additional file"), GUIIconSubSys::getIcon(GUIIcon::SAVE), this, MID_GNE_TLSFRAME_FILE_SAVEPROGRAM, GUIDesignButton);
2823 // show TLSFile
2824 show();
2825}
2826
2827
2829
2830
2831void
2833 show();
2834}
2835
2836
2837void
2839 hide();
2840}
2841
2842
2843long
2845 FXFileDialog opendialog(getCollapsableFrame(), "Load TLS Program");
2846 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::MODETLS));
2847 opendialog.setSelectMode(SELECTFILE_EXISTING);
2848 opendialog.setPatternList("XML files (*.xml,*.xml.gz)\nAll files (*)");
2849 if (gCurrentFolder.length() != 0) {
2850 opendialog.setDirectory(gCurrentFolder);
2851 }
2852 if (opendialog.execute()) {
2853 // run parser
2854 NBTrafficLightLogicCont tmpTLLCont;
2855 NIXMLTrafficLightsHandler tllHandler(tmpTLLCont, myTLSEditorParent->getViewNet()->getNet()->getEdgeCont(), true);
2856 tmpTLLCont.insert(myTLSEditorParent->myEditedDef);
2857 XMLSubSys::runParser(tllHandler, opendialog.getFilename().text());
2858
2859 NBLoadedSUMOTLDef* newDefSameProgram = nullptr;
2860 std::set<NBLoadedSUMOTLDef*> newDefsOtherProgram;
2861 for (auto item : tmpTLLCont.getPrograms(myTLSEditorParent->myEditedDef->getID())) {
2862 if (item.second != myTLSEditorParent->myEditedDef) {
2863 NBLoadedSUMOTLDef* sdef = dynamic_cast<NBLoadedSUMOTLDef*>(item.second);
2864 if (item.first == myTLSEditorParent->myEditedDef->getProgramID()) {
2865 newDefSameProgram = sdef;
2866 } else {
2867 newDefsOtherProgram.insert(sdef);
2868 }
2869 }
2870 }
2871 const int newPrograms = (int)newDefsOtherProgram.size();
2872 if (newPrograms > 0 || newDefSameProgram != nullptr) {
2873 std::vector<NBNode*> nodes = myTLSEditorParent->myEditedDef->getNodes();
2874 for (auto newProg : newDefsOtherProgram) {
2875 for (auto it_node : nodes) {
2876 GNEJunction* junction = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
2877 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, newProg, true), true);
2878 }
2879 }
2880 if (newPrograms > 0) {
2881 WRITE_MESSAGE("Loaded " + toString(newPrograms) + " new programs for tlLogic '" + myTLSEditorParent->myEditedDef->getID() + "'");
2882 }
2883 if (newDefSameProgram != nullptr) {
2884 // replace old program when loading the same program ID
2885 myTLSEditorParent->myEditedDef = newDefSameProgram;
2886 WRITE_MESSAGE("Updated program '" + newDefSameProgram->getProgramID() + "' for tlLogic '" + myTLSEditorParent->myEditedDef->getID() + "'");
2887 }
2888 } else {
2889 if (tllHandler.getSeenIDs().count(myTLSEditorParent->myEditedDef->getID()) == 0) {
2890 myTLSEditorParent->getViewNet()->setStatusBarText("No programs found for traffic light '" + myTLSEditorParent->myEditedDef->getID() + "'");
2891 }
2892 }
2893
2894 // clean up temporary container to avoid deletion of defs when it's destruct is called
2895 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
2896 tmpTLLCont.removeProgram(def->getID(), def->getProgramID(), false);
2897 }
2898
2899 myTLSEditorParent->myTLSPhases->initPhaseTable();
2900 myTLSEditorParent->myTLSDefinition->markAsModified();
2901 }
2902 return 0;
2903}
2904
2905
2906long
2908 FXString file = MFXUtils::getFilename2Write(this,
2909 TL("Save TLS Program as"), ".xml",
2912 // check file
2913 if (file != "") {
2914 // add xml extension
2915 file = FileHelpers::addExtension(file.text(), ".xml").c_str();
2916 OutputDevice& device = OutputDevice::getDevice(file.text());
2917 // save program
2918 device.writeXMLHeader("additional", "additional_file.xsd");
2919 device.openTag(SUMO_TAG_TLLOGIC);
2920 device.writeAttr(SUMO_ATTR_ID, myTLSEditorParent->myEditedDef->getLogic()->getID());
2921 device.writeAttr(SUMO_ATTR_TYPE, myTLSEditorParent->myEditedDef->getLogic()->getType());
2922 device.writeAttr(SUMO_ATTR_PROGRAMID, myTLSEditorParent->myEditedDef->getLogic()->getProgramID());
2923 device.writeAttr(SUMO_ATTR_OFFSET, writeSUMOTime(myTLSEditorParent->myEditedDef->getLogic()->getOffset()));
2924 myTLSEditorParent->myEditedDef->writeParams(device);
2925 // write the phases
2926 const bool TLSActuated = (myTLSEditorParent->myEditedDef->getLogic()->getType() == TrafficLightType::ACTUATED);
2927 const bool TLSDelayBased = (myTLSEditorParent->myEditedDef->getLogic()->getType() == TrafficLightType::DELAYBASED);
2928 const bool TLSNEMA = (myTLSEditorParent->myEditedDef->getLogic()->getType() == TrafficLightType::NEMA);
2929 // write the phases
2930 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2931 for (const auto& phase : phases) {
2932 device.openTag(SUMO_TAG_PHASE);
2933 device.writeAttr(SUMO_ATTR_DURATION, writeSUMOTime(phase.duration));
2934 device.writeAttr(SUMO_ATTR_STATE, phase.state);
2935 // write specific actuated parameters
2936 if (TLSActuated || TLSDelayBased) {
2938 device.writeAttr(SUMO_ATTR_MINDURATION, writeSUMOTime(phase.minDur));
2939 }
2941 device.writeAttr(SUMO_ATTR_MAXDURATION, writeSUMOTime(phase.maxDur));
2942 }
2943 if (phase.earliestEnd != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
2944 device.writeAttr(SUMO_ATTR_MAXDURATION, writeSUMOTime(phase.maxDur));
2945 }
2946 if (phase.earliestEnd != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
2947 device.writeAttr(SUMO_ATTR_EARLIEST_END, writeSUMOTime(phase.maxDur));
2948 }
2949 if (phase.latestEnd != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
2950 device.writeAttr(SUMO_ATTR_LATEST_END, writeSUMOTime(phase.maxDur));
2951 }
2952 }
2953 // write specific NEMA parameters
2954 if (TLSNEMA) {
2956 device.writeAttr(SUMO_ATTR_MINDURATION, writeSUMOTime(phase.minDur));
2957 }
2959 device.writeAttr(SUMO_ATTR_MAXDURATION, writeSUMOTime(phase.maxDur));
2960 }
2962 device.writeAttr(SUMO_ATTR_MINDURATION, writeSUMOTime(phase.vehExt));
2963 }
2965 device.writeAttr(SUMO_ATTR_MAXDURATION, writeSUMOTime(phase.red));
2966 }
2968 device.writeAttr(SUMO_ATTR_MAXDURATION, writeSUMOTime(phase.yellow));
2969 }
2970 }
2971 device.closeTag();
2972 }
2973 device.close();
2974 }
2975 return 1;
2976}
2977
2978
2979std::string
2981 const double time = STEPS2TIME(steps);
2982 if (time == std::floor(time)) {
2983 return toString(int(time));
2984 } else {
2985 return toString(time);
2986 }
2987}
2988
2989
2990long
2991GNETLSEditorFrame::TLSFile::onUpdButtons(FXObject* sender, FXSelector, void*) {
2992 if (myTLSEditorParent->myTLSDefinition->getNumberOfTLSDefinitions() == 0) {
2993 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2994 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2995 // selecting E1, disable buttons
2996 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2997 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2998 // joining TLSs, disable button
2999 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
3000 } else {
3001 return sender->handle(getCollapsableFrame(), FXSEL(SEL_COMMAND, FXWindow::ID_ENABLE), nullptr);
3002 }
3003}
3004
3005/****************************************************************************/
static const int NUM_POINTS
FXDEFMAP(GNETLSEditorFrame::TLSJunction) TLSJunctionMap[]
long long int SUMOTime
Definition: GUI.h:36
@ MID_GNE_TLSFRAME_TLSJUNCTION_DISJOIN
Disjoin TLS.
Definition: GUIAppEnum.h:1041
@ MID_GNE_TLSFRAME_DEFINITION_RESETCURRENT
reset current (single) TLS program
Definition: GUIAppEnum.h:1057
@ MID_GNE_TLSFRAME_PHASES_ADDUNUSED
add unused states
Definition: GUIAppEnum.h:1081
@ MID_GNE_TLSFRAME_ATTRIBUTES_TOGGLEDETECTOR
set detectors in TLS
Definition: GUIAppEnum.h:1051
@ MID_GNE_TLSFRAME_TLSJUNCTION_TOGGLEJOIN
join TLS
Definition: GUIAppEnum.h:1039
@ MID_GNE_TLSFRAME_PHASES_CLEANUP
cleanup unused states
Definition: GUIAppEnum.h:1077
@ MID_GNE_TLSFRAME_PHASES_GROUPSTATES
group states
Definition: GUIAppEnum.h:1083
@ MID_GNE_TLSFRAME_DEFINITION_DELETE
delete TLS
Definition: GUIAppEnum.h:1055
@ MID_GNE_TLSFRAME_FILE_SAVEPROGRAM
cleanup unused states
Definition: GUIAppEnum.h:1089
@ MID_GNE_TLSFRAME_PHASES_UNGROUPSTATES
ungroup states
Definition: GUIAppEnum.h:1085
@ MID_GNE_TLSFRAME_DEFINITION_CREATE
Create TLS.
Definition: GUIAppEnum.h:1053
@ MID_GNE_TLSFRAME_DEFINITION_SAVE
accept TLS modification
Definition: GUIAppEnum.h:1063
@ MID_GNE_TLSFRAME_DEFINITION_SWITCHPROGRAM
switch between programs
Definition: GUIAppEnum.h:1061
@ MID_GNE_TLSFRAME_DEFINITION_DISCARD
cancel TLS modification
Definition: GUIAppEnum.h:1065
@ MID_GNE_TLSFRAME_DEFINITION_RESETALL
reset all TLS programs
Definition: GUIAppEnum.h:1059
@ MID_GNE_TLSFRAME_TLSJUNCTION_TYPE
current TLS ID
Definition: GUIAppEnum.h:1037
@ MID_GNE_TLSFRAME_TLSJUNCTION_ID
current TLS ID
Definition: GUIAppEnum.h:1035
@ MID_GNE_TLSFRAME_ATTRIBUTES_OFFSET
TLS offset.
Definition: GUIAppEnum.h:1045
@ MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERSDIALOG
TLS parameters.
Definition: GUIAppEnum.h:1049
@ MID_GNE_TLSFRAME_FILE_LOADPROGRAM
Load Program.
Definition: GUIAppEnum.h:1087
@ MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERS
TLS parameters.
Definition: GUIAppEnum.h:1047
#define GUIDesignButtonAttribute
button extended over over column with thick and raise frame
Definition: GUIDesigns.h:80
#define GUIDesignButton
Definition: GUIDesigns.h:77
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition: GUIDesigns.h:315
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:321
#define GUIDesignTextField
Definition: GUIDesigns.h:48
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition: GUIDesigns.h:397
#define GUIDesignLabelAttribute
label extended over the matrix column with thick frame
Definition: GUIDesigns.h:241
#define GUIDesignAuxiliarHorizontalFrameUniform
design for auxiliar (Without borders) horizontal frame used to pack another frames uniform
Definition: GUIDesigns.h:400
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:69
FXString gCurrentFolder
The folder used as last.
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:276
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:267
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
#define TLF(string,...)
Definition: MsgHandler.h:283
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
@ SUMO_TAG_PHASE
a single phase description
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_YELLOW_MAJOR
The link has yellow light, may pass.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_DEADEND
This is a dead end link.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ SUMO_ATTR_LATEST_END
The maximum time within the cycle for switching (for coordinated actuation)
@ SUMO_ATTR_OFFSET
@ SUMO_ATTR_TLTYPE
node: the type of traffic light
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_MAXDURATION
maximum duration of a phase
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_MINDURATION
@ SUMO_ATTR_STATE
The state of a link.
@ SUMO_ATTR_EARLIEST_END
The minimum time within the cycle for switching (for coordinated actuation)
T MIN2(T a, T b)
Definition: StdDefs.h:71
T MAX2(T a, T b)
Definition: StdDefs.h:77
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static std::string addExtension(const std::string &path, const std::string &extension)
Add an extension to the given file path.
Definition: FileHelpers.cpp:93
An Element which don't belong to GNENet but has influence in the simulation.
Definition: GNEAdditional.h:48
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
GNENet * getNet() const
get pointer to net
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:839
GNEViewNet * getViewNet() const
get view net
Definition: GNEFrame.cpp:150
GNEViewNet * myViewNet
FOX need this.
Definition: GNEFrame.h:117
virtual void show()
show Frame
Definition: GNEFrame.cpp:115
virtual void hide()
hide Frame
Definition: GNEFrame.cpp:124
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
LinkState getLinkState() const
whether link state has been modified
int getTLIndex() const
get Traffic Light index
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
std::string getAttribute(SumoXMLAttr key) const
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
NBNode * getNBNode() const
Return net build node.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
GNEEdge * getParentEdge() const
get parent edge
Definition: GNELane.cpp:124
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
std::vector< GNELane * > getSelectedLanes() const
get selected lanes
std::vector< GNEEdge * > getSelectedEdges() const
return all edges
SUMORTree & getGrid()
Returns the RTree used for visualisation speed-up.
Definition: GNENet.cpp:151
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1993
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:132
NBEdgeCont & getEdgeCont()
returns the NBEdgeCont of the underlying netbuilder
Definition: GNENet.cpp:1999
void hideOverlappedInspection()
hide template editor
int getNumberOfOverlappedACs() const
get number of overlapped ACSs
void showOverlappedInspection(const GNEViewNetHelper::ObjectsUnderCursor &objectsUnderCursor, const Position &clickedPosition)
show template editor
Dialog for edit parameters.
long onCmdSetParameters(FXObject *, FXSelector, void *)
Called when the user changes parameters of a TLS.
long onCmdSetOffset(FXObject *, FXSelector, void *)
bool isValidOffset()
is current offset valid
long onCmdParametersDialog(FXObject *, FXSelector, void *ptr)
Called when user press edit parameters button.
long onUpdParameters(FXObject *, FXSelector, void *)
Called when the offset is updated.
MFXToggleButtonTooltip * mySetDetectorsToggleButton
toggle button for set detectors mode
bool isSetDetectorsToggleButtonEnabled() const
toggle button for set detectors mode
bool isValidParameters()
are current parameter valid
FXTextField * myOffsetTextField
the TextField for modifying offset
void updateE1Detectors()
FOX needs this.
void disableE1DetectorMode()
disable detector mode
SUMOTime getOffset() const
get current offset in string format
long onUpdSetDetectorMode(FXObject *, FXSelector, void *)
Called when occurs an update of set detector mode.
void setParameters(const std::string &parameters)
set new parameters
const std::map< std::string, std::string > & getE1Detectors() const
get E1 detectors vinculated with this TLS
void clearTLSAttributes()
clear TLS attributes
long onUpdOffset(FXObject *, FXSelector, void *)
Called when the offset is updated.
void setOffset(const SUMOTime &offset)
set new offset
std::string getParameters() const
get current parameters in string format
bool toggleE1DetectorSelection(const GNEAdditional *E1)
select or unselect E1 detector in the current TLS
void initTLSAttributes()
initializes the definitions and corresponding listbox
FXButton * myButtonEditParameters
button for edit parameters
TLSAttributes(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
FXTextField * myParametersTextField
the TextField for modifying parameters
void hideTLSAttributes()
hide TLSAttributes
void showTLSAttributes()
show TLSAttributes
long onCmdToggleDetectorMode(FXObject *, FXSelector, void *ptr)
Called when user toggle set detector mode.
void createTLS(GNEJunction *junction)
FOX needs this.
void clearTLSDefinitions()
clear TLS Definitions
long onCmdDefSwitchTLSProgram(FXObject *, FXSelector, void *)
Called when the user switches a TLS.
long onUpdTLSDisableResetAll(FXObject *, FXSelector, void *)
Called when occurs an update of switch definition.
bool checkHaveModifications() const
check if current TLS was modified
void hideTLSDefinition()
hide TLSDefinition
long onCmdSaveChanges(FXObject *, FXSelector, void *)
Called when the user presses the save-Button.
long onCmdDiscardChanges(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button.
void markAsModified()
mark Program as modified
FXComboBox * myProgramComboBox
the comboBox for selecting the tl-definition to edit
const std::string getCurrentTLSProgramID() const
get current program ID
int getNumberOfTLSDefinitions() const
get number of TLS definitions
long onCmdResetCurrentProgram(FXObject *, FXSelector, void *)
Called when the user press button reset current TLS Program.
long onCmdDelete(FXObject *, FXSelector, void *)
Called when the user press button delete TLS Program.
int getNumberOfPrograms() const
get number of programs
void showTLSDefinition()
show TLSDefinition
long onUpdCreate(FXObject *, FXSelector, void *)
Called when occurs an update of create definition.
bool initTLSDefinitions()
init TLS Definitions
NBTrafficLightDefinition * getCurrentTLSDefinition() const
get current definition
long onCmdCreate(FXObject *, FXSelector, void *)
TLSDefinition(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
void discardChanges(const bool editJunctionAgain)
discard changes
long onUpdTLSEnableModified(FXObject *, FXSelector, void *)
Called when occurs an update of switch definition.
long onCmdResetAll(FXObject *, FXSelector, void *)
Called when the user press button reset all TLS Programs.
FXButton * myCreateButton
button for create new Traffic light program
long onUpdTLSDisableModified(FXObject *, FXSelector, void *)
Called when occurs an update of switch definition.
void showTLSFile()
show TLSPhases
void hideTLSFile()
hide TLSPhases
long onCmdLoadTLSProgram(FXObject *, FXSelector, void *)
TLSFile(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
std::string writeSUMOTime(SUMOTime steps)
convert SUMOTime into string
long onUpdButtons(FXObject *, FXSelector, void *)
enable buttons, only when a tlLogic is being edited
long onCmdSaveTLSProgram(FXObject *, FXSelector, void *)
save TLS Program to an additional file
long onCmdChangeType(FXObject *, FXSelector, void *)
Called when the user change TLS Type.
long onCmdDisjoinTLS(FXObject *, FXSelector, void *)
Called when the user join TLS.
const std::vector< std::string > & getSelectedJunctionIDs() const
get selected junction IDs
long onUpdTLSType(FXObject *, FXSelector, void *)
Called when occurs an update of modified.
long onCmdToggleJoinTLS(FXObject *, FXSelector, void *)
Called when the user join TLS.
long onCmdRenameTLS(FXObject *, FXSelector, void *)
TLSJunction(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
long onUpdJoinTLS(FXObject *, FXSelector, void *)
Called when update join TLS.
MFXToggleButtonTooltip * myJoinTLSToggleButton
Toggle button for join TLS.
void updateJunctionDescription()
update junction description
void toggleJunctionSelected(const GNEJunction *junction)
select or unselect junction in the current TLS
GNEJunction * getCurrentJunction() const
get current modified junction
void setCurrentJunction(GNEJunction *junction)
set current junction
long onUpdDisjoinTLS(FXObject *, FXSelector, void *)
Called when update join TLS.
FXLabel * myJunctionIDLabel
label for junction ID
bool isJunctionSelected(const GNEJunction *junction) const
check if given junction is selected (used fo joining)
void disableJoiningJunctionMode()
disable joining junction mode
MFXButtonTooltip * myDisjoinTLSButton
button for disjoin TLS
bool isJoiningJunctions() const
is joining junctions
MFXTextFieldTooltip * myTLSIDTextField
text field for junction ID
long onUpdTLSID(FXObject *, FXSelector, void *)
Called when occurs an update of modified.
MFXTextFieldTooltip * myJunctionIDTextField
text field for junction ID
MFXIconComboBox * myTLSTypeComboBox
ComboBox for TLS Types.
bool setEarliestEnd(const int row, const std::string &value)
set earliestEnd
long onCmdUngroupStates(FXObject *, FXSelector, void *)
Called when the user ungroups states.
void showTLSPhases()
show TLSPhases
GNETLSTable * myPhaseTable
table for selecting and rearranging phases and for changing duration
long onCmdCleanStates(FXObject *, FXSelector, void *)
long onCmdGroupStates(FXObject *, FXSelector, void *)
Called when the user groups states.
bool setVehExt(const int row, const std::string &value)
set vehExt
int buildDefaultPhase(const int row)
build default phase
TLSPhases(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
void movePhaseDown(const int row)
move phase down
void initActuatedPhaseTable()
init actuated phase table
void initPhaseTable()
initializes the phase table
void initNEMAPhaseTable()
init NEMA phase table
bool setYellow(const int row, const std::string &value)
set yellow
bool changePhaseValue(const int col, const int row, const std::string &value)
change phase value (state, name, next, etc.)
long onUpdNeedsSingleDef(FXObject *, FXSelector, void *)
Called to buttons that modify link indices.
void initDelayBasePhaseTable()
init delayBase phase table
void movePhaseUp(const int row)
move phase up
bool setMinDur(const int row, const std::string &value)
set minDur
bool setLatestEnd(const int row, const std::string &value)
set latestEnd
void updateStateSize(const int col)
update state size
long onCmdAddUnusedStates(FXObject *, FXSelector, void *)
Called when the user cleans up states.
void initStaticPhaseTable()
FOX needs this.
long onUpdUngroupStates(FXObject *, FXSelector, void *)
Called to update the ungroups states button.
bool setDuration(const int col, const int row, const std::string &value)
set duration
bool setMaxDur(const int row, const std::string &value)
set maxDur
long onUpdNeedsDef(FXObject *, FXSelector, void *)
enable buttons, only when a tlLogic is being edited
void updateTLSColoring()
update TLS coloring
GNETLSTable * getPhaseTable() const
get phase table
void removePhase(const int row)
delete phase
bool setRed(const int row, const std::string &value)
set red
bool setName(const int row, const std::string &value)
set name
bool setState(const int col, const int row, const std::string &value)
set state
bool setNext(const int col, const int row, const std::string &value)
set next
long onUpdNeedsDefAndPhase(FXObject *, FXSelector, void *)
Called when occurs an update of needs definition and phase.
void duplicatePhase(const int row)
duplicate phase
void addPhase(const int row, const char c=' ')
add phase
GNETLSEditorFrame * getTLSEditorParent() const
get TLSEditor Parent
void hideTLSPhases()
hide TLSPhases
void updateCycleDuration(const int col)
recomputes cycle duration and updates label
void handleChange(GNEInternalLane *lane)
update phase definition for the current traffic light and phase
GNEOverlappedInspection * myOverlappedInspection
Overlapped Inspection.
GNETLSEditorFrame::TLSAttributes * getTLSAttributes() const
get module for TLS attributes
GNETLSEditorFrame::TLSAttributes * myTLSAttributes
module for TLS attributes
static std::string varDurString(SUMOTime dur)
convert duration (potentially undefined) to string
bool isTLSSaved()
check if modifications in TLS was saved
void editJunction(GNEJunction *junction)
edits the traffic light for the given junction
GNETLSEditorFrame::TLSPhases * myTLSPhases
module for TLS Phases
void selectedOverlappedElement(GNEAttributeCarrier *AC)
open GNEAttributesCreator extended dialog (can be reimplemented in frame children)
std::map< int, std::vector< GNEInternalLane * > > myInternalLanes
the internal lanes belonging the the current junction indexed by their tl-index
bool parseTLSPrograms(const std::string &file)
parse TLS Programs from a file
bool controlsEdge(GNEEdge *edge) const
whether the given edge is controlled by the currently edited tlDef
static const std::string getSteps2Time(const SUMOTime value)
converts to SUMOTime
void buildInternalLanes(const NBTrafficLightDefinition *tlDef)
builds internal lanes for the given tlDef
const NBTrafficLightLogic::PhaseDefinition & getPhase(const int index)
get certain phase of the current traffic light
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
GNETLSEditorFrame::TLSDefinition * myTLSDefinition
module for TLS Definition
GNETLSEditorFrame::TLSJunction * getTLSJunction() const
get module for TLS Junction
static SUMOTime getSUMOTime(const std::string &value)
converts to SUMOTime
~GNETLSEditorFrame()
Destructor.
NBLoadedSUMOTLDef * myEditedDef
the traffic light definition being edited
void frameWidthUpdated()
function called after setting new width in current frame
GNETLSEditorFrame::TLSJunction * myTLSJunction
module for TLS Junction
void editTLS(const Position &clickedPosition, const GNEViewNetHelper::ObjectsUnderCursor &objectsUnderCursor)
edits the traffic light for the given clicked junction
void cleanup()
cleans up previous lanes
GNETLSEditorFrame::TLSDefinition * getTLSDefinition() const
get module for TLS Definition
void show()
show inspector frame
void selectRow(const int rowIndex)
Select a row.
int getCurrentSelectedRow() const
Get current selected row.
void recalcTableWidth()
recalc width (call when all labels and contents are fill)
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
class used to group all variables related with objects under cursor after a click over view
GNEAdditional * getAdditionalFront() const
get front additional element or a pointer to nullptr
GNEJunction * getJunctionFront() const
get front junction or a pointer to nullptr
GNENet * getNet() const
get the net object
bool changeAllPhases() const
change all phases
Definition: GNEViewNet.cpp:796
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
void setStatusBarText(const std::string &text)
set statusBar text
Definition: GNEViewNet.cpp:768
A single child window which contains a view of the simulation area.
Definition: GNEViewParent.h:84
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
Definition: GUIGlObject.h:141
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXStaticToolTip * getStaticTooltipMenu() const
get static toolTip for menus
MFXGroupBoxModule (based on FXGroupBox)
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
Options
GroupBoxModule options.
ComboBox with icon.
FXint getNumItems() const
Return the number of items in the list.
void setNumVisible(FXint nvis)
Set the number of visible items in the drop down list.
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extension, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition: MFXUtils.cpp:82
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:112
A loaded (complete) traffic light logic.
NBTrafficLightLogic * getLogic()
Returns the internal logic.
void setProgramID(const std::string &programID)
Sets the programID.
Represents a single node (junction) during network building.
Definition: NBNode.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:326
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:321
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:44
The base class for traffic light logic definitions.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
const std::string & getProgramID() const
Returns the ProgramID.
TrafficLightType getType() const
get the algorithm type (static etc..)
virtual void setProgramID(const std::string &programID)
Sets the programID.
SUMOTime getOffset()
Returns the offset.
const NBConnectionVector & getControlledLinks() const
returns the controlled links (depends on previous call to collectLinks)
NBTrafficLightLogic * compute(OptionsCont &oc)
Computes the traffic light logic.
static const SUMOTime UNSPECIFIED_DURATION
The definition of a single phase of the logic.
A container for traffic light definitions and built programs.
bool removeProgram(const std::string id, const std::string programID, bool del=true)
Removes a program of a logic definition from the dictionary.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
NBTrafficLightLogic * getLogic(const std::string &id, const std::string &programID) const
Returns the computed logic for the given name.
std::string getNextProgramID(const std::string &id) const
Returns a new (unused) programID for the given traffic light.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
A SUMO-compliant built logic for a traffic light.
void setPhaseState(int phaseIndex, int tlIndex, LinkState linkState)
Modifies the state for an existing phase (used by NETEDIT)
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
Importer for edge connections stored in XML.
const std::set< std::string > & getSeenIDs()
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:59
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:251
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
static bool areParametersValid(const std::string &value, bool report=false, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
void append(const PositionVector &v, double sameThreshold=2.0)
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
PositionVector reverse() const
reverse position vector
static const RGBColor BLACK
Definition: RGBColor.h:193
static const RGBColor RED
named colors
Definition: RGBColor.h:185
void addAdditionalGLObject(GUIGlObject *o, const double exaggeration=1)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:124
void removeAdditionalGLObject(GUIGlObject *o, const double exaggeration=1)
Removes an additional object (detector/shape/trigger) from being visualised.
Definition: SUMORTree.h:160
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:55
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:137
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:201
PositionVector viaShape
shape of via
Definition: NBEdge.h:299
PositionVector shape
shape of Connection
Definition: NBEdge.h:287