Eclipse SUMO - Simulation of Urban MObility
GNEPlanCreator.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-2024 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 // Frame for create paths
19 /****************************************************************************/
20 #include <config.h>
21 
23 #include <netedit/GNENet.h>
24 #include <netedit/GNEViewNet.h>
25 #include <netedit/GNEViewParent.h>
30 #include <utils/gui/div/GLHelper.h>
33 
34 #include "GNEPlanCreator.h"
35 
36 
37 // ===========================================================================
38 // FOX callback mapping
39 // ===========================================================================
40 
41 FXDEFMAP(GNEPlanCreator) PathCreatorMap[] = {
47 };
48 
49 // Object implementation
50 FXIMPLEMENT(GNEPlanCreator, MFXGroupBoxModule, PathCreatorMap, ARRAYNUMBER(PathCreatorMap))
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
56 
57 
58 GNEPlanCreator::PlanPath::PlanPath(GNEViewNet* viewNet, const SUMOVehicleClass vClass, GNEEdge* fromEdge, GNEEdge* toEdge) :
59  myConflictVClass(false),
60  myConflictDisconnected(false) {
61  // calculate subpath using given vClass
62  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, fromEdge, toEdge);
63  // if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
64  if (mySubPath.empty()) {
65  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(SVC_PEDESTRIAN, fromEdge, toEdge);
66  if (mySubPath.empty()) {
67  mySubPath = {fromEdge, toEdge};
68  myConflictDisconnected = true;
69  } else {
70  myConflictVClass = true;
71  }
72  }
73 }
74 
75 
76 GNEPlanCreator::PlanPath::PlanPath(GNEViewNet* viewNet, const SUMOVehicleClass vClass, GNEEdge* fromEdge, GNEJunction* toJunction) :
77  myConflictVClass(false),
78  myConflictDisconnected(false) {
79  // calculate subpath using given vClass
80  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, fromEdge, toJunction);
81  // if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
82  if (mySubPath.empty()) {
83  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(SVC_PEDESTRIAN, fromEdge, toJunction);
84  if (mySubPath.empty()) {
85  mySubPath = {fromEdge};
87  } else {
88  myConflictVClass = true;
89  }
90  }
91 
92 }
93 
94 
95 GNEPlanCreator::PlanPath::PlanPath(GNEViewNet* viewNet, const SUMOVehicleClass vClass, GNEJunction* fromJunction, GNEEdge* toEdge) :
96  myConflictVClass(false),
97  myConflictDisconnected(false) {
98  // calculate subpath using given vClass
99  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, fromJunction, toEdge);
100  // if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
101  if (mySubPath.empty()) {
102  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(SVC_PEDESTRIAN, fromJunction, toEdge);
103  if (mySubPath.empty()) {
104  mySubPath = {toEdge};
105  myConflictDisconnected = true;
106  } else {
107  myConflictVClass = true;
108  }
109  }
110 
111 }
112 
113 
114 GNEPlanCreator::PlanPath::PlanPath(GNEViewNet* viewNet, const SUMOVehicleClass vClass, GNEJunction* fromJunction, GNEJunction* toJunction) :
115  myConflictVClass(false),
116  myConflictDisconnected(false) {
117  // calculate subpath using the given vClass
118  mySubPath = viewNet->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, fromJunction, toJunction);
119  // if subPath is empty, try it with pedestrian (i.e. ignoring vCass)
120  if (mySubPath.empty()) {
121  if (mySubPath.empty()) {
122  myConflictDisconnected = true;
123  } else {
124  myConflictVClass = true;
125  }
126  }
127 
128 }
129 
130 
131 const std::vector<GNEEdge*>&
133  return mySubPath;
134 }
135 
136 
137 bool
139  return myConflictVClass;
140 }
141 
142 
143 bool
145  return myConflictDisconnected;
146 }
147 
148 
150  myConflictVClass(false),
151  myConflictDisconnected(false) {
152 }
153 
154 
156  MFXGroupBoxModule(frameParent, TL("Route creator")),
157  myFrameParent(frameParent),
159  myPlanParents(0) {
160  // create button for use last route
162  myUseLastRoute->disable();
163  // create button for finish route creation
165  myFinishCreationButton->disable();
166  // create button for abort route creation
168  myAbortCreationButton->disable();
169  // create button for remove last inserted edge
171  myRemoveLastInsertedElement->disable();
172  // create info label
173  myInfoLabel = new FXLabel(this, "", 0, GUIDesignLabelFrameInformation);
174 }
175 
176 
178 
179 
180 bool
182  if (planTemplate == nullptr) {
183  return false;
184  } else if (planTemplate->getTagProperty().isPlanPersonTrip()) {
186  } else if (planTemplate->getTagProperty().isPlanWalk()) {
188  } else if (planTemplate->getTagProperty().isPlanRide()) {
190  } else if (planTemplate->getTagProperty().isPlanTransport()) {
192  } else if (planTemplate->getTagProperty().isPlanTranship()) {
194  } else if (planTemplate->getTagProperty().isPlanStopPerson()) {
196  } else if (planTemplate->getTagProperty().isPlanStopContainer()) {
198  } else {
199  return false;
200  }
201 }
202 
203 
204 void
205 GNEPlanCreator::showPlanCreatorModule(const GNEPlanSelector* planSelector, const GNEDemandElement* previousPlan) {
206  // first abort creation
208  // hide creation buttons
210  // reset plan parents
211  myPlanParents = 0;
212  // set previous plan element
213  myPreviousPlanElement = previousPlan;
214  // get current plan template
215  const auto& planTagProperties = planSelector->getCurrentPlanTagProperties();
216  // continue depending of plan selector template
217  if (planTagProperties.planRoute()) {
218  myPlanParents |= ROUTE;
219  // show use last inserted route
220  myUseLastRoute->show();
221  } else {
222  // hide use last inserted route
223  myUseLastRoute->hide();
224  }
225  if (planTagProperties.planEdge()) {
226  myPlanParents |= EDGE;
227  }
228  if (planTagProperties.planStoppingPlace()) {
230  }
231  if (planTagProperties.planConsecutiveEdges()) {
233  // show creation buttons
235  }
236  if (planTagProperties.planFromEdge() || planTagProperties.planToEdge()) {
239  // show creation buttons
241  }
242  if (planTagProperties.planFromJunction() || planTagProperties.planToJunction()) {
245  // show creation buttons
247  }
248  if (planTagProperties.planFromTAZ() || planTagProperties.planToTAZ()) {
251  // show creation buttons
253  }
254  if (planTagProperties.planFromStoppingPlace() || planTagProperties.planToStoppingPlace()) {
257  // show creation buttons
259  }
260  // update info label (after setting myPlanParents)
261  updateInfoLabel();
262  // check if add first element
263  if (myPreviousPlanElement && planTagProperties.planFromTo()) {
264  const auto previousTagProperty = myPreviousPlanElement->getTagProperty();
265  // add last element of previous plan
266  if (previousTagProperty.planToEdge() || previousTagProperty.planEdge()) {
268  } else if (previousTagProperty.planToJunction()) {
270  } else if (previousTagProperty.planToTAZ()) {
272  } else if (previousTagProperty.planToStoppingPlace() || previousTagProperty.planStoppingPlace()) {
274  }
275  }
276  // set vClass
277  if (planTagProperties.isPlanRide() || planTagProperties.isPlanContainer()) {
279  } else {
281  }
282  // recalc before show (to avoid graphic problems)
283  recalc();
284  // show modul
285  show();
286 }
287 
288 
289 void
291  // clear path
292  clearPath();
293  // hide modul
294  hide();
295 }
296 
297 
298 bool
300  // check if routes are allowed
301  if ((myPlanParents & ROUTE) == 0) {
302  return false;
303  }
304  // add edge
305  myPlanParameteres.toRoute = route->getID();
306  // create path
307  return myFrameParent->createPath(false);
308 }
309 
310 
311 bool
313  // continue depending of plan parent
315  return addConsecutiveEdge(lane->getParentEdge());
316  } else if (myPlanParents & EDGE) {
317  return addSingleEdge(lane);
318  } else if ((myPlanParents & START_EDGE) || (myPlanParents & END_EDGE)) {
319  return addFromToEdge(lane->getParentEdge());
320  } else {
321  return false;
322  }
323 }
324 
325 
326 bool
329  return addFromToJunction(junction);
330  } else {
331  return false;
332  }
333 }
334 
335 
336 bool
338  if ((myPlanParents & START_TAZ) || (myPlanParents & END_TAZ)) {
339  return addFromToTAZ(taz);
340  } else {
341  return false;
342  }
343 }
344 
345 
346 bool
349  return addSingleStoppingPlace(stoppingPlace);
351  return addFromToStoppingPlace(stoppingPlace);
352  } else {
353  return false;
354  }
355 }
356 
357 
360  return myPlanParameteres;
361 }
362 
363 
364 double
367 }
368 
369 
370 const std::vector<GNEPlanCreator::PlanPath>&
372  return myPath;
373 }
374 
375 
376 void
378  const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
379  const double lineWidth = 0.35;
380  const double lineWidthin = 0.25;
381  // Add a draw matrix
383  // Start with the drawing of the area traslating matrix to origin
384  glTranslated(0, 0, GLO_MAX - 0.1);
385  // check if draw bewteen junction or edges
386  if (myPath.size() > 0) {
387  // set first color
389  // iterate over path
390  for (int i = 0; i < (int)myPath.size(); i++) {
391  // get path
392  const GNEPlanCreator::PlanPath& path = myPath.at(i);
393  // draw line over
394  for (int j = 0; j < (int)path.getSubPath().size(); j++) {
395  const GNELane* lane = path.getSubPath().at(j)->getLanes().back();
396  if (((i == 0) && (j == 0)) || (j > 0)) {
397  GLHelper::drawBoxLines(lane->getLaneShape(), lineWidth);
398  }
399  // draw connection between lanes
400  if ((j + 1) < (int)path.getSubPath().size()) {
401  const GNELane* nextLane = path.getSubPath().at(j + 1)->getLanes().back();
402  if (lane->getLane2laneConnections().exist(nextLane)) {
404  } else {
405  GLHelper::drawBoxLines({lane->getLaneShape().back(), nextLane->getLaneShape().front()}, lineWidth);
406  }
407  }
408  }
409  }
410  glTranslated(0, 0, 0.1);
411  // iterate over path again
412  for (int i = 0; i < (int)myPath.size(); i++) {
413  // get path
414  const GNEPlanCreator::PlanPath& path = myPath.at(i);
415  // set path color color
416  if (path.isConflictDisconnected()) {
418  } else if (path.isConflictVClass()) {
420  } else {
422  }
423  // draw line over
424  for (int j = 0; j < (int)path.getSubPath().size(); j++) {
425  const GNELane* lane = path.getSubPath().at(j)->getLanes().back();
426  if (((i == 0) && (j == 0)) || (j > 0)) {
427  GLHelper::drawBoxLines(lane->getLaneShape(), lineWidthin);
428  }
429  // draw connection between lanes
430  if ((j + 1) < (int)path.getSubPath().size()) {
431  const GNELane* nextLane = path.getSubPath().at(j + 1)->getLanes().back();
432  if (lane->getLane2laneConnections().exist(nextLane)) {
434  } else {
435  GLHelper::drawBoxLines({ lane->getLaneShape().back(), nextLane->getLaneShape().front() }, lineWidthin);
436  }
437  }
438  }
439  }
440  } else if (!myPlanParameteres.fromJunction.empty() && !myPlanParameteres.toJunction.empty()) {
441  // set color
443  // get two points
444  const Position posA = ACs->getJunctions().at(myPlanParameteres.fromJunction)->getPositionInView();
445  const Position posB = ACs->getJunctions().at(myPlanParameteres.toJunction)->getPositionInView();
446  const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
447  const double len = posA.distanceTo2D(posB);
448  // draw line
449  GLHelper::drawBoxLine(posA, rot, len, 0.25);
450  } else if (!myPlanParameteres.fromTAZ.empty() && !myPlanParameteres.toTAZ.empty()) {
451  // set color
453  // get two points
454  const Position posA = ACs->retrieveAdditional(SUMO_TAG_TAZ, myPlanParameteres.fromTAZ)->getPositionInView();
455  const Position posB = ACs->retrieveAdditional(SUMO_TAG_TAZ, myPlanParameteres.toTAZ)->getPositionInView();
456  const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
457  const double len = posA.distanceTo2D(posB);
458  // draw line
459  GLHelper::drawBoxLine(posA, rot, len, 0.25);
460  }
461  // Pop last matrix
463 }
464 
465 
466 void
468  // first check that there is elements
469  if (getNumberOfSelectedElements() > 0) {
470  // unblock undo/redo
472  // clear edges
473  clearPath();
474  // disable buttons
475  myFinishCreationButton->disable();
476  myAbortCreationButton->disable();
477  myRemoveLastInsertedElement->disable();
478  // update view (to see the new route)
480  }
481 }
482 
483 
484 void
486  if (myRemoveLastInsertedElement->isEnabled()) {
487  if (myPlanParameteres.consecutiveEdges.size() > 0) {
489  } else if (!myPlanParameteres.toEdge.empty()) {
490  myPlanParameteres.toEdge.clear();
491  } else if (!myPlanParameteres.toJunction.empty()) {
493  } else if (!myPlanParameteres.toTAZ.empty()) {
494  myPlanParameteres.toTAZ.clear();
495  } else if (!myPlanParameteres.toBusStop.empty()) {
497  } else if (!myPlanParameteres.toTrainStop.empty()) {
499  } else if (!myPlanParameteres.toContainerStop.empty()) {
501  } else if (!myPlanParameteres.toChargingStation.empty()) {
503  } else if (!myPlanParameteres.toParkingArea.empty()) {
505  } else if (!myPlanParameteres.fromEdge.empty()) {
506  myPlanParameteres.fromEdge.clear();
507  } else if (!myPlanParameteres.fromJunction.empty()) {
509  } else if (!myPlanParameteres.fromTAZ.empty()) {
510  myPlanParameteres.fromTAZ.clear();
511  } else if (!myPlanParameteres.fromBusStop.empty()) {
513  } else if (!myPlanParameteres.fromTrainStop.empty()) {
515  } else if (!myPlanParameteres.fromContainerStop.empty()) {
517  } else if (!myPlanParameteres.fromChargingStation.empty()) {
519  } else if (!myPlanParameteres.fromParkingArea.empty()) {
521  }
522  // update remove last item button
524  // recalculate path
525  recalculatePath();
526  }
527 }
528 
529 
530 long
531 GNEPlanCreator::onCmdCreatePath(FXObject*, FXSelector, void*) {
532  // call create path
533  return myFrameParent->createPath(false);
534 }
535 
536 
537 long
538 GNEPlanCreator::onCmdUseLastRoute(FXObject*, FXSelector, void*) {
539  // call create path using last route
540  return myFrameParent->createPath(true);
541 }
542 
543 
544 long
545 GNEPlanCreator::onUpdUseLastRoute(FXObject* sender, FXSelector, void*) {
547  return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
548  } else {
549  return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
550  }
551 }
552 
553 long
554 GNEPlanCreator::onCmdAbortPathCreation(FXObject*, FXSelector, void*) {
555  // just call abort path creation
557  return 1;
558 }
559 
560 
561 long
562 GNEPlanCreator::onCmdRemoveLastElement(FXObject*, FXSelector, void*) {
563  // just call remove last element
565  return 1;
566 }
567 
568 
569 void
571  // clear all elements
574  // clear path
575  myPath.clear();
576 }
577 
578 
579 void
581  const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
582  // first clear path
583  myPath.clear();
584  // continue depending of elements
585  if (myPlanParameteres.consecutiveEdges.size() > 0) {
586  // add every segment
587  for (int i = 1; i < (int)myPlanParameteres.consecutiveEdges.size(); i++) {
589  ACs->retrieveEdge(myPlanParameteres.consecutiveEdges.at(i - 1)),
590  ACs->retrieveEdge(myPlanParameteres.consecutiveEdges.at(i))));
591  }
592  } else {
593  // get from edge
594  GNEEdge* fromEdge = nullptr;
595  if (!myPlanParameteres.fromEdge.empty()) {
596  fromEdge = ACs->retrieveEdge(myPlanParameteres.fromEdge);
597  } else if (!myPlanParameteres.fromBusStop.empty()) {
598  fromEdge = ACs->retrieveAdditional(SUMO_TAG_BUS_STOP, myPlanParameteres.fromBusStop)->getParentLanes().front()->getParentEdge();
599  } else if (!myPlanParameteres.fromTrainStop.empty()) {
600  fromEdge = ACs->retrieveAdditional(SUMO_TAG_TRAIN_STOP, myPlanParameteres.fromTrainStop)->getParentLanes().front()->getParentEdge();
601  } else if (!myPlanParameteres.fromContainerStop.empty()) {
602  fromEdge = ACs->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, myPlanParameteres.fromContainerStop)->getParentLanes().front()->getParentEdge();
603  } else if (!myPlanParameteres.fromChargingStation.empty()) {
604  fromEdge = ACs->retrieveAdditional(SUMO_TAG_CHARGING_STATION, myPlanParameteres.fromChargingStation)->getParentLanes().front()->getParentEdge();
605  } else if (!myPlanParameteres.fromParkingArea.empty()) {
606  fromEdge = ACs->retrieveAdditional(SUMO_TAG_PARKING_AREA, myPlanParameteres.fromParkingArea)->getParentLanes().front()->getParentEdge();
607  }
608  // get to edge
609  GNEEdge* toEdge = nullptr;
610  if (!myPlanParameteres.toEdge.empty()) {
611  toEdge = ACs->retrieveEdge(myPlanParameteres.toEdge);
612  } else if (!myPlanParameteres.toBusStop.empty()) {
613  toEdge = ACs->retrieveAdditional(SUMO_TAG_BUS_STOP, myPlanParameteres.toBusStop)->getParentLanes().front()->getParentEdge();
614  } else if (!myPlanParameteres.toTrainStop.empty()) {
615  toEdge = ACs->retrieveAdditional(SUMO_TAG_TRAIN_STOP, myPlanParameteres.toTrainStop)->getParentLanes().front()->getParentEdge();
616  } else if (!myPlanParameteres.toContainerStop.empty()) {
617  toEdge = ACs->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, myPlanParameteres.toContainerStop)->getParentLanes().front()->getParentEdge();
618  } else if (!myPlanParameteres.toChargingStation.empty()) {
619  toEdge = ACs->retrieveAdditional(SUMO_TAG_CHARGING_STATION, myPlanParameteres.toChargingStation)->getParentLanes().front()->getParentEdge();
620  } else if (!myPlanParameteres.toParkingArea.empty()) {
621  toEdge = ACs->retrieveAdditional(SUMO_TAG_PARKING_AREA, myPlanParameteres.toParkingArea)->getParentLanes().front()->getParentEdge();
622  }
623  // continue depending of edges and junctions
624  if (fromEdge && toEdge) {
625  myPath.push_back(PlanPath(myFrameParent->getViewNet(), myVClass, fromEdge, toEdge));
626  } else if (fromEdge && !myPlanParameteres.toJunction.empty()) {
627  myPath.push_back(PlanPath(myFrameParent->getViewNet(), myVClass, fromEdge, ACs->getJunctions().at(myPlanParameteres.toJunction)));
628  } else if (!myPlanParameteres.fromJunction.empty() && toEdge) {
629  myPath.push_back(PlanPath(myFrameParent->getViewNet(), myVClass, ACs->getJunctions().at(myPlanParameteres.fromJunction), toEdge));
630  } else if (!myPlanParameteres.fromJunction.empty() && !myPlanParameteres.toJunction.empty()) {
632  ACs->getJunctions().at(myPlanParameteres.fromJunction),
633  ACs->getJunctions().at(myPlanParameteres.toJunction)));
634  }
635  }
636 }
637 
638 
639 int
642 }
643 
644 
645 void
647  if (myPreviousPlanElement) {
648  if (getNumberOfSelectedElements() == 2) {
649  myRemoveLastInsertedElement->enable();
650  } else {
651  myRemoveLastInsertedElement->disable();
652  }
653  } else {
654  if (getNumberOfSelectedElements() > 0) {
655  myRemoveLastInsertedElement->enable();
656  } else {
657  myRemoveLastInsertedElement->disable();
658  }
659  }
660 }
661 
662 
663 void
665  myFinishCreationButton->show();
666  myAbortCreationButton->show();
668 }
669 
670 
671 void
673  myFinishCreationButton->hide();
674  myAbortCreationButton->hide();
676 }
677 
678 
679 void
681  // declare booleans
682  const bool consecutiveEdges = (myPlanParents & CONSECUTIVE_EDGES);
683  const bool route = (myPlanParents & ROUTE);
684  const bool edges = (myPlanParents & EDGE) ||
687  const bool TAZs = (myPlanParents & START_TAZ) ||
689  const bool junctions = (myPlanParents & START_JUNCTION) ||
691  const bool stoppingPlace = (myPlanParents & STOPPINGPLACE) ||
694 
695  // declare ostringstream for label and fill it
696  std::ostringstream information;
697  information
698  << TL("Click over:") << "\n"
699  << (consecutiveEdges ? "- Consecutive edges\n" : "")
700  << (route ? "- Routes\n" : "")
701  << (edges ? "- Edges\n" : "")
702  << (TAZs ? "- TAZs\n" : "")
703  << (junctions ? "- Junctions\n" : "")
704  << (stoppingPlace ? "- StoppingPlaces\n" : "");
705  // remove last \n
706  std::string informationStr = information.str();
707  informationStr.pop_back();
708  // set label text
709  myInfoLabel->setText(informationStr.c_str());
710 }
711 
712 
713 bool
715  // add edge
717  // set position over lane
718  const auto clickedPos = myFrameParent->getViewNet()->getPositionInformation();
720  // create path
721  return myFrameParent->createPath(false);
722 }
723 
724 
725 bool
727  // continue depending of stoppingPlace tag
728  switch (stoppingPlace->getTagProperty().getTag()) {
729  case SUMO_TAG_BUS_STOP:
730  myPlanParameteres.toBusStop = stoppingPlace->getID();
731  break;
732  case SUMO_TAG_TRAIN_STOP:
733  myPlanParameteres.toTrainStop = stoppingPlace->getID();
734  break;
736  myPlanParameteres.toContainerStop = stoppingPlace->getID();
737  break;
739  myPlanParameteres.toChargingStation = stoppingPlace->getID();
740  break;
742  myPlanParameteres.toParkingArea = stoppingPlace->getID();
743  break;
744  default:
745  // abort creation
746  return false;
747  }
748  // create path
749  return myFrameParent->createPath(false);
750 }
751 
752 
753 bool
755  // check double edges
756  if ((myPlanParameteres.consecutiveEdges.size() > 0) && (myPlanParameteres.consecutiveEdges.back() == edge->getID())) {
757  // Write warning
758  WRITE_WARNING(TL("Double edges aren't allowed"));
759  // abort add edge
760  return false;
761  }
762  // All checks ok, then add it in selected elements
763  myPlanParameteres.consecutiveEdges.push_back(edge->getID());
764  // enable abort route button
765  myAbortCreationButton->enable();
766  // enable finish button
767  myFinishCreationButton->enable();
768  // update remove last item button
770  // recalculate path
771  recalculatePath();
772  // edge added, then return true
773  return true;
774 }
775 
776 
777 bool
779  // avoid double junctions
780  if (myPlanParameteres.fromJunction == junction->getID()) {
781  // Write warning
782  WRITE_WARNING(TL("Double junctions aren't allowed"));
783  // abort add junction
784  return false;
785  }
786  // check number of selected items
787  if (getNumberOfSelectedElements() == 2) {
788  // Write warning
789  WRITE_WARNING(TL("Only two from-to elements are allowed"));
790  // abort add function
791  return false;
792  }
793  // set junction
794  if (getNumberOfSelectedElements() == 0) {
795  myPlanParameteres.fromJunction = junction->getID();
796  } else {
797  myPlanParameteres.toJunction = junction->getID();
798  }
799  // enable abort route button
800  myAbortCreationButton->enable();
801  // enable finish button
802  myFinishCreationButton->enable();
803  // update remove last item button
805  // recalculate path
806  recalculatePath();
807  return true;
808 }
809 
810 
811 bool
813  // avoid double TAZs
814  if (myPlanParameteres.fromTAZ == TAZ->getID()) {
815  // Write warning
816  WRITE_WARNING(TL("Double TAZs aren't allowed"));
817  // abort add TAZ
818  return false;
819  }
820  // check number of selected items
821  if (getNumberOfSelectedElements() == 2) {
822  // Write warning
823  WRITE_WARNING(TL("Only two from-to elements are allowed"));
824  // abort add function
825  return false;
826  }
827  // set TAZ
828  if (getNumberOfSelectedElements() == 0) {
829  myPlanParameteres.fromTAZ = TAZ->getID();
830  } else {
831  myPlanParameteres.toTAZ = TAZ->getID();
832  }
833  // enable abort route button
834  myAbortCreationButton->enable();
835  // enable finish button
836  myFinishCreationButton->enable();
837  // update remove last item button
839  // recalculate path
840  recalculatePath();
841  return true;
842 }
843 
844 
845 bool
847  // check double edges
848  if (myPlanParameteres.fromEdge == edge->getID()) {
849  // Write warning
850  WRITE_WARNING(TL("Double edges aren't allowed"));
851  // abort add edge
852  return false;
853  }
854  // check number of selected items
855  if (getNumberOfSelectedElements() == 2) {
856  // Write warning
857  WRITE_WARNING(TL("Only two from-to elements are allowed"));
858  // abort add function
859  return false;
860  }
861  // set edge
862  if (getNumberOfSelectedElements() == 0) {
863  myPlanParameteres.fromEdge = edge->getID();
864  } else {
865  myPlanParameteres.toEdge = edge->getID();
866  }
867  // enable abort route button
868  myAbortCreationButton->enable();
869  // enable finish button
870  myFinishCreationButton->enable();
871  // update remove last item button
873  // recalculate path
874  recalculatePath();
875  // edge added, then return true
876  return true;
877 }
878 
879 
880 bool
882  // check double stoppingPlaces
883  const auto stoppingPlaceID = stoppingPlace->getID();
884  if ((myPlanParameteres.toBusStop == stoppingPlaceID) ||
885  (myPlanParameteres.toTrainStop == stoppingPlaceID) ||
886  (myPlanParameteres.toContainerStop == stoppingPlaceID) ||
887  (myPlanParameteres.toChargingStation == stoppingPlaceID) ||
888  (myPlanParameteres.toParkingArea == stoppingPlaceID)) {
889  // Write warning
890  WRITE_WARNING(TL("Double stoppingPlaces aren't allowed"));
891  // abort add stopping place
892  return false;
893  }
894  // check number of selected items
895  if (getNumberOfSelectedElements() == 2) {
896  // Write warning
897  WRITE_WARNING(TL("Only two from-to elements are allowed"));
898  // abort add function
899  return false;
900  }
901  // add stoppingPlace
902  if (getNumberOfSelectedElements() == 0) {
903  // continue depending of stoppingPlace tag
904  switch (stoppingPlace->getTagProperty().getTag()) {
905  case SUMO_TAG_BUS_STOP:
906  myPlanParameteres.fromBusStop = stoppingPlaceID;
907  break;
908  case SUMO_TAG_TRAIN_STOP:
909  myPlanParameteres.fromTrainStop = stoppingPlaceID;
910  break;
912  myPlanParameteres.fromContainerStop = stoppingPlaceID;
913  break;
915  myPlanParameteres.fromChargingStation = stoppingPlaceID;
916  break;
918  myPlanParameteres.fromParkingArea = stoppingPlaceID;
919  break;
920  default:
921  return false;
922  }
923  } else {
924  // continue depending of stoppingPlace tag
925  switch (stoppingPlace->getTagProperty().getTag()) {
926  case SUMO_TAG_BUS_STOP:
927  myPlanParameteres.toBusStop = stoppingPlaceID;
928  break;
929  case SUMO_TAG_TRAIN_STOP:
930  myPlanParameteres.toTrainStop = stoppingPlaceID;
931  break;
933  myPlanParameteres.toContainerStop = stoppingPlaceID;
934  break;
936  myPlanParameteres.toChargingStation = stoppingPlaceID;
937  break;
939  myPlanParameteres.toParkingArea = stoppingPlaceID;
940  break;
941  default:
942  return false;
943  }
944  }
945  // enable abort route button
946  myAbortCreationButton->enable();
947  // enable finish button
948  myFinishCreationButton->enable();
949  // disable undo/redo
951  // enable or disable remove last item button
953  // recalculate path
954  recalculatePath();
955  // stopping place added, then return true
956  return true;
957 }
958 
959 /****************************************************************************/
FXDEFMAP(GNEPlanCreator) PathCreatorMap[]
@ MID_GNE_PATHCREATOR_FINISH
finish edge path creation
Definition: GUIAppEnum.h:985
@ MID_GNE_PATHCREATOR_REMOVELAST
remove last inserted element in path
Definition: GUIAppEnum.h:989
@ MID_GNE_PATHCREATOR_USELASTROUTE
use last inserted route
Definition: GUIAppEnum.h:987
@ MID_GNE_PATHCREATOR_ABORT
abort edge path creation
Definition: GUIAppEnum.h:983
#define GUIDesignButton
Definition: GUIDesigns.h:88
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:285
@ GLO_MAX
empty max
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_NOTHING
invalid tag, must be the last one
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
plan parameters (used for group all from-to parameters related with plans)
std::string fromJunction
from junction
std::string fromContainerStop
from containerStop
std::string toTrainStop
to trainStop
int getNumberOfDefinedParameters() const
get number of defined plans
std::string fromTrainStop
from trainStop
std::string toParkingArea
to parkingArea
std::string fromBusStop
from busStop
std::vector< std::string > consecutiveEdges
consecutive edges
std::string fromChargingStation
from chargingStation
std::string toChargingStation
to chargingStation
std::string fromParkingArea
from parkingArea
std::string toContainerStop
to containerStop
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:654
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:130
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:347
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:295
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:117
An Element which don't belong to GNENet but has influence in the simulation.
Definition: GNEAdditional.h:49
void disableUndoRedo(const std::string &reason)
disable undo-redo giving a string with the reason
void enableUndoRedo()
disable undo-redo
const std::string getID() const
get ID (all Attribute Carriers have one)
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
static std::pair< SumoXMLTag, GUIIcon > getPersonTripTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the personTrip tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getContainerStopTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the container stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getRideTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the ride tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getPersonStopTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the person stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getWalkTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the walk tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTranshipTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the tranship tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTransportTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the transport tag and icon for the combination
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
GNEViewNet * getViewNet() const
get view net
Definition: GNEFrame.cpp:150
virtual bool createPath(const bool useLastRoute)
create path between two elements
Definition: GNEFrame.cpp:304
const std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
const std::vector< GNEAdditional * > getParentStoppingPlaces() const
get parent stoppingPlaces (used by plans)
const std::vector< GNEAdditional * > getParentTAZs() const
get parent TAZs (used by plans)
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
bool exist(const GNELane *toLane) const
check if exist a lane2lane geometry for the given toLane
const GUIGeometry & getLane2laneGeometry(const GNELane *toLane) const
get lane2lane geometry
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
const PositionVector & getLaneShape() const
get elements shape
Definition: GNELane.cpp:214
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition: GNELane.cpp:657
GNEEdge * getParentEdge() const
get parent edge
Definition: GNELane.cpp:196
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:123
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:135
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &edges) const
calculate Dijkstra path between a list of edges (for example, from-via-to edges)
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
bool myConflictVClass
flag to mark this path as conflicted
bool isConflictDisconnected() const
check if current path is conflict due is disconnected
bool myConflictDisconnected
flag to mark this path as disconnected
const std::vector< GNEEdge * > & getSubPath() const
get sub path
PlanPath()
default constructor
std::vector< GNEEdge * > mySubPath
sub path
bool isConflictVClass() const
check if current path is conflict due vClass
bool addStoppingPlace(GNEAdditional *stoppingPlace)
add from to stoppingPlace
bool addConsecutiveEdge(GNEEdge *edge)
add consecutive edge
void removeLastElement()
remove path element
bool addRoute(GNEDemandElement *route)
add route
double myClickedPositionOverLane
clicked position over lane
const GNEDemandElement * myPreviousPlanElement
previous person plan element
double getClickedPositionOverLane() const
get clicked position over lane
bool addFromToJunction(GNEJunction *junction)
add junction
bool planCanBeCreated(const GNEDemandElement *planTemplate) const
check if plan can be created
long onUpdUseLastRoute(FXObject *, FXSelector, void *)
Called when update button "Use last route".
bool addSingleEdge(GNELane *lane)
add edge
GNEFrame * myFrameParent
current frame parent
int myPlanParents
allowed plan parents
void hidePathCreatorModule()
show GNEPlanCreator
long onCmdCreatePath(FXObject *, FXSelector, void *)
void showCreationButtons()
show creation buttons
long onCmdUseLastRoute(FXObject *, FXSelector, void *)
Called when the user click over button "Use last route".
bool addTAZ(GNEAdditional *taz)
add TAZ
void updateRemoveLastItemButton() const
check if enable remove last item button
bool addJunction(GNEJunction *junction)
add junction
int getNumberOfSelectedElements() const
get number of selected elements
void recalculatePath()
recalculate path
CommonXMLStructure::PlanParameters myPlanParameteres
plan parameters
bool addEdge(GNELane *lane)
add edge (clicking over lanes)
SUMOVehicleClass myVClass
current vClass
bool addFromToEdge(GNEEdge *edge)
add from to edge
~GNEPlanCreator()
destructor
FXButton * myAbortCreationButton
button for abort route creation
void abortPathCreation()
abort path creation
long onCmdAbortPathCreation(FXObject *, FXSelector, void *)
Called when the user click over button "Abort route creation".
void clearPath()
clear edges
FXButton * myFinishCreationButton
button for finish route creation
void drawTemporalRoute(const GUIVisualizationSettings &s) const
draw temporal route
bool addFromToTAZ(GNEAdditional *taz)
add TAZ
long onCmdRemoveLastElement(FXObject *, FXSelector, void *)
Called when the user click over button "Remove las inserted edge".
FXButton * myRemoveLastInsertedElement
button for removing last inserted element
std::vector< PlanPath > myPath
vector with current path
const std::vector< PlanPath > & getPath() const
get path route
GNEPlanCreator(GNEFrame *frameParent)
default constructor
FXButton * myUseLastRoute
button for use last inserted route
bool addFromToStoppingPlace(GNEAdditional *stoppingPlace)
add from to stoppingPlace
FXLabel * myInfoLabel
info label
void hideCreationButtons()
hide creation buttons
void showPlanCreatorModule(const GNEPlanSelector *planSelector, const GNEDemandElement *previousPlan)
show plan creator for the given tag property
const CommonXMLStructure::PlanParameters & getPlanParameteres() const
get plan parameters
void updateInfoLabel()
update info label
bool addSingleStoppingPlace(GNEAdditional *stoppingPlace)
add stoppingPlace
const GNETagProperties & getCurrentPlanTagProperties() const
get current plan tag properties
bool isPlanTransport() const
return true if tag correspond to a transport
bool isPlanStopContainer() const
return true if tag correspond to a container stop plan
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isPlanPersonTrip() const
return true if tag correspond to a person trip plan
bool isPlanRide() const
return true if tag correspond to a ride plan
bool isPlanStopPerson() const
return true if tag correspond to a person stop plan
bool isPlanWalk() const
return true if tag correspond to a walk plan
bool isPlanTranship() const
return true if tag correspond to a tranship
GNENet * getNet() const
get the net object
GNEDemandElement * getLastCreatedRoute() const
get last created route
GNEViewParent * getViewParent() const
get the net object
void updateViewNet() const
Mark the entire GNEViewNet to be repainted later.
Definition: GNEViewNet.cpp:419
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
Definition: GUIDesigns.cpp:128
const PositionVector & getShape() const
The shape of the additional element.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
Stores the information about how to visualize structures.
GUIVisualizationCandidateColorSettings candidateColorSettings
candidate color settings
MFXGroupBoxModule (based on FXGroupBox)
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:276
double x() const
Returns the x-position.
Definition: Position.h:55
double y() const
Returns the y-position.
Definition: Position.h:60
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
static const RGBColor GREY
Definition: RGBColor.h:194
static const RGBColor ORANGE
Definition: RGBColor.h:191
#define M_PI
Definition: odrSpiral.cpp:45
static const RGBColor special
color for selected special candidate element (Usually selected using shift+click)
static const RGBColor conflict
color for selected conflict candidate element (Usually selected using ctrl+click)