Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNETLSEditorFrame.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 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
22#include <netbuild/NBOwnTLDef.h>
24#include <netedit/GNENet.h>
26#include <netedit/GNEUndoList.h>
41#include <utils/xml/XMLSubSys.h>
42
43#include "GNETLSEditorFrame.h"
44
45// ===========================================================================
46// FOX callback mapping
47// ===========================================================================
48
57
67
74
81
86
87// Object implementation
88FXIMPLEMENT(GNETLSEditorFrame::TLSJunction, MFXGroupBoxModule, TLSJunctionMap, ARRAYNUMBER(TLSJunctionMap))
89FXIMPLEMENT(GNETLSEditorFrame::TLSPrograms, MFXGroupBoxModule, TLSProgramsMap, ARRAYNUMBER(TLSProgramsMap))
90FXIMPLEMENT(GNETLSEditorFrame::TLSAttributes, MFXGroupBoxModule, TLSAttributesMap, ARRAYNUMBER(TLSAttributesMap))
91FXIMPLEMENT(GNETLSEditorFrame::TLSPhases, MFXGroupBoxModule, TLSPhasesMap, ARRAYNUMBER(TLSPhasesMap))
92FXIMPLEMENT(GNETLSEditorFrame::TLSFile, MFXGroupBoxModule, TLSFileMap, ARRAYNUMBER(TLSFileMap))
93
94
95// ===========================================================================
96// method definitions
97// ===========================================================================
98
100 GNEFrame(viewParent, viewNet, TL("Edit Traffic Light")),
101 myEditedDef(nullptr) {
102
103 // Create Overlapped Inspection module only for junctions
104 myOverlappedInspection = new GNEOverlappedInspection(this, true);
105
106 // create TLSJunction module
107 myTLSJunction = new GNETLSEditorFrame::TLSJunction(this);
108
109 // create TLSPrograms module
110 myTLSPrograms = new GNETLSEditorFrame::TLSPrograms(this);
111
112 // create TLSAttributes module
113 myTLSAttributes = new GNETLSEditorFrame::TLSAttributes(this);
114
115 // create TLSPhases module
116 myTLSPhases = new GNETLSEditorFrame::TLSPhases(this);
117
118 // create TLSFile module
119 myTLSFile = new GNETLSEditorFrame::TLSFile(this);
120}
121
122
126
127
128void
134
135
136void
141
142
143void
159
160
161void
162GNETLSEditorFrame::editTLS(GNEViewNetHelper::ViewObjectsSelector& viewObjects, const Position& clickedPosition, const bool shiftKeyPressed) {
163 // first check if in viewObjects there is a junction
164 if (viewObjects.getJunctionFront()) {
165 // check if we're adding or removing joined TLSs
168 } else {
169 // show objects under cursor
170 myOverlappedInspection->showOverlappedInspection(viewObjects, clickedPosition, shiftKeyPressed);
171 // hide if we inspect only one junction
175 }
176 for (const auto& junction : viewObjects.getJunctions()) {
177 if (junction == myOverlappedInspection->getCurrentAC()) {
178 editJunction(junction);
179 }
180 }
181 }
182 }
186 }
187 myViewNet->update();
188}
189
190
191bool
194 // open question box
195 FXuint answer = FXMessageBox::question(this, MBOX_YES_NO_CANCEL,
196 TL("Save TLS Changes"), "%s",
197 TL("There are unsaved changes in the currently edited traffic light.\nDo you want to save it before changing mode?"));
198 if (answer == MBOX_CLICKED_YES) { //1:yes, 2:no, 4:esc/cancel
199 // save modifications
200 myTLSPrograms->onCmdSaveChanges(nullptr, 0, nullptr);
201 return true;
202 } else if (answer == MBOX_CLICKED_NO) {
203 // cancel modifications
204 myTLSPrograms->onCmdSaveChanges(nullptr, 0, nullptr);
205 return true;
206 } else {
207 // abort changing mode
208 return false;
209 }
210 } else {
211 return true;
212 }
213}
214
215
216bool
217GNETLSEditorFrame::parseTLSPrograms(const std::string& file) {
219 NBTrafficLightLogicCont tmpTLLCont;
220 NIXMLTrafficLightsHandler tllHandler(tmpTLLCont, myViewNet->getNet()->getEdgeCont());
221 // existing definitions must be available to update their programs
222 std::set<NBTrafficLightDefinition*> origDefs;
223 for (NBTrafficLightDefinition* def : tllCont.getDefinitions()) {
224 // make a duplicate of every program
225 NBTrafficLightLogic* logic = tllCont.getLogic(def->getID(), def->getProgramID());
226 if (logic != nullptr) {
227 NBTrafficLightDefinition* duplicate = new NBLoadedSUMOTLDef(*def, *logic);
228 std::vector<NBNode*> nodes = def->getNodes();
229 for (auto it_node : nodes) {
230 GNEJunction* junction = myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
231 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, def, false, false), true);
232 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, duplicate, true), true);
233 }
234 tmpTLLCont.insert(duplicate);
235 origDefs.insert(duplicate);
236 } else {
237 WRITE_WARNINGF(TL("tlLogic '%', program '%' could not be built"), def->getID(), def->getProgramID());
238 }
239 }
240 //std::cout << " initialized tmpCont with " << origDefs.size() << " defs\n";
241 XMLSubSys::runParser(tllHandler, file);
242
243 std::vector<NBLoadedSUMOTLDef*> loadedTLS;
244 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
245 NBLoadedSUMOTLDef* sdef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
246 if (sdef != nullptr) {
247 loadedTLS.push_back(sdef);
248 }
249 }
250 myViewNet->setStatusBarText(TL("Loaded ") + toString(loadedTLS.size()) + TL(" programs"));
251 for (auto def : loadedTLS) {
252 if (origDefs.count(def) != 0) {
253 // already add to undolist before
254 //std::cout << " skip " << def->getDescription() << "\n";
255 continue;
256 }
257 std::vector<NBNode*> nodes = def->getNodes();
258 //std::cout << " add " << def->getDescription() << " for nodes=" << toString(nodes) << "\n";
259 for (auto it_node : nodes) {
260 GNEJunction* junction = myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
261 //myViewNet->getUndoList()->add(new GNEChange_TLS(junction, myTLSEditorParent->myEditedDef, false), true);
262 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, def, true), true);
263 }
264 }
265 // clean up temporary container to avoid deletion of defs when its destruct is called
266 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
267 tmpTLLCont.removeProgram(def->getID(), def->getProgramID(), false);
268 }
269 return true;
270}
271
272
273void
275 auto junction = dynamic_cast<GNEJunction*>(AC);
276 if (junction) {
277 editJunction(junction);
278 }
279}
280
281
282void
287 for (const auto& node : myTLSPrograms->getCurrentTLSPrograms()->getNodes()) {
288 myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(node->getID())->selectTLS(false);
289 }
290 }
291 }
292 // clean data structures
294 // check if delete myEditedDef
295 if (myEditedDef) {
296 delete myEditedDef;
297 myEditedDef = nullptr;
298 }
299 // clear internal lanes
300 buildInternalLanes(nullptr);
301 // clean up attributes
303 // clean up attributes
305 // only clears when there are no definitions
307}
308
309
314
315
320
321
326
327
332
333
334void
336 // clean up previous internal lanes
337 for (const auto& internalLanes : myInternalLanes) {
338 for (const auto& internalLane : internalLanes.second) {
339 // remove internal lane from ACs
341 // delete internal lane
342 delete internalLane;
343 }
344 }
345 // clear container
346 myInternalLanes.clear();
347 // create new internal lanes
348 if (tlDef != nullptr) {
349 const int NUM_POINTS = 10;
350 const NBNode* nbnCurrentJunction = myTLSJunction->getCurrentJunction()->getNBNode();
351 // get innerID NWWriter_SUMO::writeInternalEdges
352 const std::string innerID = ":" + nbnCurrentJunction->getID();
353 const NBConnectionVector& links = tlDef->getControlledLinks();
354 // iterate over links
355 for (const auto& link : links) {
356 int tlIndex = link.getTLIndex();
357 PositionVector shape;
358 try {
359 const NBEdge::Connection& con = link.getFrom()->getConnection(link.getFromLane(), link.getTo(), link.getToLane());
360 shape = con.shape;
361 shape.append(con.viaShape);
362 } catch (ProcessError&) {
363 shape = link.getFrom()->getToNode()->computeInternalLaneShape(link.getFrom(), NBEdge::Connection(link.getFromLane(),
364 link.getTo(), link.getToLane()), NUM_POINTS);
365 }
366 if (shape.length() < 2) {
367 // enlarge shape to ensure visibility
368 shape.clear();
369 const PositionVector laneShapeFrom = link.getFrom()->getLaneShape(link.getFromLane());
370 const PositionVector laneShapeTo = link.getTo()->getLaneShape(link.getToLane());
371 shape.push_back(laneShapeFrom.positionAtOffset(MAX2(0.0, laneShapeFrom.length() - 1)));
372 shape.push_back(laneShapeTo.positionAtOffset(MIN2(1.0, laneShapeFrom.length())));
373 }
374 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), innerID + '_' + toString(tlIndex), shape, tlIndex);
375 // add into atribute carriers
377 myInternalLanes[tlIndex].push_back(internalLane);
378 }
379 // iterate over crossings
380 for (const auto& nbn : tlDef->getNodes()) {
381 for (const auto& crossing : nbn->getCrossings()) {
382 if (crossing->tlLinkIndex2 > 0 && crossing->tlLinkIndex2 != crossing->tlLinkIndex) {
383 // draw both directions
384 PositionVector forward = crossing->shape;
385 forward.move2side(crossing->width / 4);
386 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id, forward, crossing->tlLinkIndex);
387 // add into atribute carriers
389 myInternalLanes[crossing->tlLinkIndex].push_back(internalLane);
390 PositionVector backward = crossing->shape.reverse();
391 backward.move2side(crossing->width / 4);
392 GNEInternalLane* internalLaneReverse = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id + "_r", backward, crossing->tlLinkIndex2);
393 // add into atribute carriers
394 myViewNet->getNet()->getAttributeCarriers()->insertInternalLane(internalLaneReverse);
395 myInternalLanes[crossing->tlLinkIndex2].push_back(internalLaneReverse);
396 } else {
397 // draw only one lane for both directions
398 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id, crossing->shape, crossing->tlLinkIndex);
399 // add into atribute carriers
401 myInternalLanes[crossing->tlLinkIndex].push_back(internalLane);
402 }
403 }
404 }
405 }
406}
407
408
409std::string
413
414
417 if ((index >= 0) || (index < (int)myEditedDef->getLogic()->getPhases().size())) {
418 return myEditedDef->getLogic()->getPhases().at(index);
419 } else {
420 throw ProcessError(TL("Invalid phase index"));
421 }
422}
423
424
425void
428 // get current selected row
429 const auto selectedRow = myTLSPhases->getPhaseTable()->getCurrentSelectedRow();
430 if (myViewNet->changeAllPhases()) {
431 for (int row = 0; row < (int)myEditedDef->getLogic()->getPhases().size(); row++) {
432 myEditedDef->getLogic()->setPhaseState(row, lane->getTLIndex(), lane->getLinkState());
433 }
434 } else {
436 }
437 // init phaseTable
439 // select row
440 myTLSPhases->getPhaseTable()->selectRow(selectedRow);
441 // focus table
442 myTLSPhases->getPhaseTable()->setFocus();
443}
444
445
446void
447GNETLSEditorFrame::handleMultiChange(GNELane* lane, FXObject* obj, FXSelector sel, void* eventData) {
448 if (myEditedDef != nullptr) {
451 std::set<std::string> fromIDs;
452 fromIDs.insert(lane->getMicrosimID());
453 // if neither the lane nor its edge are selected, apply changes to the whole edge
455 for (auto it_lane : lane->getParentEdge()->getChildLanes()) {
456 fromIDs.insert(it_lane->getMicrosimID());
457 }
458 } else {
459 // if the edge is selected, apply changes to all lanes of all selected edges
461 const auto selectedEdge = myViewNet->getNet()->getAttributeCarriers()->getSelectedEdges();
462 for (const auto& edge : selectedEdge) {
463 for (auto it_lane : edge->getChildLanes()) {
464 fromIDs.insert(it_lane->getMicrosimID());
465 }
466 }
467 }
468 // if the lane is selected, apply changes to all selected lanes
469 if (lane->isAttributeCarrierSelected()) {
470 const auto selectedLanes = myViewNet->getNet()->getAttributeCarriers()->getSelectedLanes();
471 for (auto it_lane : selectedLanes) {
472 fromIDs.insert(it_lane->getMicrosimID());
473 }
474 }
475
476 }
477 // set new state for all connections from the chosen lane IDs
478 for (auto it : links) {
479 if (fromIDs.count(it.getFrom()->getLaneID(it.getFromLane())) > 0) {
480 std::vector<GNEInternalLane*> lanes = myInternalLanes[it.getTLIndex()];
481 for (auto it_lane : lanes) {
482 it_lane->onDefault(obj, sel, eventData);
483 }
484 }
485 }
486 }
487}
488
489
490bool
492 if (myEditedDef != nullptr) {
494 for (auto it : links) {
495 if (it.getFrom()->getID() == edge->getMicrosimID()) {
496 return true;
497 }
498 }
499 }
500 return false;
501}
502
503
504void
507 // discard previous changes
509 // set junction
511 // init TLS definitions
513 // init TLSAttributes
515 // begin undo-list
516 myViewNet->getUndoList()->begin(GUIIcon::MODETLS, TL("modifying TLS definition"));
517 // only select TLS if getCurrentJunction exist
520 }
523 myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(node->getID())->selectTLS(true);
524 }
525 // update color
527 }
528 }
529 } else {
530 myViewNet->setStatusBarText(TL("Unsaved modifications. Abort or Save"));
531 }
533}
534
535
537GNETLSEditorFrame::getSUMOTime(const std::string& string) {
538 return TIME2STEPS(GNEAttributeCarrier::parse<double>(string));
539}
540
541const std::string
543 return toString(STEPS2TIME(value));
544}
545
546// ---------------------------------------------------------------------------
547// GNETLSEditorFrame::TLSAttributes - methods
548// ---------------------------------------------------------------------------
549
551 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light Attributes")),
552 myTLSEditorParent(TLSEditorParent) {
553 // create frame, label and TextField for Offset (By default disabled)
554 FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
555 new FXLabel(horizontalFrame, toString(SUMO_ATTR_OFFSET).c_str(), nullptr, GUIDesignLabelThickedFixed(100));
557 myOffsetTextField->disable();
558 // create frame, label and TextField for parameters (By default disabled)
559 horizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
562 myButtonEditParameters->disable();
563 myParametersTextField->disable();
564 // create set detectors button (By default disabled)
567 TL("Assign E1 detectors") + std::string("\t") + TL("Enable assign E1 mode") + std::string("\t") + TL("Assign E1 detectors to the current TLS"),
568 TL("Assign E1 detectors") + std::string("\t") + TL("Disable assign E1 mode") + std::string("\t") + TL("Assign E1 detectors to the current TLS"),
572}
573
574
576
577
578void
580 if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 0) {
581 // no TLS programs, disable elements
582 myOffsetTextField->disable();
583 myButtonEditParameters->disable();
584 myParametersTextField->disable();
585 // disable E1 detector mode
586 disableE1DetectorMode();
587 mySetDetectorsToggleButton->disable();
588 // clear E1 detectors
589 if (myE1Detectors.size() > 0) {
590 myE1Detectors.clear();
591 myTLSEditorParent->getViewNet()->update();
592 }
593 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
594 // joining TLSs, disable button
595 myOffsetTextField->disable();
596 myButtonEditParameters->disable();
597 myParametersTextField->disable();
598 // disable E1 detector mode
599 disableE1DetectorMode();
600 mySetDetectorsToggleButton->disable();
601 // clear E1 detectors
602 if (myE1Detectors.size() > 0) {
603 myE1Detectors.clear();
604 myTLSEditorParent->getViewNet()->update();
605 }
606 } else if (isSetDetectorsToggleButtonEnabled()) {
607 // set detectors toggle button is enabled, disable elements
608 myOffsetTextField->disable();
609 myButtonEditParameters->disable();
610 myParametersTextField->disable();
611 } else {
612 myOffsetTextField->enable();
613 myButtonEditParameters->enable();
614 myParametersTextField->enable();
615 // disable E1 detector mode in static
616 if (myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms()->getType() == TrafficLightType::STATIC) {
617 // disable E1 detector mode
618 disableE1DetectorMode();
619 mySetDetectorsToggleButton->disable();
620 // clear E1 detectors
621 if (myE1Detectors.size() > 0) {
622 myE1Detectors.clear();
623 myTLSEditorParent->getViewNet()->update();
624 }
625 } else {
626 mySetDetectorsToggleButton->enable();
627 }
628 }
629}
630
631
632void
636
637
638void
642
643
644void
646 // get current edited junction
647 const auto junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
648 if (junction == nullptr) {
649 throw ProcessError("Junction cannot be NULL");
650 } else {
651 // enable Offset
652 myOffsetTextField->enable();
653 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
654 // enable parameters
655 myButtonEditParameters->enable();
656 myParametersTextField->enable();
657 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
658 // reset mySetDetectorsToggleButton
659 disableE1DetectorMode();
660 }
661}
662
663
664void
666 // clear and disable Offset TextField
667 myOffsetTextField->setText("");
668 myOffsetTextField->disable();
669 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
670 // clear and disable parameters TextField
671 myButtonEditParameters->disable();
672 myParametersTextField->setText("");
673 myParametersTextField->disable();
674 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
675}
676
677
680 return getSUMOTime(myOffsetTextField->getText().text());
681}
682
683
684void
686 myOffsetTextField->setText(getSteps2Time(offset).c_str());
687 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
688}
689
690
691bool
693 if (GNEAttributeCarrier::canParse<SUMOTime>(myOffsetTextField->getText().text())) {
694 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
695 return true;
696 } else {
697 myOffsetTextField->setTextColor(MFXUtils::getFXColor(RGBColor::RED));
698 return false;
699 }
700}
701
702
703std::string
705 return myParametersTextField->getText().text();
706}
707
708
709void
711 myParametersTextField->setText(parameters.c_str());
712 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
713 // update E1 detectors
714 if (myTLSEditorParent->myEditedDef->getType() != TrafficLightType::STATIC) {
715 updateE1Detectors();
716 }
717}
718
719
720bool
722 if (Parameterised::areParametersValid(myParametersTextField->getText().text())) {
723 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::BLACK));
724 return true;
725 } else {
726 myParametersTextField->setTextColor(MFXUtils::getFXColor(RGBColor::RED));
727 return false;
728 }
729}
730
731
732bool
734 return (mySetDetectorsToggleButton->getState() == TRUE);
735}
736
737
738bool
740 // get E1 lane ID
741 const auto laneID = E1->getParentLanes().front()->getID();
742 // iterate over all E1 detectors
743 for (auto it = myE1Detectors.begin(); it != myE1Detectors.end(); it++) {
744 if (E1->getID() == it->second) {
745 // already selected, then remove it from detectors
746 myE1Detectors.erase(it);
747 // and remove it from parameters
748 myTLSEditorParent->myEditedDef->unsetParameter(laneID);
749 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
750 // mark TL as modified
751 myTLSEditorParent->myTLSPrograms->markAsModified();
752 return true;
753 } else if (laneID == it->first) {
754 // there is another E1 in the same lane, then swap
755 myE1Detectors.erase(it);
756 myE1Detectors[laneID] = E1->getID();
757 // also in parameters
758 myTLSEditorParent->myEditedDef->setParameter(laneID, E1->getID());
759 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
760 // mark TL as modified
761 myTLSEditorParent->myTLSPrograms->markAsModified();
762 return true;
763 }
764 }
765 // add it in parameters
766 myE1Detectors[laneID] = E1->getID();
767 myTLSEditorParent->myEditedDef->setParameter(laneID, E1->getID());
768 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
769 // mark TL as modified
770 myTLSEditorParent->myTLSPrograms->markAsModified();
771 return true;
772}
773
774
775const std::map<std::string, std::string>&
777 return myE1Detectors;
778}
779
780
781void
783 mySetDetectorsToggleButton->setState(FALSE, TRUE);
784}
785
786
787long
789 if (isValidOffset()) {
790 myTLSEditorParent->myTLSPrograms->markAsModified();
791 myTLSEditorParent->myEditedDef->setOffset(getOffset());
792 myOffsetTextField->killFocus();
793 myTLSEditorParent->updateModules();
794 }
795 return 1;
796}
797
798
799long
801 if (isValidParameters()) {
802 myTLSEditorParent->myTLSPrograms->markAsModified();
803 myTLSEditorParent->myEditedDef->setParametersStr(getParameters());
804 myParametersTextField->killFocus();
805 myTLSEditorParent->updateModules();
806 }
807 return 1;
808}
809
810
811long
813 // continue depending of myEditedDef
814 if (myTLSEditorParent->myEditedDef) {
815 // get previous parameters
816 const auto previousParameters = getParameters();
817 const auto internalTests = myTLSEditorParent->getViewNet()->getViewParent()->getGNEAppWindows()->getInternalTest();
818 if (GNESingleParametersDialog(myTLSEditorParent->getViewNet()->getApp(), myTLSEditorParent->myEditedDef).openModalDialog(internalTests)) {
819 // set parameters in textfield
820 setParameters(myTLSEditorParent->myEditedDef->getParametersStr());
821 // only mark as modified if parameters are different
822 if (getParameters() != previousParameters) {
823 myTLSEditorParent->myTLSPrograms->markAsModified();
824 }
825 }
826 myTLSEditorParent->updateModules();
827 }
828 return 1;
829}
830
831
832long
834 if (mySetDetectorsToggleButton->getState()) {
835 // set special color
836 mySetDetectorsToggleButton->setBackColor(FXRGBA(253, 255, 206, 255));
837 } else {
838 // restore default color
839 mySetDetectorsToggleButton->setBackColor(4293980400);
840 }
841 myTLSEditorParent->updateModules();
842 // update view
843 myTLSEditorParent->getViewNet()->update();
844 return 1;
845}
846
847
848void
850 // first clear E1 detectors
851 myE1Detectors.clear();
852 // iterate over parameters
853 for (const auto& parameter : myTLSEditorParent->myEditedDef->getParametersMap()) {
854 // check if both lane and E1 exists
855 if (myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveLane(parameter.first, false) &&
856 myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_INDUCTION_LOOP, parameter.second, false)) {
857 // add it into list
858 myE1Detectors[parameter.first] = parameter.second;
859 }
860 }
861 myTLSEditorParent->updateModules();
862 // update view net
863 myTLSEditorParent->getViewNet()->update();
864}
865
866// ---------------------------------------------------------------------------
867// GNETLSEditorFrame::TLSJunction - methods
868// ---------------------------------------------------------------------------
869
871 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light")),
872 myTLSEditorParent(TLSEditorParent),
873 myCurrentJunction(nullptr) {
874 // Create frame for junction IDs
875 FXHorizontalFrame* junctionIDFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
876 myJunctionIDLabel = new FXLabel(junctionIDFrame, TL("Junction ID"), nullptr, GUIDesignLabelThickedFixed(100));
877 myJunctionIDTextField = new MFXTextFieldTooltip(junctionIDFrame,
880 // junction ID remains always disabled
881 myJunctionIDTextField->disable();
882 // Create frame for TLS Program ID
883 FXHorizontalFrame* TLSIDFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
884 new FXLabel(TLSIDFrame, TL("TLS ID"), nullptr, GUIDesignLabelThickedFixed(100));
885 myTLSIDTextField = new MFXTextFieldTooltip(TLSIDFrame,
888 // create frame, label and textfield for type
889 FXHorizontalFrame* typeFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
890 new FXLabel(typeFrame, toString(SUMO_ATTR_TYPE).c_str(), nullptr, GUIDesignLabelThickedFixed(100));
893 // fill comboBox (only certain TL types)
898 // create frame for join buttons
899 FXHorizontalFrame* joinButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
900 // create join states button
903 TL("Join") + std::string("\t") + TL("Enable join mode") + std::string("\t") + TL("Join TLS and junctions in the current junction."),
904 TL("Join") + std::string("\t") + TL("Disable join mode") + std::string("\t") + TL("Join TLS and junctions in the current junction."),
907 myDisjoinTLSButton = new MFXButtonTooltip(joinButtons,
909 TL("Disjoin") + std::string("\t") + TL("Disjoin current TLS") + std::string("\t") + TL("Disjoin current TLS."),
911 // create frame for join control buttons
913 // create create tlDef button
914 GUIDesigns::buildFXButton(myJoinControlButtons, TL("Accept"), "", TL("Finish join."),
916 GUIDesigns::buildFXButton(myJoinControlButtons, TL("Cancel"), "", TL("Cancel Join."),
918 // update junction description after creation
920 // show TLS Junction
921 show();
922}
923
924
926
927
928void
930 if ((myCurrentJunction == nullptr) ||
931 (myCurrentJunction->getNBNode()->getControllingTLS().size() == 0)) {
932 // no TLS
933 myTLSIDTextField->setText("");
934 myTLSIDTextField->disable();
935 myTLSTypeComboBox->disable();
936 myJoinTLSToggleButton->disable();
937 myDisjoinTLSButton->disable();
938 myJoinControlButtons->hide();
939 } else {
940 // get first controled TLS
941 const auto TLS = (*myCurrentJunction->getNBNode()->getControllingTLS().begin());
942 // set text field ID
943 myTLSIDTextField->setText(TLS->getID().c_str());
944 // continue with more options
945 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled() ||
946 myTLSEditorParent->myTLSPrograms->checkHaveModifications()) {
947 // disable if selecting selecting detectors or we modified the program
948 myTLSIDTextField->setText("");
949 myTLSIDTextField->disable();
950 myTLSTypeComboBox->disable();
951 myJoinTLSToggleButton->disable();
952 myDisjoinTLSButton->disable();
953 myJoinControlButtons->hide();
954 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
955 // partial disable due joining
956 myTLSIDTextField->setText("");
957 myTLSIDTextField->disable();
958 myTLSTypeComboBox->disable();
959 myDisjoinTLSButton->disable();
960 // enable join TLS and show control buttons
961 myJoinTLSToggleButton->enable();
962 myJoinControlButtons->show();
963 } else {
964 // enable
965 myTLSIDTextField->enable();
966 myTLSTypeComboBox->enable();
967 myJoinTLSToggleButton->enable();
968 // disjoint button only if we have more than one TLS controlled
969 if (TLS->getNodes().size() == 1) {
970 myDisjoinTLSButton->disable();
971 } else {
972 myDisjoinTLSButton->enable();
973 }
974 }
975 }
976}
977
978
981 return myCurrentJunction;
982}
983
984
985void
987 myCurrentJunction = junction;
988 // resfresh module
989 refreshTLSJunction();
990}
991
992
993bool
995 return (myJoinTLSToggleButton->getState() == TRUE);
996}
997
998
999bool
1001 return (std::find(mySelectedJunctionIDs.begin(), mySelectedJunctionIDs.end(), junction->getID()) != mySelectedJunctionIDs.end());
1002}
1003
1004
1005void
1007 // avoid current junction
1008 if (junction != myCurrentJunction) {
1009 // find ID in selected junctions
1010 auto it = std::find(mySelectedJunctionIDs.begin(), mySelectedJunctionIDs.end(), junction->getID());
1011 // check if add or remove
1012 if (it == mySelectedJunctionIDs.end()) {
1013 mySelectedJunctionIDs.push_back(junction->getID());
1014 } else {
1015 mySelectedJunctionIDs.erase(it);
1016 }
1017 }
1018}
1019
1020
1021const std::vector<std::string>&
1023 return mySelectedJunctionIDs;
1024}
1025
1026
1027long
1029 // get IDs
1030 const std::string currentTLID = (*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getID();
1031 const std::string newTLID = myTLSIDTextField->getText().text();
1032 // check if ID is valid
1033 if (newTLID.empty() || (newTLID == currentTLID)) {
1034 // same ID or empty
1035 myTLSIDTextField->setTextColor(FXRGB(0, 0, 0));
1036 myTLSIDTextField->setText(currentTLID.c_str());
1037 myTLSIDTextField->killFocus();
1038 myTLSEditorParent->update();
1039 // show all moduls
1040 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1041 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1042 myTLSEditorParent->myTLSPhases->showTLSPhases();
1043 myTLSEditorParent->myTLSFile->showTLSFile();
1044 } else if (!SUMOXMLDefinitions::isValidNetID(newTLID) || myCurrentJunction->getNet()->getTLLogicCont().exist(newTLID)) {
1045 // set invalid color
1046 myTLSIDTextField->setTextColor(FXRGB(255, 0, 0));
1047 // hide moduls
1048 myTLSEditorParent->myTLSPrograms->hideTLSPrograms();
1049 myTLSEditorParent->myTLSAttributes->hideTLSAttributes();
1050 myTLSEditorParent->myTLSPhases->hideTLSPhases();
1051 myTLSEditorParent->myTLSFile->hideTLSFile();
1052 } else {
1053 // make a copy of myCurrentJunction and current tlDef (because will be reset after calling discardChanges)
1054 auto junction = myCurrentJunction;
1055 const auto tlDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1056 // restore color
1057 myTLSIDTextField->setTextColor(FXRGB(0, 0, 0));
1058 myTLSIDTextField->killFocus();
1059 myTLSEditorParent->update();
1060 // discard previous changes
1061 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1062 // change name using undo-List
1063 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("rename TLS"));
1064 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, tlDef, newTLID), true);
1065 myTLSEditorParent->getViewNet()->getUndoList()->end();
1066 // show all moduls
1067 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1068 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1069 myTLSEditorParent->myTLSPhases->showTLSPhases();
1070 myTLSEditorParent->myTLSFile->showTLSFile();
1071 // edit junction again
1072 myTLSEditorParent->editJunction(junction);
1073 }
1074 myTLSEditorParent->updateModules();
1075 return 1;
1076}
1077
1078
1079long
1081 // get IDs
1082 const std::string currentTLType = toString((*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getType());
1083 const std::string newTLType = myTLSTypeComboBox->getText().text();
1084 // check if ID is valid
1085 if (newTLType.empty() || (newTLType == currentTLType)) {
1086 // same ID or empty, don't change
1087 myTLSTypeComboBox->setTextColor(FXRGB(0, 0, 0));
1088 // set value
1089 const int index = myTLSTypeComboBox->findItem(currentTLType.c_str());
1090 if (index == -1) {
1091 myTLSTypeComboBox->disable();
1092 } else {
1093 myTLSTypeComboBox->setCurrentItem(index);
1094 myTLSTypeComboBox->enable();
1095 }
1096 myTLSTypeComboBox->killFocus();
1097 myTLSEditorParent->update();
1098 // show all moduls
1099 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1100 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1101 myTLSEditorParent->myTLSPhases->showTLSPhases();
1102 myTLSEditorParent->myTLSFile->showTLSFile();
1103 } else if (!SUMOXMLDefinitions::TrafficLightTypes.hasString(newTLType)) {
1104 // set invalid color
1105 myTLSTypeComboBox->setTextColor(FXRGB(255, 0, 0));
1106 // hide moduls
1107 myTLSEditorParent->myTLSPrograms->hideTLSPrograms();
1108 myTLSEditorParent->myTLSAttributes->hideTLSAttributes();
1109 myTLSEditorParent->myTLSPhases->hideTLSPhases();
1110 myTLSEditorParent->myTLSFile->hideTLSFile();
1111 } else {
1112 // reset color
1113 myTLSTypeComboBox->setTextColor(FXRGB(0, 0, 0));
1114 myTLSTypeComboBox->killFocus();
1115 myTLSEditorParent->update();
1116 // make a copy of myCurrentJunction (because will be reset after calling discardChanges)
1117 auto junction = myCurrentJunction;
1118 // discard previous changes
1119 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1120 // change name using undo-List
1121 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("change TLS type"));
1122 junction->setAttribute(SUMO_ATTR_TLTYPE, newTLType, myTLSEditorParent->getViewNet()->getUndoList());
1123 myTLSEditorParent->getViewNet()->getUndoList()->end();
1124 // show all moduls
1125 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1126 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1127 myTLSEditorParent->myTLSPhases->showTLSPhases();
1128 myTLSEditorParent->myTLSFile->showTLSFile();
1129 // edit junction again
1130 myTLSEditorParent->editJunction(junction);
1131 }
1132 myTLSEditorParent->updateModules();
1133 return 1;
1134
1135}
1136
1137
1138long
1140 if (myJoinTLSToggleButton->getState()) {
1141 // set special color
1142 myJoinTLSToggleButton->setBackColor(FXRGBA(253, 255, 206, 255));
1143 // clear and fill mySelectedJunctionIDs
1144 mySelectedJunctionIDs.clear();
1145 // get all nodes controlled by this TLS
1146 const auto TLNodes = (*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getNodes();
1147 // fill mySelectedJunctionIDs with TLNodes
1148 mySelectedJunctionIDs.clear();
1149 for (const auto& TLNode : TLNodes) {
1150 mySelectedJunctionIDs.push_back(TLNode->getID());
1151 }
1152 // make a copy of selected junctions
1153 myOriginalSelectedJunctionIDs = mySelectedJunctionIDs;
1154 // show control buttons
1155 myJoinControlButtons->show();
1156 getCollapsableFrame()->recalc();
1157 } else {
1158 // hide control buttons
1159 myJoinControlButtons->hide();
1160 getCollapsableFrame()->recalc();
1161 // make a copy of current junction
1162 const auto currentJunction = myCurrentJunction;
1163 // declare vectors for junctions
1164 std::vector<GNEJunction*> selectedJunctions, resetTLJunctions;
1165 // get selected junctions (all except current
1166 for (const auto& selectedJunctionID : mySelectedJunctionIDs) {
1167 if (selectedJunctionID != currentJunction->getID()) {
1168 selectedJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(selectedJunctionID));
1169 }
1170 }
1171 // get junctions to reset TL (all TL nodes except current)
1172 for (const auto& TLNBNode : (*currentJunction->getNBNode()->getControllingTLS().begin())->getNodes()) {
1173 if (TLNBNode != currentJunction->getNBNode()) {
1174 resetTLJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLNBNode->getID()));
1175 }
1176 }
1177 // discard changes
1178 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1179 // begin undo list
1180 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("join TLS"));
1181 // remove tl from TLNBNode
1182 for (const auto& resetTLJunction : resetTLJunctions) {
1183 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, "priority", myTLSEditorParent->getViewNet()->getUndoList());
1184 }
1185 // now update it in all joined junctions
1186 for (const auto& selectedJunction : selectedJunctions) {
1187 selectedJunction->setAttribute(SUMO_ATTR_TYPE, currentJunction->getAttribute(SUMO_ATTR_TYPE), myTLSEditorParent->getViewNet()->getUndoList());
1188 selectedJunction->setAttribute(SUMO_ATTR_TLID, currentJunction->getAttribute(SUMO_ATTR_TLID), myTLSEditorParent->getViewNet()->getUndoList());
1189 }
1190 // end undo list
1191 myTLSEditorParent->getViewNet()->getUndoList()->end();
1192 // restore default color
1193 myJoinTLSToggleButton->setBackColor(4293980400);
1194 // clear selected junction IDs
1195 mySelectedJunctionIDs.clear();
1196 // edit junction again
1197 myTLSEditorParent->editJunction(currentJunction);
1198 }
1199 myTLSEditorParent->updateModules();
1200 // update view
1201 myTLSEditorParent->getViewNet()->update();
1202 return 1;
1203}
1204
1205
1206long
1208 // make a copy of current junction
1209 const auto currentJunction = myCurrentJunction;
1210 // declare vectors for junctions
1211 std::vector<GNEJunction*> resetTLJunctions;
1212 // get junctions to reset TL
1213 for (const auto& TLNBNode : (*currentJunction->getNBNode()->getControllingTLS().begin())->getNodes()) {
1214 resetTLJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLNBNode->getID()));
1215 }
1216 // save TL types
1217 const auto type = resetTLJunctions.front()->getAttribute(SUMO_ATTR_TYPE);
1218 const auto tlType = resetTLJunctions.front()->getAttribute(SUMO_ATTR_TLTYPE);
1219 // discard changes
1220 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1221 // begin undo list
1222 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("disjoin TLS"));
1223 // the disjoint tlIds will be the junction ids. Ensure that there is no name clash with the current tlId
1224 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1225 const std::string oldId = currentJunction->getAttribute(SUMO_ATTR_TLID);
1226 const std::string tmpIdBase = oldId + "_TMP";
1227 int tmpIndex = 0;
1228 std::string tmpId = tmpIdBase + toString(tmpIndex);
1229 while (tllCont.exist(tmpId)) {
1230 tmpId = tmpIdBase + toString(++tmpIndex);
1231 }
1232 for (NBTrafficLightDefinition* tlDef : currentJunction->getNBNode()->getControllingTLS()) {
1233 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(currentJunction, tlDef, tmpId), true);
1234 }
1235 // remove tl from TLNBNode and the re-initialize as single traffic light
1236 for (const auto& resetTLJunction : resetTLJunctions) {
1237 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, "priority", myTLSEditorParent->getViewNet()->getUndoList());
1238 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, type, myTLSEditorParent->getViewNet()->getUndoList());
1239 resetTLJunction->setAttribute(SUMO_ATTR_TLTYPE, tlType, myTLSEditorParent->getViewNet()->getUndoList());
1240 }
1241 // end undo list
1242 myTLSEditorParent->getViewNet()->getUndoList()->end();
1243 // restore default color
1244 myJoinTLSToggleButton->setBackColor(4293980400);
1245 // clear selected junction IDs
1246 mySelectedJunctionIDs.clear();
1247 // edit junction again
1248 myTLSEditorParent->editJunction(currentJunction);
1249 myTLSEditorParent->updateModules();
1250 return 1;
1251}
1252
1253
1254long
1256 myJoinTLSToggleButton->setState(FALSE, TRUE);
1257 myTLSEditorParent->updateModules();
1258 return 1;
1259}
1260
1261
1262long
1264 // restore selected junction
1265 mySelectedJunctionIDs = myOriginalSelectedJunctionIDs;
1266 myJoinTLSToggleButton->setState(FALSE, TRUE);
1267 myTLSEditorParent->updateModules();
1268 return 1;
1269}
1270
1271
1272void
1274 // first reset junction label
1275 myJunctionIDLabel->setText(TL("Junction ID"));
1276 // clear selected junctions
1277 mySelectedJunctionIDs.clear();
1278 // cancel joining junction mode
1279 onCmdCancelJoin(nullptr, 0, nullptr);
1280 // continue depending of current junction
1281 if (myCurrentJunction == nullptr) {
1282 myJunctionIDTextField->setText(TL("No junction selected"));
1283 } else {
1284 // get all TLS assigned to this node
1285 const auto& TLSs = myCurrentJunction->getNBNode()->getControllingTLS();
1286 // check if junction is controlled
1287 if (TLSs.size() > 0) {
1288 // get first TLS
1289 const auto TLS = (*TLSs.begin());
1290 // update junction ID text field
1291 if (TLS->getNodes().size() > 1) {
1292 // declare string
1293 std::string TLSNodesStr;
1294 for (auto it = TLS->getNodes().begin(); it != TLS->getNodes().end(); it++) {
1295 if (it == (TLS->getNodes().end() - 1)) {
1296 TLSNodesStr += (*it)->getID();
1297 } else {
1298 TLSNodesStr += (*it)->getID() + ", ";
1299 }
1300 }
1301 // updated junction fields
1302 myJunctionIDTextField->setText(TLSNodesStr.c_str());
1303 // update junction label if we have multiple nodes
1304 if (TLS->getNodes().size() > 1) {
1305 myJunctionIDLabel->setText(TL("Junction IDs"));
1306 }
1307 // set TLS type in comboBox
1308 const int index = myTLSTypeComboBox->findItem(myCurrentJunction->getAttribute(SUMO_ATTR_TLTYPE).c_str());
1309 if (index != -1) {
1310 myTLSTypeComboBox->setCurrentItem(index, FALSE);
1311 }
1312 }
1313 } else {
1314 // update junction ID text field
1315 myJunctionIDTextField->setText(myCurrentJunction->getID().c_str());
1316 myTLSTypeComboBox->setCurrentItem(0, FALSE);
1317 }
1318 }
1319 // update TLS junction
1320 updateTLSJunction();
1321}
1322
1323// ---------------------------------------------------------------------------
1324// GNETLSEditorFrame::TLSPrograms - methods
1325// ---------------------------------------------------------------------------
1326
1328 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light Programs")),
1329 myTLSEditorParent(TLSEditorParent) {
1330 // create frame, label and comboBox for programID
1331 FXHorizontalFrame* programFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1332 new FXLabel(programFrame, toString(SUMO_ATTR_PROGRAMID).c_str(), nullptr, GUIDesignLabelThickedFixed(100));
1336 // create auxiliar frames
1337 FXHorizontalFrame* horizontalFrameAux = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
1338 FXVerticalFrame* verticalFrameAuxA = new FXVerticalFrame(horizontalFrameAux, GUIDesignAuxiliarHorizontalFrame);
1339 FXVerticalFrame* verticalFrameAuxB = new FXVerticalFrame(horizontalFrameAux, GUIDesignAuxiliarHorizontalFrame);
1340 // create create tlDef button
1341 myCreateButton = GUIDesigns::buildFXButton(verticalFrameAuxA, TL("Create TLS"), "", TL("Create a new traffic light program."),
1343 myCreateButton->disable();
1344 // create delete tlDef button
1345 myDeleteButton = GUIDesigns::buildFXButton(verticalFrameAuxA, TL("Delete"), "", TL("Delete a traffic light program. If all programs are deleted the junction turns into a priority junction."),
1347 myDeleteButton->disable();
1348 // create reset current tlDef button
1349 myResetSingleButton = GUIDesigns::buildFXButton(verticalFrameAuxB, TL("Reset single"), "", TL("Reset current TLS program."),
1351 myResetSingleButton->disable();
1352 // create reset all tlDefs button
1353 myResetAllButton = GUIDesigns::buildFXButton(verticalFrameAuxB, TL("Reset all"), "", TL("Reset all TLS programs."),
1355 myResetAllButton->disable();
1356 // create save modifications button
1357 mySaveButon = GUIDesigns::buildFXButton(verticalFrameAuxA, TL("Save"), "", TL("Save program modifications. (Enter)"),
1359 mySaveButon->disable();
1360 // create cancel modifications buttons
1361 myCancelButon = GUIDesigns::buildFXButton(verticalFrameAuxB, TL("Cancel"), "", TL("Discard program modifications. (Esc)"),
1363 myCancelButon->disable();
1364 // show GroupBox
1365 show();
1366}
1367
1368
1370
1371
1372void
1374 if (getNumberOfPrograms() == 0) {
1375 // no TLS Programs, disable buttons except create (if we have a junction)
1376 if (myTLSEditorParent->getTLSJunction()->getCurrentJunction() != nullptr) {
1377 myCreateButton->enable();
1378 } else {
1379 myCreateButton->disable();
1380 }
1381 myDeleteButton->disable();
1382 myResetSingleButton->disable();
1383 myProgramComboBox->disable();
1384 myResetAllButton->disable();
1385 mySaveButon->disable();
1386 myCancelButon->disable();
1387 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1388 // selecting E1, disable buttons
1389 myCreateButton->disable();
1390 myDeleteButton->disable();
1391 myResetSingleButton->disable();
1392 myProgramComboBox->disable();
1393 myResetAllButton->disable();
1394 mySaveButon->disable();
1395 myCancelButon->disable();
1396 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1397 // joining TLSs, disable button
1398 myCreateButton->disable();
1399 myDeleteButton->disable();
1400 myResetSingleButton->disable();
1401 myProgramComboBox->disable();
1402 myResetAllButton->disable();
1403 mySaveButon->disable();
1404 myCancelButon->disable();
1405 } else if (myHaveModifications) {
1406 // modifications, disable button
1407 myCreateButton->disable();
1408 myDeleteButton->disable();
1409 myResetSingleButton->disable();
1410 myProgramComboBox->disable();
1411 myResetAllButton->disable();
1412 // enable save and cancel buttons
1413 mySaveButon->enable();
1414 myCancelButon->enable();
1415 } else {
1416 myCreateButton->enable();
1417 myDeleteButton->enable();
1418 myResetSingleButton->enable();
1419 myProgramComboBox->enable();
1420 // disable save and cancel buttons
1421 mySaveButon->disable();
1422 myCancelButon->disable();
1423 // check if enable reset all
1424 if (getNumberOfPrograms() > 1) {
1425 myResetAllButton->enable();
1426 } else {
1427 myResetAllButton->disable();
1428 }
1429 }
1430 // get current junction
1431 const auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1432 // update button text
1433 if (currentJunction == nullptr) {
1434 myCreateButton->setText(TL("Create"));
1435 } else if (currentJunction->getNBNode()->isTLControlled()) {
1436 myCreateButton->setText(TL("Duplicate"));
1437 } else {
1438 myCreateButton->setText(TL("Create"));
1439 }
1440}
1441
1442
1443void
1447
1448
1449void
1453
1454
1455bool
1457 // get current edited junction
1458 const auto junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1459 if (junction == nullptr) {
1460 throw ProcessError("Junction cannot be NULL");
1461 } else {
1462 // clear definitions
1463 myTLSPrograms.clear();
1464 // obtain TLSs sorted by ID
1465 std::set<std::string> programIDs;
1466 for (const auto& TLS : junction->getNBNode()->getControllingTLS()) {
1467 myTLSPrograms.push_back(TLS);
1468 programIDs.insert(TLS->getProgramID());
1469 }
1470 for (const auto& programID : programIDs) {
1471 myProgramComboBox->appendIconItem(programID.c_str());
1472 }
1473 // check if enable TLS definitions
1474 if (myTLSPrograms.size() > 0) {
1475 myProgramComboBox->enable();
1476 myProgramComboBox->setCurrentItem(0);
1477 // switch TLS Program
1478 return switchProgram();
1479 }
1480 return false;
1481 }
1482}
1483
1484
1485void
1487 // clear definitions
1488 myTLSPrograms.clear();
1489 // clear and disable myProgramComboBox
1490 myProgramComboBox->clearItems();
1491 myProgramComboBox->disable();
1492}
1493
1494
1495int
1497 return myProgramComboBox->getNumItems();
1498}
1499
1500
1501bool
1503 return myHaveModifications;
1504}
1505
1506
1507void
1509 myHaveModifications = true;
1510 myTLSEditorParent->updateModules();
1511}
1512
1513
1516 // find TLS definition
1517 for (const auto& TLSPrograms : myTLSPrograms) {
1518 if (TLSPrograms->getProgramID() == myProgramComboBox->getText().text()) {
1519 return TLSPrograms;
1520 }
1521 }
1522 throw ProcessError(TL("TLSPrograms cannot be found"));
1523}
1524
1525
1526const std::string
1528 if (myProgramComboBox->getNumItems() == 0) {
1529 return "";
1530 } else {
1531 return myProgramComboBox->getText().text();
1532 }
1533}
1534
1535
1536void
1538 // get junction copy
1539 auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1540 if (currentJunction != nullptr) {
1541 myTLSEditorParent->getViewNet()->getUndoList()->abortAllChangeGroups();
1542 myTLSEditorParent->cleanup();
1543 myTLSEditorParent->getViewNet()->updateViewNet();
1544 // edit junction again
1545 if (editJunctionAgain) {
1546 myTLSEditorParent->editJunction(currentJunction);
1547 }
1548 }
1549 myTLSEditorParent->updateModules();
1550}
1551
1552
1553long
1554GNETLSEditorFrame::TLSPrograms::onCmdCreate(FXObject*, FXSelector, void*) {
1555 // get current edited junction (needed because onCmdDiscardChanges clear junction)
1556 GNEJunction* currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1557 // abort because we onCmdOk assumes we wish to save an edited definition
1558 discardChanges(false);
1559 // check number of edges
1560 if (currentJunction->getGNEIncomingEdges().empty() && currentJunction->getGNEOutgoingEdges().empty()) {
1561 // open question box
1562 FXMessageBox::warning(this, MBOX_OK,
1563 TL("TLS cannot be created"), "%s",
1564 (TL("Traffic Light cannot be created because junction must have") + std::string("\n") +
1565 TL("at least one incoming edge and one outgoing edge.")).c_str());
1566 return 1;
1567 }
1568 // check number of connections
1569 if (currentJunction->getGNEConnections().empty()) {
1570 // open question box
1571 FXMessageBox::warning(this, MBOX_OK,
1572 TL("TLS cannot be created"), "%s",
1573 (TL("Traffic Light cannot be created because junction") + std::string("\n") +
1574 TL("must have at least one connection.")).c_str());
1575 return 1;
1576 }
1577 // check uncontrolled connections
1578 bool connectionControlled = false;
1579 for (const auto& connection : currentJunction->getGNEConnections()) {
1580 if (!connection->getNBEdgeConnection().uncontrolled) {
1581 connectionControlled = true;
1582 }
1583 }
1584 if (!connectionControlled) {
1585 // open question box
1586 FXMessageBox::warning(this, MBOX_OK,
1587 TL("TLS cannot be created"), "%s",
1588 (TL("Traffic Light cannot be created because junction") + std::string("\n") +
1589 TL("must have at least one controlled connection.")).c_str());
1590 return 1;
1591 }
1592 // all checks ok, then create TLS in junction
1593 createTLS(currentJunction);
1594 // edit junction
1595 myTLSEditorParent->editJunction(currentJunction);
1596 // switch to the last program
1597 myProgramComboBox->setCurrentItem(myProgramComboBox->getNumItems() - 1, TRUE);
1598 myTLSEditorParent->updateModules();
1599 return 1;
1600}
1601
1602
1603long
1604GNETLSEditorFrame::TLSPrograms::onCmdDelete(FXObject*, FXSelector, void*) {
1605 // get current junction
1606 GNEJunction* currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1607 // get current edited tlDef
1608 NBTrafficLightDefinition* tlDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1609 // check if remove entire TLS or only one program
1610 const bool changeJunctionType = (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 1);
1611 // abort because onCmdOk assumes we wish to save an edited definition
1612 discardChanges(false);
1613 // check if change junction type
1614 if (changeJunctionType) {
1615 currentJunction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::PRIORITY), myTLSEditorParent->getViewNet()->getUndoList());
1616 } else {
1617 // just remove TLDef
1618 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(currentJunction, tlDef, false), true);
1619 // edit junction again
1620 myTLSEditorParent->editJunction(currentJunction);
1621 }
1622 myTLSEditorParent->updateModules();
1623 return 1;
1624}
1625
1626
1627long
1629 // obtain junction and old definitions
1630 GNEJunction* junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1631 NBTrafficLightDefinition* oldDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1632 const std::string programID = oldDef->getProgramID();
1633 // discard changes
1634 discardChanges(false);
1635 // begin undo
1636 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("reset current program"));
1637 // remove old definition
1638 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, oldDef, false), true);
1639 // create new definition, and add it
1640 NBOwnTLDef* newDef = new NBOwnTLDef(oldDef->getID(), oldDef->getNodes(), oldDef->getOffset(), oldDef->getType());
1641 newDef->setProgramID(programID);
1642 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, newDef, true, true), true);
1643 // set old index
1644 // end undo
1645 myTLSEditorParent->getViewNet()->getUndoList()->end();
1646 // inspect junction again
1647 myTLSEditorParent->editJunction(junction);
1648 // switch to programID
1649 int index = -1;
1650 for (int i = 0; i < myProgramComboBox->getNumItems(); i++) {
1651 if (myProgramComboBox->getItemText(i) == programID) {
1652 index = i;
1653 }
1654 }
1655 if (index != -1) {
1656 myProgramComboBox->setCurrentItem(index, TRUE);
1657 }
1658 myTLSEditorParent->updateModules();
1659 return 1;
1660}
1661
1662
1663long
1665 // obtain junction and old definitions
1666 GNEJunction* junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1667 NBTrafficLightDefinition* oldDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1668 // get a list of all affected nodes
1669 std::vector<GNEJunction*> TLSJunctions;
1670 for (const auto& TLSNode : oldDef->getNodes()) {
1671 TLSJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLSNode->getID()));
1672 }
1673 // discard all previous changes
1674 discardChanges(false);
1675 // begin undo
1676 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("reset TLS"));
1677 // set junction as priority (this will also remove all program, see GNEJunction::setJunctionType)
1678 for (const auto& TLSJunction : TLSJunctions) {
1679 TLSJunction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::PRIORITY), myTLSEditorParent->getViewNet()->getUndoList());
1680 }
1681 // create TLS in junction
1682 createTLS(junction);
1683 // set TLS in all other junctions
1684 for (const auto& TLSJunction : TLSJunctions) {
1685 if (TLSJunction != junction) {
1686 TLSJunction->setAttribute(SUMO_ATTR_TYPE, TLSJunction->getAttribute(SUMO_ATTR_TYPE), myTLSEditorParent->getViewNet()->getUndoList());
1687 TLSJunction->setAttribute(SUMO_ATTR_TLID, TLSJunction->getAttribute(SUMO_ATTR_TLID), myTLSEditorParent->getViewNet()->getUndoList());
1688 }
1689 }
1690 // end undo
1691 myTLSEditorParent->getViewNet()->getUndoList()->end();
1692 // edit junction
1693 myTLSEditorParent->editJunction(junction);
1694 return 1;
1695}
1696
1697
1698long
1700 // check if program is valid (user may input arbitrary text)
1701 bool found = false;
1702 for (const auto& TLSPrograms : myTLSPrograms) {
1703 if (TLSPrograms->getProgramID() == myProgramComboBox->getText().text()) {
1704 found = true;
1705 break;
1706 }
1707 }
1708 if (!found) {
1709 // reset field to a valid program
1710 myProgramComboBox->setText(myTLSPrograms.front()->getProgramID().c_str());
1711 }
1712 switchProgram();
1713 return 1;
1714}
1715
1716
1717long
1719 // get junction copy
1720 const auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1721 // get current program
1722 const auto currentProgram = myProgramComboBox->getCurrentItem();
1723 // check that junction is valid
1724 if (currentJunction != nullptr) {
1725 const auto oldDefinition = getCurrentTLSPrograms();
1726 std::vector<NBNode*> nodes = oldDefinition->getNodes();
1727 GNEUndoList* undoList = myTLSEditorParent->getViewNet()->getUndoList();
1728 for (const auto& node : nodes) {
1729 GNEJunction* junction = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(node->getID());
1730 undoList->add(new GNEChange_TLS(junction, oldDefinition, false), true);
1731 undoList->add(new GNEChange_TLS(junction, myTLSEditorParent->myEditedDef, true), true);
1732 // synchronize crossing tl-indices in case they were changed (via onCmdCleanStates)
1733 for (const auto& gc : junction->getGNECrossings()) {
1734 NBNode::Crossing* c = gc->getNBCrossing();
1735 if (c) {
1736 gc->setAttribute(SUMO_ATTR_TLLINKINDEX, toString(c->tlLinkIndex), undoList);
1737 gc->setAttribute(SUMO_ATTR_TLLINKINDEX2, toString(c->tlLinkIndex2), undoList);
1738 }
1739 }
1740
1741
1742 }
1743 // end change
1744 myTLSEditorParent->getViewNet()->getUndoList()->end();
1745 // mark as saved
1746 myHaveModifications = false;
1747 // reset myEditedDef (because is already in eine undo-list)
1748 myTLSEditorParent->myEditedDef = nullptr;
1749 myTLSEditorParent->cleanup();
1750 myTLSEditorParent->getViewNet()->updateViewNet();
1751 // edit junction again
1752 myTLSEditorParent->editJunction(currentJunction);
1753 // change program
1754 myProgramComboBox->setCurrentItem(currentProgram, TRUE);
1755 } else {
1756 // discard changes inspecting junction again
1757 discardChanges(true);
1758 }
1759 myTLSEditorParent->updateModules();
1760 return 1;
1761}
1762
1763
1764long
1766 // discard changes inspecting junction again
1767 discardChanges(true);
1768 return 1;
1769}
1770
1771
1772void
1774 // get current TLS program id
1775 const auto currentTLS = getCurrentTLSProgramID();
1776 // check conditions
1777 if (junction == nullptr) {
1778 throw ProcessError("junction cannot be null");
1780 // set junction as TLS
1781 junction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::TRAFFIC_LIGHT), myTLSEditorParent->getViewNet()->getUndoList());
1782 } else if (junction->getNBNode()->isTLControlled()) {
1783 // use existing traffic light as template for type, signal groups, controlled nodes etc
1784 NBTrafficLightDefinition* tpl = nullptr;
1785 for (const auto& TLS : junction->getNBNode()->getControllingTLS()) {
1786 if (TLS->getProgramID() == currentTLS) {
1787 tpl = TLS;
1788 }
1789 }
1790 // if template is empty, use first TLS
1791 if (tpl == nullptr) {
1792 tpl = *junction->getNBNode()->getControllingTLS().begin();
1793 }
1794 // create new logic
1796 // create new TLDef
1797 NBLoadedSUMOTLDef* newDef = new NBLoadedSUMOTLDef(*tpl, *newLogic);
1798 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1799 newDef->setProgramID(tllCont.getNextProgramID(newDef->getID()));
1800 // remove new logic
1801 delete newLogic;
1802 // add it using GNEChange_TLS
1803 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TLF("duplicate program '%' of traffic light '%'", tpl->getProgramID(), tpl->getID()));
1804 for (NBNode* node : newDef->getNodes()) {
1805 GNEJunction* j = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(node->getID());
1806 // not forcing insertion because we already ensured a new id and multiple junctions will attempt insertion
1807 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(j, newDef, true, false), true);
1808 }
1809 myTLSEditorParent->getViewNet()->getUndoList()->end();
1810 } else {
1811 // for some reason the traffic light was not built, try again
1812 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, nullptr, true, true), true);
1813 }
1814}
1815
1816
1817bool
1819 if (myTLSEditorParent->myTLSJunction->getCurrentJunction() == nullptr) {
1820 throw ProcessError("Junction cannot be NULL");
1821 } else {
1822 // reset save flag
1823 myHaveModifications = false;
1824 // get current definition
1825 NBTrafficLightDefinition* tlDef = getCurrentTLSPrograms();
1826 // logic may not have been recomputed yet. recompute to be sure
1827 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1828 // compute junction
1829 myTLSEditorParent->getViewNet()->getNet()->computeJunction(myTLSEditorParent->myTLSJunction->getCurrentJunction());
1830 // obtain TrafficLight logic vinculated with tlDef
1831 NBTrafficLightLogic* tllogic = tllCont.getLogic(tlDef->getID(), tlDef->getProgramID());
1832 // check that tllLogic exist
1833 if (tllogic != nullptr) {
1834 // now we can be sure that the tlDef is up to date (i.e. re-guessed)
1835 myTLSEditorParent->buildInternalLanes(tlDef);
1836 // create working duplicate from original def
1837 delete myTLSEditorParent->myEditedDef;
1838 myTLSEditorParent->myEditedDef = new NBLoadedSUMOTLDef(*tlDef, *tllogic);
1839 // set values
1840 myTLSEditorParent->myTLSAttributes->setOffset(myTLSEditorParent->myEditedDef->getLogic()->getOffset());
1841 myTLSEditorParent->myTLSAttributes->setParameters(myTLSEditorParent->myEditedDef->getLogic()->getParametersStr());
1842 // init phaseTable with the new TLS
1843 myTLSEditorParent->myTLSPhases->initPhaseTable();
1844 } else {
1845 // tlDef has no valid logic (probably because id does not control any links
1846 discardChanges(false);
1847 myTLSEditorParent->getViewNet()->setStatusBarText(TL("Traffic Light does not control any links"));
1848 return false;
1849 }
1850 }
1851 return true;
1852}
1853
1854// ---------------------------------------------------------------------------
1855// GNETLSEditorFrame::TLSPhases - methods
1856// ---------------------------------------------------------------------------
1857
1859 MFXGroupBoxModule(TLSEditorParent, TL("Phases"), MFXGroupBoxModule::Options::COLLAPSIBLE | MFXGroupBoxModule::Options::EXTENSIBLE),
1860 myTLSEditorParent(TLSEditorParent) {
1861 // create GNETLSTable
1862 myPhaseTable = new GNETLSTable(this);
1863 // hide phase table
1864 myPhaseTable->hide();
1865 FXHorizontalFrame* phaseButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
1866 FXVerticalFrame* col1 = new FXVerticalFrame(phaseButtons, GUIDesignAuxiliarHorizontalFrame); // left button columm
1867 FXVerticalFrame* col2 = new FXVerticalFrame(phaseButtons, GUIDesignAuxiliarHorizontalFrame); // right button column
1868 // create cleanup states button
1870 TL("Clean States") + std::string("\t") +
1871 TL("Clean unused states from all phase") + std::string("\t") +
1872 TL("Clean unused states from all phase. (Not allowed for multiple programs)"),
1874 myCleanStatesButton->disable();
1875 // add unused states button
1877 TL("Add States") + std::string("\t") +
1878 TL("Extend the state vector for all phases by one entry") + std::string("\t") +
1879 TL("Extend the state vector for all phases by one entry. (Unused until a connection or crossing is assigned to the new index)"),
1881 myAddStates->disable();
1882 // group states button
1884 TL("Group Sig.") + std::string("\t") +
1885 TL("Shorten state definition by letting connections with the same signal states use the same index") + std::string("\t") +
1886 TL("Shorten state definition by letting connections with the same signal states use the same index. (Not allowed for multiple programs)"),
1888 myGroupSignalsButton->disable();
1889 // ungroup states button
1891 TL("Ungroup Sig.") + std::string("\t") +
1892 TL("Let every connection use a distinct index (reverse state grouping)") + std::string("\t") +
1893 TL("Let every connection use a distinct index (reverse state grouping). (Not allowed for multiple programs)"),
1895 myUngroupSignalsButton->disable();
1896 // show TLSFile
1897 show();
1898}
1899
1900
1903
1904
1905void
1907 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1908 // selecting E1, disable buttons
1909 myPhaseTable->disable();
1910 myCleanStatesButton->disable();
1911 myAddStates->disable();
1912 myGroupSignalsButton->disable();
1913 myUngroupSignalsButton->disable();
1914 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1915 // joining TLSs, disable buttons
1916 myPhaseTable->disable();
1917 myCleanStatesButton->disable();
1918 myAddStates->disable();
1919 myGroupSignalsButton->disable();
1920 myUngroupSignalsButton->disable();
1921 myUngroupSignalsButton->disable();
1922 } else if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 0) {
1923 // no TLSs, disable buttons
1924 myPhaseTable->disable();
1925 myCleanStatesButton->disable();
1926 myAddStates->disable();
1927 myGroupSignalsButton->disable();
1928 myUngroupSignalsButton->disable();
1929 } else if (myTLSEditorParent->myEditedDef == nullptr) {
1930 // no edited definition, disable buttons
1931 myPhaseTable->disable();
1932 myCleanStatesButton->disable();
1933 myAddStates->disable();
1934 myGroupSignalsButton->disable();
1935 myUngroupSignalsButton->disable();
1936 } else {
1937 myPhaseTable->enable();
1938 myCleanStatesButton->enable();
1939 myAddStates->enable();
1940 myGroupSignalsButton->enable();
1941 if (myTLSEditorParent->myEditedDef->usingSignalGroups()) {
1942 myUngroupSignalsButton->enable();
1943 } else {
1944 myUngroupSignalsButton->disable();
1945 }
1946 }
1947}
1948
1949
1950void
1954
1955
1956void
1960
1961
1964 return myTLSEditorParent;
1965}
1966
1967
1970 return myPhaseTable;
1971}
1972
1973
1974void
1976 // first clear table
1977 clearPhaseTable();
1978 if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() > 0) {
1979 if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC) {
1980 initStaticPhaseTable();
1981 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::ACTUATED) {
1982 initActuatedPhaseTable();
1983 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::DELAYBASED) {
1984 initDelayBasePhaseTable();
1985 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA) {
1986 initNEMAPhaseTable();
1987 }
1988 // select first element (by default)
1989 myPhaseTable->selectRow(0);
1990 // recalc width and show
1991 myPhaseTable->recalcTableWidth();
1992 myPhaseTable->show();
1993 } else {
1994 myPhaseTable->hide();
1995 }
1996 update();
1997}
1998
1999
2000void
2002 myPhaseTable->clearTable();
2003}
2004
2005
2006bool
2007GNETLSEditorFrame::TLSPhases::changePhaseValue(const int col, const int row, const std::string& value) {
2008 // Declare columns
2009 int colDuration = 1;
2010 int colState = -1;
2011 int colNext = -1;
2012 int colName = -1;
2013 int colMinDur = -1;
2014 int colMaxDur = -1;
2015 int colEarliestEnd = -1;
2016 int colLatestEnd = -1;
2017 int colVehExt = -1;
2018 int colYellow = -1;
2019 int colRed = -1;
2020 // set columns depending of traffic light type
2021 if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC) {
2022 colState = 2;
2023 colNext = 3;
2024 colName = 4;
2025 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::ACTUATED) {
2026 colMinDur = 2;
2027 colMaxDur = 3;
2028 colState = 4;
2029 colEarliestEnd = 5;
2030 colLatestEnd = 6;
2031 colNext = 7;
2032 colName = 8;
2033 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::DELAYBASED) {
2034 colMinDur = 2;
2035 colMaxDur = 3;
2036 colState = 4;
2037 colNext = 5;
2038 colName = 6;
2039 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA) {
2040 colMinDur = 2;
2041 colMaxDur = 3;
2042 colState = 4;
2043 colVehExt = 5;
2044 colYellow = 6;
2045 colRed = 7;
2046 colNext = 8;
2047 colName = 9;
2048 }
2049 // check column
2050 if (col == colDuration) {
2051 return setDuration(col, row, value);
2052 } else if (col == colState) {
2053 return setState(col, row, value);
2054 } else if (col == colNext) {
2055 return setNext(row, value);
2056 } else if (col == colName) {
2057 return setName(row, value);
2058 } else if (col == colMinDur) {
2059 return setMinDur(row, value);
2060 } else if (col == colMaxDur) {
2061 return setMaxDur(row, value);
2062 } else if (col == colEarliestEnd) {
2063 return setEarliestEnd(row, value);
2064 } else if (col == colLatestEnd) {
2065 return setLatestEnd(row, value);
2066 } else if (col == colVehExt) {
2067 return setVehExt(row, value);
2068 } else if (col == colYellow) {
2069 return setYellow(row, value);
2070 } else if (col == colRed) {
2071 return setRed(row, value);
2072 } else {
2073 throw ProcessError(TL("invalid column"));
2074 }
2075}
2076
2077
2078void
2079GNETLSEditorFrame::TLSPhases::addPhase(const int row, const char c) {
2080 // mark TLS as modified
2081 myTLSEditorParent->myTLSPrograms->markAsModified();
2082 // build default phase
2083 const int newIndex = buildDefaultPhase(row);
2084 // check if override state
2085 switch (c) {
2086 case 'r':
2087 case 'y':
2088 case 'g':
2089 case 'G':
2090 myTLSEditorParent->myEditedDef->getLogic()->overrideState(newIndex, c);
2091 break;
2092 default:
2093 break;
2094 }
2095 // int phase table again
2096 initPhaseTable();
2097 // mark new row as selected
2098 myPhaseTable->selectRow(newIndex);
2099 // set focus in table
2100 getPhaseTable()->setFocus();
2101}
2102
2103
2104void
2106 // mark TLS as modified
2107 myTLSEditorParent->myTLSPrograms->markAsModified();
2108 // build default phase
2109 const int newIndex = buildDefaultPhase(row);
2110 // coply old phase in the new phase
2111 myTLSEditorParent->myEditedDef->getLogic()->copyPhase(row, row + 1);
2112 // int phase table again
2113 initPhaseTable();
2114 // mark new row as selected
2115 myPhaseTable->selectRow(newIndex);
2116 // set focus in table
2117 getPhaseTable()->setFocus();
2118}
2119
2120
2121void
2123 // mark TLS ad modified
2124 myTLSEditorParent->myTLSPrograms->markAsModified();
2125 // calculate new row
2126 const auto newRow = MAX2(0, (row - 1));
2127 // delete selected row
2128 myTLSEditorParent->myEditedDef->getLogic()->deletePhase(row);
2129 // int phase table again
2130 initPhaseTable();
2131 // mark new row as selected
2132 myPhaseTable->selectRow(newRow);
2133 // set focus in table
2134 getPhaseTable()->setFocus();
2135}
2136
2137
2138void
2140 // mark TLS ad modified
2141 myTLSEditorParent->myTLSPrograms->markAsModified();
2142 // delete selected row
2143 if (row == 0) {
2144 myTLSEditorParent->myEditedDef->getLogic()->swapfirstPhase();
2145 } else {
2146 myTLSEditorParent->myEditedDef->getLogic()->swapPhase(row, row - 1);
2147 }
2148 // int phase table again
2149 initPhaseTable();
2150 // mark new row as selected
2151 if (row == 0) {
2152 myPhaseTable->selectRow((int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1);
2153 } else {
2154 myPhaseTable->selectRow(row - 1);
2155 }
2156 // set focus in table
2157 getPhaseTable()->setFocus();
2158}
2159
2160
2161void
2163 // mark TLS ad modified
2164 myTLSEditorParent->myTLSPrograms->markAsModified();
2165 // delete selected row
2166 if (row == (int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1) {
2167 myTLSEditorParent->myEditedDef->getLogic()->swaplastPhase();
2168 } else {
2169 myTLSEditorParent->myEditedDef->getLogic()->swapPhase(row, row + 1);
2170 }
2171 // int phase table again
2172 initPhaseTable();
2173 // mark new row as selected
2174 if (row == (int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1) {
2175 myPhaseTable->selectRow(0);
2176 } else {
2177 myPhaseTable->selectRow(row + 1);
2178 }
2179 // set focus in table
2180 getPhaseTable()->setFocus();
2181}
2182
2183
2184void
2186 // get phase
2187 const auto& phase = myTLSEditorParent->getPhase(myPhaseTable->getCurrentSelectedRow());
2188 // need not hold since links could have been deleted somewhere else and indices may be reused
2189 for (const auto& internalLane : myTLSEditorParent->myInternalLanes) {
2190 int tlIndex = internalLane.first;
2191 std::vector<GNEInternalLane*> lanes = internalLane.second;
2193 if (tlIndex >= 0 && tlIndex < (int)phase.state.size()) {
2194 state = (LinkState)phase.state[tlIndex];
2195 }
2196 for (const auto& lane : lanes) {
2197 lane->setLinkState(state);
2198 }
2199 }
2200 // update view net (for coloring)
2201 myTLSEditorParent->getViewNet()->updateViewNet();
2202}
2203
2204
2205long
2207 if (myTLSEditorParent->myEditedDef->cleanupStates()) {
2208 myTLSEditorParent->myTLSPrograms->markAsModified();
2209 }
2210 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2211 initPhaseTable();
2212 myPhaseTable->setFocus();
2213 myTLSEditorParent->myTLSPrograms->markAsModified();
2214 myTLSEditorParent->updateModules();
2215 return 1;
2216}
2217
2218
2219long
2221 myTLSEditorParent->myEditedDef->getLogic()->setStateLength(myTLSEditorParent->myEditedDef->getLogic()->getNumLinks() + 1);
2222 myTLSEditorParent->myTLSPrograms->markAsModified();
2223 initPhaseTable();
2224 myPhaseTable->setFocus();
2225 myTLSEditorParent->updateModules();
2226 return 1;
2227}
2228
2229
2230long
2232 myTLSEditorParent->myEditedDef->groupSignals();
2233 myTLSEditorParent->myTLSPrograms->markAsModified();
2234 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2235 initPhaseTable();
2236 myPhaseTable->setFocus();
2237 myTLSEditorParent->updateModules();
2238 return 1;
2239}
2240
2241
2242long
2244 myTLSEditorParent->myEditedDef->setParticipantsInformation();
2245 myTLSEditorParent->myEditedDef->ungroupSignals();
2246 myTLSEditorParent->myTLSPrograms->markAsModified();
2247 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2248 initPhaseTable();
2249 myPhaseTable->setFocus();
2250 myTLSEditorParent->updateModules();
2251 return 1;
2252}
2253
2254
2255void
2257 // declare constants for columns
2258 const int colDuration = 1;
2259 const int colState = 2;
2260 const int colNext = 3;
2261 const int colName = 4;
2262 // get phases
2263 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2264 // adjust table
2265 myPhaseTable->setTableSize("sup-midtb", (int)phases.size());
2266 // fill rows
2267 for (int row = 0; row < (int)phases.size(); row++) {
2268 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2269 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2270 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2271 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2272 }
2273 // set columns
2274 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2275 myPhaseTable->setColumnLabelTop(colState, "state");
2276 myPhaseTable->setColumnLabelTop(colNext, "next");
2277 myPhaseTable->setColumnLabelTop(colName, "name");
2278 // set bot labels
2279 updateCycleDuration(colDuration);
2280 updateStateSize(colState);
2281 // set focus
2282 myPhaseTable->setFocus();
2283}
2284
2285
2286void
2288 // declare constants for columns
2289 const int colDuration = 1;
2290 const int colMinDur = 2;
2291 const int colMaxDur = 3;
2292 const int colState = 4;
2293 const int colEarliestEnd = 5;
2294 const int colLatestEnd = 6;
2295 const int colNext = 7;
2296 const int colName = 8;
2297 // get phases
2298 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2299 // adjust table
2300 myPhaseTable->setTableSize("suffpff-midtb", (int)phases.size());
2301 // fill rows
2302 for (int row = 0; row < (int)phases.size(); row++) {
2303 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2304 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2305 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2306 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2307 myPhaseTable->setItemText(row, colEarliestEnd, varDurString(phases.at(row).earliestEnd).c_str());
2308 myPhaseTable->setItemText(row, colLatestEnd, varDurString(phases.at(row).latestEnd).c_str());
2309 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2310 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2311 }
2312 // set columns
2313 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2314 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2315 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2316 myPhaseTable->setColumnLabelTop(colEarliestEnd, "ear.end", "earlyEnd");
2317 myPhaseTable->setColumnLabelTop(colLatestEnd, "lat.end", "latestEnd");
2318 myPhaseTable->setColumnLabelTop(colState, "state");
2319 myPhaseTable->setColumnLabelTop(colNext, "next");
2320 myPhaseTable->setColumnLabelTop(colName, "name");
2321 // set bot labels
2322 updateCycleDuration(colDuration);
2323 updateStateSize(colState);
2324 // set focus
2325 myPhaseTable->setFocus();
2326}
2327
2328
2329void
2331 // declare constants for columns
2332 const int colDuration = 1;
2333 const int colMinDur = 2;
2334 const int colMaxDur = 3;
2335 const int colState = 4;
2336 const int colNext = 5;
2337 const int colName = 6;
2338 // get phases
2339 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2340 // adjust table
2341 myPhaseTable->setTableSize("suffp-midtb", (int)phases.size());
2342 // fill rows
2343 for (int row = 0; row < (int)phases.size(); row++) {
2344 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2345 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2346 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2347 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2348 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2349 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2350 }
2351 // set columns
2352 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2353 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2354 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2355 myPhaseTable->setColumnLabelTop(colState, "state");
2356 myPhaseTable->setColumnLabelTop(colNext, "next");
2357 myPhaseTable->setColumnLabelTop(colName, "name");
2358 // set bot labels
2359 updateCycleDuration(colDuration);
2360 updateStateSize(colState);
2361 // set focus
2362 myPhaseTable->setFocus();
2363}
2364
2365
2366void
2368 // declare constants for columns
2369 const int colDuration = 1;
2370 const int colMinDur = 2;
2371 const int colMaxDur = 3;
2372 const int colState = 4;
2373 const int colVehExt = 5;
2374 const int colYellow = 6;
2375 const int colRed = 7;
2376 const int colNext = 8;
2377 const int colName = 9;
2378 // get phases
2379 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2380 // adjust table
2381 myPhaseTable->setTableSize("suffpfff-midtb", (int)phases.size());
2382 // fill rows
2383 for (int row = 0; row < (int)phases.size(); row++) {
2384 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2385 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2386 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2387 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2388 myPhaseTable->setItemText(row, colVehExt, varDurString(phases.at(row).vehExt).c_str());
2389 myPhaseTable->setItemText(row, colYellow, varDurString(phases.at(row).yellow).c_str());
2390 myPhaseTable->setItemText(row, colRed, varDurString(phases.at(row).red).c_str());
2391 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2392 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2393 }
2394 // set columns
2395 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2396 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2397 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2398 myPhaseTable->setColumnLabelTop(colState, "state");
2399 myPhaseTable->setColumnLabelTop(colVehExt, "vehExt", "vehicle extension");
2400 myPhaseTable->setColumnLabelTop(colYellow, "yellow");
2401 myPhaseTable->setColumnLabelTop(colRed, "red");
2402 myPhaseTable->setColumnLabelTop(colNext, "next");
2403 myPhaseTable->setColumnLabelTop(colName, "name");
2404 // set bot labels
2405 updateCycleDuration(colDuration);
2406 updateStateSize(colState);
2407 // set focus
2408 myPhaseTable->setFocus();
2409}
2410
2411
2412int
2414 // get option container
2415 const auto& neteditOptions = OptionsCont::getOptions();
2416 // check if TLS is static
2417 const bool TLSStatic = (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC);
2418 const bool NEMA = (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA);
2419 // calculate new index
2420 const int newIndex = row + 1;
2421 // duplicate current row
2422 auto duration = getSUMOTime(myPhaseTable->getItemText(row, 1));
2423 const auto oldState = myPhaseTable->getItemText(row, TLSStatic ? 2 : 4);
2424 auto state = oldState;
2425 // update crossingINdices
2426 std::set<int> crossingIndices;
2427 for (const auto& node : myTLSEditorParent->myEditedDef->getNodes()) {
2428 for (const auto& crossing : node->getCrossings()) {
2429 crossingIndices.insert(crossing->tlLinkIndex);
2430 crossingIndices.insert(crossing->tlLinkIndex2);
2431 }
2432 }
2433 // smart adapations for new state
2434 bool haveGreen = false;
2435 bool haveYellow = false;
2436 for (const auto& linkStateChar : state) {
2437 if ((linkStateChar == LINKSTATE_TL_GREEN_MAJOR) || (linkStateChar == LINKSTATE_TL_GREEN_MINOR)) {
2438 haveGreen = true;
2439 } else if ((linkStateChar == LINKSTATE_TL_YELLOW_MAJOR) || (linkStateChar == LINKSTATE_TL_YELLOW_MINOR)) {
2440 haveYellow = true;
2441 }
2442 }
2443 if (haveGreen && haveYellow) {
2444 // guess left-mover state
2445 duration = TIME2STEPS(neteditOptions.getInt("tls.left-green.time"));
2446 for (int i = 0; i < (int)state.size(); i++) {
2447 if ((state[i] == LINKSTATE_TL_YELLOW_MAJOR) || (state[i] == LINKSTATE_TL_YELLOW_MINOR)) {
2448 state[i] = LINKSTATE_TL_RED;
2449 } else if (state[i] == LINKSTATE_TL_GREEN_MINOR) {
2450 state[i] = LINKSTATE_TL_GREEN_MAJOR;
2451 }
2452 }
2453 } else if (haveGreen) {
2454 // guess yellow state
2455 myTLSEditorParent->myEditedDef->setParticipantsInformation();
2456 duration = TIME2STEPS(myTLSEditorParent->myEditedDef->computeBrakingTime(neteditOptions.getFloat("tls.yellow.min-decel")));
2457 for (int i = 0; i < (int)state.size(); i++) {
2458 if ((state[i] == LINKSTATE_TL_GREEN_MAJOR) || (state[i] == LINKSTATE_TL_GREEN_MINOR)) {
2459 if (crossingIndices.count(i) == 0) {
2460 state[i] = LINKSTATE_TL_YELLOW_MINOR;
2461 } else {
2462 state[i] = LINKSTATE_TL_RED;
2463 }
2464 }
2465 }
2466 } else if (haveYellow) {
2467 duration = TIME2STEPS(neteditOptions.isDefault("tls.allred.time") ? 2 : neteditOptions.getInt("tls.allred.time"));
2468 // guess all-red state
2469 for (int i = 0; i < (int)state.size(); i++) {
2470 if ((state[i] == LINKSTATE_TL_YELLOW_MAJOR) || (state[i] == LINKSTATE_TL_YELLOW_MINOR)) {
2471 state[i] = LINKSTATE_TL_RED;
2472 }
2473 }
2474 }
2475 // fix continuous green states
2476 const int nextIndex = (myPhaseTable->getNumRows() > newIndex) ? newIndex : 0;
2477 const std::string state2 = myPhaseTable->getItemText(nextIndex, (TLSStatic ? 2 : 4));
2478 for (int i = 0; i < (int)state.size(); i++) {
2479 if (((oldState[i] == LINKSTATE_TL_GREEN_MAJOR) || (oldState[i] == LINKSTATE_TL_GREEN_MINOR)) &&
2480 ((state2[i] == LINKSTATE_TL_GREEN_MAJOR) || (state2[i] == LINKSTATE_TL_GREEN_MINOR))) {
2481 state[i] = oldState[i];
2482 }
2483 }
2484 // add new step
2485 if (NEMA) {
2486 myTLSEditorParent->myEditedDef->getLogic()->addStep(string2time("90"), state, string2time("5"), string2time("50"),
2488 string2time("2"), string2time("3"), string2time("2"), "1", std::vector<int>(), newIndex);
2489 } else {
2490 myTLSEditorParent->myEditedDef->getLogic()->addStep(duration, state, std::vector<int>(), "", newIndex);
2491 }
2492 // return new index
2493 return newIndex;
2494}
2495
2496
2497bool
2498GNETLSEditorFrame::TLSPhases::setDuration(const int col, const int row, const std::string& value) {
2499 // check value
2500 if (value.empty()) {
2501 // input empty, reset
2502 getPhaseTable()->setItemText(row, col, getSteps2Time(myTLSEditorParent->getPhase(row).duration).c_str());
2503 return true;
2504 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2505 const auto duration = getSUMOTime(value);
2506 // check that duration > 0
2507 if (duration > 0) {
2508 myTLSEditorParent->myEditedDef->getLogic()->setPhaseDuration(row, duration);
2509 myTLSEditorParent->myTLSPrograms->markAsModified();
2510 // update Cycle duration
2511 updateCycleDuration(col);
2512 return true;
2513 } else {
2514 return false;
2515 }
2516 } else {
2517 return false;
2518 }
2519}
2520
2521
2522bool
2523GNETLSEditorFrame::TLSPhases::setState(const int col, const int row, const std::string& value) {
2524 // get state
2525 const auto& phase = myTLSEditorParent->getPhase(row);
2526 // declare new state. If value is empty, use previous value (reset)
2527 const auto newState = value.empty() ? phase.state : value;
2528 // insert phase
2529 try {
2530 myTLSEditorParent->myEditedDef->getLogic()->addStep(phase.duration, newState, phase.next, phase.name, row);
2531 } catch (ProcessError&) {
2532 // invalid character in newState
2533 return false;
2534 }
2535 // delete next phase
2536 try {
2537 myTLSEditorParent->myEditedDef->getLogic()->deletePhase(row + 1);
2538 } catch (InvalidArgument&) {
2539 WRITE_ERROR(TL("Error deleting phase '") + toString(row + 1) + "'");
2540 return false;
2541 }
2542 // mark TLS as modified depending of value
2543 if (value.size() > 0) {
2544 myTLSEditorParent->myTLSPrograms->markAsModified();
2545 // select row
2546 myPhaseTable->selectRow(row);
2547 } else {
2548 // input empty, reset
2549 getPhaseTable()->setItemText(row, col, newState);
2550 }
2551 // update state size
2552 updateStateSize(col);
2553 return true;
2554}
2555
2556
2557bool
2558GNETLSEditorFrame::TLSPhases::setNext(const int row, const std::string& value) {
2559 // check next
2560 if (GNEAttributeCarrier::canParse<std::vector<int> >(value)) {
2561 const auto nextEdited = GNEAttributeCarrier::parse<std::vector<int> >(value);
2562 for (const auto nextPhase : nextEdited) {
2563 if ((nextPhase < 0) || (nextPhase >= myPhaseTable->getNumRows())) {
2564 return false;
2565 }
2566 }
2567 // set new next
2568 myTLSEditorParent->myEditedDef->getLogic()->setPhaseNext(row, nextEdited);
2569 myTLSEditorParent->myTLSPrograms->markAsModified();
2570 return true;
2571 } else {
2572 return false;
2573 }
2574}
2575
2576
2577bool
2578GNETLSEditorFrame::TLSPhases::setName(const int row, const std::string& value) {
2579 // update name (currently no check needed)
2580 myTLSEditorParent->myEditedDef->getLogic()->setPhaseName(row, value);
2581 myTLSEditorParent->myTLSPrograms->markAsModified();
2582 return true;
2583}
2584
2585
2586bool
2587GNETLSEditorFrame::TLSPhases::setMinDur(const int row, const std::string& value) {
2588 // check value
2589 if (value.empty()) {
2590 // set empty value
2591 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2592 myTLSEditorParent->myTLSPrograms->markAsModified();
2593 return true;
2594 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2595 const auto minDur = getSUMOTime(value);
2596 // check that minDur > 0
2597 if (minDur > 0) {
2598 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, minDur);
2599 myTLSEditorParent->myTLSPrograms->markAsModified();
2600 return true;
2601 } else {
2602 return false;
2603 }
2604 } else if (StringUtils::prune(value).empty()) {
2605 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2606 myTLSEditorParent->myTLSPrograms->markAsModified();
2607 return true;
2608 } else {
2609 return false;
2610 }
2611}
2612
2613
2614bool
2615GNETLSEditorFrame::TLSPhases::setMaxDur(const int row, const std::string& value) {
2616 // check value
2617 if (value.empty()) {
2618 // set empty value
2619 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2620 myTLSEditorParent->myTLSPrograms->markAsModified();
2621 return true;
2622 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2623 const auto maxDur = getSUMOTime(value);
2624 // check that minDur > 0
2625 if (maxDur > 0) {
2626 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, maxDur);
2627 myTLSEditorParent->myTLSPrograms->markAsModified();
2628 return true;
2629 } else {
2630 return false;
2631 }
2632 } else if (StringUtils::prune(value).empty()) {
2633 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2634 myTLSEditorParent->myTLSPrograms->markAsModified();
2635 return true;
2636 } else {
2637 return false;
2638 }
2639}
2640
2641
2642bool
2643GNETLSEditorFrame::TLSPhases::setEarliestEnd(const int row, const std::string& value) {
2644 // check value
2645 if (value.empty()) {
2646 // set empty value
2647 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2648 myTLSEditorParent->myTLSPrograms->markAsModified();
2649 return true;
2650 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2651 const auto earliestEnd = getSUMOTime(value);
2652 // check that earliestEnd > 0
2653 if (earliestEnd > 0) {
2654 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, earliestEnd);
2655 myTLSEditorParent->myTLSPrograms->markAsModified();
2656 return true;
2657 } else {
2658 return false;
2659 }
2660 } else if (StringUtils::prune(value).empty()) {
2661 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2662 myTLSEditorParent->myTLSPrograms->markAsModified();
2663 return true;
2664 } else {
2665 return false;
2666 }
2667}
2668
2669
2670bool
2671GNETLSEditorFrame::TLSPhases::setLatestEnd(const int row, const std::string& value) {
2672 // check value
2673 if (value.empty()) {
2674 // set empty value
2675 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2676 myTLSEditorParent->myTLSPrograms->markAsModified();
2677 return true;
2678 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2679 const auto latestEnd = getSUMOTime(value);
2680 // check that latestEnd > 0
2681 if (latestEnd > 0) {
2682 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, latestEnd);
2683 myTLSEditorParent->myTLSPrograms->markAsModified();
2684 return true;
2685 } else {
2686 return false;
2687 }
2688 } else if (StringUtils::prune(value).empty()) {
2689 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2690 myTLSEditorParent->myTLSPrograms->markAsModified();
2691 return true;
2692 } else {
2693 return false;
2694 }
2695}
2696
2697
2698bool
2699GNETLSEditorFrame::TLSPhases::setVehExt(const int row, const std::string& value) {
2700 // check value
2701 if (value.empty()) {
2702 // set empty value
2703 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2704 myTLSEditorParent->myTLSPrograms->markAsModified();
2705 return true;
2706 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2707 const auto vehExt = getSUMOTime(value);
2708 // check that vehExt > 0
2709 if (vehExt > 0) {
2710 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, vehExt);
2711 myTLSEditorParent->myTLSPrograms->markAsModified();
2712 return true;
2713 } else {
2714 return false;
2715 }
2716 } else if (StringUtils::prune(value).empty()) {
2717 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2718 myTLSEditorParent->myTLSPrograms->markAsModified();
2719 return true;
2720 } else {
2721 return false;
2722 }
2723}
2724
2725
2726bool
2727GNETLSEditorFrame::TLSPhases::setYellow(const int row, const std::string& value) {
2728 // check value
2729 if (value.empty()) {
2730 // set empty value
2731 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2732 myTLSEditorParent->myTLSPrograms->markAsModified();
2733 return true;
2734 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2735 const auto yellow = getSUMOTime(value);
2736 // check that yellow > 0
2737 if (yellow > 0) {
2738 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, yellow);
2739 myTLSEditorParent->myTLSPrograms->markAsModified();
2740 return true;
2741 } else {
2742 return false;
2743 }
2744 } else if (StringUtils::prune(value).empty()) {
2745 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2746 myTLSEditorParent->myTLSPrograms->markAsModified();
2747 return true;
2748 } else {
2749 return false;
2750 }
2751}
2752
2753
2754bool
2755GNETLSEditorFrame::TLSPhases::setRed(const int row, const std::string& value) {
2756 // check value
2757 if (value.empty()) {
2758 // set empty value
2759 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2760 myTLSEditorParent->myTLSPrograms->markAsModified();
2761 return true;
2762 } else if (GNEAttributeCarrier::canParse<double>(value)) {
2763 const auto red = getSUMOTime(value);
2764 // check that red > 0
2765 if (red > 0) {
2766 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, red);
2767 myTLSEditorParent->myTLSPrograms->markAsModified();
2768 return true;
2769 } else {
2770 return false;
2771 }
2772 } else if (StringUtils::prune(value).empty()) {
2773 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2774 myTLSEditorParent->myTLSPrograms->markAsModified();
2775 return true;
2776 } else {
2777 return false;
2778 }
2779}
2780
2781
2782void
2784 SUMOTime cycleDuration = 0;
2785 for (const auto& phase : myTLSEditorParent->myEditedDef->getLogic()->getPhases()) {
2786 cycleDuration += phase.duration;
2787 }
2788 // update bot label with cycle duration
2789 myPhaseTable->setColumnLabelBot(col, getSteps2Time(cycleDuration));
2790}
2791
2792
2793void
2795 // update bot label with number of links
2796 myPhaseTable->setColumnLabelBot(col, "Links: " + toString(myTLSEditorParent->myEditedDef->getLogic()->getNumLinks()));
2797}
2798
2799// ---------------------------------------------------------------------------
2800// GNETLSEditorFrame::TLSFile - methods
2801// ---------------------------------------------------------------------------
2802
2804 MFXGroupBoxModule(TLSEditorParent, TL("TLS Program File")),
2805 myTLSEditorParent(TLSEditorParent) {
2806 FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
2807 // create create tlDef button
2808 myLoadButton = GUIDesigns::buildFXButton(buttonsFrame, TL("Load"), "", TL("Load TLS program from additional file"), GUIIconSubSys::getIcon(GUIIcon::OPEN), this, MID_GNE_TLSFRAME_FILE_LOADPROGRAM, GUIDesignButton);
2809 myLoadButton->disable();
2810 // create create tlDef button
2811 mySaveButton = GUIDesigns::buildFXButton(buttonsFrame, TL("Save"), "", TL("Save TLS program to additional file"), GUIIconSubSys::getIcon(GUIIcon::SAVE), this, MID_GNE_TLSFRAME_FILE_SAVEPROGRAM, GUIDesignButton);
2812 mySaveButton->disable();
2813 // show TLSFile
2814 show();
2815}
2816
2817
2819
2820
2821void
2823 if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 0) {
2824 myLoadButton->disable();
2825 mySaveButton->disable();
2826 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2827 // selecting E1, disable buttons
2828 myLoadButton->disable();
2829 mySaveButton->disable();
2830 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2831 // joining TLSs, disable button
2832 myLoadButton->disable();
2833 mySaveButton->disable();
2834 } else {
2835 myLoadButton->enable();
2836 mySaveButton->enable();
2837 }
2838}
2839
2840
2841void
2845
2846
2847void
2851
2852
2853long
2855 FXFileDialog opendialog(getCollapsableFrame(), "Load TLS Program");
2856 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::MODETLS));
2857 opendialog.setSelectMode(SELECTFILE_EXISTING);
2858 opendialog.setPatternList(SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str());
2859 if (gCurrentFolder.length() != 0) {
2860 opendialog.setDirectory(gCurrentFolder);
2861 }
2862 if (opendialog.execute()) {
2863 // run parser
2864 NBTrafficLightLogicCont tmpTLLCont;
2865 NIXMLTrafficLightsHandler tllHandler(tmpTLLCont, myTLSEditorParent->getViewNet()->getNet()->getEdgeCont(), true);
2866 tmpTLLCont.insert(myTLSEditorParent->myEditedDef);
2867 XMLSubSys::runParser(tllHandler, opendialog.getFilename().text());
2868
2869 NBLoadedSUMOTLDef* newDefSameProgram = nullptr;
2870 std::set<NBLoadedSUMOTLDef*> newDefsOtherProgram;
2871 for (auto item : tmpTLLCont.getPrograms(myTLSEditorParent->myEditedDef->getID())) {
2872 if (item.second != myTLSEditorParent->myEditedDef) {
2873 NBLoadedSUMOTLDef* sdef = dynamic_cast<NBLoadedSUMOTLDef*>(item.second);
2874 if (item.first == myTLSEditorParent->myEditedDef->getProgramID()) {
2875 newDefSameProgram = sdef;
2876 } else {
2877 newDefsOtherProgram.insert(sdef);
2878 }
2879 }
2880 }
2881 const int newPrograms = (int)newDefsOtherProgram.size();
2882 if (newPrograms > 0 || newDefSameProgram != nullptr) {
2883 std::vector<NBNode*> nodes = myTLSEditorParent->myEditedDef->getNodes();
2884 for (auto newProg : newDefsOtherProgram) {
2885 for (auto it_node : nodes) {
2886 GNEJunction* junction = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
2887 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, newProg, true), true);
2888 }
2889 }
2890 if (newPrograms > 0) {
2891 WRITE_MESSAGE(TL("Loaded ") + toString(newPrograms) + TL(" new programs for tlLogic '") + myTLSEditorParent->myEditedDef->getID() + "'");
2892 }
2893 if (newDefSameProgram != nullptr) {
2894 // replace old program when loading the same program ID
2895 myTLSEditorParent->myEditedDef = newDefSameProgram;
2896 WRITE_MESSAGE(TL("Updated program '") + newDefSameProgram->getProgramID() + TL("' for tlLogic '") + myTLSEditorParent->myEditedDef->getID() + "'");
2897 }
2898 } else {
2899 if (tllHandler.getSeenIDs().count(myTLSEditorParent->myEditedDef->getID()) == 0) {
2900 myTLSEditorParent->getViewNet()->setStatusBarText(TL("No programs found for traffic light '") + myTLSEditorParent->myEditedDef->getID() + "'");
2901 }
2902 }
2903
2904 // clean up temporary container to avoid deletion of defs when its destruct is called
2905 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
2906 tmpTLLCont.removeProgram(def->getID(), def->getProgramID(), false);
2907 }
2908
2909 myTLSEditorParent->myTLSPhases->initPhaseTable();
2910 myTLSEditorParent->myTLSPrograms->markAsModified();
2911 }
2912 myTLSEditorParent->updateModules();
2913 return 0;
2914}
2915
2916
2917long
2919 FXString file = MFXUtils::getFilename2Write(this, TL("Save TLS Program as"),
2920 SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str(),
2922 // check file
2923 if (file != "") {
2924 // add xml extension
2925 file = FileHelpers::addExtension(file.text(), ".xml").c_str();
2926 OutputDevice& device = OutputDevice::getDevice(file.text());
2927 // save program
2928 device.writeXMLHeader("additional", "additional_file.xsd");
2929 NWWriter_SUMO::writeTrafficLight(device, myTLSEditorParent->myEditedDef->getLogic());
2930 device.close();
2931 }
2932 myTLSEditorParent->updateModules();
2933 return 1;
2934}
2935
2936
2937std::string
2939 const double time = STEPS2TIME(steps);
2940 if (time == std::floor(time)) {
2941 return toString(int(time));
2942 } else {
2943 return toString(time);
2944 }
2945}
2946
2947/****************************************************************************/
FXDEFMAP(GNETLSEditorFrame::TLSJunction) TLSJunctionMap[]
long long int SUMOTime
Definition GUI.h:36
@ MID_GNE_TLSFRAME_TLSJUNCTION_DISJOIN
Disjoin TLS.
@ MID_GNE_TLSFRAME_DEFINITION_RESETCURRENT
reset current (single) TLS program
@ MID_GNE_TLSFRAME_PHASES_ADDUNUSED
add unused states
@ MID_GNE_TLSFRAME_ATTRIBUTES_TOGGLEDETECTOR
set detectors in TLS
@ MID_GNE_TLSFRAME_TLSJUNCTION_TOGGLEJOIN
join TLS
@ MID_GNE_TLSFRAME_PHASES_CLEANUP
cleanup unused states
@ MID_GNE_TLSFRAME_PHASES_GROUPSTATES
group states
@ MID_GNE_BUTTON_CANCEL
cancel button
@ MID_GNE_TLSFRAME_DEFINITION_DELETE
delete TLS
@ MID_GNE_TLSFRAME_FILE_SAVEPROGRAM
cleanup unused states
@ MID_GNE_TLSFRAME_PHASES_UNGROUPSTATES
ungroup states
@ MID_GNE_TLSFRAME_DEFINITION_CREATE
Create TLS.
@ MID_GNE_TLSFRAME_DEFINITION_SAVE
accept TLS modification
@ MID_GNE_TLSFRAME_DEFINITION_SWITCHPROGRAM
switch between programs
@ MID_GNE_TLSFRAME_DEFINITION_DISCARD
cancel TLS modification
@ MID_GNE_TLSFRAME_DEFINITION_RESETALL
reset all TLS programs
@ MID_GNE_TLSFRAME_TLSJUNCTION_TYPE
current TLS ID
@ MID_GNE_TLSFRAME_TLSJUNCTION_ID
current TLS ID
@ MID_GNE_BUTTON_ACCEPT
accept button
@ MID_GNE_TLSFRAME_ATTRIBUTES_OFFSET
TLS offset.
@ MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERSDIALOG
TLS parameters.
@ MID_GNE_TLSFRAME_FILE_LOADPROGRAM
Load Program.
@ MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERS
TLS parameters.
#define GUIDesignButtonAttribute
button extended over over column with thick and raise frame
Definition GUIDesigns.h:88
#define GUIDesignButton
Definition GUIDesigns.h:82
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition GUIDesigns.h:302
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition GUIDesigns.h:311
#define GUIDesignTextField
Definition GUIDesigns.h:59
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:399
#define GUIDesignAuxiliarHorizontalFrameUniform
design for auxiliar (Without borders) horizontal frame used to pack another frames uniform
Definition GUIDesigns.h:405
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition GUIDesigns.h:74
#define GUIDesignComboBoxVisibleItems
Definition GUIDesigns.h:49
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:252
FXString gCurrentFolder
The folder used as last.
@ OPEN
open icons
@ SAVE
save icons
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:289
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define TL(string)
Definition MsgHandler.h:305
#define TLF(string,...)
Definition MsgHandler.h:307
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define TIME2STEPS(x)
Definition SUMOTime.h:57
@ 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_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ 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_PROGRAMID
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
const unsigned char TLS[]
Definition TLS.cpp:22
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.
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * getNet() const
get pointer to net
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:155
GNEViewNet * myViewNet
FOX need this.
Definition GNEFrame.h:121
virtual void show()
show Frame
Definition GNEFrame.cpp:120
virtual void hide()
hide Frame
Definition GNEFrame.cpp:129
const GNEHierarchicalContainerChildren< GNELane * > & getChildLanes() const
get child lanes
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.
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
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)
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
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:202
void deleteInternalLane(GNEInternalLane *internalLane)
delete internalLane from container
void insertInternalLane(GNEInternalLane *internalLane)
insert internalLane in container
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
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition GNENet.cpp:2201
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:147
NBEdgeCont & getEdgeCont()
returns the NBEdgeCont of the underlying netbuilder
Definition GNENet.cpp:2207
void clearOverlappedInspection()
clear overlapped inspection
GNEAttributeCarrier * getCurrentAC() const
get current AC
void hiderOverlappedInspection()
hide overlapped inspection
void showOverlappedInspection(GNEViewNetHelper::ViewObjectsSelector &viewObjects, const Position &clickedPosition, const bool shiftKeyPressed)
show overlapped inspection
int getNumberOfOverlappedACs() const
get number of overlapped ACs
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.
MFXToggleButtonTooltip * mySetDetectorsToggleButton
toggle button for set detectors mode
bool isSetDetectorsToggleButtonEnabled() const
toggle button for set detectors mode
bool isValidParameters()
are current parameter valid
void updateTLSAttributes()
update TLSAttributes module
FXTextField * myOffsetTextField
the TextField for modifying offset
void disableE1DetectorMode()
disable detector mode
SUMOTime getOffset() const
get current offset in string format
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
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 updateTLSFile()
update TLSFile module
FXButton * myLoadButton
load button
FXButton * mySaveButton
save button
long onCmdLoadTLSProgram(FXObject *, FXSelector, void *)
load TLS Program from an additional file
TLSFile(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
std::string writeSUMOTime(SUMOTime steps)
FOX needs this.
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.
void refreshTLSJunction()
FOX needs this.
FXHorizontalFrame * myJoinControlButtons
frame for accept/cancel buttons
const std::vector< std::string > & getSelectedJunctionIDs() const
get selected junction IDs
long onCmdToggleJoinTLS(FXObject *, FXSelector, void *)
Called when the user join TLS.
long onCmdRenameTLS(FXObject *, FXSelector, void *)
TLSJunction(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
long onCmdCancelJoin(FXObject *, FXSelector, void *)
cancel join
MFXComboBoxIcon * myTLSTypeComboBox
ComboBox for TLS Types.
MFXToggleButtonTooltip * myJoinTLSToggleButton
Toggle button for join TLS.
void updateTLSJunction()
update TLSJunction module
void toggleJunctionSelected(const GNEJunction *junction)
select or unselect junction in the current TLS
long onCmdAcceptJoin(FXObject *, FXSelector, void *)
accept join
GNEJunction * getCurrentJunction() const
get current modified junction
void setCurrentJunction(GNEJunction *junction)
set current junction
FXLabel * myJunctionIDLabel
label for junction ID
bool isJunctionSelected(const GNEJunction *junction) const
check if given junction is selected (used fo joining)
MFXButtonTooltip * myDisjoinTLSButton
button for disjoin TLS
bool isJoiningJunctions() const
is joining junctions
MFXTextFieldTooltip * myTLSIDTextField
text field for junction ID
MFXTextFieldTooltip * myJunctionIDTextField
text field for junction ID
bool setEarliestEnd(const int row, const std::string &value)
set earliestEnd
long onCmdUngroupStates(FXObject *, FXSelector, void *)
Called when the user ungroups states.
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.
void clearPhaseTable()
clear phase thable
MFXButtonTooltip * myGroupSignalsButton
group signals button
bool setVehExt(const int row, const std::string &value)
set vehExt
MFXButtonTooltip * myAddStates
add states button
int buildDefaultPhase(const int row)
build default phase
void updateTLSPhases()
update TLSPhases module
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.)
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
MFXButtonTooltip * myCleanStatesButton
clean states button
void updateStateSize(const int col)
update state size
MFXButtonTooltip * myUngroupSignalsButton
ungroup signals button
long onCmdAddUnusedStates(FXObject *, FXSelector, void *)
Called when the user cleans up states.
void initStaticPhaseTable()
init static phase table
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
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
void duplicatePhase(const int row)
duplicate phase
void addPhase(const int row, const char c=' ')
add phase
GNETLSEditorFrame * getTLSEditorParent() const
get TLSEditor Parent
bool setNext(const int row, const std::string &value)
set next
void updateCycleDuration(const int col)
recomputes cycle duration and updates label
bool checkHaveModifications() const
check if current TLS was modified
FXButton * mySaveButon
button for save TLS program
void updateTLSPrograms()
update TLSPrograms module
bool initTLSPrograms()
init TLS Definitions
long onCmdDefSwitchTLSProgram(FXObject *, FXSelector, void *)
Called when the user switches a TLS.
MFXComboBoxIcon * myProgramComboBox
the comboBox for selecting the tl-definition to edit
FXButton * myCancelButon
button for cancel TLS program
void clearTLSProgramss()
clear TLS Definitions
int getNumberOfPrograms() const
get number of programs
long onCmdSaveChanges(FXObject *, FXSelector, void *)
Called when the user presses the save-Button.
void hideTLSPrograms()
hide TLSPrograms
void createTLS(GNEJunction *junction)
FOX needs this.
FXButton * myDeleteButton
button for delete existent TLS program
long onCmdDiscardChanges(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button.
void discardChanges(const bool editJunctionAgain)
discard changes
long onCmdCreate(FXObject *, FXSelector, void *)
FXButton * myResetAllButton
button for reset all TLS program
long onCmdResetAll(FXObject *, FXSelector, void *)
Called when the user press button reset all TLS Programs.
FXButton * myResetSingleButton
button for reset TLS program
long onCmdResetCurrentProgram(FXObject *, FXSelector, void *)
Called when the user press button reset current TLS Program.
NBTrafficLightDefinition * getCurrentTLSPrograms() const
get current definition
TLSPrograms(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
void showTLSPrograms()
show TLSPrograms
void markAsModified()
mark Program as modified
long onCmdDelete(FXObject *, FXSelector, void *)
Called when the user press button delete TLS Program.
const std::string getCurrentTLSProgramID() const
get current program ID
FXButton * myCreateButton
button for create new TLS program
GNETLSEditorFrame::TLSPrograms * myTLSPrograms
module for TLS Definition
void handleChange(GNEInternalLane *lane)
update phase definition for the current traffic light and phase
GNEOverlappedInspection * myOverlappedInspection
Overlapped Inspection.
GNETLSEditorFrame::TLSPhases * getTLSPhases() const
get module for TLS Phases
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 to the current junction indexed by their tl-index
void updateModules()
update modules
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::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
void editTLS(GNEViewNetHelper::ViewObjectsSelector &viewObjects, const Position &clickedPosition, const bool shiftKeyPressed)
edits the traffic light for the given clicked junction
GNETLSEditorFrame::TLSJunction * myTLSJunction
module for TLS Junction
GNETLSEditorFrame::TLSPrograms * getTLSPrograms() const
get module for TLS Definition
void cleanup()
cleans up previous lanes
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
const std::vector< GNEJunction * > & getJunctions() const
get vector with junctions
GNENet * getNet() const
get the net object
bool changeAllPhases() const
change all phases
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
void setStatusBarText(const std::string &text)
set statusBar text
A single child window which contains a view of the simulation area.
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXStaticToolTip * getStaticTooltipMenu() const
get static toolTip for menus
void disable()
Disable combo box.
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
FXuint openModalDialog(InternalTest *internalTests, FXuint placement=PLACEMENT_CURSOR)
Run modal invocation of the dialog.
MFXGroupBoxModule (based on FXGroupBox)
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
void setText(const std::string &text)
set text
Options
GroupBoxModule options.
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:116
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition MFXUtils.cpp:145
A loaded (complete) traffic light logic.
NBTrafficLightLogic * getLogic()
Returns the internal logic.
void setProgramID(const std::string &programID)
Sets the programID.
A definition of a pedestrian crossing.
Definition NBNode.h:135
int tlLinkIndex
the traffic light index of this crossing (if controlled)
Definition NBNode.h:162
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:340
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:331
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.
NBTrafficLightLogic * compute(const OptionsCont &oc)
Computes the traffic light logic.
SUMOTime getOffset()
Returns the offset.
const NBConnectionVector & getControlledLinks() const
returns the controlled links (depends on previous call to collectLinks)
static const SUMOTime UNSPECIFIED_DURATION
The definition of a single phase of the logic.
A container for traffic light definitions and built programs.
bool exist(const std::string &newID, bool requireComputed=true) const
check if exists a definition with the given ID
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()
static void writeTrafficLight(OutputDevice &into, const NBTrafficLightLogic *logic)
writes a single traffic light logic to the given device
const std::string & getID() const
Returns the id.
Definition Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
void close()
Closes the device and removes it from the dictionary.
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 amount
PositionVector reverse() const
reverse position vector
static const RGBColor BLACK
Definition RGBColor.h:196
static const RGBColor RED
named colors
Definition RGBColor.h:188
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< XMLFileExtension > XMLFileExtensions
XML file Extensions.
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.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
A structure which describes a connection between edges or lanes.
Definition NBEdge.h:201
PositionVector viaShape
shape of via
Definition NBEdge.h:282
PositionVector shape
shape of Connection
Definition NBEdge.h:270