Eclipse SUMO - Simulation of Urban MObility
GNERouteFrame.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-2019 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 // The Widget for remove network-elements
16 /****************************************************************************/
17 
18 
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23 
26 #include <utils/gui/div/GLHelper.h>
33 #include <netedit/GNEViewNet.h>
34 #include <netedit/GNENet.h>
35 #include <netedit/GNEUndoList.h>
36 #include <netedit/GNEViewParent.h>
38 
39 #include "GNERouteFrame.h"
40 
41 // ===========================================================================
42 // FOX callback mapping
43 // ===========================================================================
44 
45 FXDEFMAP(GNERouteFrame::RouteModeSelector) RouteModeSelectorMap[] = {
48 };
49 
50 FXDEFMAP(GNERouteFrame::ConsecutiveEdges) ConsecutiveEdgesMap[] = {
54 };
55 
56 FXDEFMAP(GNERouteFrame::NonConsecutiveEdges) NonConsecutiveEdgesMap[] = {
60 };
61 
62 // Object implementation
63 FXIMPLEMENT(GNERouteFrame::RouteModeSelector, FXGroupBox, RouteModeSelectorMap, ARRAYNUMBER(RouteModeSelectorMap))
64 FXIMPLEMENT(GNERouteFrame::ConsecutiveEdges, FXGroupBox, ConsecutiveEdgesMap, ARRAYNUMBER(ConsecutiveEdgesMap))
65 FXIMPLEMENT(GNERouteFrame::NonConsecutiveEdges, FXGroupBox, NonConsecutiveEdgesMap, ARRAYNUMBER(NonConsecutiveEdgesMap))
66 
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
71 
72 // ---------------------------------------------------------------------------
73 // GNERouteFrame::RouteModeSelector - methods
74 // ---------------------------------------------------------------------------
75 
77  FXGroupBox(routeFrameParent->myContentFrame, "Route mode", GUIDesignGroupBoxFrame),
78  myRouteFrameParent(routeFrameParent),
79  myCurrentRouteMode(ROUTEMODE_CONSECUTIVE_EDGES),
80  myCurrentVehicleClass(SVC_PASSENGER),
81  myValidVClass(true) {
82  // first fill myRouteModesStrings
83  myRouteModesStrings.push_back(std::make_pair(ROUTEMODE_CONSECUTIVE_EDGES, "consecutive edges"));
84  myRouteModesStrings.push_back(std::make_pair(ROUTEMODE_NONCONSECUTIVE_EDGES, "non consecutive edges"));
85  // Create FXComboBox for Route mode
86  myRouteModeMatchBox = new FXComboBox(this, GUIDesignComboBoxNCol, this, MID_GNE_ROUTEFRAME_ROUTEMODE, GUIDesignComboBox);
87  // fill myRouteModeMatchBox with route modes
88  for (const auto& i : myRouteModesStrings) {
89  myRouteModeMatchBox->appendItem(i.second.c_str());
90  }
91  // Set visible items
92  myRouteModeMatchBox->setNumVisible((int)myRouteModeMatchBox->getNumItems());
93  // Create FXComboBox for VClass
94  myVClassMatchBox = new FXComboBox(this, GUIDesignComboBoxNCol, this, MID_GNE_ROUTEFRAME_VCLASS, GUIDesignComboBox);
95  // fill myVClassMatchBox with all VCLass
96  for (const auto& i : SumoVehicleClassStrings.getStrings()) {
97  myVClassMatchBox->appendItem(i.c_str());
98  }
99  // set Passenger als default VCLass
100  myVClassMatchBox->setCurrentItem(7);
101  // Set visible items
102  myVClassMatchBox->setNumVisible((int)myVClassMatchBox->getNumItems());
103  // RouteModeSelector is always shown
104  show();
105 }
106 
107 
109 
110 
113  return myCurrentRouteMode;
114 }
115 
116 
119  return myCurrentVehicleClass;
120 }
121 
122 
123 bool
125  return myValidVClass;
126 }
127 
128 
129 void
131  // make sure that route isn't invalid
132  if (routemode != ROUTEMODE_INVALID) {
133  // restore color
134  myRouteModeMatchBox->setTextColor(FXRGB(0, 0, 0));
135  // set current route mode
136  myCurrentRouteMode = routemode;
137  // set item in myTypeMatchBox
138  for (int i = 0; i < (int)myRouteModesStrings.size(); i++) {
139  if (myRouteModesStrings.at(i).first == myCurrentRouteMode) {
140  myRouteModeMatchBox->setCurrentItem(i);
141  }
142  }
143  // show route attributes modul
144  myRouteFrameParent->myRouteAttributes->showAttributesCreatorModul(GNEAttributeCarrier::getTagProperties(SUMO_TAG_ROUTE));
145  // show modes moduls
146  if ((routemode == ROUTEMODE_CONSECUTIVE_EDGES) && (myCurrentVehicleClass != SVC_IGNORING)) {
147  myRouteFrameParent->myConsecutiveEdges->showConsecutiveEdgesModul();
148  myRouteFrameParent->myNonConsecutiveEdges->hideNonConsecutiveEdgesModul();
149  } else if ((routemode == ROUTEMODE_NONCONSECUTIVE_EDGES) && (myCurrentVehicleClass != SVC_IGNORING)) {
150  myRouteFrameParent->myConsecutiveEdges->hideConsecutiveEdgesModul();
151  myRouteFrameParent->myNonConsecutiveEdges->showNonConsecutiveEdgesModul();
152  }
153  } else {
154  // hide all moduls if route mode isnt' valid
155  myRouteFrameParent->myRouteAttributes->hideAttributesCreatorModul();
156  myRouteFrameParent->myConsecutiveEdges->hideConsecutiveEdgesModul();
157  myRouteFrameParent->myNonConsecutiveEdges->hideNonConsecutiveEdgesModul();
158  }
159 }
160 
161 
162 long
164  // first abort all current operations in moduls
165  myRouteFrameParent->myConsecutiveEdges->onCmdAbortRoute(0, 0, 0);
166  myRouteFrameParent->myNonConsecutiveEdges->onCmdAbortRoute(0, 0, 0);
167  // Check if value of myTypeMatchBox correspond of an allowed additional tags
168  for (const auto& i : myRouteModesStrings) {
169  if (i.second == myRouteModeMatchBox->getText().text()) {
170  // set color of myTypeMatchBox to black (valid)
171  myRouteModeMatchBox->setTextColor(FXRGB(0, 0, 0));
172  // Set new current type
173  myCurrentRouteMode = i.first;
174  // show route attributes modul
175  myRouteFrameParent->myRouteAttributes->showAttributesCreatorModul(GNEAttributeCarrier::getTagProperties(SUMO_TAG_ROUTE));
176  // show modes moduls
177  if ((myCurrentRouteMode == ROUTEMODE_CONSECUTIVE_EDGES) && (myCurrentVehicleClass != SVC_IGNORING)) {
178  myRouteFrameParent->myConsecutiveEdges->showConsecutiveEdgesModul();
179  myRouteFrameParent->myNonConsecutiveEdges->hideNonConsecutiveEdgesModul();
180  } else if ((myCurrentRouteMode == ROUTEMODE_NONCONSECUTIVE_EDGES) && (myCurrentVehicleClass != SVC_IGNORING)) {
181  myRouteFrameParent->myConsecutiveEdges->hideConsecutiveEdgesModul();
182  myRouteFrameParent->myNonConsecutiveEdges->showNonConsecutiveEdgesModul();
183  }
184  // Write Warning in console if we're in testing mode
185  WRITE_DEBUG(("Selected RouteMode '" + myRouteModeMatchBox->getText() + "' in RouteModeSelector").text());
186  return 1;
187  }
188  }
189  // if Route mode isn't correct, set ROUTEMODE_INVALID as current route mde
190  myCurrentRouteMode = ROUTEMODE_INVALID;
191  // hide all moduls if route mode isn't valid
192  myRouteFrameParent->myRouteAttributes->hideAttributesCreatorModul();
193  myRouteFrameParent->myConsecutiveEdges->hideConsecutiveEdgesModul();
194  myRouteFrameParent->myNonConsecutiveEdges->hideNonConsecutiveEdgesModul();
195  // set color of myTypeMatchBox to red (invalid)
196  myRouteModeMatchBox->setTextColor(FXRGB(255, 0, 0));
197  // Write Warning in console if we're in testing mode
198  WRITE_DEBUG("Selected invalid RouteMode in RouteModeSelector");
199  return 1;
200 }
201 
202 
203 long
205  // first abort all current operations in moduls
206  myRouteFrameParent->myConsecutiveEdges->onCmdAbortRoute(0, 0, 0);
207  myRouteFrameParent->myNonConsecutiveEdges->onCmdAbortRoute(0, 0, 0);
208  // Check if value of myTypeMatchBox correspond of an allowed additional tags
209  for (const auto& i : SumoVehicleClassStrings.getStrings()) {
210  if (i == myVClassMatchBox->getText().text()) {
211  // set color of myTypeMatchBox to black (valid)
212  myVClassMatchBox->setTextColor(FXRGB(0, 0, 0));
213  // Set new current type
214  myCurrentVehicleClass = SumoVehicleClassStrings.get(i);
215  // change flag
216  myValidVClass = true;
217  // show route attributes modul
218  myRouteFrameParent->myRouteAttributes->showAttributesCreatorModul(GNEAttributeCarrier::getTagProperties(SUMO_TAG_ROUTE));
219  // enable moduls if current route is valid
220  if (myCurrentRouteMode == ROUTEMODE_CONSECUTIVE_EDGES) {
221  myRouteFrameParent->myConsecutiveEdges->showConsecutiveEdgesModul();
222  myRouteFrameParent->myNonConsecutiveEdges->hideNonConsecutiveEdgesModul();
223  } else if (myCurrentRouteMode == ROUTEMODE_NONCONSECUTIVE_EDGES) {
224  myRouteFrameParent->myConsecutiveEdges->hideConsecutiveEdgesModul();
225  myRouteFrameParent->myNonConsecutiveEdges->showNonConsecutiveEdgesModul();
226  }
227  // Write Warning in console if we're in testing mode
228  WRITE_DEBUG(("Selected VClass '" + myVClassMatchBox->getText() + "' in RouteModeSelector").text());
229  return 1;
230  }
231  }
232  // if VClass name isn't correct, set SVC_IGNORING as current type
233  myCurrentVehicleClass = SVC_IGNORING;
234  // change flag
235  myValidVClass = false;
236  // hide all moduls if route mode isnt' valid
237  myRouteFrameParent->myRouteAttributes->hideAttributesCreatorModul();
238  myRouteFrameParent->myConsecutiveEdges->hideConsecutiveEdgesModul();
239  myRouteFrameParent->myNonConsecutiveEdges->hideNonConsecutiveEdgesModul();
240  // set color of myTypeMatchBox to red (invalid)
241  myVClassMatchBox->setTextColor(FXRGB(255, 0, 0));
242  // Write Warning in console if we're in testing mode
243  WRITE_DEBUG("Selected invalid VClass in RouteModeSelector");
244  return 1;
245 }
246 
247 // ---------------------------------------------------------------------------
248 // GNERouteFrame::ConsecutiveEdges - methods
249 // ---------------------------------------------------------------------------
250 
252  FXGroupBox(routeFrameParent->myContentFrame, "Consecutive edges", GUIDesignGroupBoxFrame),
253  myRouteFrameParent(routeFrameParent) {
254  // create label for route info
255  myInfoRouteLabel = new FXLabel(this, "No edges selected", 0, GUIDesignLabelFrameInformation);
256  // Create button for create routes
257  myCreateRouteButton = new FXButton(this, "Create route", 0, this, MID_GNE_EDGEPATH_FINISH, GUIDesignButton);
258  myCreateRouteButton->disable();
259  // Create button for create routes
260  myAbortCreationButton = new FXButton(this, "Abort creation", 0, this, MID_GNE_EDGEPATH_ABORT, GUIDesignButton);
261  myAbortCreationButton->disable();
262  // create button for remove last inserted edge
263  myRemoveLastInsertedEdge = new FXButton(this, "Remove last inserted edge", nullptr, this, MID_GNE_EDGEPATH_REMOVELAST, GUIDesignButton);
264  myRemoveLastInsertedEdge->disable();
265  // ConsecutiveEdges is by default shown
266  show();
267 }
268 
269 
271 
272 
273 void
275  // recalc before show (to avoid graphic problems)
276  recalc();
277  // show modul
278  show();
279 }
280 
281 
282 void
284  // first abort route creation
285  onCmdAbortRoute(0, 0, 0);
286  // now hide modul
287  hide();
288 }
289 
290 
291 bool
293  // check if currently we're creating a new route
294  if (myRouteEdges.empty()) {
295  // block undo/redo
296  myRouteFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->disableUndoRedo("route creation");
297  // add edge into list
298  myRouteEdges.push_back(edge);
299  // refresh edge candidates
300  refreshEdgeCandidates();
301  // enable create route and abort edge route
302  myCreateRouteButton->enable();
303  myAbortCreationButton->enable();
304  // edge added, then return true
305  return true;
306  } else {
307  // check if clicked edge is in the candidate edges
308  for (const auto& i : myRouteEdges.back()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
309  if ((i == edge) && GNEDemandElement::getRouteCalculatorInstance()->areEdgesConsecutives(myRouteFrameParent->myRouteModeSelector->getCurrentVehicleClass(), myRouteEdges.back(), edge)) {
310  // restore colors of outgoing edges
311  for (const auto& j : myRouteEdges.back()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
312  for (const auto& k : j->getLanes()) {
313  k->setSpecialColor(nullptr);
314  }
315  }
316  // add new edge in the list of route edges
317  myRouteEdges.push_back(edge);
318  // enable remove last inserted edge
319  myRemoveLastInsertedEdge->enable();
320  // refresh edge candidates
321  refreshEdgeCandidates();
322  // edge added, then return true
323  return true;
324  }
325  }
326  // edge isn't a candidate edge, then return false
327  return false;
328  }
329 }
330 
331 
332 void
334  // first check that at least there is a candidate edge
335  if (myRouteEdges.size() > 0) {
336  // set selected color in all edges
337  for (const auto& j : myRouteEdges) {
338  for (const auto& k : j->getLanes()) {
339  k->setSpecialColor(&myRouteFrameParent->getEdgeCandidateColor());
340  }
341  }
342  // set new candidate colors
343  for (const auto& j : myRouteEdges.back()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
344  // check if exist a connection between both edges
345  if (GNEDemandElement::getRouteCalculatorInstance()->areEdgesConsecutives(myRouteFrameParent->myRouteModeSelector->getCurrentVehicleClass(), myRouteEdges.back(), j)) {
346  for (const auto& k : j->getLanes()) {
347  k->setSpecialColor(&myRouteFrameParent->getEdgeCandidateSelectedColor());
348  }
349  }
350  }
351  // update route label
352  updateInfoRouteLabel();
353  // update view
354  myRouteFrameParent->getViewNet()->update();
355  }
356 }
357 
358 
359 void
361  // disable special color in candidate edges
362  for (const auto& j : myRouteEdges.back()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
363  for (const auto& k : j->getLanes()) {
364  k->setSpecialColor(nullptr);
365  }
366  }
367  // disable special color in current route edges
368  for (const auto& j : myRouteEdges) {
369  for (const auto& k : j->getLanes()) {
370  k->setSpecialColor(nullptr);
371  }
372  }
373  // clear route edges
374  myRouteEdges.clear();
375 }
376 
377 
378 const std::vector<GNEEdge*>&
380  return myRouteEdges;
381 }
382 
383 
384 long
386  // check that route attributes are valid
387  if (!myRouteFrameParent->myRouteAttributes->areValuesValid()) {
388  myRouteFrameParent->myRouteAttributes->showWarningMessage();
389  } else if (myRouteEdges.size() > 0) {
390  // obtain Color
391  std::map<SumoXMLAttr, std::string> routeAttributes = myRouteFrameParent->myRouteAttributes->getAttributesAndValues(true);
392  // declare a route parameter
393  GNERouteHandler::RouteParameter routeParameters;
394  // generate Route ID
395  routeParameters.routeID = myRouteFrameParent->getViewNet()->getNet()->generateDemandElementID("", SUMO_TAG_ROUTE);
396  // fill rest of elements
397  routeParameters.color = GNEAttributeCarrier::parse<RGBColor>(routeAttributes.at(SUMO_ATTR_COLOR));
398  routeParameters.edges = myRouteEdges;
399  routeParameters.VClass = myRouteFrameParent->myRouteModeSelector->getCurrentVehicleClass();
400  // create route
401  GNERoute* route = new GNERoute(myRouteFrameParent->getViewNet(), routeParameters);
402  // add it into GNENet using GNEChange_DemandElement (to allow undo-redo)
403  myRouteFrameParent->getViewNet()->getUndoList()->p_begin("add " + route->getTagStr());
404  myRouteFrameParent->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
405  myRouteFrameParent->getViewNet()->getUndoList()->p_end();
406  // abort route creation (because route was already created and vector/colors has to be cleaned)
407  onCmdAbortRoute(0, 0, 0);
408  }
409  return 1;
410 }
411 
412 
413 long
415  // first check that there is route edges selected
416  if (myRouteEdges.size() > 0) {
417  // unblock undo/redo
418  myRouteFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->enableUndoRedo();
419  // clear edges
420  clearEdges();
421  // disable buttons
422  myCreateRouteButton->disable();
423  myAbortCreationButton->disable();
424  myRemoveLastInsertedEdge->disable();
425  // update route label
426  updateInfoRouteLabel();
427  // update view
428  myRouteFrameParent->getViewNet()->update();
429  }
430  return 1;
431 }
432 
433 
434 long
436  if (myRouteEdges.size() > 1) {
437  // restore colors of last inserted edge edges
438  for (const auto& j : myRouteEdges.back()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
439  for (const auto& k : j->getLanes()) {
440  k->setSpecialColor(nullptr);
441  }
442  }
443  // add new edge in the list of route edges
444  myRouteEdges.pop_back();
445  // set selected color in all edges
446  for (const auto& j : myRouteEdges) {
447  for (const auto& k : j->getLanes()) {
448  k->setSpecialColor(&myRouteFrameParent->getEdgeCandidateColor());
449  }
450  }
451  // set new candidate colors
452  for (const auto& j : myRouteEdges.back()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
453  if (j != myRouteEdges.back()) {
454  for (const auto& k : j->getLanes()) {
455  k->setSpecialColor(&myRouteFrameParent->getEdgeCandidateSelectedColor());
456  }
457  }
458  }
459  // disable remove last edge button if there is only one edge
460  if (myRouteEdges.size() == 1) {
461  myRemoveLastInsertedEdge->disable();
462  }
463  // update route label
464  updateInfoRouteLabel();
465  // update view
466  myRouteFrameParent->getViewNet()->update();
467  // edge added, then return true
468  return true;
469  } else {
470  return false;
471  }
472 }
473 
474 void
476  if (myRouteEdges.size() > 0) {
477  // declare variables for route info
478  double lenght = 0;
479  double speed = 0;
480  for (const auto& i : myRouteEdges) {
481  lenght += i->getNBEdge()->getLength();
482  speed += i->getNBEdge()->getSpeed();
483  }
484  // declare ostringstream for label and fill it
485  std::ostringstream information;
486  information
487  << "- Number of Edges: " << toString(myRouteEdges.size()) << "\n"
488  << "- Lenght: " << toString(lenght) << "\n"
489  << "- Average speed: " << toString(speed / myRouteEdges.size());
490  // set new label
491  myInfoRouteLabel->setText(information.str().c_str());
492  } else {
493  myInfoRouteLabel->setText("No edges selected");
494  }
495 }
496 
497 // ---------------------------------------------------------------------------
498 // GNERouteFrame::NonConsecutiveEdges - methods
499 // ---------------------------------------------------------------------------
500 
502  FXGroupBox(routeFrameParent->myContentFrame, "Route creator", GUIDesignGroupBoxFrame),
503  myRouteFrameParent(routeFrameParent) {
504  // create label for route info
505  myInfoRouteLabel = new FXLabel(this, "No edges selected", 0, GUIDesignLabelFrameInformation);
506  // create button for finish route creation
507  myFinishCreationButton = new FXButton(this, "Finish route creation", nullptr, this, MID_GNE_EDGEPATH_FINISH, GUIDesignButton);
508  myFinishCreationButton->disable();
509  // create button for abort route creation
510  myAbortCreationButton = new FXButton(this, "Abort route creation", nullptr, this, MID_GNE_EDGEPATH_ABORT, GUIDesignButton);
511  myAbortCreationButton->disable();
512  // create button for remove last inserted edge
513  myRemoveLastInsertedEdge = new FXButton(this, "Remove last inserted edge", nullptr, this, MID_GNE_EDGEPATH_REMOVELAST, GUIDesignButton);
514  myRemoveLastInsertedEdge->disable();
515 }
516 
517 
519 }
520 
521 
522 void
524  // disable buttons
525  myFinishCreationButton->disable();
526  myAbortCreationButton->disable();
527  myRemoveLastInsertedEdge->disable();
528  // recalc before show (to avoid graphic problems)
529  recalc();
530  // show modul
531  show();
532 }
533 
534 
535 void
537  hide();
538 }
539 
540 
541 std::vector<GNEEdge*>
543  return mySelectedEdges;
544 }
545 
546 
547 bool
549  if (mySelectedEdges.empty() || ((mySelectedEdges.size() > 0) && (mySelectedEdges.back() != edge))) {
550  mySelectedEdges.push_back(edge);
551  // enable abort route button
552  myAbortCreationButton->enable();
553  // enable finish button
554  myFinishCreationButton->enable();
555  // disable undo/redo
556  myRouteFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->disableUndoRedo("route creation");
557  // set special color
558  for (auto i : edge->getLanes()) {
559  i->setSpecialColor(&myRouteFrameParent->getEdgeCandidateSelectedColor());
560  }
561  // calculate route if there is more than two edges
562  if (mySelectedEdges.size() > 1) {
563  // enable remove last edge button
564  myRemoveLastInsertedEdge->enable();
565  // calculate temporal route
566  myTemporalRoute = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(myRouteFrameParent->myRouteModeSelector->getCurrentVehicleClass(), mySelectedEdges);
567  } else {
568  // Routes with only one edge are allowed
569  myTemporalRoute.clear();
570  myTemporalRoute.push_back(mySelectedEdges.front());
571  }
572  // update info route label
573  updateInfoRouteLabel();
574  return true;
575  } else {
576  return false;
577  }
578 }
579 
580 
581 void
583  // restore colors
584  for (const auto& i : mySelectedEdges) {
585  for (const auto& j : i->getLanes()) {
586  j->setSpecialColor(nullptr);
587  }
588  }
589  // clear edges
590  mySelectedEdges.clear();
591  myTemporalRoute.clear();
592 }
593 
594 
595 const std::vector<GNEEdge*>&
597  return myTemporalRoute;
598 }
599 
600 
601 bool
603  return mySelectedEdges.size() > 0;
604 }
605 
606 
607 long
609  // check that route attributes are valid
610  if (!myRouteFrameParent->myRouteAttributes->areValuesValid()) {
611  myRouteFrameParent->myRouteAttributes->showWarningMessage();
612  } else if (mySelectedEdges.size() > 0) {
613  // declare a route parameter
614  GNERouteHandler::RouteParameter routeParameters;
615  routeParameters.edges.reserve(myTemporalRoute.size());
616  for (const auto& i : myTemporalRoute) {
617  routeParameters.edges.push_back(myRouteFrameParent->myViewNet->getNet()->retrieveEdge(i->getID()));
618  }
619  // obtain Color
620  std::map<SumoXMLAttr, std::string> routeAttributes = myRouteFrameParent->myRouteAttributes->getAttributesAndValues(true);
621  // generate Route ID
622  routeParameters.routeID = myRouteFrameParent->getViewNet()->getNet()->generateDemandElementID("", SUMO_TAG_ROUTE);
623  // fill rest of elements
624  routeParameters.color = GNEAttributeCarrier::parse<RGBColor>(routeAttributes.at(SUMO_ATTR_COLOR));
625  routeParameters.VClass = myRouteFrameParent->myRouteModeSelector->getCurrentVehicleClass();
626  // create route
627  GNERoute* route = new GNERoute(myRouteFrameParent->getViewNet(), routeParameters);
628  // add it into GNENet using GNEChange_DemandElement (to allow undo-redo)
629  myRouteFrameParent->getViewNet()->getUndoList()->p_begin("add " + route->getTagStr());
630  myRouteFrameParent->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
631  myRouteFrameParent->getViewNet()->getUndoList()->p_end();
632  // abort route creation (because route was already created and vector/colors has to be cleaned)
633  onCmdAbortRoute(0, 0, 0);
634  }
635  return 1;
636 }
637 
638 
639 long
641  // first check that there is route edges selected
642  if (mySelectedEdges.size() > 0) {
643  // unblock undo/redo
644  myRouteFrameParent->myViewNet->getViewParent()->getGNEAppWindows()->enableUndoRedo();
645  // clear edges
646  clearEdges();
647  // disable buttons
648  myFinishCreationButton->disable();
649  myAbortCreationButton->disable();
650  myRemoveLastInsertedEdge->disable();
651  // update info route label
652  updateInfoRouteLabel();
653  // update view (to see the new route)
654  myRouteFrameParent->getViewNet()->update();
655  }
656  return 1;
657 }
658 
659 
660 long
662  if (mySelectedEdges.size() > 1) {
663  // remove special color of last selected edge
664  for (auto i : mySelectedEdges.back()->getLanes()) {
665  i->setSpecialColor(0);
666  }
667  // remove last edge
668  mySelectedEdges.pop_back();
669  // check if remove last route edge button has to be disabled
670  if (mySelectedEdges.size() == 1) {
671  // avoid remove last edge
672  myRemoveLastInsertedEdge->disable();
673  // Routes with only one edge are allowed
674  myTemporalRoute.clear();
675  myTemporalRoute.push_back(mySelectedEdges.front());
676  } else {
677  // calculate temporal route
678  myTemporalRoute = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(myRouteFrameParent->myRouteModeSelector->getCurrentVehicleClass(), mySelectedEdges);
679  }
680  // update info route label
681  updateInfoRouteLabel();
682  // update view
683  myRouteFrameParent->myViewNet->update();
684  return true;
685  } else {
686  return false;
687  }
688 }
689 
690 void
692  if (myTemporalRoute.size() > 0) {
693  // declare variables for route info
694  double lenght = 0;
695  double speed = 0;
696  for (const auto& i : myTemporalRoute) {
697  lenght += i->getNBEdge()->getLength();
698  speed += i->getNBEdge()->getSpeed();
699  }
700  // declare ostringstream for label and fill it
701  std::ostringstream information;
702  information
703  << "- Number of Edges: " << toString(myTemporalRoute.size()) << "\n"
704  << "- Lenght: " << toString(lenght) << "\n"
705  << "- Average speed: " << toString(speed / myTemporalRoute.size());
706  // set new label
707  myInfoRouteLabel->setText(information.str().c_str());
708  } else {
709  myInfoRouteLabel->setText("No edges selected");
710  }
711 }
712 
713 // ---------------------------------------------------------------------------
714 // GNERouteFrame - methods
715 // ---------------------------------------------------------------------------
716 
717 GNERouteFrame::GNERouteFrame(FXHorizontalFrame* horizontalFrameParent, GNEViewNet* viewNet) :
718  GNEFrame(horizontalFrameParent, viewNet, "Routes") {
719 
720  // create route mode Selector modul
722 
723  // Create route parameters
725 
726  // create consecutive edges modul
728 
729  // create non consecutive edges modul
731 
732  // set ROUTEMODE_CONSECUTIVE_EDGES as default mode
734 }
735 
736 
738 
739 
740 void
742  // refresh myRouteModeSelector
744  // show route frame
745  GNEFrame::show();
746 }
747 
748 
749 void
751  GNEFrame::hide();
752 }
753 
754 
755 void
757  // first check if current vClass is valid and edge exist
758  if (myRouteModeSelector->isValidVehicleClass() && clickedEdge) {
759  // continue dependig of current mode
762  // check if edge can be inserted in consecutive edges modul modul
763  if (myConsecutiveEdges->addEdge(clickedEdge)) {
764  WRITE_DEBUG("Edge added in ConsecutiveEdges mode");
765  } else {
766  WRITE_DEBUG("Edge wasn't added in ConsecutiveEdges mode");
767  }
768  break;
770  // check if edge can be inserted in non consecutive edges modul modul
771  if (myNonConsecutiveEdges->addEdge(clickedEdge)) {
772  WRITE_DEBUG("Edge added in NonConsecutiveEdges mode");
773  } else {
774  WRITE_DEBUG("Edge wasn't added in NonConsecutiveEdges mode");
775  }
776  break;
777  default:
778  break;
779  }
780  // update view
781  myViewNet->update();
782  }
783 }
784 
785 
786 void
788  // first check if current vClass is valid
790  // continue dependig of current mode
794  break;
797  break;
798  default:
799  break;
800  }
801  // update view
802  myViewNet->update();
803  }
804 }
805 
806 
807 void
809  // first check if current vClass is valid
811  // continue dependig of current mode
815  break;
818  break;
819  default:
820  break;
821  }
822  // update view
823  myViewNet->update();
824  }
825 }
826 
827 
828 void
830  // first check if current vClass is valid
832  // continue dependig of current mode
836  break;
839  break;
840  default:
841  break;
842  }
843  // update view
844  myViewNet->update();
845  }
846 }
847 
848 
849 void
851  // declare a vector with temporal route edges
852  std::vector<GNEEdge*> temporalRoute;
853  // obtain temporal route depending of current route mode
856  // convert GNEEdges to NBEdges
857  temporalRoute.reserve(myConsecutiveEdges->getRouteEdges().size());
858  for (const auto& i : myConsecutiveEdges->getRouteEdges()) {
859  temporalRoute.push_back(i);
860  }
861  break;
863  temporalRoute = myNonConsecutiveEdges->getTemporalRoute();
864  break;
865  default:
866  break;
867  }
868  // only draw if there is at least two edges
869  if (temporalRoute.size() > 1) {
870  // Add a draw matrix
871  glPushMatrix();
872  // Start with the drawing of the area traslating matrix to origin
873  glTranslated(0, 0, GLO_MAX);
874  // set orange color
876  // set line width
877  glLineWidth(5);
878  // draw first line
879  GLHelper::drawLine(temporalRoute.at(0)->getNBEdge()->getLanes().front().shape.front(),
880  temporalRoute.at(0)->getNBEdge()->getLanes().front().shape.back());
881  // draw rest of lines
882  for (int i = 1; i < (int)temporalRoute.size(); i++) {
883  GLHelper::drawLine(temporalRoute.at(i - 1)->getNBEdge()->getLanes().front().shape.back(),
884  temporalRoute.at(i)->getNBEdge()->getLanes().front().shape.front());
885  GLHelper::drawLine(temporalRoute.at(i)->getNBEdge()->getLanes().front().shape.front(),
886  temporalRoute.at(i)->getNBEdge()->getLanes().front().shape.back());
887  }
888  // Pop last matrix
889  glPopMatrix();
890  }
891 }
892 
893 /****************************************************************************/
GNERouteFrame::drawTemporalRoute
void drawTemporalRoute() const
draw temporal route
Definition: GNERouteFrame.cpp:850
GLO_MAX
empty max
Definition: GUIGlObjectTypes.h:166
SUMOVehicleClass
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
Definition: SUMOVehicleClass.h:134
GNERouteFrame::NonConsecutiveEdges::onCmdCreateRoute
long onCmdCreateRoute(FXObject *, FXSelector, void *)
Definition: GNERouteFrame.cpp:608
FXDEFMAP
FXDEFMAP(GNERouteFrame::RouteModeSelector) RouteModeSelectorMap[]
GNEChange_DemandElement
Definition: GNEChange_DemandElement.h:46
GNERouteFrame::hotkeyEnter
void hotkeyEnter()
function called when user press ENTER key
Definition: GNERouteFrame.cpp:787
GNERouteFrame::NonConsecutiveEdges
Definition: GNERouteFrame.h:182
GNERouteFrame::RouteModeSelector::setCurrentRouteMode
void setCurrentRouteMode(RouteMode routemode)
set current route mode type manually
Definition: GNERouteFrame.cpp:130
GNERouteFrame::NonConsecutiveEdges::hideNonConsecutiveEdgesModul
void hideNonConsecutiveEdgesModul()
show NonConsecutiveEdges
Definition: GNERouteFrame.cpp:536
GNEDemandElement::getRouteCalculatorInstance
static RouteCalculator * getRouteCalculatorInstance()
obtain instance of RouteCalculator
Definition: GNEDemandElement.cpp:435
GNERouteFrame::hotkeyEsc
void hotkeyEsc()
function called when user press ESC key
Definition: GNERouteFrame.cpp:829
GNEChange_DemandElement.h
GNERouteHandler::RouteParameter::edges
std::vector< GNEEdge * > edges
edges
Definition: GNERouteHandler.h:72
GNERouteFrame::NonConsecutiveEdges::getSelectedEdges
std::vector< GNEEdge * > getSelectedEdges() const
get current selected edgesm
Definition: GNERouteFrame.cpp:542
GNERouteFrame::RouteModeSelector::~RouteModeSelector
~RouteModeSelector()
destructor
Definition: GNERouteFrame.cpp:108
GNERouteFrame::ConsecutiveEdges::myRemoveLastInsertedEdge
FXButton * myRemoveLastInsertedEdge
button for removing last inserted edge
Definition: GNERouteFrame.h:172
GNEFrameAttributesModuls::AttributesCreator
Definition: GNEFrameAttributesModuls.h:157
GNERouteFrame::ConsecutiveEdges::updateInfoRouteLabel
void updateInfoRouteLabel()
update InfoRouteLabel
Definition: GNERouteFrame.cpp:475
GNERouteFrame::NonConsecutiveEdges::myAbortCreationButton
FXButton * myAbortCreationButton
button for abort route creation
Definition: GNERouteFrame.h:250
GNERouteFrame::ConsecutiveEdges::myAbortCreationButton
FXButton * myAbortCreationButton
@bief FXButton for abort creating route
Definition: GNERouteFrame.h:169
GNERoute
Definition: GNERoute.h:42
Route
C++ TraCI client API implementation.
GUIDesignComboBoxNCol
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:233
GNERouteFrame::ConsecutiveEdges::ConsecutiveEdges
ConsecutiveEdges()
FOX needs this.
Definition: GNERouteFrame.h:153
GNERouteFrame::ConsecutiveEdges::onCmdCreateRoute
long onCmdCreateRoute(FXObject *, FXSelector, void *)
Definition: GNERouteFrame.cpp:385
GNEFrame
Definition: GNEFrame.h:35
SUMO_ATTR_COLOR
A color information.
Definition: SUMOXMLDefinitions.h:701
GNERouteFrame::myRouteModeSelector
RouteModeSelector * myRouteModeSelector
route mode selector
Definition: GNERouteFrame.h:288
GNEViewNet
Definition: GNEViewNet.h:43
MID_GNE_EDGEPATH_ABORT
abort edge path creation
Definition: GUIAppEnum.h:649
GNERouteFrame::ConsecutiveEdges::~ConsecutiveEdges
~ConsecutiveEdges()
destructor
Definition: GNERouteFrame.cpp:270
MID_GNE_ROUTEFRAME_VCLASS
select a VClass
Definition: GUIAppEnum.h:803
GNERouteFrame::RouteModeSelector::onCmdSelectRouteMode
long onCmdSelectRouteMode(FXObject *, FXSelector, void *)
Definition: GNERouteFrame.cpp:163
GNEDemandElement::getViewNet
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which demand element element is located.
Definition: GNEDemandElement.cpp:408
GLHelper.h
GUIDesigns.h
GNEViewNet::update
void update() const
Mark the entire GNEViewNet to be repainted later.
Definition: GNEViewNet.cpp:292
GNERouteFrame::myNonConsecutiveEdges
NonConsecutiveEdges * myNonConsecutiveEdges
Create routes using non consecutive edges modul.
Definition: GNERouteFrame.h:297
GNEFrame::myContentFrame
FXVerticalFrame * myContentFrame
Vertical frame that holds all widgets of frame.
Definition: GNEFrame.h:123
GLHelper::setColor
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:616
GNERouteFrame::ConsecutiveEdges::getRouteEdges
const std::vector< GNEEdge * > & getRouteEdges() const
get temporal route
Definition: GNERouteFrame.cpp:379
GUIDesignButton
#define GUIDesignButton
Definition: GUIDesigns.h:66
GNERouteHandler::RouteParameter::color
RGBColor color
string for saving parsed route colors
Definition: GNERouteHandler.h:75
SumoVehicleClassStrings
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
GNERouteFrame.h
GUIAppEnum.h
GNEJunction.h
GUIDesignLabelFrameInformation
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:210
GNERouteFrame::NonConsecutiveEdges::myRemoveLastInsertedEdge
FXButton * myRemoveLastInsertedEdge
button for removing last inserted edge
Definition: GNERouteFrame.h:253
GNEEdge
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
GNERoute.h
GNERouteFrame::NonConsecutiveEdges::clearEdges
void clearEdges()
clear edges (and restore colors)
Definition: GNERouteFrame.cpp:582
GNERouteFrame::show
void show()
show delete frame
Definition: GNERouteFrame.cpp:741
GNERouteFrame::NonConsecutiveEdges::myFinishCreationButton
FXButton * myFinishCreationButton
button for finish route creation
Definition: GNERouteFrame.h:247
GNERouteHandler::RouteParameter
struct for saving route parameters
Definition: GNERouteHandler.h:54
GNERouteFrame::ConsecutiveEdges::myCreateRouteButton
FXButton * myCreateRouteButton
FXButton for create routes.
Definition: GNERouteFrame.h:166
GNERouteFrame::RouteModeSelector::getCurrentVehicleClass
SUMOVehicleClass getCurrentVehicleClass() const
get current selected VClass
Definition: GNERouteFrame.cpp:118
GNERouteHandler::RouteParameter::VClass
SUMOVehicleClass VClass
VClass used by this route.
Definition: GNERouteHandler.h:78
GNERouteFrame::myRouteAttributes
GNEFrameAttributesModuls::AttributesCreator * myRouteAttributes
internal additional attributes
Definition: GNERouteFrame.h:291
RGBColor::ORANGE
static const RGBColor ORANGE
Definition: RGBColor.h:196
GNERouteFrame::ConsecutiveEdges::showConsecutiveEdgesModul
void showConsecutiveEdgesModul()
show ConsecutiveEdges modul
Definition: GNERouteFrame.cpp:274
GNERouteFrame
Definition: GNERouteFrame.h:32
GNEViewNet.h
SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
Definition: SUMOVehicleClass.h:160
GNERouteFrame::hotkeyBackSpace
void hotkeyBackSpace()
function called when user press BACKSPACE key
Definition: GNERouteFrame.cpp:808
GNERouteFrame::RouteModeSelector::getCurrentRouteMode
const RouteMode & getCurrentRouteMode() const
get current route mode
Definition: GNERouteFrame.cpp:112
GNERouteFrame::ROUTEMODE_INVALID
Definition: GNERouteFrame.h:38
GNEApplicationWindow.h
GNERouteFrame::NonConsecutiveEdges::NonConsecutiveEdges
NonConsecutiveEdges()
FOX needs this.
Definition: GNERouteFrame.h:228
GNEEdge.h
GNEFrame::myViewNet
GNEViewNet * myViewNet
View Net.
Definition: GNEFrame.h:120
GNERouteHandler::RouteParameter::routeID
std::string routeID
string for saving parsed Route ID
Definition: GNERouteHandler.h:69
GNEViewNet::getUndoList
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:933
GNERouteFrame::NonConsecutiveEdges::onCmdRemoveLastRouteEdge
long onCmdRemoveLastRouteEdge(FXObject *, FXSelector, void *)
Called when the user click over button "Remove las inserted edge".
Definition: GNERouteFrame.cpp:661
GLHelper::drawLine
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:274
GNERouteFrame::ConsecutiveEdges
Definition: GNERouteFrame.h:110
GUIDesignGroupBoxFrame
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:255
GNEEdge::getLanes
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:840
GNELane.h
GNERouteFrame::ConsecutiveEdges::onCmdRemoveLastRouteEdge
long onCmdRemoveLastRouteEdge(FXObject *, FXSelector, void *)
Called when the user click over button "Remove las inserted edge".
Definition: GNERouteFrame.cpp:435
GNERouteFrame::RouteMode
RouteMode
route creation modes
Definition: GNERouteFrame.h:37
GNEViewParent.h
GLIncludes.h
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
GNEDemandElement::RouteCalculator::areEdgesConsecutives
bool areEdgesConsecutives(SUMOVehicleClass vClass, GNEEdge *from, GNEEdge *to) const
check if exist a route between the two given consecutives edges
Definition: GNEDemandElement.cpp:282
GNERouteFrame::RouteModeSelector::isValidVehicleClass
bool isValidVehicleClass() const
check if current VClass is Valid
Definition: GNERouteFrame.cpp:124
GNERouteFrame::myConsecutiveEdges
ConsecutiveEdges * myConsecutiveEdges
Create routes using consecutive edges modul.
Definition: GNERouteFrame.h:294
GNERouteFrame::NonConsecutiveEdges::getTemporalRoute
const std::vector< GNEEdge * > & getTemporalRoute() const
get temporal route
Definition: GNERouteFrame.cpp:596
GNERouteFrame::ConsecutiveEdges::refreshEdgeCandidates
void refreshEdgeCandidates()
refresh edge candidates
Definition: GNERouteFrame.cpp:333
GNERouteFrame::ConsecutiveEdges::hideConsecutiveEdgesModul
void hideConsecutiveEdgesModul()
hide ConsecutiveEdges modul
Definition: GNERouteFrame.cpp:283
GUIDesignComboBox
#define GUIDesignComboBox
Definition: GUIDesigns.h:221
GNERouteFrame::ConsecutiveEdges::addEdge
bool addEdge(GNEEdge *edge)
add edge to current route (note: edge must be included in set of candidate edges
Definition: GNERouteFrame.cpp:292
GNERouteFrame::~GNERouteFrame
~GNERouteFrame()
Destructor.
Definition: GNERouteFrame.cpp:737
MID_GNE_ROUTEFRAME_ROUTEMODE
select a route mode
Definition: GUIAppEnum.h:801
GNERouteFrame::NonConsecutiveEdges::myInfoRouteLabel
FXLabel * myInfoRouteLabel
label with route info
Definition: GNERouteFrame.h:238
GNERouteFrame::handleEdgeClick
void handleEdgeClick(GNEEdge *clickedEdge)
handle edge click
Definition: GNERouteFrame.cpp:756
SUMO_TAG_ROUTE
begin/end of the description of a route
Definition: SUMOXMLDefinitions.h:126
config.h
GNEAttributeCarrier::getTagProperties
static const TagProperties & getTagProperties(SumoXMLTag tag)
get Tag Properties
Definition: GNEAttributeCarrier.cpp:1196
GNERouteFrame::ROUTEMODE_NONCONSECUTIVE_EDGES
Definition: GNERouteFrame.h:40
GNERouteFrame::ROUTEMODE_CONSECUTIVE_EDGES
Definition: GNERouteFrame.h:39
GNEDemandElement::RouteCalculator::calculateDijkstraRoute
std::vector< GNEEdge * > calculateDijkstraRoute(SUMOVehicleClass vClass, const std::vector< GNEEdge * > &partialEdges) const
calculate Dijkstra route between a list of partial edges
Definition: GNEDemandElement.cpp:225
GNERouteFrame::ConsecutiveEdges::myInfoRouteLabel
FXLabel * myInfoRouteLabel
label with route info
Definition: GNERouteFrame.h:163
GNERouteFrame::GNERouteFrame
GNERouteFrame(FXHorizontalFrame *horizontalFrameParent, GNEViewNet *viewNet)
Constructor.
Definition: GNERouteFrame.cpp:717
GNERouteFrame::NonConsecutiveEdges::updateInfoRouteLabel
void updateInfoRouteLabel()
update InfoRouteLabel
Definition: GNERouteFrame.cpp:691
GNERouteFrame::ConsecutiveEdges::onCmdAbortRoute
long onCmdAbortRoute(FXObject *, FXSelector, void *)
Called when the user press create route button.
Definition: GNERouteFrame.cpp:414
GNERouteFrame::ConsecutiveEdges::clearEdges
void clearEdges()
clear edges (and restore colors)
Definition: GNERouteFrame.cpp:360
GNERouteFrame::NonConsecutiveEdges::onCmdAbortRoute
long onCmdAbortRoute(FXObject *, FXSelector, void *)
Called when the user click over button "Abort route creation".
Definition: GNERouteFrame.cpp:640
GNEAttributeCarrier::getTagStr
const std::string & getTagStr() const
get tag assigned to this object in string format
Definition: GNEAttributeCarrier.cpp:1165
GNERouteFrame::NonConsecutiveEdges::~NonConsecutiveEdges
~NonConsecutiveEdges()
destructor
Definition: GNERouteFrame.cpp:518
MID_GNE_EDGEPATH_FINISH
finish edge path creation
Definition: GUIAppEnum.h:651
GNERouteFrame::hide
void hide()
hide delete frame
Definition: GNERouteFrame.cpp:750
GNERouteFrame::RouteModeSelector
Definition: GNERouteFrame.h:47
GNEUndoList::p_begin
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:73
SVC_IGNORING
vehicles ignoring classes
Definition: SUMOVehicleClass.h:136
GNERouteFrame::NonConsecutiveEdges::showNonConsecutiveEdgesModul
void showNonConsecutiveEdgesModul()
show NonConsecutiveEdges
Definition: GNERouteFrame.cpp:523
GNEFrame::show
virtual void show()
show Frame
Definition: GNEFrame.cpp:108
GNERouteFrame::RouteModeSelector::onCmdSelectVClass
long onCmdSelectVClass(FXObject *, FXSelector, void *)
Called when the user select another VClass.
Definition: GNERouteFrame.cpp:204
GNERouteFrame::NonConsecutiveEdges::isValid
bool isValid(SUMOVehicleClass vehicleClass) const
check if from and to edges create a valid route
Definition: GNERouteFrame.cpp:602
WRITE_DEBUG
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:246
GNEFrame::hide
virtual void hide()
hide Frame
Definition: GNEFrame.cpp:117
GNERouteFrame::NonConsecutiveEdges::addEdge
bool addEdge(GNEEdge *edge)
set edge from (and change color)
Definition: GNERouteFrame.cpp:548
GNENet.h
MID_GNE_EDGEPATH_REMOVELAST
remove last inserted element in path
Definition: GUIAppEnum.h:653
GNEUndoList.h