SUMO - Simulation of Urban MObility
GNEDialog_FixAdditionalPositions.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // Dialog used to fix invalid stopping places
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 
23 #include <iostream>
24 #include <netbuild/NBEdge.h>
28 #include <utils/common/ToString.h>
34 #include <netedit/GNEViewNet.h>
35 #include <netedit/GNEUndoList.h>
39 
41 
42 
43 // ===========================================================================
44 // FOX callback mapping
45 // ===========================================================================
46 
47 FXDEFMAP(GNEDialog_FixAdditionalPositions) GNEDialog_FixAdditionalPositionsMap[] = {
51 };
52 
53 // Object implementation
54 FXIMPLEMENT(GNEDialog_FixAdditionalPositions, FXDialogBox, GNEDialog_FixAdditionalPositionsMap, ARRAYNUMBER(GNEDialog_FixAdditionalPositionsMap))
55 
56 // ===========================================================================
57 // member method definitions
58 // ===========================================================================
59 
60 GNEDialog_FixAdditionalPositions::GNEDialog_FixAdditionalPositions(GNEViewNet* viewNet, const std::vector<GNEStoppingPlace*>& invalidStoppingPlaces, const std::vector<GNEDetector*>& invalidDetectors) :
61  FXDialogBox(viewNet->getApp(), ("Fix stoppingPlaces positions"), GUIDesignDialogBoxExplicit, 0, 0, 458, 300, 0, 0, 0, 0),
62  myViewNet(viewNet),
63  myInvalidStoppingPlaces(invalidStoppingPlaces),
64  myInvalidDetectors(invalidDetectors) {
65  // set busStop icon for this dialog
67  // create main frame
68  FXVerticalFrame* mainFrame = new FXVerticalFrame(this, GUIDesignAuxiliarFrame);
69  // create label for table
70  new FXLabel(mainFrame, "List of Stopping places and E2 detectors with conflicts", 0, GUIDesignLabelCenterThick);
71  // Create table, copy intervals and update table
72  myTable = new FXTable(mainFrame, this, MID_GNE_FIXSTOPPINGPLACES_CHANGE, GUIDesignTableAdditionals);
73  myTable->setSelBackColor(FXRGBA(255, 255, 255, 255));
74  myTable->setSelTextColor(FXRGBA(0, 0, 0, 255));
75  myTable->setEditable(false);
76  // clear table
77  myTable->clearItems();
78  // set number of rows
79  myTable->setTableSize(int(myInvalidStoppingPlaces.size() + myInvalidDetectors.size()), 3);
80  // Configure list
81  myTable->setVisibleColumns(4);
82  myTable->setColumnWidth(0, GUIDesignTableIconCellWidth);
83  myTable->setColumnWidth(1, 160);
84  myTable->setColumnWidth(2, 260);
85  myTable->setColumnText(0, "");
86  myTable->setColumnText(1, toString(SUMO_ATTR_ID).c_str());
87  myTable->setColumnText(2, "Conflict");
88  myTable->getRowHeader()->setWidth(0);
89  // Declare index for rows and pointer to FXTableItem
90  int indexRow = 0;
91  FXTableItem* item = 0;
92  // iterate over stopping places
93  for (auto i : myInvalidStoppingPlaces) {
94  // Set icon
95  item = new FXTableItem("", i->getIcon());
96  item->setIconPosition(FXTableItem::CENTER_X);
97  myTable->setItem(indexRow, 0, item);
98  // Set ID
99  item = new FXTableItem(i->getID().c_str());
100  item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
101  myTable->setItem(indexRow, 1, item);
102  // Set conflict
103  std::string errorStartPosition, errorEndPosition, separator;
104  // check start position
105  if (i->getStartPosition() < 0) {
106  errorStartPosition = (toString(SUMO_ATTR_STARTPOS) + " < 0");
107  }
108  // check end position
109  if (i->getEndPosition() > i->getLane()->getParentEdge().getNBEdge()->getFinalLength()) {
110  errorEndPosition = (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
111  }
112  // check separator
113  if ((errorStartPosition.size() > 0) && (errorEndPosition.size() > 0)) {
114  separator = " and ";
115  }
116  item = new FXTableItem((errorStartPosition + separator + errorEndPosition).c_str());
117  item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
118  myTable->setItem(indexRow, 2, item);
119  // Update index
120  indexRow++;
121  }
122  // iterate over detectors
123  for (auto i : myInvalidDetectors) {
124  // Set icon
125  item = new FXTableItem("", i->getIcon());
126  item->setIconPosition(FXTableItem::CENTER_X);
127  myTable->setItem(indexRow, 0, item);
128  // Set ID
129  item = new FXTableItem(i->getID().c_str());
130  item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
131  myTable->setItem(indexRow, 1, item);
132  // Set conflict
133  std::string errorPosition, errorLenght, separator;
134  // check position over lane
135  if (i->getPositionOverLane() < 0) {
136  errorPosition = (toString(SUMO_ATTR_POSITION) + " < 0");
137  } else if (i->getPositionOverLane() > i->getLane()->getParentEdge().getNBEdge()->getFinalLength()) {
138  errorPosition = (toString(SUMO_ATTR_POSITION) + " > lanes's length");
139  }
140  GNEDetectorE2* E2Detector = dynamic_cast<GNEDetectorE2*>(i);
141  if ((E2Detector != nullptr) && ((E2Detector->getPositionOverLane() + E2Detector->getLength()) > i->getLane()->getParentEdge().getNBEdge()->getFinalLength())) {
142  errorLenght = (toString(SUMO_ATTR_LENGTH) + " > lanes's length");
143  }
144 
145  // check separator
146  if ((errorPosition.size() > 0) && (errorLenght.size() > 0)) {
147  separator = " and ";
148  }
149  item = new FXTableItem((errorPosition + separator + errorLenght).c_str());
150  item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
151  myTable->setItem(indexRow, 2, item);
152  // Update index
153  indexRow++;
154  }
155  // create label for elements
156  new FXLabel(mainFrame, "Select a solution:", 0, GUIDesignLabelCenterThick);
157  // create horizontal frames for radio buttons
158  FXHorizontalFrame* RadioButtons = new FXHorizontalFrame(mainFrame, GUIDesignHorizontalFrame);
159  // create Vertical Frame for left options
160  FXVerticalFrame* RadioButtonsLeft = new FXVerticalFrame(RadioButtons, GUIDesignAuxiliarVerticalFrame);
161  myOptionA = new FXRadioButton(RadioButtonsLeft, "Activate friendlyPos and save\t\tFriendly pos parameter will be activated in all stopping places and E2 detectors",
163  myOptionC = new FXRadioButton(RadioButtonsLeft, "Save invalid positions\t\tSave stopping places and E2 detectors with invalid positions",
165  // create Vertical Frame for right options
166  FXVerticalFrame* RadioButtonsRight = new FXVerticalFrame(RadioButtons, GUIDesignAuxiliarVerticalFrame);
167  myOptionB = new FXRadioButton(RadioButtonsRight, "Fix positions and save\t\tPosition of stopping places and E2 detectors will be fixed",
169  myOptionD = new FXRadioButton(RadioButtonsRight, "Select invalid additionals\t\tCancel saving of additionals and select invalid stopping places and E2 detectors",
171  // leave option a as default
172  myOptionA->setCheck(true);
173  // create dialog buttons bot centered
174  FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(mainFrame, GUIDesignHorizontalFrame);
175  new FXHorizontalFrame(buttonsFrame, GUIDesignAuxiliarHorizontalFrame);
176  myAcceptButton = new FXButton(buttonsFrame, FXWindow::tr("&Accept"), GUIIconSubSys::getIcon(ICON_ACCEPT), this, MID_GNE_ADDITIONALDIALOG_BUTTONACCEPT, GUIDesignButtonAccept);
177  myCancelButton = new FXButton(buttonsFrame, FXWindow::tr("&Cancel"), GUIIconSubSys::getIcon(ICON_CANCEL), this, MID_GNE_ADDITIONALDIALOG_BUTTONCANCEL, GUIDesignButtonCancel);
178  new FXHorizontalFrame(buttonsFrame, GUIDesignAuxiliarHorizontalFrame);
179  // set focus in accept button
180  myAcceptButton->setFocus();
181 }
182 
183 
185 }
186 
187 
188 long
189 GNEDialog_FixAdditionalPositions::onCmdSelectOption(FXObject* obj, FXSelector, void*) {
190  if (obj == myOptionA) {
191  myOptionA->setCheck(true);
192  myOptionB->setCheck(false);
193  myOptionC->setCheck(false);
194  myOptionD->setCheck(false);
195  return 1;
196  } else if (obj == myOptionB) {
197  myOptionA->setCheck(false);
198  myOptionB->setCheck(true);
199  myOptionC->setCheck(false);
200  myOptionD->setCheck(false);
201  return 1;
202  } else if (obj == myOptionC) {
203  myOptionA->setCheck(false);
204  myOptionB->setCheck(false);
205  myOptionC->setCheck(true);
206  myOptionD->setCheck(false);
207  return 1;
208  } else if (obj == myOptionD) {
209  myOptionA->setCheck(false);
210  myOptionB->setCheck(false);
211  myOptionC->setCheck(false);
212  myOptionD->setCheck(true);
213  return 1;
214  } else {
215  return 0;
216  }
217 }
218 
219 
220 long
221 GNEDialog_FixAdditionalPositions::onCmdAccept(FXObject*, FXSelector, void*) {
222  if (myOptionA->getCheck() == TRUE) {
223  myViewNet->getUndoList()->p_begin(toString(SUMO_ATTR_FRIENDLY_POS) + " of invalid additionals");
224  // iterate over invalid stopping places to enable friendly position
225  for (auto i : myInvalidStoppingPlaces) {
226  i->setAttribute(SUMO_ATTR_FRIENDLY_POS, "true", myViewNet->getUndoList());
227  }
228  // iterate over invalid detectors to enable friendly position
229  for (auto i : myInvalidDetectors) {
230  i->setAttribute(SUMO_ATTR_FRIENDLY_POS, "true", myViewNet->getUndoList());
231  }
233  // stop modal with TRUE (continue saving)
234  getApp()->stopModal(this, TRUE);
235  return 1;
236  } else if (myOptionB->getCheck() == TRUE) {
237  myViewNet->getUndoList()->p_begin("Fixed positions of invalid additionals");
238  // iterate over invalid stopping places to fix positions
239  for (auto i = myInvalidStoppingPlaces.begin(); i != myInvalidStoppingPlaces.end(); i++) {
240  GNEStoppingPlace* stoppingPlace = dynamic_cast<GNEStoppingPlace*>(*i);
241  if (stoppingPlace != nullptr) {
242  // obtain start and end position
243  std::string startPos = stoppingPlace->getAttribute(SUMO_ATTR_STARTPOS);
244  std::string endPos = stoppingPlace->getAttribute(SUMO_ATTR_ENDPOS);
245  // fix start and end positions using fixStoppinPlacePosition (0.01 is used to avoid precision problems)
246  GNEAdditionalHandler::fixStoppinPlacePosition(startPos, endPos, stoppingPlace->getLane()->getLaneParametricLength() - 0.01, POSITION_EPS + 0.01, true);
247  // set new start and end positions
248  stoppingPlace->setAttribute(SUMO_ATTR_STARTPOS, toString(startPos), myViewNet->getUndoList());
249  stoppingPlace->setAttribute(SUMO_ATTR_ENDPOS, toString(endPos), myViewNet->getUndoList());
250  }
251  }
252  // iterate over invalid detectors
253  for (auto i : myInvalidDetectors) {
254  GNEDetectorE2* E2Detector = dynamic_cast<GNEDetectorE2*>(i);
255  // Check if we're handling a E2 detector o a E1/Entry/Exit
256  if (E2Detector != nullptr) {
257  // obtain position and lenght
258  double pos = GNEAttributeCarrier::parse<double>(E2Detector->getAttribute(SUMO_ATTR_POSITION));
259  double length = GNEAttributeCarrier::parse<double>(E2Detector->getAttribute(SUMO_ATTR_LENGTH));
260  // fix pos and lenght using fixE2DetectorPositionPosition
262  // set new position and length
264  E2Detector->setAttribute(SUMO_ATTR_LENGTH, toString(length), myViewNet->getUndoList());
265  } else {
266  // obtain position
267  double pos = GNEAttributeCarrier::parse<double>(i->getAttribute(SUMO_ATTR_POSITION));
268  // fix pos and lenght checkAndFixDetectorPositionPosition
269  GNEAdditionalHandler::checkAndFixDetectorPositionPosition(pos, i->getLane()->getParentEdge().getNBEdge()->getFinalLength(), true);
270  // set new position
271  i->setAttribute(SUMO_ATTR_POSITION, toString(pos), myViewNet->getUndoList());
272  }
273  }
275  // stop modal with TRUE (continue saving)
276  getApp()->stopModal(this, TRUE);
277  return 1;
278  } else if (myOptionC->getCheck() == TRUE) {
279  // simply stop modal with TRUE to save additionals with invalid positions
280  getApp()->stopModal(this, TRUE);
281  return 1;
282  } else if (myOptionD->getCheck() == TRUE) {
283  std::set<GUIGlID> GLIDsToSelect;
284  myViewNet->getUndoList()->p_begin("select invalid additionals");
285  for (auto i : myInvalidStoppingPlaces) {
286  i->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
287  }
289  // stop modal with FALSE (abort saving)
290  getApp()->stopModal(this, FALSE);
291  return 0;
292  } else {
293  // stop modal with FALSE (abort saving)
294  getApp()->stopModal(this, FALSE);
295  return 0;
296  }
297 }
298 
299 
300 long
301 GNEDialog_FixAdditionalPositions::onCmdCancel(FXObject*, FXSelector, void*) {
302  // Stop Modal (abort saving)
303  getApp()->stopModal(this, FALSE);
304  return 1;
305 }
306 
307 /****************************************************************************/
#define GUIDesignTableIconCellWidth
width of cells that only contains an Icon
Definition: GUIDesigns.h:447
#define GUIDesignHorizontalFrame
Definition: GUIDesigns.h:212
double getPositionOverLane() const
get position over lane
Definition: GNEDetector.cpp:85
static bool fixStoppinPlacePosition(std::string &startPos, std::string &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check if the position of an stoppingPlace over a lane is valid
FXRadioButton * myOptionD
Option "Select invalid stops and cancel".
FXRadioButton * myOptionA
Option "Activate friendlyPos and save".
long onCmdAccept(FXObject *, FXSelector, void *)
event after press accept button
static bool checkAndFixDetectorPositionPosition(double &pos, const double laneLength, const bool friendlyPos)
check if the position of a detector over a lane is valid
#define GUIDesignButtonCancel
Cancel Button.
Definition: GUIDesigns.h:102
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform additional changes ...
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:78
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform additional changes ...
FXRadioButton * myOptionC
Option "Save invalid".
std::vector< GNEStoppingPlace * > myInvalidStoppingPlaces
vector with the invalid stoppingplaces
FixStoppingPlaces dialog.
Definition: GUIAppEnum.h:885
GNELane * getLane() const
get Lane
GNEUndoList * getUndoList() const
get the undoList object
set type of selection
Definition: GUIAppEnum.h:344
#define GUIDesignAuxiliarFrame
design for auxiliar (Without borders) frames used to pack another frames extended in all directions ...
Definition: GUIDesigns.h:255
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:715
#define GUIDesignDialogBoxExplicit
design for dialog box with specift width and height (for example, additional dialogs) ...
Definition: GUIDesigns.h:419
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1230
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:85
virtual std::string getAttribute(SumoXMLAttr key) const =0
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames ...
Definition: GUIDesigns.h:258
#define POSITION_EPS
Definition: config.h:172
#define GUIDesignTableAdditionals
design for tables used in additional dialogs
Definition: GUIDesigns.h:444
#define GUIDesignAuxiliarVerticalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames ...
Definition: GUIDesigns.h:261
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3523
#define GUIDesignButtonAccept
Accept Button.
Definition: GUIDesigns.h:99
std::string getAttribute(SumoXMLAttr key) const
double getLength() const
get length of E2 Detector
#define GUIDesignLabelCenterThick
label extended over frame with thick and with text justify to center and height of 23 ...
Definition: GUIDesigns.h:163
static bool fixE2DetectorPositionPosition(double &pos, double &length, const double laneLength, const bool friendlyPos)
check if the position of a detector over a lane is valid
element is selected
FXRadioButton * myOptionB
Option "Fix Positions and save".
FXDEFMAP(GNEDialog_FixAdditionalPositions) GNEDialog_FixAdditionalPositionsMap[]
GNELane * getLane() const
get lane
Definition: GNEDetector.cpp:79
std::vector< GNEDetector * > myInvalidDetectors
vector with the invalid stoppingplaces
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:586
long onCmdCancel(FXObject *, FXSelector, void *)
event after press cancel button
#define GUIDesignRadioButton
Definition: GUIDesigns.h:135
long onCmdSelectOption(FXObject *obj, FXSelector, void *)
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon