Eclipse SUMO - Simulation of Urban MObility
GNERoute.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // A class for visualizing routes in Netedit
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEUndoList.h>
24 #include <netedit/GNEViewNet.h>
27 #include <utils/gui/div/GLHelper.h>
30 
31 #include "GNERoute.h"
32 
33 // ===========================================================================
34 // FOX callback mapping
35 // ===========================================================================
36 FXDEFMAP(GNERoute::GNERoutePopupMenu) GNERoutePopupMenuMap[] = {
38 };
39 
40 // Object implementation
41 FXIMPLEMENT(GNERoute::GNERoutePopupMenu, GUIGLObjectPopupMenu, GNERoutePopupMenuMap, ARRAYNUMBER(GNERoutePopupMenuMap))
42 
43 // ===========================================================================
44 // GNERoute::GNERoutePopupMenu - methods
45 // ===========================================================================
46 
48  GUIGLObjectPopupMenu(app, parent, o) {
49 }
50 
51 
53 
54 
55 long
56 GNERoute::GNERoutePopupMenu::onCmdApplyDistance(FXObject*, FXSelector, void*) {
57  GNERoute* route = static_cast<GNERoute*>(myObject);
58  GNEUndoList* undoList = route->myNet->getViewNet()->getUndoList();
59  undoList->begin(GUIIcon::ROUTE, "apply distance along route");
60  double dist = (route->getParentEdges().size() > 0) ? route->getParentEdges().front()->getNBEdge()->getDistance() : 0;
61  for (GNEEdge* edge : route->getParentEdges()) {
62  undoList->changeAttribute(new GNEChange_Attribute(edge, SUMO_ATTR_DISTANCE, toString(dist), edge->getAttribute(SUMO_ATTR_DISTANCE)));
63  dist += edge->getNBEdge()->getFinalLength();
64  }
65  undoList->end();
66  return 1;
67 }
68 
69 // ===========================================================================
70 // GNERoute - methods
71 // ===========================================================================
72 
74  GNEDemandElement("", net, GLO_ROUTE, tag,
76 {}, {}, {}, {}, {}, {}, {}, {}),
78 myColor(RGBColor::YELLOW),
79 myCustomColor(false),
80 myRepeat(0),
81 myCycleTime(0),
82 myVClass(SVC_PASSENGER) {
83  // reset default values
84  resetDefaultValues();
85 }
86 
87 
89  GNEDemandElement(net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE), net, GLO_ROUTE, SUMO_TAG_ROUTE,
90  GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
91 {}, {}, {}, {}, {}, {}, {}, {}),
93 myColor(RGBColor::YELLOW),
94 myCustomColor(false),
95 myRepeat(0),
96 myCycleTime(0),
97 myVClass(SVC_PASSENGER) {
98  // reset default values
99  resetDefaultValues();
100 }
101 
102 
103 GNERoute::GNERoute(GNENet* net, const std::string& id, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges,
104  const RGBColor& color, const int repeat, const SUMOTime cycleTime, const std::map<std::string, std::string>& parameters) :
106  GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
107 {}, edges, {}, {}, {}, {}, {}, {}),
108 Parameterised(parameters),
109 myColor(color),
110 myCustomColor(color != RGBColor(false)),
111 myRepeat(repeat),
112 myCycleTime(cycleTime),
113 myVClass(vClass) {
114 }
115 
116 
117 GNERoute::GNERoute(GNENet* net, GNEDemandElement* vehicleParent, const std::vector<GNEEdge*>& edges,
118  const RGBColor& color, const int repeat, const SUMOTime cycleTime, const std::map<std::string, std::string>& parameters) :
120  GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
121 {}, edges, {}, {}, {}, {}, {vehicleParent}, {}),
122 Parameterised(parameters),
123 myColor(color),
124 myCustomColor(color != RGBColor::INVISIBLE),
125 myRepeat(repeat),
126 myCycleTime(cycleTime),
127 myVClass(vehicleParent->getVClass()) {
128 }
129 
130 
132  GNEDemandElement(route, route->getNet(), GLO_ROUTE, SUMO_TAG_ROUTE,
133  GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
134 {}, route->getParentEdges(), {}, {}, {}, {}, {}, {}),
135 Parameterised(),
136 myColor(route->getColor()),
137 myCustomColor(!route->getAttribute(SUMO_ATTR_COLOR).empty()),
138 myRepeat(parse<int>(route->getAttribute(SUMO_ATTR_REPEAT))),
139 myCycleTime(parse<SUMOTime>(route->getAttribute(SUMO_ATTR_CYCLETIME))),
140 myVClass(route->getVClass()) {
141 }
142 
143 
145 
146 
149  return nullptr;
150 }
151 
152 
155  GUIGLObjectPopupMenu* ret = new GNERoutePopupMenu(app, parent, *this);
156  // build header
157  buildPopupHeader(ret, app);
158  // build menu command for center button and copy cursor position to clipboard
160  buildPositionCopyEntry(ret, false);
161  // buld menu commands for names
162  GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " name to clipboard", nullptr, ret, MID_COPY_NAME);
163  GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " typed name to clipboard", nullptr, ret, MID_COPY_TYPED_NAME);
164  new FXMenuSeparator(ret);
165  // build selection and show parameters menu
168  // show option to open demand element dialog
169  if (myTagProperty.hasDialog()) {
170  GUIDesigns::buildFXMenuCommand(ret, "Open " + getTagStr() + " Dialog", getIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
171  new FXMenuSeparator(ret);
172  }
173  GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
174  new FXMenuSeparator(ret);
175  GUIDesigns::buildFXMenuCommand(ret, "Apply distance along route", nullptr, ret, MID_GNE_ROUTE_APPLY_DISTANCE);
176  return ret;
177 }
178 
179 
180 void
182  device.openTag(SUMO_TAG_ROUTE);
183  // write id only for non-embedded routes
185  device.writeAttr(SUMO_ATTR_ID, getID());
186  }
188  if (myCustomColor) {
190  }
191  if (myRepeat != 0) {
193  }
194  if (myCycleTime != 0) {
196  }
197  // write sorted stops
199  const auto sortedStops = getSortedStops(getParentEdges());
200  for (const auto& stop : sortedStops) {
201  stop->writeDemandElement(device);
202  }
203  }
204  // write parameters
205  writeParams(device);
206  // close tag
207  device.closeTag();
208 }
209 
210 
213  // get sorted stops and check number
214  std::vector<GNEDemandElement*> stops;
215  for (const auto& routeChild : getChildDemandElements()) {
216  if (routeChild->getTagProperty().isStop()) {
217  stops.push_back(routeChild);
218  }
219  }
220  const auto sortedStops = getSortedStops(getParentEdges());
221  if (sortedStops.size() != stops.size()) {
223  }
224  // check parent edges
225  if ((getParentEdges().size() == 2) && (getParentEdges().at(0) == getParentEdges().at(1))) {
226  // from and to are the same edges, then return true
227  return Problem::OK;
228  } else if (getParentEdges().size() > 0) {
229  // check that exist a connection between every edge
230  if (isRouteValid(getParentEdges()).size() > 0) {
231  return Problem::INVALID_PATH;
232  } else {
233  return Problem::OK;
234  }
235  } else {
237  }
238 }
239 
240 
241 std::string
243  // get sorted stops and check number
244  std::vector<GNEDemandElement*> stops;
245  for (const auto& routeChild : getChildDemandElements()) {
246  if (routeChild->getTagProperty().isStop()) {
247  stops.push_back(routeChild);
248  }
249  }
250  const auto sortedStops = getSortedStops(getParentEdges());
251  if (sortedStops.size() != stops.size()) {
252  return toString(stops.size() - sortedStops.size()) + " stops are outside of route (downstream)";
253  }
254  // return string with the problem obtained from isRouteValid
255  return isRouteValid(getParentEdges());
256 }
257 
258 
259 void
261  // currently the only solution is removing Route
262 }
263 
264 
267  return myVClass;
268 }
269 
270 
271 const RGBColor&
273  if (myCustomColor) {
274  return myColor;
275  } else if (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED) {
276  return getParentDemandElements().front()->getColor();
277  } else if (getChildDemandElements().size() > 0) {
278  return getChildDemandElements().front()->getColor();
279  } else {
280  return RGBColor::YELLOW;
281  }
282 }
283 
284 
285 void
287  // compute geometry
289  // update child demand elementss
290  for (const auto& demandElement : getChildDemandElements()) {
291  if (!demandElement->getTagProperty().isStopPerson() && !demandElement->getTagProperty().isStop()) {
292  demandElement->updateGeometry();
293  }
294  }
295 }
296 
297 
298 Position
301 }
302 
303 
304 std::string
306  return getParentEdges().front()->getID();
307 }
308 
309 
310 double
312  return s.vehicleSize.getExaggeration(s, this);
313 }
314 
315 
316 Boundary
318  Boundary routeBoundary;
319  // return the combination of all parent edges's boundaries
320  for (const auto& i : getParentEdges()) {
321  routeBoundary.add(i->getCenteringBoundary());
322  }
323  // check if is valid
324  if (routeBoundary.isInitialised()) {
325  return routeBoundary;
326  } else {
327  return Boundary(-0.1, -0.1, 0.1, 0.1);
328  }
329 }
330 
331 
332 void
333 GNERoute::splitEdgeGeometry(const double /*splitPosition*/, const GNENetworkElement* originalElement, const GNENetworkElement* newElement, GNEUndoList* undoList) {
334  // obtain new list of route edges
335  std::string newRouteEdges = getNewListOfParents(originalElement, newElement);
336  // update route edges
337  if (newRouteEdges.size() > 0) {
338  setAttribute(SUMO_ATTR_EDGES, newRouteEdges, undoList);
339  }
340 }
341 
342 
343 void
345  // Routes are drawn in drawPartialGL
346 }
347 
348 
349 void
352  // get parent vehicle
353  const GNEDemandElement* parentVehicle = getParentDemandElements().at(0);
354  // declare lane vector
355  std::vector<GNELane*> lanes;
356  // get first and last path lane
357  GNELane* firstLane = parentVehicle->getFirstPathLane();
358  GNELane* lastLane = parentVehicle->getLastPathLane();
359  // insert first vehicle lane
360  if (firstLane) {
361  lanes.push_back(firstLane);
362  }
363  // add middle lanes
364  for (int i = 1; i < ((int)getParentEdges().size() - 1); i++) {
365  lanes.push_back(getParentEdges().at(i)->getLaneByAllowedVClass(getVClass()));
366  }
367  // insert last vehicle lane
368  if (lastLane) {
369  lanes.push_back(lastLane);
370  }
371  // calculate consecutive path using vClass of vehicle parent
373  } else {
374  // calculate path using SVC_PASSENGER
376  // if path is empty, then calculate path again using SVC_IGNORING
377  if (!myNet->getPathManager()->isPathValid(this)) {
379  }
380  }
381 }
382 
383 
384 void
385 GNERoute::drawPartialGL(const GUIVisualizationSettings& s, const GNELane* lane, const GNEPathManager::Segment* segment, const double offsetFront) const {
386  // get inspected and front flags
387  const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) || (myNet->getViewNet()->getFrontAttributeCarrier() == this);
388  // check conditions
392  myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, lane, myTagProperty.getTag())) {
393  // get embedded route flag
394  const bool embedded = (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED);
395  // get route width
396  const double routeWidth = getExaggeration(s) * (embedded ? s.widthSettings.embeddedRouteWidth : s.widthSettings.routeWidth);
397  // calculate startPos
398  const double geometryDepartPos = embedded ? (getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_DEPARTPOS) + getParentDemandElements().at(0)->getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_LENGTH)) : -1;
399  // get endPos
400  const double geometryEndPos = embedded ? getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_ARRIVALPOS) : -1;
401  // declare path geometry
402  GUIGeometry routeGeometry;
403  // update pathGeometry depending of first and last segment
404  if (segment->isFirstSegment() && segment->isLastSegment()) {
405  routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
406  geometryDepartPos, geometryEndPos, // extrem positions
407  Position::INVALID, Position::INVALID); // extra positions
408  } else if (segment->isFirstSegment()) {
409  routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
410  geometryDepartPos, -1, // extrem positions
411  Position::INVALID, Position::INVALID); // extra positions
412  } else if (segment->isLastSegment()) {
413  routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
414  -1, geometryEndPos, // extrem positions
415  Position::INVALID, Position::INVALID); // extra positions
416  } else {
417  routeGeometry = lane->getLaneGeometry();
418  }
419  // obtain color
421  // Start drawing adding an gl identificator
423  // Add a draw matrix
425  // Start with the drawing of the area traslating matrix to origin
426  myNet->getViewNet()->drawTranslateFrontAttributeCarrier(this, getType(), offsetFront + (embedded ? 0.1 : 0));
427  // Set color
428  GLHelper::setColor(routeColor);
429  // draw route geometry
430  GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), routeGeometry, routeWidth);
431  // Pop last matrix
433  // Draw name if isn't being drawn for selecting
434  if (!s.drawForRectangleSelection) {
435  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
436  }
437  // Pop name
439  // check if we have to draw a red line to the next segment
440  if (segment->getNextSegment()) {
441  // push draw matrix
443  // Start with the drawing of the area traslating matrix to origin
445  // Set red color
447  // get firstPosition (last position of current lane shape)
448  const Position firstPosition = lane->getLaneShape().back();
449  // get lastPosition (first position of next lane shape)
450  const Position arrivalPos = segment->getNextSegment()->getPathElement()->getPathElementArrivalPos();
451  // draw box line
452  GLHelper::drawBoxLine(arrivalPos,
453  RAD2DEG(firstPosition.angleTo2D(arrivalPos)) - 90,
454  firstPosition.distanceTo2D(arrivalPos), .05);
455  // pop draw matrix
457  }
458  // check if shape dotted contour has to be drawn
459  if (dottedElement) {
460  // declare trim geometry to draw
461  const auto shape = (segment->isFirstSegment() || segment->isLastSegment() ? routeGeometry.getShape() : lane->getLaneShape());
462  // draw inspected dotted contour
465  }
466  // draw front dotted contour
467  if ((myNet->getViewNet()->getFrontAttributeCarrier() == this)) {
469  }
470  }
471  }
472 }
473 
474 
475 void
476 GNERoute::drawPartialGL(const GUIVisualizationSettings& s, const GNELane* fromLane, const GNELane* toLane, const GNEPathManager::Segment* /*segment*/, const double offsetFront) const {
477  // get inspected and front flags
478  const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) || (myNet->getViewNet()->getFrontAttributeCarrier() == this);
479  // check conditions
482  fromLane->getLane2laneConnections().exist(toLane) &&
484  myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, fromLane, toLane, myTagProperty.getTag())) {
485  // get embedded route flag
486  const bool embedded = (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED);
487  // get route width
488  const double routeWidth = getExaggeration(s) * (embedded ? s.widthSettings.embeddedRouteWidth : s.widthSettings.routeWidth);
489  // obtain lane2lane geometry
490  const GUIGeometry& lane2laneGeometry = fromLane->getLane2laneConnections().getLane2laneGeometry(toLane);
491  // obtain color
493  // Start drawing adding an gl identificator
495  // Add a draw matrix
497  // Start with the drawing of the area traslating matrix to origin
498  myNet->getViewNet()->drawTranslateFrontAttributeCarrier(this, getType(), offsetFront + (embedded ? 0.1 : 0));
499  // Set color
500  GLHelper::setColor(routeColor);
501  // draw lane2lane
502  GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), lane2laneGeometry, routeWidth);
503  // Pop last matrix
505  // Pop name
507  // draw lock icon
509  // check if shape dotted contour has to be drawn
510  if (dottedElement) {
511  // check if exist lane2lane connection
512  if (fromLane->getLane2laneConnections().exist(toLane)) {
513  // draw inspected dotted contour
516  routeWidth, 1, false, false);
517  }
518  // draw front dotted contour
519  if ((myNet->getViewNet()->getFrontAttributeCarrier() == this)) {
521  routeWidth, 1, false, false);
522  }
523  }
524  }
525  }
526 }
527 
528 
529 GNELane*
532  return getParentEdges().front()->getLaneByAllowedVClass(SVC_PASSENGER);
533  } else {
534  return getParentDemandElements().at(0)->getFirstPathLane();
535  }
536 }
537 
538 
539 GNELane*
542  return getParentEdges().back()->getLaneByAllowedVClass(SVC_PASSENGER);
543  } else {
544  return getParentDemandElements().at(0)->getLastPathLane();
545  }
546 }
547 
548 
549 std::string
551  switch (key) {
552  case SUMO_ATTR_ID:
553  return getID();
554  case SUMO_ATTR_EDGES:
555  return parseIDs(getParentEdges());
556  case SUMO_ATTR_COLOR:
557  if (myCustomColor) {
558  return toString(myColor);
559  } else {
560  return "";
561  }
562  case SUMO_ATTR_REPEAT:
563  return toString(myRepeat);
564  case SUMO_ATTR_CYCLETIME:
565  return time2string(myCycleTime);
566  case GNE_ATTR_SELECTED:
568  case GNE_ATTR_PARAMETERS:
569  return getParametersStr();
570  default:
571  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
572  }
573 }
574 
575 
576 double
578  switch (key) {
579  case SUMO_ATTR_DEPARTPOS:
580  return 0;
582  return getParentEdges().back()->getLanes().front()->getLaneShape().length2D();
583  default:
584  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
585  }
586 }
587 
588 
589 Position
591  switch (key) {
592  case SUMO_ATTR_DEPARTPOS:
593  return getParentEdges().front()->getLanes().front()->getLaneShape().front();
595  return getParentEdges().back()->getLanes().front()->getLaneShape().back();
596  default:
597  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
598  }
599 }
600 
601 
602 void
603 GNERoute::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
604  if (value == getAttribute(key)) {
605  return; //avoid needless changes, later logic relies on the fact that attributes have changed
606  }
607  switch (key) {
608  case SUMO_ATTR_ID:
609  case SUMO_ATTR_COLOR:
610  case SUMO_ATTR_REPEAT:
611  case SUMO_ATTR_CYCLETIME:
612  case GNE_ATTR_SELECTED:
613  case GNE_ATTR_PARAMETERS:
614  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
615  break;
616  // special case due depart and arrival edge vehicles
617  case SUMO_ATTR_EDGES: {
618  // extract all vehicle childrens
619  std::vector<GNEDemandElement*> vehicles;
620  for (const auto& childDemandElement : getChildDemandElements()) {
621  if (childDemandElement->getTagProperty().isVehicle()) {
622  vehicles.push_back(childDemandElement);
623  }
624  }
625  // check vehicles
626  if (vehicles.size() > 0) {
627  undoList->begin(GUIIcon::ROUTE, "reset start and end edges");
628  for (const auto& vehicle : vehicles) {
629  undoList->changeAttribute(new GNEChange_Attribute(vehicle, SUMO_ATTR_DEPARTEDGE, ""));
630  undoList->changeAttribute(new GNEChange_Attribute(vehicle, SUMO_ATTR_ARRIVALEDGE, ""));
631  }
632  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
633  undoList->end();
634  } else if (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED) {
635  undoList->begin(GUIIcon::ROUTE, "reset start and end edges");
638  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
639  undoList->end();
640  } else {
641  // just change edges
642  undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
643  }
644  break;
645  }
646  default:
647  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
648  }
649 }
650 
651 
652 bool
653 GNERoute::isValid(SumoXMLAttr key, const std::string& value) {
654  switch (key) {
655  case SUMO_ATTR_ID:
656  return isValidDemandElementID(value);
657  case SUMO_ATTR_EDGES:
658  if (canParse<std::vector<GNEEdge*> >(myNet, value, false)) {
659  // all edges exist, then check if compounds a valid route
660  return isRouteValid(parse<std::vector<GNEEdge*> >(myNet, value)).empty();
661  } else {
662  return false;
663  }
664  case SUMO_ATTR_COLOR:
665  if (value.empty()) {
666  return true;
667  } else {
668  return canParse<RGBColor>(value);
669  }
670  case SUMO_ATTR_REPEAT:
671  return canParse<int>(value);
672  case SUMO_ATTR_CYCLETIME:
673  if (canParse<double>(value)) {
674  return (parse<double>(value) >= 0);
675  } else {
676  return false;
677  }
678  case GNE_ATTR_SELECTED:
679  return canParse<bool>(value);
680  case GNE_ATTR_PARAMETERS:
681  return Parameterised::areParametersValid(value);
682  default:
683  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
684  }
685 }
686 
687 
688 void
690  //
691 }
692 
693 
694 void
696  //
697 }
698 
699 
700 bool
702  return true;
703 }
704 
705 
706 std::string
708  return getTagStr();
709 }
710 
711 
712 std::string
714  return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID) ;
715 }
716 
717 
718 const std::map<std::string, std::string>&
720  return getParametersMap();
721 }
722 
723 
724 std::string
725 GNERoute::isRouteValid(const std::vector<GNEEdge*>& edges) {
726  if (edges.size() == 0) {
727  // routes cannot be empty
728  return ("list of route edges cannot be empty");
729  } else if (edges.size() == 1) {
730  // routes with a single edge are valid, then return an empty string
731  return ("");
732  } else {
733  // iterate over edges to check that compounds a chain
734  auto it = edges.begin();
735  while (it != edges.end() - 1) {
736  const GNEEdge* currentEdge = *it;
737  const GNEEdge* nextEdge = *(it + 1);
738  // same consecutive edges aren't allowed
739  if (currentEdge->getID() == nextEdge->getID()) {
740  return ("consecutive duplicated edges (" + currentEdge->getID() + ") aren't allowed in a route");
741  }
742  // obtain outgoing edges of currentEdge
743  const std::vector<GNEEdge*>& outgoingEdges = currentEdge->getToJunction()->getGNEOutgoingEdges();
744  // check if nextEdge is in outgoingEdges
745  if (std::find(outgoingEdges.begin(), outgoingEdges.end(), nextEdge) == outgoingEdges.end()) {
746  return ("Edges '" + currentEdge->getID() + "' and '" + nextEdge->getID() + "' aren't consecutives");
747  }
748  it++;
749  }
750  // all edges consecutives, then return an empty string
751  return ("");
752  }
753 }
754 
755 // ===========================================================================
756 // private
757 // ===========================================================================
758 
759 void
760 GNERoute::setAttribute(SumoXMLAttr key, const std::string& value) {
761  switch (key) {
762  case SUMO_ATTR_ID:
763  // update microsimID
764  setMicrosimID(value);
765  break;
766  case SUMO_ATTR_EDGES:
768  // compute route
770  break;
771  case SUMO_ATTR_COLOR:
772  if (value.empty()) {
773  myCustomColor = false;
775  } else {
776  myCustomColor = true;
777  myColor = parse<RGBColor>(value);
778  }
779  break;
780  case SUMO_ATTR_REPEAT:
781  myRepeat = parse<int>(value);
782  break;
783  case SUMO_ATTR_CYCLETIME:
784  myCycleTime = string2time(value);
785  break;
786  case GNE_ATTR_SELECTED:
787  if (parse<bool>(value)) {
789  } else {
791  }
792  break;
793  case GNE_ATTR_PARAMETERS:
794  setParametersStr(value);
795  break;
796  default:
797  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
798  }
799 }
800 
801 
802 void
803 GNERoute::toogleAttribute(SumoXMLAttr /*key*/, const bool /*value*/, const int /*previousParameters*/) {
804  // nothing to toogle
805 }
806 
807 
808 void
809 GNERoute::setMoveShape(const GNEMoveResult& /*moveResult*/) {
810  // routes cannot be moved
811 }
812 
813 
814 void
815 GNERoute::commitMoveShape(const GNEMoveResult& /*moveResult*/, GNEUndoList* /*undoList*/) {
816  // routes cannot be moved
817 }
818 
819 /****************************************************************************/
FXDEFMAP(GNERoute::GNERoutePopupMenu) GNERoutePopupMenuMap[]
@ MID_COPY_TYPED_NAME
Copy typed object name - popup entry.
Definition: GUIAppEnum.h:413
@ MID_OPEN_ADDITIONAL_DIALOG
open additional dialog (used in netedit)
Definition: GUIAppEnum.h:423
@ MID_COPY_NAME
Copy object name - popup entry.
Definition: GUIAppEnum.h:411
@ MID_GNE_ROUTE_APPLY_DISTANCE
apply distance
Definition: GUIAppEnum.h:1178
@ GLO_ROUTE
a route
#define RAD2DEG(x)
Definition: GeomHelper.h:36
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
long long int SUMOTime
Definition: SUMOTime.h:32
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ GNE_TAG_ROUTE_EMBEDDED
embedded route (used in NETEDIT)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_DEPARTEDGE
@ SUMO_ATTR_ARRIVALEDGE
@ SUMO_ATTR_ARRIVALPOS
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_EDGES
the edges of a route
@ GNE_ATTR_PARAMETERS
parameters "key1=value1|key2=value2|...|keyN=valueN"
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_REPEAT
@ SUMO_ATTR_CYCLETIME
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:215
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:507
static void pushName(unsigned int name)
push Name
Definition: GLHelper.cpp:132
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:123
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:231
static void popName()
pop Name
Definition: GLHelper.cpp:141
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:114
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
friend class GNEChange_Attribute
declare friend class
static T parse(const std::string &string)
parses a value of type T from string (used for basic types: int, double, bool, etc....
const std::string & getTagStr() const
get tag assigned to this object in string format
void unselectAttributeCarrier(const bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
FXIcon * getIcon() const
get FXIcon associated to this AC
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
GNENet * myNet
pointer to net
static std::string parseIDs(const std::vector< T > &ACs)
parses a list of specific Attribute Carriers into a string of IDs
void selectAttributeCarrier(const bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
const GNETagProperties & myTagProperty
reference to tagProperty associated with this attribute carrier
An Element which don't belongs to GNENet but has influency in the simulation.
void replaceDemandParentEdges(const std::string &value)
replace demand parent edges
virtual GNELane * getLastPathLane() const =0
get last path lane
std::vector< const GNEDemandElement * > getSortedStops(const std::vector< GNEEdge * > &edges) const
get sorted stops
virtual GNELane * getFirstPathLane() const =0
get first path lane
Problem
enum class for demandElement problems
bool isValidDemandElementID(const std::string &newID) const
check if a new demand element ID is valid
const std::string & getID() const
get ID
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:82
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
std::string getNewListOfParents(const GNENetworkElement *currentElement, const GNENetworkElement *newNextElement) const
if use edge/parent lanes as a list of consecutive elements, obtain a list of IDs of elements after in...
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
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:131
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition: GNELane.cpp:838
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition: GNELane.cpp:238
const GUIGeometry & getLaneGeometry() const
Definition: GNELane.cpp:125
move operation
move result
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:131
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1964
const std::string & getID() const
get ID
bool drawPathGeometry(const bool dottedElement, const GNELane *lane, SumoXMLTag tag)
check if path element geometry must be drawn in the given lane
PathElement()
default constructor
virtual Position getPathElementArrivalPos() const =0
get path element arrival position
PathElement * getPathElement() const
get path element
Segment * getNextSegment() const
get next segment
bool isLastSegment() const
check if segment is the last path's segment
bool isFirstSegment() const
check if segment is the first path's segment
PathDraw * getPathDraw()
obtain instance of PathDraw
void calculateConsecutivePathEdges(PathElement *pathElement, SUMOVehicleClass vClass, const std::vector< GNEEdge * > edges)
calculate consecutive path edges
bool isPathValid(const PathElement *pathElement) const
check if path element is valid
void calculateConsecutivePathLanes(PathElement *pathElement, const std::vector< GNELane * > lanes)
calculate consecutive path lanes
class used in GUIGLObjectPopupMenu for routes
Definition: GNERoute.h:44
~GNERoutePopupMenu()
Destructor.
Definition: GNERoute.cpp:52
long onCmdApplyDistance(FXObject *, FXSelector, void *)
Called to modify edge distance values along the route.
Definition: GNERoute.cpp:56
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition: GNERoute.cpp:713
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children)
Definition: GNERoute.cpp:260
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration asociated with this GLObject
Definition: GNERoute.cpp:311
GNELane * getLastPathLane() const
get last path lane
Definition: GNERoute.cpp:540
Position getPositionInView() const
Returns position of additional in view.
Definition: GNERoute.cpp:299
SUMOVehicleClass myVClass
SUMOVehicleClass (Only used for drawing)
Definition: GNERoute.h:292
std::string getParentName() const
Returns the name of the parent object.
Definition: GNERoute.cpp:305
SUMOTime myCycleTime
cycleTime
Definition: GNERoute.h:289
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNERoute.cpp:707
std::string getAttribute(SumoXMLAttr key) const
inherited from GNEAttributeCarrier
Definition: GNERoute.cpp:550
Position getAttributePosition(SumoXMLAttr key) const
Definition: GNERoute.cpp:590
void updateGeometry()
update pre-computed geometry information
Definition: GNERoute.cpp:286
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNERoute.cpp:154
const std::map< std::string, std::string > & getACParametersMap() const
get parameters map
Definition: GNERoute.cpp:719
void splitEdgeGeometry(const double splitPosition, const GNENetworkElement *originalElement, const GNENetworkElement *newElement, GNEUndoList *undoList)
split geometry
Definition: GNERoute.cpp:333
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
Definition: GNERoute.cpp:809
void enableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
Definition: GNERoute.cpp:689
GNELane * getFirstPathLane() const
get first path lane
Definition: GNERoute.cpp:530
double getAttributeDouble(SumoXMLAttr key) const
Definition: GNERoute.cpp:577
GNEMoveOperation * getMoveOperation()
get move operation
Definition: GNERoute.cpp:148
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
Definition: GNERoute.cpp:815
SUMOVehicleClass getVClass() const
Definition: GNERoute.cpp:266
void disableAttribute(SumoXMLAttr key, GNEUndoList *undoList)
Definition: GNERoute.cpp:695
GNERoute(SumoXMLTag tag, GNENet *net)
default constructor
Definition: GNERoute.cpp:73
void drawPartialGL(const GUIVisualizationSettings &s, const GNELane *lane, const GNEPathManager::Segment *segment, const double offsetFront) const
Draws partial object.
Definition: GNERoute.cpp:385
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNERoute.cpp:317
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
Definition: GNERoute.cpp:653
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNERoute.cpp:344
static std::string isRouteValid(const std::vector< GNEEdge * > &edges)
check if a route is valid
Definition: GNERoute.cpp:725
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform demand element changes
Definition: GNERoute.cpp:603
int myRepeat
repeat
Definition: GNERoute.h:286
void toogleAttribute(SumoXMLAttr key, const bool value, const int previousParameters)
method for enable or disable the attribute and nothing else (used in GNEChange_EnableAttribute)
Definition: GNERoute.cpp:803
void computePathElement()
compute pathElement
Definition: GNERoute.cpp:350
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
Definition: GNERoute.cpp:242
RGBColor myColor
route color
Definition: GNERoute.h:280
void writeDemandElement(OutputDevice &device) const
writte demand element element into a xml file
Definition: GNERoute.cpp:181
~GNERoute()
destructor
Definition: GNERoute.cpp:144
bool isAttributeEnabled(SumoXMLAttr key) const
Definition: GNERoute.cpp:701
const RGBColor & getColor() const
get color
Definition: GNERoute.cpp:272
Problem isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
Definition: GNERoute.cpp:212
bool myCustomColor
flag for enable/disable color
Definition: GNERoute.h:283
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool hasDialog() const
return true if tag correspond to an element that can be edited using a dialog
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void changeAttribute(GNEChange_Attribute *change)
special method for change attributes, avoid empty changes, always execute
const GNEViewNetHelper::DataViewOptions & getDataViewOptions() const
get data view options
Definition: GNEViewNet.cpp:537
const GNEAttributeCarrier * getFrontAttributeCarrier() const
get front attributeCarrier
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:525
void drawTranslateFrontAttributeCarrier(const GNEAttributeCarrier *AC, double typeOrLayer, const double extraOffset=0)
draw front attributeCarrier
GNEUndoList * getUndoList() const
get the undoList object
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
Definition: GNEViewNet.cpp:432
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:531
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel)
build menu command
Definition: GUIDesigns.cpp:42
static void drawDottedContourShape(const DottedContourType type, const GUIVisualizationSettings &s, const PositionVector &shape, const double width, const double exaggeration, const bool drawFirstExtrem, const bool drawLastExtrem, const double lineWidth=-1)
draw dotted contour for the given shape (used by additionals)
The popup menu of a globject.
static void drawGeometry(const GUIVisualizationSettings &s, const Position &mousePos, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
const PositionVector & getShape() const
The shape of the additional element.
void updateGeometry(const PositionVector &shape)
update entire geometry
Definition: GUIGeometry.cpp:58
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used,...
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GUIGlID getGlID() const
Returns the numerical id of the object.
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0, bool forceShow=false) const
draw name of item
Position getPositionInformation() const
Returns the cursor's x/y position within the network.
Stores the information about how to visualize structures.
GUIVisualizationTextSettings addName
GUIVisualizationSizeSettings vehicleSize
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
GUIVisualizationWidthSettings widthSettings
width settings
GUIVisualizationColorSettings colorSettings
color settings
double scale
information about a lane's width (temporary, used for a single view)
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
An upper class for objects with additional parameters.
Definition: Parameterised.h:41
static bool areParametersValid(const std::string &value, bool report=false, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
void setParametersStr(const std::string &paramsString, const std::string kvsep="=", const std::string sep="|")
set the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN"
void writeParams(OutputDevice &device) const
write Params in the given outputdevice
std::string getParametersStr(const std::string kvsep="=", const std::string sep="|") const
Returns the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN".
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:293
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:252
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
Definition: Position.h:262
static const RGBColor YELLOW
Definition: RGBColor.h:188
static const RGBColor INVISIBLE
Definition: RGBColor.h:195
static const RGBColor RED
named colors
Definition: RGBColor.h:185
bool showDemandElements() const
check if show demand elements checkbox is enabled
bool showNonInspectedDemandElements(const GNEDemandElement *demandElement) const
check if non inspected element has to be hidden
static void drawLockIcon(const GNEAttributeCarrier *AC, GUIGlObjectType type, const Position viewPosition, const double exaggeration, const double size=0.5, const double offsetx=0, const double offsety=0)
draw lock icon
bool showDemandElements() const
check if show demand elements checkbox is enabled
RGBColor selectedRouteColor
route selection color (used for routes and vehicle stops)
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
static const double embeddedRouteWidth
width for embeddedroutes
static const double routeWidth
width for routes